@@ -54,8 +54,7 @@ class DroidBootFlow : WizardFlow() {
5454 Start (vm)
5555 }, WizardPage (" input" ,
5656 NavButton (vm.activity.getString(R .string.prev)) { it.navigate(" start" ) },
57- NavButton (vm.activity.getString(R .string.next)) { it.navigate(if (vm.deviceInfo.postInstallScript || ! booted)
58- " dload" else " flash" ) }
57+ NavButton (" " ) {}
5958 ) {
6059 Input (vm)
6160 }, WizardPage (" dload" ,
@@ -92,9 +91,11 @@ private fun Start(vm: WizardActivityState) {
9291 }
9392}
9493
94+ // shared across DroidBootFlow, UpdateDroidBootFlow, FixDroidBootFlow
9595@Composable
96- private fun Input (vm : WizardActivityState ) {
96+ fun LoadDroidBootJson (vm : WizardActivityState , content : @Composable () -> Unit ) {
9797 var loading by remember { mutableStateOf(! vm.deviceInfo.isBooted(vm.logic) || vm.deviceInfo.postInstallScript) }
98+ var error by remember { mutableStateOf(false ) }
9899 LaunchedEffect (Unit ) {
99100 if (! loading) return @LaunchedEffect
100101 CoroutineScope (Dispatchers .IO ).launch {
@@ -107,7 +108,7 @@ private fun Input(vm: WizardActivityState) {
107108 if (! vm.deviceInfo.isBooted(vm.logic)) {
108109 val bl = json.getJSONObject(" bootloader" )
109110 val url = bl.getString(" url" )
110- val sha = if ( bl.has (" sha256" )) bl.getString( " sha256 " ) else null
111+ val sha = bl.optString (" sha256" )
111112 vm.inetAvailable[" droidboot" ] = WizardActivityState .Downloadable (
112113 url, sha, vm.activity.getString(R .string.droidboot_online)
113114 )
@@ -116,7 +117,7 @@ private fun Input(vm: WizardActivityState) {
116117 if (vm.deviceInfo.postInstallScript) {
117118 val i = json.getJSONObject(" installScript" )
118119 val url = i.getString(" url" )
119- val sha = if (i.has (" sha256" )) i.getString( " sha256 " ) else null
120+ val sha = i.optString (" sha256" )
120121 vm.inetAvailable[" install" ] = WizardActivityState .Downloadable (
121122 url, sha, vm.activity.getString(R .string.installer_sh)
122123 )
@@ -128,156 +129,59 @@ private fun Input(vm: WizardActivityState) {
128129 Toast .makeText(vm.activity, R .string.dl_error, Toast .LENGTH_LONG ).show()
129130 }
130131 Log .e(" ABM droidboot json" , Log .getStackTraceString(e))
132+ error = true
131133 }
132134 }
133135 }
134136 if (loading) {
135- LoadingCircle (stringResource(R .string.loading), modifier = Modifier .fillMaxSize())
136- return
137- }
138- Column (horizontalAlignment = Alignment .CenterHorizontally , verticalArrangement = Arrangement .Center ,
139- modifier = Modifier .fillMaxSize()
140- ) {
141- LaunchedEffect (Unit ) { // TODO can't I do this better?
142- if (vm.texts.isBlank())
143- vm.texts = vm.activity.getString(R .string.android)
144- }
145- val e = vm.texts.isBlank() || ! vm.texts.matches(Regex (" [\\ dA-Za-z]+" ))
146-
147- Text (stringResource(R .string.enter_name_for_current), textAlign = TextAlign .Center , modifier = Modifier .padding(vertical = 5 .dp))
148- TextField (
149- value = vm.texts,
150- onValueChange = {
151- vm.texts = it
152- },
153- label = { Text (stringResource(R .string.os_name)) },
154- isError = e
155- )
156- if (e) {
157- Text (stringResource(R .string.invalid_in), color = MaterialTheme .colorScheme.error)
137+ if (error) {
138+ Text (stringResource(R .string.dl_error))
158139 } else {
159- Text (" " ) // Budget spacer
160- }
161- LaunchedEffect (e) {
162- if (e) {
163- vm.nextText = " "
164- vm.onNext = {}
165- } else {
166- vm.nextText = vm.activity.getString(R .string.next)
167- vm.onNext = { it.navigate(" select" ) }
168- }
140+ LoadingCircle (stringResource(R .string.loading), modifier = Modifier .fillMaxSize())
169141 }
170- }
142+ } else content()
171143}
172144
173- // shared across DroidBootFlow, UpdateDroidBootFlow, FixDroidBootFlow
174145@Composable
175- fun SelectDroidBoot (vm : WizardActivityState ) {
176- var nextButtonAvailable by remember { mutableStateOf(false ) }
177-
178- Column (horizontalAlignment = Alignment .CenterHorizontally , verticalArrangement = Arrangement .Center ,
179- modifier = Modifier .fillMaxSize()
180- ) {
181- Icon (
182- painterResource(R .drawable.ic_droidbooticon),
183- stringResource(R .string.droidboot_icon_content_desc),
184- Modifier .defaultMinSize(32 .dp, 32 .dp)
185- )
186-
187- if (nextButtonAvailable) {
188- Text (stringResource(id = R .string.successfully_selected))
189- } else {
190- // Text(stringResource(R.string.choose_droidboot_online))
191- Button (onClick = {
192- vm.activity.chooseFile(" */*" ) {
193- vm.flashes[" DroidBootFlashType" ] = Pair (it, null )
194- nextButtonAvailable = true
195- vm.nextText = vm.activity.getString(R .string.next)
196- vm.onNext = { n -> n.navigate(" flash" ) }
197- }
198- }) {
199- Text (stringResource(id = R .string.choose_file))
200- }
201- val ctx = LocalContext .current
202- Button (onClick = {
203- CoroutineScope (Dispatchers .IO ).launch {
204- try {
205- val jsonText =
206- URL (" https://raw.githubusercontent.com/Android-Boot-Manager/ABM-json/master/devices/" + vm.codename + " .json" ).readText()
207- val json = JSONTokener (jsonText).nextValue() as JSONObject
208- if (BuildConfig .VERSION_CODE < json.getInt(" minAppVersion" ))
209- throw IllegalStateException (" please upgrade app" )
210- val bl = json.getJSONObject(" bootloader" )
211- val url = bl.getString(" url" )
212- val sha = if (bl.has(" sha256" )) bl.getString(" sha256" ) else null
213- vm.flashes[" DroidBootFlashType" ] = Pair (Uri .parse(url), sha)
214- nextButtonAvailable = true
215- vm.nextText = vm.activity.getString(R .string.next)
216- vm.onNext = { n -> n.navigate(" flash" ) }
217- } catch (e: Exception ) {
218- Handler (Looper .getMainLooper()).post {
219- Toast .makeText(ctx, R .string.dl_error, Toast .LENGTH_LONG ).show()
220- }
221- Log .e(" ABM droidboot json" , Log .getStackTraceString(e))
222- }
223- }
224- }) {
225- Text (stringResource(id = R .string.download))
146+ private fun Input (vm : WizardActivityState ) {
147+ LoadDroidBootJson (vm) {
148+ Column (
149+ horizontalAlignment = Alignment .CenterHorizontally ,
150+ verticalArrangement = Arrangement .Center ,
151+ modifier = Modifier .fillMaxSize()
152+ ) {
153+ LaunchedEffect (Unit ) { // TODO can't I do this better?
154+ if (vm.texts.isBlank())
155+ vm.texts = vm.activity.getString(R .string.android)
226156 }
227- }
228- }
229- }
230-
231- // shared across DroidBootFlow, UpdateDroidBootFlow, FixDroidBootFlow
232- @Composable
233- fun SelectInstallSh (vm : WizardActivityState , update : Boolean = false) {
234- var nextButtonAvailable by remember { mutableStateOf(false ) }
235- val flashType = " InstallShFlashType"
157+ val e = vm.texts.isBlank() || ! vm.texts.matches(Regex (" [\\ dA-Za-z]+" ))
236158
237- Column (horizontalAlignment = Alignment . CenterHorizontally , verticalArrangement = Arrangement . Center ,
238- modifier = Modifier .fillMaxSize()
239- ) {
240- if (nextButtonAvailable) {
241- Text (stringResource(id = R .string.successfully_selected) )
242- } else {
243- // Text(stringResource(R.string.choose_install_s_online))
244- Button (onClick = {
245- vm.activity.chooseFile( " */* " ) {
246- vm.flashes[flashType] = Pair (it, null )
247- nextButtonAvailable = true
248- vm.nextText = vm.activity.getString( R .string.next)
249- vm.onNext = { n -> n.navigate(
250- if (! vm.deviceInfo.isBooted(vm.logic) || update) " select " else " flash " ) }
251- }
252- }) {
253- Text (stringResource(id = R .string.choose_file))
159+ Text (
160+ stringResource( R .string.enter_name_for_current),
161+ textAlign = TextAlign . Center ,
162+ modifier = Modifier .padding(vertical = 5 .dp)
163+ )
164+ TextField (
165+ value = vm.texts,
166+ onValueChange = {
167+ vm.texts = it
168+ },
169+ label = { Text (stringResource( R .string.os_name)) },
170+ isError = e
171+ )
172+ if (e) {
173+ Text (stringResource( R .string.invalid_in), color = MaterialTheme .colorScheme.error)
174+ } else {
175+ Text (" " ) // Budget spacer
254176 }
255- val ctx = LocalContext .current
256- Button (onClick = {
257- CoroutineScope (Dispatchers .IO ).launch {
258- try {
259- val jsonText =
260- URL (" https://raw.githubusercontent.com/Android-Boot-Manager/ABM-json/master/devices/" + vm.codename + " .json" ).readText()
261- val json = JSONTokener (jsonText).nextValue() as JSONObject
262- if (BuildConfig .VERSION_CODE < json.getInt(" minAppVersion" ))
263- throw IllegalStateException (" please upgrade app" )
264- val i = json.getJSONObject(" installScript" )
265- val url = i.getString(" url" )
266- val sha = if (i.has(" sha256" )) i.getString(" sha256" ) else null
267- vm.flashes[flashType] = Pair (Uri .parse(url), sha)
268- nextButtonAvailable = true
269- vm.nextText = vm.activity.getString(R .string.next)
270- vm.onNext = { n -> n.navigate(
271- if (! vm.deviceInfo.isBooted(vm.logic) || update) " select" else " flash" ) }
272- } catch (e: Exception ) {
273- Handler (Looper .getMainLooper()).post {
274- Toast .makeText(ctx, R .string.dl_error, Toast .LENGTH_LONG ).show()
275- }
276- Log .e(" ABM install json" , Log .getStackTraceString(e))
277- }
177+ LaunchedEffect (e) {
178+ if (e) {
179+ vm.nextText = " "
180+ vm.onNext = {}
181+ } else {
182+ vm.nextText = vm.activity.getString(R .string.next)
183+ vm.onNext = { it.navigate(if (vm.idNeeded.isNotEmpty()) " dload" else " flash" ) }
278184 }
279- }) {
280- Text (stringResource(id = R .string.download))
281185 }
282186 }
283187 }
@@ -372,7 +276,7 @@ private fun Flash(vm: WizardActivityState) {
372276 }
373277 val tmpFile = if (vm.deviceInfo.postInstallScript) {
374278 val tmpFile = createTempFileSu(" abm" , " .sh" , vm.logic.rootTmpDir)
375- vm.copyPriv(vm.flashStream( " InstallShFlashType " ), tmpFile)
279+ vm.copyPriv(vm.chosen[ " install " ] !! .openInputStream(vm ), tmpFile)
376280 tmpFile.setExecutable(true )
377281 tmpFile
378282 } else null
@@ -401,18 +305,12 @@ private fun Flash(vm: WizardActivityState) {
401305 terminal.add(vm.activity.getString(R .string.term_cant_write_bl))
402306 vm.copyPriv(SuFileInputStream .open(vm.deviceInfo.blBlock), backupLk)
403307 try {
404- vm.copyPriv(vm.flashStream(flashType ), File (vm.deviceInfo.blBlock))
308+ vm.copyPriv(vm.chosen[ " droidboot " ] !! .openInputStream(vm ), File (vm.deviceInfo.blBlock))
405309 } catch (e: IOException ) {
406310 terminal.add(vm.activity.getString(R .string.term_bl_failed))
407311 terminal.add(e.message ? : " (null)" )
408312 terminal.add(vm.activity.getString(R .string.term_consult_doc))
409313 return @Terminal
410- } catch (e: HashMismatchException ) {
411- terminal.add(e.message ? : " (null)" )
412- terminal.add(vm.activity.getString(R .string.restoring_backup))
413- vm.copyPriv(SuFileInputStream .open(backupLk), File (vm.deviceInfo.blBlock))
414- terminal.add(vm.activity.getString(R .string.term_consult_doc))
415- return @Terminal
416314 }
417315 }
418316 if (vm.deviceInfo.postInstallScript) {
0 commit comments