Updated the install flow

Now the binary is downloaded after user selects a method. It also shows download progress as the file's being downloaded
This commit is contained in:
Viktor De Pasquale 2019-10-25 19:13:54 +02:00
parent 8a2872afa4
commit 3cc5cb3123
13 changed files with 461 additions and 159 deletions

View File

@ -4,6 +4,7 @@ import com.topjohnwu.magisk.redesign.MainViewModel
import com.topjohnwu.magisk.redesign.flash.FlashViewModel import com.topjohnwu.magisk.redesign.flash.FlashViewModel
import com.topjohnwu.magisk.redesign.hide.HideViewModel import com.topjohnwu.magisk.redesign.hide.HideViewModel
import com.topjohnwu.magisk.redesign.home.HomeViewModel import com.topjohnwu.magisk.redesign.home.HomeViewModel
import com.topjohnwu.magisk.redesign.install.InstallViewModel
import com.topjohnwu.magisk.redesign.log.LogViewModel import com.topjohnwu.magisk.redesign.log.LogViewModel
import com.topjohnwu.magisk.redesign.module.ModuleViewModel import com.topjohnwu.magisk.redesign.module.ModuleViewModel
import com.topjohnwu.magisk.redesign.request.RequestViewModel import com.topjohnwu.magisk.redesign.request.RequestViewModel
@ -11,7 +12,6 @@ import com.topjohnwu.magisk.redesign.safetynet.SafetynetViewModel
import com.topjohnwu.magisk.redesign.settings.SettingsViewModel import com.topjohnwu.magisk.redesign.settings.SettingsViewModel
import com.topjohnwu.magisk.redesign.superuser.SuperuserViewModel import com.topjohnwu.magisk.redesign.superuser.SuperuserViewModel
import com.topjohnwu.magisk.redesign.theme.ThemeViewModel import com.topjohnwu.magisk.redesign.theme.ThemeViewModel
import com.topjohnwu.magisk.ui.install.InstallViewModel
import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module

View File

@ -128,6 +128,10 @@ abstract class RemoteFileService : NotificationService() {
fun send(progress: Float, subject: DownloadSubject) { fun send(progress: Float, subject: DownloadSubject) {
internalProgressBroadcast.postValue(progress to subject) internalProgressBroadcast.postValue(progress to subject)
} }
fun reset() {
internalProgressBroadcast.value = null
}
} }
} }

View File

@ -6,11 +6,11 @@ import android.os.Build
import com.topjohnwu.magisk.ClassMap import com.topjohnwu.magisk.ClassMap
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.redesign.install.InstallFragment
import com.topjohnwu.magisk.redesign.safetynet.SafetynetFragment import com.topjohnwu.magisk.redesign.safetynet.SafetynetFragment
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.ui.hide.MagiskHideFragment import com.topjohnwu.magisk.ui.hide.MagiskHideFragment
import com.topjohnwu.magisk.ui.home.HomeFragment import com.topjohnwu.magisk.ui.home.HomeFragment
import com.topjohnwu.magisk.ui.install.InstallFragment
import com.topjohnwu.magisk.ui.log.LogFragment import com.topjohnwu.magisk.ui.log.LogFragment
import com.topjohnwu.magisk.ui.module.ModulesFragment import com.topjohnwu.magisk.ui.module.ModulesFragment
import com.topjohnwu.magisk.ui.module.ReposFragment import com.topjohnwu.magisk.ui.module.ReposFragment

View File

@ -8,7 +8,9 @@ import com.topjohnwu.magisk.utils.KObservableField
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
abstract class CompatViewModel : BaseViewModel(), KoinComponent { abstract class CompatViewModel(
initialState: State = State.LOADING
) : BaseViewModel(initialState), KoinComponent {
val insets = KObservableField(Insets.NONE) val insets = KObservableField(Insets.NONE)

View File

@ -81,7 +81,7 @@ class HomeViewModel(
init { init {
RemoteFileService.progressBroadcast.observeForever { RemoteFileService.progressBroadcast.observeForever {
when (it.second) { when (it?.second) {
is Magisk.Download, is Magisk.Download,
is Magisk.Flash -> stateMagiskProgress.value = it.first.times(100f).roundToInt() is Magisk.Flash -> stateMagiskProgress.value = it.first.times(100f).roundToInt()
is Manager -> stateManagerProgress.value = it.first.times(100f).roundToInt() is Manager -> stateManagerProgress.value = it.first.times(100f).roundToInt()

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.ui.install package com.topjohnwu.magisk.redesign.install
import android.content.Intent import android.content.Intent
import android.graphics.Insets import android.graphics.Insets

View File

@ -1,9 +1,10 @@
package com.topjohnwu.magisk.ui.install package com.topjohnwu.magisk.redesign.install
import android.net.Uri import android.net.Uri
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
import com.topjohnwu.magisk.model.download.DownloadService import com.topjohnwu.magisk.model.download.DownloadService
import com.topjohnwu.magisk.model.download.RemoteFileService
import com.topjohnwu.magisk.model.entity.internal.Configuration import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.events.RequestFileEvent import com.topjohnwu.magisk.model.events.RequestFileEvent
@ -12,8 +13,9 @@ import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import org.koin.core.get import org.koin.core.get
import kotlin.math.roundToInt
class InstallViewModel : CompatViewModel() { class InstallViewModel : CompatViewModel(State.LOADED) {
val isRooted = Shell.rootAccess() val isRooted = Shell.rootAccess()
val isAB = isABDevice() val isAB = isABDevice()
@ -21,9 +23,23 @@ class InstallViewModel : CompatViewModel() {
val step = KObservableField(0) val step = KObservableField(0)
val method = KObservableField(-1) val method = KObservableField(-1)
val progress = KObservableField(0)
var data = KObservableField<Uri?>(null) var data = KObservableField<Uri?>(null)
init { init {
RemoteFileService.reset()
RemoteFileService.progressBroadcast.observeForever {
val (progress, subject) = it ?: return@observeForever
if (subject !is DownloadSubject.Magisk) {
return@observeForever
}
this.progress.value = progress.times(100).roundToInt()
if (this.progress.value >= 100) {
// this might cause issues if the flash activity launches on top of this sooner
back()
}
}
method.addOnPropertyChangedCallback { method.addOnPropertyChangedCallback {
if (method.value == R.id.method_patch) { if (method.value == R.id.method_patch) {
RequestFileEvent().publish() RequestFileEvent().publish()
@ -37,7 +53,7 @@ class InstallViewModel : CompatViewModel() {
fun install() = DownloadService(get()) { fun install() = DownloadService(get()) {
subject = DownloadSubject.Magisk(resolveConfiguration()) subject = DownloadSubject.Magisk(resolveConfiguration())
} }.also { state = State.LOADING }
// --- // ---

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path"
android:fillColor="#000"
android:pathData="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 Z" />
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/overshoot_interpolator"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.8"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/overshoot_interpolator"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.8"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:propertyName="scaleX"
android:startOffset="200"
android:valueFrom="0.8"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:propertyName="scaleY"
android:startOffset="200"
android:valueFrom="0.8"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="100"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="fillAlpha"
android:startOffset="200"
android:valueFrom="0.3"
android:valueTo="1"
android:valueType="floatType" />
</aapt:attr>
</target>
</animated-vector>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path"
android:fillAlpha="0.7"
android:fillColor="#000"
android:pathData="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 Z" />
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/overshoot_interpolator"
android:propertyName="scaleX"
android:valueFrom="1"
android:valueTo="0.8"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/overshoot_interpolator"
android:propertyName="scaleY"
android:valueFrom="1"
android:valueTo="0.8"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:propertyName="scaleX"
android:startOffset="200"
android:valueFrom="0.8"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="200"
android:interpolator="@android:anim/anticipate_overshoot_interpolator"
android:propertyName="scaleY"
android:startOffset="200"
android:valueFrom="0.8"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="path">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="100"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="fillAlpha"
android:startOffset="200"
android:valueFrom="1"
android:valueTo="0.3"
android:valueType="floatType" />
</aapt:attr>
</target>
</animated-vector>

View File

@ -0,0 +1,17 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="forth"
android:pivotX="12"
android:pivotY="12"
android:rotation="180">
<path
android:fillColor="#000"
android:pathData="M20,11H6.83l2.88,-2.88c0.39,-0.39 0.39,-1.02 0,-1.41 -0.39,-0.39 -1.02,-0.39 -1.41,0L3.71,11.3c-0.39,0.39 -0.39,1.02 0,1.41L8.3,17.3c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L6.83,13H20c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1z" />
</group>
</vector>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/collapsed"
android:state_checked="true">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path"
android:fillColor="#000"
android:pathData="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 Z" />
</group>
</vector>
</item>
<item android:id="@+id/expanded">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path"
android:fillAlpha="0.3"
android:fillColor="#000"
android:pathData="M 12 2 C 9.349 2 6.804 3.054 4.929 4.929 C 3.054 6.804 2 9.349 2 12 C 2 14.651 3.054 17.196 4.929 19.071 C 6.804 20.946 9.349 22 12 22 C 13.755 22 15.48 21.538 17 20.66 C 18.52 19.783 19.783 18.52 20.66 17 C 21.538 15.48 22 13.755 22 12 C 22 10.245 21.538 8.52 20.66 7 C 19.783 5.48 18.52 4.217 17 3.34 C 15.48 2.462 13.755 2 12 2 Z" />
</group>
</vector>
</item>
<transition
android:drawable="@drawable/avd_circle_from_filled"
android:fromId="@+id/expanded"
android:toId="@+id/collapsed" />
<transition
android:drawable="@drawable/avd_circle_to_filled"
android:fromId="@+id/collapsed"
android:toId="@id/expanded" />
</animated-selector>

View File

@ -7,7 +7,7 @@
<variable <variable
name="viewModel" name="viewModel"
type="com.topjohnwu.magisk.ui.install.InstallViewModel" /> type="com.topjohnwu.magisk.redesign.install.InstallViewModel" />
</data> </data>
@ -20,194 +20,259 @@
android:paddingBottom="@{viewModel.insets.bottom + (int) @dimen/l2}" android:paddingBottom="@{viewModel.insets.bottom + (int) @dimen/l2}"
tools:paddingTop="24dp"> tools:paddingTop="24dp">
<LinearLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:clipToPadding="false"
android:orientation="vertical"
android:paddingTop="@dimen/l1">
<com.google.android.material.card.MaterialCardView <LinearLayout
style="?styleCardElevated" goneUnless="@{viewModel.loaded}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginStart="@dimen/l1" android:clipToPadding="false"
android:layout_marginEnd="@dimen/l1" android:orientation="vertical"
app:cardElevation="@{viewModel.step != 0 ? 0f : @dimen/l_25}"> android:paddingTop="@dimen/l1">
<LinearLayout <com.google.android.material.card.MaterialCardView
style="?styleCardElevated"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginStart="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
app:cardCornerRadius="@dimen/l1"
app:cardElevation="@{viewModel.step != 0 ? 0f : @dimen/l_25}">
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeightSmall"> android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/install_step_options_icon" android:layout_width="match_parent"
style="?styleIconNormal"
isSelected="@{viewModel.step > 0}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_check_circle_md2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/install_step_options_title"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:minHeight="?listPreferredItemHeightSmall">
android:text="Options"
android:textAppearance="?appearanceTextBodyNormal"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/install_step_options_button"
app:layout_constraintStart_toEndOf="@+id/install_step_options_icon"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/install_step_options_button" android:id="@+id/install_step_options_icon"
style="?styleButtonText" style="?styleIconNormal"
isSelected="@{viewModel.step > 0}"
android:layout_marginStart="@dimen/l_25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_check_circle_md2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/install_step_options_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1"
android:gravity="start"
android:text="Options"
android:textAppearance="?appearanceTextBodyNormal"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/install_step_options_button"
app:layout_constraintStart_toEndOf="@+id/install_step_options_icon"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/install_step_options_button"
style="?styleButtonText"
gone="@{viewModel.step != 0}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.step(1)}"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
gone="@{viewModel.step != 0}" gone="@{viewModel.step != 0}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.step(1)}"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
gone="@{viewModel.step != 0}"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/include_install_options"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginStart="@dimen/l_50" />
</FrameLayout> <include
layout="@layout/include_install_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l_50"
android:layout_marginEnd="@dimen/l1"
android:layout_marginBottom="@dimen/l_50" />
</LinearLayout> </FrameLayout>
</com.google.android.material.card.MaterialCardView> </LinearLayout>
<com.google.android.material.card.MaterialCardView </com.google.android.material.card.MaterialCardView>
style="?styleCardElevated"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
app:cardElevation="@{viewModel.step != 1 ? 0f : @dimen/l_25}">
<LinearLayout <com.google.android.material.card.MaterialCardView
style="?styleCardElevated"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
app:cardCornerRadius="@dimen/l1"
app:cardElevation="@{viewModel.step != 1 ? 0f : @dimen/l_25}">
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeightSmall"> android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/install_step_method_icon" android:layout_width="match_parent"
style="?styleIconNormal"
isSelected="@{viewModel.step > 1}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_check_circle_md2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/install_step_method_title"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="start" android:minHeight="?listPreferredItemHeightSmall">
android:text="Method"
android:textAppearance="?appearanceTextBodyNormal"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/install_step_method_button"
app:layout_constraintStart_toEndOf="@+id/install_step_method_icon"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/install_step_method_button" android:id="@+id/install_step_method_icon"
style="?styleButtonText" style="?styleIconNormal"
isSelected="@{viewModel.step > 1}"
android:layout_marginStart="@dimen/l_25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_check_circle_md2" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/install_step_method_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1"
android:gravity="start"
android:text="Method"
android:textAppearance="?appearanceTextBodyNormal"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/install_step_method_button"
app:layout_constraintStart_toEndOf="@+id/install_step_method_icon"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/install_step_method_button"
style="?styleButtonText"
gone="@{viewModel.step != 1}"
isEnabled="@{viewModel.method == @id/method_patch ? viewModel.data != null : viewModel.method != -1}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.step(2)}"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RadioGroup
gone="@{viewModel.step != 1}" gone="@{viewModel.step != 1}"
isEnabled="@{viewModel.method == @id/method_patch ? viewModel.data != null : viewModel.method != -1}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.step(2)}"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RadioGroup
gone="@{viewModel.step != 1}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l_50"
android:checkedButton="@={viewModel.method}">
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_download"
style="?styleRadioNormal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/download_zip_only" /> android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l_50"
android:layout_marginEnd="@dimen/l1"
android:layout_marginBottom="@dimen/l_50"
android:checkedButton="@={viewModel.method}">
<com.google.android.material.radiobutton.MaterialRadioButton <com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_patch" android:id="@+id/method_download"
style="?styleRadioNormal" style="?styleRadioNormal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/select_patch_file" /> android:text="@string/download_zip_only"
tools:checked="true" />
<com.google.android.material.radiobutton.MaterialRadioButton <com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_direct" android:id="@+id/method_patch"
style="?styleRadioNormal" style="?styleRadioNormal"
android:layout_width="match_parent" android:layout_width="match_parent"
gone="@{!viewModel.rooted}" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:button="@drawable/ic_radio_check_button"
android:text="@string/direct_install" /> android:text="@string/select_patch_file" />
<com.google.android.material.radiobutton.MaterialRadioButton <com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_inactive_slot" android:id="@+id/method_direct"
style="?styleRadioNormal" style="?styleRadioNormal"
gone="@{!viewModel.rooted || !viewModel.aB}" gone="@{!viewModel.rooted}"
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:button="@drawable/ic_radio_check_button"
android:text="@string/direct_install" />
</RadioGroup> <com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_inactive_slot"
style="?styleRadioNormal"
gone="@{!viewModel.rooted || !viewModel.aB}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:button="@drawable/ic_radio_check_button"
android:text="@string/install_inactive_slot" />
</LinearLayout> </RadioGroup>
</com.google.android.material.card.MaterialCardView> </LinearLayout>
<com.google.android.material.button.MaterialButton </com.google.android.material.card.MaterialCardView>
style="?styleButtonText"
gone="@{viewModel.step != 2}"
android:layout_width="wrap_content"
android:onClick="@{() -> viewModel.install()}"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_margin="@dimen/l1"
android:text="@string/install" />
</LinearLayout> <com.google.android.material.button.MaterialButton
style="?styleButtonText"
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="Let's go"
app:icon="@drawable/ic_forth_md2"
app:iconGravity="textEnd" />
</LinearLayout>
<LinearLayout
goneUnless="@{viewModel.loading}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginStart="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
android:gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/safetynet_attest_loading"
android:textAppearance="?appearanceTextTitleNormal" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l1">
<ProgressBar
style="?styleProgressDeterminate"
invisible="@{viewModel.progress &lt;= 0}"
android:layout_width="100dp"
android:layout_gravity="center"
android:progress="@{viewModel.progress}" />
<ProgressBar
style="?styleProgressIndeterminate"
invisibleUnless="@{viewModel.progress &lt;= 0}"
android:layout_width="100dp"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>

View File

@ -136,6 +136,7 @@ variant. Make sure to use style referenced by attribute defined it attrs.xml.
<item name="android:paddingStart">@dimen/l1</item> <item name="android:paddingStart">@dimen/l1</item>
<item name="android:paddingEnd">@dimen/l1</item> <item name="android:paddingEnd">@dimen/l1</item>
<item name="tint">?colorPrimary</item> <item name="tint">?colorPrimary</item>
<item name="buttonCompat">@drawable/ic_radio_check_button</item>
</style> </style>
<style name="WidgetFoundation.RadioButton" parent="Widget.AppCompat.CompoundButton.RadioButton"> <style name="WidgetFoundation.RadioButton" parent="Widget.AppCompat.CompoundButton.RadioButton">
@ -144,6 +145,7 @@ variant. Make sure to use style referenced by attribute defined it attrs.xml.
<item name="android:paddingStart">@dimen/l1</item> <item name="android:paddingStart">@dimen/l1</item>
<item name="android:paddingEnd">@dimen/l1</item> <item name="android:paddingEnd">@dimen/l1</item>
<item name="tint">?colorPrimary</item> <item name="tint">?colorPrimary</item>
<item name="buttonCompat">@drawable/ic_radio_check_button</item>
</style> </style>
<style name="WidgetFoundation.ProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal"> <style name="WidgetFoundation.ProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">