Added install implementation

This commit is contained in:
Viktor De Pasquale 2019-10-23 19:14:39 +02:00
parent 067cb0cd9d
commit 04576ca828
7 changed files with 81 additions and 2 deletions

View File

@ -1,6 +1,7 @@
package com.topjohnwu.magisk.model.events package com.topjohnwu.magisk.model.events
import android.app.Activity import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.karumi.dexter.Dexter import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport import com.karumi.dexter.MultiplePermissionsReport
@ -96,3 +97,20 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
activity.recreate() activity.recreate()
} }
} }
class RequestFileEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: AppCompatActivity) {
Intent(Intent.ACTION_GET_CONTENT)
.setType("*/*")
.addCategory(Intent.CATEGORY_OPENABLE)
.also { activity.startActivityForResult(it, REQUEST_CODE) }
}
companion object {
private const val REQUEST_CODE = 10
fun resolve(requestCode: Int, resultCode: Int, data: Intent?) = data
?.takeIf { resultCode == Activity.RESULT_OK }
?.takeIf { requestCode == REQUEST_CODE }
?.data
}
}

View File

@ -1,5 +1,6 @@
package com.topjohnwu.magisk.redesign.compat package com.topjohnwu.magisk.redesign.compat
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -29,6 +30,11 @@ abstract class CompatActivity<ViewModel : CompatViewModel, Binding : ViewDataBin
internal abstract val navHost: Int internal abstract val navHost: Int
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
navigation?.onActivityResult(requestCode, resultCode, data)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@ -31,6 +31,9 @@ class CompatNavigationDelegate<out Source>(
source.baseFragments[index].java.newInstance() source.baseFragments[index].java.newInstance()
//endregion //endregion
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
controller.currentFrag?.onActivityResult(requestCode, resultCode, data)
}
fun onCreate(savedInstanceState: Bundle?) = controller.run { fun onCreate(savedInstanceState: Bundle?) = controller.run {
rootFragmentListener = this@CompatNavigationDelegate rootFragmentListener = this@CompatNavigationDelegate

View File

@ -6,8 +6,9 @@ import androidx.databinding.Observable
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel import com.topjohnwu.magisk.base.viewmodel.BaseViewModel
import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.KObservableField
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import org.koin.core.KoinComponent
abstract class CompatViewModel : BaseViewModel() { abstract class CompatViewModel : BaseViewModel(), KoinComponent {
val insets = KObservableField(Insets.NONE) val insets = KObservableField(Insets.NONE)

View File

@ -1,8 +1,10 @@
package com.topjohnwu.magisk.ui.install package com.topjohnwu.magisk.ui.install
import android.content.Intent
import android.graphics.Insets import android.graphics.Insets
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
import com.topjohnwu.magisk.model.events.RequestFileEvent
import com.topjohnwu.magisk.redesign.compat.CompatFragment import com.topjohnwu.magisk.redesign.compat.CompatFragment
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
@ -13,6 +15,11 @@ class InstallFragment : CompatFragment<InstallViewModel, FragmentInstallMd2Bindi
override fun consumeSystemWindowInsets(insets: Insets) = insets override fun consumeSystemWindowInsets(insets: Insets) = insets
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
viewModel.data.value = RequestFileEvent.resolve(requestCode, resultCode, data)
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
requireActivity().setTitle(R.string.install) requireActivity().setTitle(R.string.install)

View File

@ -1,15 +1,56 @@
package com.topjohnwu.magisk.ui.install package com.topjohnwu.magisk.ui.install
import android.net.Uri
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
import com.topjohnwu.magisk.model.download.DownloadService
import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.events.RequestFileEvent
import com.topjohnwu.magisk.redesign.compat.CompatViewModel import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import org.koin.core.get
class InstallViewModel : CompatViewModel() { class InstallViewModel : CompatViewModel() {
val isRooted = Shell.rootAccess()
val isAB = isABDevice()
val step = KObservableField(0) val step = KObservableField(0)
val method = KObservableField(-1) val method = KObservableField(-1)
var data = KObservableField<Uri?>(null)
init {
method.addOnPropertyChangedCallback {
if (method.value == R.id.method_patch) {
RequestFileEvent().publish()
}
}
}
fun step(nextStep: Int) { fun step(nextStep: Int) {
step.value = nextStep step.value = nextStep
} }
fun install() = DownloadService(get()) {
subject = DownloadSubject.Magisk(resolveConfiguration())
}
// ---
private fun resolveConfiguration() = when (method.value) {
R.id.method_download -> Configuration.Download
R.id.method_patch -> Configuration.Patch(data.value!!)
R.id.method_direct -> Configuration.Flash.Primary
R.id.method_inactive_slot -> Configuration.Flash.Secondary
else -> throw IllegalArgumentException("Unknown value")
}
private fun isABDevice() = ShellUtils
.fastCmd("grep_prop ro.build.ab_update")
.let { it.isNotEmpty() && it.toBoolean() }
} }

View File

@ -143,7 +143,7 @@
android:id="@+id/install_step_method_button" android:id="@+id/install_step_method_button"
style="?styleButtonText" style="?styleButtonText"
gone="@{viewModel.step != 1}" gone="@{viewModel.step != 1}"
isEnabled="@{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.step(2)}"
@ -179,12 +179,14 @@
android:id="@+id/method_direct" android:id="@+id/method_direct"
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:text="@string/direct_install" /> android:text="@string/direct_install" />
<com.google.android.material.radiobutton.MaterialRadioButton <com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/method_inactive_slot" android:id="@+id/method_inactive_slot"
style="?styleRadioNormal" style="?styleRadioNormal"
gone="@{!viewModel.rooted || !viewModel.aB}"
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" />
@ -199,6 +201,7 @@
style="?styleButtonText" style="?styleButtonText"
gone="@{viewModel.step != 2}" gone="@{viewModel.step != 2}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:onClick="@{() -> viewModel.install()}"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_margin="@dimen/l1" android:layout_margin="@dimen/l1"