Improvements to the installation UI

- No longer show irrelevant options to the user
- No longer require an additional button press to start installation
This commit is contained in:
topjohnwu 2020-08-24 04:04:52 -07:00
parent ccde8b73a2
commit e437ffdbae
8 changed files with 44 additions and 40 deletions

View File

@ -106,6 +106,10 @@ object Config : PreferenceModel, DBConfig {
else else
Value.DEFAULT_CHANNEL Value.DEFAULT_CHANNEL
@JvmStatic var keepVerity = false
@JvmStatic var keepEnc = false
@JvmStatic var recovery = false
var bootId by preference(Key.BOOT_ID, "") var bootId by preference(Key.BOOT_ID, "")
var askedHome by preference(Key.ASKED_HOME, false) var askedHome by preference(Key.ASKED_HOME, false)

View File

@ -26,14 +26,10 @@ object Info {
var remote = UpdateInfo() var remote = UpdateInfo()
// Toggle-able options // Device state
@JvmStatic var keepVerity = false
@JvmStatic var keepEnc = false
@JvmStatic var recovery = false
// Immutable device state
@JvmStatic var isSAR = false @JvmStatic var isSAR = false
@JvmStatic var isAB = false @JvmStatic var isAB = false
@JvmStatic var isFBE = false
@JvmStatic var ramdisk = false @JvmStatic var ramdisk = false
@JvmStatic var hasGMS = true @JvmStatic var hasGMS = true

View File

@ -9,15 +9,15 @@ import androidx.annotation.WorkerThread
import androidx.core.os.postDelayed import androidx.core.os.postDelayed
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.data.network.GithubRawServices import com.topjohnwu.magisk.data.network.GithubRawServices
import com.topjohnwu.magisk.di.Protected import com.topjohnwu.magisk.di.Protected
import com.topjohnwu.magisk.events.dialog.EnvFixDialog import com.topjohnwu.magisk.events.dialog.EnvFixDialog
import com.topjohnwu.magisk.ktx.reboot import com.topjohnwu.magisk.ktx.reboot
import com.topjohnwu.magisk.ktx.withStreams import com.topjohnwu.magisk.ktx.withStreams
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.signing.SignBoot import com.topjohnwu.signing.SignBoot
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@ -272,8 +272,8 @@ abstract class MagiskInstallImpl : KoinComponent {
return false return false
} }
if (!("KEEPFORCEENCRYPT=${Info.keepEnc} KEEPVERITY=${Info.keepVerity} " + if (!("KEEPFORCEENCRYPT=${Config.keepEnc} KEEPVERITY=${Config.keepVerity} " +
"RECOVERYMODE=${Info.recovery} sh update-binary " + "RECOVERYMODE=${Config.recovery} sh update-binary " +
"sh boot_patch.sh $srcBoot").sh().isSuccess) { "sh boot_patch.sh $srcBoot").sh().isSuccess) {
return false return false
} }

View File

@ -1,13 +1,16 @@
package com.topjohnwu.magisk.core.utils package com.topjohnwu.magisk.core.utils
import android.content.Context import android.content.Context
import android.os.Build
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.ktx.rawResource import com.topjohnwu.magisk.ktx.rawResource
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.io.SuFile
class RootInit : Shell.Initializer() { class RootInit : Shell.Initializer() {
@ -39,13 +42,19 @@ class RootInit : Shell.Initializer() {
fun getBool(name: String) = getvar(name).toBoolean() fun getBool(name: String) = getvar(name).toBoolean()
Const.MAGISKTMP = getvar("MAGISKTMP") Const.MAGISKTMP = getvar("MAGISKTMP")
Info.keepVerity = getBool("KEEPVERITY")
Info.keepEnc = getBool("KEEPFORCEENCRYPT")
Info.isSAR = getBool("SYSTEM_ROOT") Info.isSAR = getBool("SYSTEM_ROOT")
Info.ramdisk = getBool("RAMDISKEXIST") Info.ramdisk = getBool("RAMDISKEXIST")
Info.recovery = getBool("RECOVERYMODE")
Info.isAB = getBool("ISAB") Info.isAB = getBool("ISAB")
// FBE does not exist pre 7.0
if (Build.VERSION.SDK_INT >= 24)
Info.isFBE = SuFile("/data/unencrypted").exists()
// Default presets
Config.recovery = getBool("RECOVERYMODE")
Config.keepVerity = getBool("KEEPVERITY")
Config.keepEnc = getBool("KEEPFORCEENCRYPT")
return true return true
} }
} }

View File

@ -1,13 +1,13 @@
package com.topjohnwu.magisk.ktx package com.topjohnwu.magisk.ktx
import android.content.Context import android.content.Context
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
fun reboot(reason: String = if (Info.recovery) "recovery" else "") { fun reboot(reason: String = if (Config.recovery) "recovery" else "") {
Shell.su("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit() Shell.su("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit()
} }

View File

@ -7,6 +7,7 @@ import com.topjohnwu.magisk.arch.BaseUIFragment
import com.topjohnwu.magisk.core.download.BaseDownloadService import com.topjohnwu.magisk.core.download.BaseDownloadService
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.events.RequestFileEvent import com.topjohnwu.magisk.events.RequestFileEvent
import com.topjohnwu.magisk.ktx.coroutineScope
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() { class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Binding>() {
@ -24,7 +25,7 @@ class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Bindi
requireActivity().setTitle(R.string.install) requireActivity().setTitle(R.string.install)
// Allow markwon to run in viewmodel scope // Allow markwon to run in viewmodel scope
binding.releaseNotes.tag = viewModel.viewModelScope binding.releaseNotes.coroutineScope = viewModel.viewModelScope
BaseDownloadService.observeProgress(this, viewModel::onProgressUpdate) BaseDownloadService.observeProgress(this, viewModel::onProgressUpdate)
} }

View File

@ -25,11 +25,11 @@ class InstallViewModel(
stringRepo: StringRepository stringRepo: StringRepository
) : BaseViewModel(State.LOADED) { ) : BaseViewModel(State.LOADED) {
val isRooted get() = Shell.rootAccess() val isRooted = Shell.rootAccess()
val isAB get() = Info.isAB val skipOptions = Info.ramdisk && Info.isFBE && Info.isSAR
@get:Bindable @get:Bindable
var step = 0 var step = if (skipOptions) 1 else 0
set(value) = set(value, field, { field = it }, BR.step) set(value) = set(value, field, { field = it }, BR.step)
@get:Bindable @get:Bindable

View File

@ -6,6 +6,7 @@
<data> <data>
<import type="com.topjohnwu.magisk.core.Info" /> <import type="com.topjohnwu.magisk.core.Info" />
<import type="com.topjohnwu.magisk.core.Config" />
<variable <variable
name="viewModel" name="viewModel"
@ -35,6 +36,7 @@
android:paddingTop="@dimen/l1"> android:paddingTop="@dimen/l1">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
gone="@{viewModel.skipOptions}"
style="@style/WidgetFoundation.Card.Variant" style="@style/WidgetFoundation.Card.Variant"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -92,31 +94,34 @@
tools:layout_gravity="center"> tools:layout_gravity="center">
<CheckBox <CheckBox
gone="@{Info.isSAR}"
style="@style/WidgetFoundation.Checkbox" style="@style/WidgetFoundation.Checkbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical" android:layout_gravity="start|center_vertical"
android:checked="@={Info.keepVerity}" android:checked="@={Config.keepVerity}"
android:gravity="center" android:gravity="center"
android:text="@string/keep_dm_verity" android:text="@string/keep_dm_verity"
tools:checked="true" /> tools:checked="true" />
<CheckBox <CheckBox
gone="@{Info.isFBE}"
style="@style/WidgetFoundation.Checkbox" style="@style/WidgetFoundation.Checkbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical" android:layout_gravity="start|center_vertical"
android:checked="@={Info.keepEnc}" android:checked="@={Config.keepEnc}"
android:gravity="center" android:gravity="center"
android:text="@string/keep_force_encryption" android:text="@string/keep_force_encryption"
app:tint="?colorPrimary" /> app:tint="?colorPrimary" />
<CheckBox <CheckBox
gone="@{Info.ramdisk}"
style="@style/WidgetFoundation.Checkbox" style="@style/WidgetFoundation.Checkbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical" android:layout_gravity="start|center_vertical"
android:checked="@={Info.recovery}" android:checked="@={Config.recovery}"
android:gravity="center" android:gravity="center"
android:text="@string/recovery_mode" android:text="@string/recovery_mode"
app:tint="?colorPrimary" /> app:tint="?colorPrimary" />
@ -168,8 +173,10 @@
isEnabled="@{viewModel.method == @id/method_patch ? viewModel.data != null : viewModel.method != -1}" isEnabled="@{viewModel.method == @id/method_patch ? viewModel.data != null : viewModel.method != -1}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.step(2)}" android:onClick="@{() -> viewModel.install()}"
android:text="@string/install_next" /> android:text="@string/install_start"
app:icon="@drawable/ic_forth_md2"
app:iconGravity="textEnd"/>
</LinearLayout> </LinearLayout>
@ -211,7 +218,7 @@
<RadioButton <RadioButton
android:id="@+id/method_inactive_slot" android:id="@+id/method_inactive_slot"
style="@style/WidgetFoundation.RadioButton" style="@style/WidgetFoundation.RadioButton"
gone="@{!viewModel.isRooted || !viewModel.isAB}" gone="@{!viewModel.isRooted || !Info.isAB}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/install_inactive_slot" /> android:text="@string/install_inactive_slot" />
@ -224,7 +231,6 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
style="@style/WidgetFoundation.Card.Variant" style="@style/WidgetFoundation.Card.Variant"
gone="@{viewModel.step != 0}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l1" android:layout_marginTop="@dimen/l1"
@ -243,18 +249,6 @@
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<Button
style="@style/WidgetFoundation.Button.Text"
gone="@{viewModel.step != 2}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_margin="@dimen/l1"
android:onClick="@{() -> viewModel.install()}"
android:text="@string/install_start"
app:icon="@drawable/ic_forth_md2"
app:iconGravity="textEnd" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout