@@ -89,8 +89,8 @@ private fun Start(vm: WizardState) {
8989
9090// shared across DroidBootFlow, UpdateDroidBootFlow, FixDroidBootFlow
9191@Composable
92- fun LoadDroidBootJson (vm : WizardState , content : @Composable () -> Unit ) {
93- var loading by remember { mutableStateOf(! vm.deviceInfo.isBooted(vm.logic) || vm.deviceInfo.postInstallScript) }
92+ fun LoadDroidBootJson (vm : WizardState , update : Boolean , content : @Composable () -> Unit ) {
93+ var loading by remember { mutableStateOf(! vm.deviceInfo.isBooted(vm.logic) || vm.deviceInfo.postInstallScript || update ) }
9494 var error by remember { mutableStateOf(false ) }
9595 LaunchedEffect (Unit ) {
9696 if (! loading) return @LaunchedEffect
@@ -101,14 +101,16 @@ fun LoadDroidBootJson(vm: WizardState, content: @Composable () -> Unit) {
101101 val json = JSONTokener (jsonText).nextValue() as JSONObject
102102 if (BuildConfig .VERSION_CODE < json.getInt(" minAppVersion" ))
103103 throw IllegalStateException (" please upgrade app" )
104- if (! vm.deviceInfo.isBooted(vm.logic)) {
104+ if (( ! vm.deviceInfo.isBooted(vm.logic) || update) && json.has( " bootloader " )) {
105105 val bl = json.getJSONObject(" bootloader" )
106- val url = bl.getString(" url" )
107- val sha = bl.getStringOrNull(" sha256" )
108- vm.inetAvailable[" droidboot" ] = WizardState .Downloadable (
109- url, sha, vm.activity.getString(R .string.droidboot_online)
110- )
111- vm.idNeeded.add(" droidboot" )
106+ if (! bl.optBoolean(" updateOnly" , false ) || update) {
107+ val url = bl.getString(" url" )
108+ val sha = bl.getStringOrNull(" sha256" )
109+ vm.inetAvailable[" droidboot" ] = WizardState .Downloadable (
110+ url, sha, vm.activity.getString(R .string.droidboot_online)
111+ )
112+ vm.idNeeded.add(" droidboot" )
113+ }
112114 }
113115 if (vm.deviceInfo.postInstallScript) {
114116 val i = json.getJSONObject(" installScript" )
@@ -140,7 +142,11 @@ fun LoadDroidBootJson(vm: WizardState, content: @Composable () -> Unit) {
140142
141143@Composable
142144private fun Input (d : DroidBootFlowDataHolder ) {
143- LoadDroidBootJson (d.vm) {
145+ LoadDroidBootJson (d.vm, false ) {
146+ if (! d.vm.deviceInfo.isBooted(d.vm.logic) && ! d.vm.idNeeded.contains(" droidboot" )) {
147+ Text (stringResource(R .string.install_bl_first))
148+ return @LoadDroidBootJson
149+ }
144150 Column (
145151 horizontalAlignment = Alignment .CenterHorizontally ,
146152 verticalArrangement = Arrangement .Center ,
@@ -241,7 +247,43 @@ private fun Flash(d: DroidBootFlowDataHolder) {
241247 return @WizardTerminalWork
242248 }
243249 } else {
244- // TODO provision for sdless
250+ if (! SuFile .open(vm.logic.abmSdLessBootset.toURI()).exists()) {
251+ if (! SuFile .open(vm.logic.abmSdLessBootset.toURI()).mkdir()) {
252+ terminal.add(vm.activity.getString(R .string.term_cant_create_bootset))
253+ return @WizardTerminalWork
254+ }
255+ }
256+ val bytes = 4L * 1024L * 1024L * 1024L // 4 GB for now
257+ if (! Shell .cmd(" fallocate -l $bytes " +
258+ vm.logic.abmSdLessBootsetImg.absolutePath).to(terminal).exec().isSuccess) {
259+ terminal.add(vm.activity.getString(R .string.term_failed_fallocate))
260+ return @WizardTerminalWork
261+ }
262+ if (! Shell .cmd(" uncrypt ${vm.logic.abmSdLessBootsetImg.absolutePath} " +
263+ vm.logic.metadataMap.absolutePath).to(terminal).exec().isSuccess) {
264+ terminal.add(vm.activity.getString(R .string.term_failed_uncrypt))
265+ return @WizardTerminalWork
266+ }
267+ val tempFile = File (vm.logic.cacheDir, " ${System .currentTimeMillis()} .txt" )
268+ if (! Shell .cmd(File (vm.logic.toolkitDir, " droidboot_map_to_dm" )
269+ .absolutePath + " " + vm.logic.metadataMap.absolutePath + " " + tempFile.absolutePath
270+ ).to(terminal).exec().isSuccess) {
271+ terminal.add(vm.activity.getString(R .string.term_failed_mapconv))
272+ return @WizardTerminalWork
273+ }
274+ if (SuFile .open(vm.logic.dmPath.toURI()).exists()) {
275+ if (! Shell .cmd(" dmsetup remove --retry ${vm.logic.dmName} " )
276+ .to(terminal).exec().isSuccess
277+ ) {
278+ terminal.add(vm.activity.getString(R .string.term_failed_unmap))
279+ return @WizardTerminalWork
280+ }
281+ }
282+ if (! Shell .cmd(" dmsetup create ${vm.logic.dmName} ${tempFile.absolutePath} " )
283+ .to(terminal).exec().isSuccess) {
284+ terminal.add(vm.activity.getString(R .string.term_failed_map))
285+ return @WizardTerminalWork
286+ }
245287 }
246288
247289 if (! vm.logic.mountBootset(vm.deviceInfo)) {
@@ -256,14 +298,14 @@ private fun Flash(d: DroidBootFlowDataHolder) {
256298 if (! SuFile .open(vm.logic.abmDb.toURI()).exists()) {
257299 if (! SuFile .open(vm.logic.abmDb.toURI()).mkdir()) {
258300 terminal.add(vm.activity.getString(R .string.term_failed_create_db_dir))
259- vm.logic.unmountBootset()
301+ vm.logic.unmountBootset(vm.deviceInfo )
260302 return @WizardTerminalWork
261303 }
262304 }
263305 if (! SuFile .open(vm.logic.abmEntries.toURI()).exists()) {
264306 if (! SuFile .open(vm.logic.abmEntries.toURI()).mkdir()) {
265307 terminal.add(vm.activity.getString(R .string.term_failed_create_entries_dir))
266- vm.logic.unmountBootset()
308+ vm.logic.unmountBootset(vm.deviceInfo )
267309 return @WizardTerminalWork
268310 }
269311 }
@@ -314,7 +356,7 @@ private fun Flash(d: DroidBootFlowDataHolder) {
314356 tmpFile.delete()
315357 }
316358 terminal.add(vm.activity.getString(R .string.term_success))
317- vm.logic.unmountBootset()
359+ vm.logic.unmountBootset(vm.deviceInfo )
318360 // TODO prompt user to reboot?
319361 }
320362}
0 commit comments