Reorganize classes
- Move base classes to its own package - Move most logic out of MagiskActivity to MainActivity
This commit is contained in:
parent
fc886a5a47
commit
08b528dc4f
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
# DelegateWorker
|
||||
-keep,allowobfuscation class * extends com.topjohnwu.magisk.model.worker.DelegateWorker
|
||||
-keep,allowobfuscation class * extends com.topjohnwu.magisk.base.DelegateWorker
|
||||
|
||||
# BootSigner
|
||||
-keepclassmembers class com.topjohnwu.signing.BootSigner { *; }
|
||||
|
@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import com.topjohnwu.magisk.model.worker.DelegateWorker;
|
||||
import com.topjohnwu.magisk.base.DelegateWorker;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
package com.topjohnwu.magisk.base
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.SharedPreferences
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.model.worker
|
||||
package com.topjohnwu.magisk.base
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Network
|
112
app/src/main/java/com/topjohnwu/magisk/base/MagiskActivity.kt
Normal file
112
app/src/main/java/com/topjohnwu/magisk/base/MagiskActivity.kt
Normal file
@ -0,0 +1,112 @@
|
||||
package com.topjohnwu.magisk.base
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.collection.SparseArrayCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.extensions.set
|
||||
import com.topjohnwu.magisk.model.events.EventHandler
|
||||
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
|
||||
import com.topjohnwu.magisk.utils.LocaleManager
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.magisk.utils.currentLocale
|
||||
|
||||
typealias RequestCallback = MagiskActivity<*, *>.(Int, Intent?) -> Unit
|
||||
|
||||
abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
AppCompatActivity(), EventHandler {
|
||||
|
||||
protected lateinit var binding: Binding
|
||||
protected abstract val layoutRes: Int
|
||||
protected abstract val viewModel: ViewModel
|
||||
protected open val snackbarView get() = binding.root
|
||||
protected open val navHostId: Int = 0
|
||||
protected open val defaultPosition: Int = 0
|
||||
|
||||
private val resultCallbacks = SparseArrayCompat<RequestCallback>()
|
||||
|
||||
init {
|
||||
val theme = if (Config.darkTheme) {
|
||||
AppCompatDelegate.MODE_NIGHT_YES
|
||||
} else {
|
||||
AppCompatDelegate.MODE_NIGHT_NO
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(theme)
|
||||
}
|
||||
|
||||
override fun applyOverrideConfiguration(config: Configuration?) {
|
||||
// Force applying our preferred local
|
||||
config?.setLocale(currentLocale)
|
||||
super.applyOverrideConfiguration(config)
|
||||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(LocaleManager.getLocaleContext(base))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
||||
|
||||
binding = DataBindingUtil.setContentView<Binding>(this, layoutRes).apply {
|
||||
setVariable(BR.viewModel, viewModel)
|
||||
lifecycleOwner = this@MagiskActivity
|
||||
}
|
||||
}
|
||||
|
||||
fun openUrl(url: String) = Utils.openLink(this, url.toUri())
|
||||
|
||||
fun withPermissions(vararg permissions: String, builder: PermissionRequestBuilder.() -> Unit) {
|
||||
val request = PermissionRequestBuilder().apply(builder).build()
|
||||
Dexter.withActivity(this)
|
||||
.withPermissions(*permissions)
|
||||
.withListener(object : MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
request.onSuccess()
|
||||
} else {
|
||||
request.onFailure()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>,
|
||||
token: PermissionToken
|
||||
) = token.continuePermissionRequest()
|
||||
}).check()
|
||||
}
|
||||
|
||||
fun withExternalRW(builder: PermissionRequestBuilder.() -> Unit) {
|
||||
withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, builder = builder)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
resultCallbacks[requestCode]?.apply {
|
||||
resultCallbacks.remove(requestCode)
|
||||
invoke(this@MagiskActivity, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
fun startActivityForResult(intent: Intent, requestCode: Int, listener: RequestCallback) {
|
||||
resultCallbacks[requestCode] = listener
|
||||
startActivityForResult(intent, requestCode)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.topjohnwu.magisk.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.model.events.EventHandler
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.ui.MainActivity
|
||||
|
||||
abstract class MagiskFragment<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
Fragment(), EventHandler {
|
||||
|
||||
protected val activity get() = requireActivity() as MainActivity
|
||||
protected lateinit var binding: Binding
|
||||
protected abstract val layoutRes: Int
|
||||
protected abstract val viewModel: ViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = DataBindingUtil.inflate<Binding>(inflater, layoutRes, container, false).apply {
|
||||
setVariable(BR.viewModel, viewModel)
|
||||
lifecycleOwner = this@MagiskFragment
|
||||
}
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
activity.onEventDispatched(event)
|
||||
}
|
||||
|
||||
open fun onBackPressed(): Boolean = false
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.viewmodel
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
@ -13,7 +13,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
||||
|
||||
@Deprecated(
|
||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
||||
ReplaceWith("state = State.LOADING", "com.topjohnwu.magisk.viewmodel.LoadingViewModel.State"),
|
||||
ReplaceWith("state = State.LOADING", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
|
||||
DeprecationLevel.WARNING
|
||||
)
|
||||
fun setLoading() {
|
||||
@ -22,7 +22,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
||||
|
||||
@Deprecated(
|
||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
||||
ReplaceWith("state = State.LOADED", "com.topjohnwu.magisk.viewmodel.LoadingViewModel.State"),
|
||||
ReplaceWith("state = State.LOADED", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
|
||||
DeprecationLevel.WARNING
|
||||
)
|
||||
fun setLoaded() {
|
||||
@ -31,7 +31,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
||||
|
||||
@Deprecated(
|
||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
||||
ReplaceWith("state = State.LOADING_FAILED", "com.topjohnwu.magisk.viewmodel.LoadingViewModel.State"),
|
||||
ReplaceWith("state = State.LOADING_FAILED", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
|
||||
DeprecationLevel.WARNING
|
||||
)
|
||||
fun setLoadingFailed() {
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
import android.app.Activity
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
@ -9,7 +9,6 @@ import com.topjohnwu.magisk.model.events.BackPressEvent
|
||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.viewmodel.LoadingViewModel
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.viewmodel
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
import androidx.databinding.Observable
|
||||
import androidx.databinding.PropertyChangeRegistry
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.viewmodel
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
abstract class StatefulViewModel<State : Enum<*>>(
|
||||
val defaultState: State
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.viewmodel
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
@ -1,6 +1,5 @@
|
||||
package com.topjohnwu.magisk.model.entity.recycler
|
||||
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
@ -12,6 +11,7 @@ import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
||||
import com.topjohnwu.magisk.model.events.HideProcessEvent
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
|
||||
class HideRvItem(val item: HideAppInfo, targets: List<HideTarget>) :
|
||||
ComparableRvItem<HideRvItem>() {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.topjohnwu.magisk.model.entity.recycler
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
@ -11,6 +10,7 @@ import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
||||
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
|
||||
class PolicyRvItem(val item: MagiskPolicy, val icon: Drawable) : ComparableRvItem<PolicyRvItem>() {
|
||||
|
||||
|
@ -15,4 +15,11 @@ internal interface EventHandler {
|
||||
* the way how you handle them.
|
||||
*/
|
||||
fun onSimpleEventDispatched(event: Int) {}
|
||||
|
||||
val viewEventObserver get() = ViewEventObserver {
|
||||
onEventDispatched(it)
|
||||
if (it is SimpleViewEvent) {
|
||||
onSimpleEventDispatched(it.event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.topjohnwu.magisk.model.events
|
||||
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
|
||||
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package com.topjohnwu.magisk.model.events
|
||||
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
|
||||
class SimpleViewEvent(
|
||||
val event: Int
|
||||
) : ViewEvent()
|
@ -3,7 +3,6 @@ package com.topjohnwu.magisk.model.events
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
|
||||
class SnackbarEvent private constructor(
|
||||
@StringRes private val messageRes: Int,
|
||||
|
@ -3,9 +3,9 @@ package com.topjohnwu.magisk.model.update
|
||||
import androidx.work.ListenableWorker
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.Info
|
||||
import com.topjohnwu.magisk.base.DelegateWorker
|
||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||
import com.topjohnwu.magisk.extensions.inject
|
||||
import com.topjohnwu.magisk.model.worker.DelegateWorker
|
||||
import com.topjohnwu.magisk.view.Notifications
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
||||
|
@ -4,15 +4,24 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.ncapdevi.fragnav.FragNavController
|
||||
import com.ncapdevi.fragnav.FragNavTransactionOptions
|
||||
import com.topjohnwu.magisk.ClassMap
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const.Key.OPEN_SECTION
|
||||
import com.topjohnwu.magisk.Info
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.ActivityMainBinding
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
import com.topjohnwu.magisk.extensions.snackbar
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.model.navigation.Navigator
|
||||
import com.topjohnwu.magisk.ui.hide.MagiskHideFragment
|
||||
import com.topjohnwu.magisk.ui.home.HomeFragment
|
||||
import com.topjohnwu.magisk.ui.log.LogFragment
|
||||
@ -23,16 +32,24 @@ import com.topjohnwu.magisk.ui.superuser.SuperuserFragment
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import timber.log.Timber
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>(), Navigator,
|
||||
FragNavController.RootFragmentListener, FragNavController.TransactionListener {
|
||||
|
||||
override val layoutRes: Int = R.layout.activity_main
|
||||
override val viewModel: MainViewModel by viewModel()
|
||||
override val navHostId: Int = R.id.main_nav_host
|
||||
override val defaultPosition: Int = 0
|
||||
|
||||
private val navigationController get() = if (navHostId == 0) null else _navigationController
|
||||
private val _navigationController by lazy {
|
||||
FragNavController(supportFragmentManager, navHostId)
|
||||
}
|
||||
private val isRootFragment get() =
|
||||
navigationController?.let { it.currentStackIndex != defaultPosition } ?: false
|
||||
|
||||
override val baseFragments: List<KClass<out Fragment>> = listOf(
|
||||
HomeFragment::class,
|
||||
SuperuserFragment::class,
|
||||
@ -50,6 +67,13 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
navigationController?.apply {
|
||||
rootFragmentListener = this@MainActivity
|
||||
transactionListener = this@MainActivity
|
||||
initialize(defaultPosition, savedInstanceState)
|
||||
}
|
||||
|
||||
checkHideSection()
|
||||
setSupportActionBar(binding.mainInclude.mainToolbar)
|
||||
|
||||
@ -64,6 +88,11 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
navigationController?.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
supportActionBar?.title = title
|
||||
}
|
||||
@ -72,21 +101,27 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
supportActionBar?.setTitle(titleId)
|
||||
}
|
||||
|
||||
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
||||
val fragmentId = when (fragment) {
|
||||
is HomeFragment -> R.id.magiskFragment
|
||||
is SuperuserFragment -> R.id.superuserFragment
|
||||
is MagiskHideFragment -> R.id.magiskHideFragment
|
||||
is ModulesFragment -> R.id.modulesFragment
|
||||
is ReposFragment -> R.id.reposFragment
|
||||
is LogFragment -> R.id.logFragment
|
||||
is SettingsFragment -> R.id.settings
|
||||
else -> return
|
||||
}
|
||||
binding.navView.setCheckedItem(fragmentId)
|
||||
override fun onBackPressed() {
|
||||
val fragment = navigationController?.currentFrag as? MagiskFragment<*, *>
|
||||
|
||||
if (fragment?.onBackPressed() == true) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
navigationController?.popFragment() ?: throw UnsupportedOperationException()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
when {
|
||||
isRootFragment -> {
|
||||
val options = FragNavTransactionOptions.newBuilder()
|
||||
.transition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
|
||||
.build()
|
||||
navigationController?.switchTab(defaultPosition, options)
|
||||
}
|
||||
else -> super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (binding.drawerLayout.isDrawerOpen(binding.navView)) {
|
||||
binding.drawerLayout.closeDrawer(binding.navView)
|
||||
} else {
|
||||
@ -94,6 +129,23 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is SnackbarEvent -> snackbar(snackbarView, event.message(this), event.length, event.f)
|
||||
is BackPressEvent -> onBackPressed()
|
||||
is MagiskNavigationEvent -> navigateTo(event)
|
||||
is ViewActionEvent -> event.action(this)
|
||||
is PermissionEvent -> withPermissions(*event.permissions.toTypedArray()) {
|
||||
onSuccess { event.callback.onNext(true) }
|
||||
onFailure {
|
||||
event.callback.onNext(false)
|
||||
event.callback.onError(SecurityException("User refused permissions"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSimpleEventDispatched(event: Int) {
|
||||
super.onSimpleEventDispatched(event)
|
||||
when (event) {
|
||||
@ -116,4 +168,84 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
||||
menu.findItem(R.id.superuserFragment).isVisible =
|
||||
Utils.showSuperUser()
|
||||
}
|
||||
|
||||
private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) =
|
||||
customAnimations(options.enter, options.exit, options.popEnter, options.popExit).apply {
|
||||
if (!options.anySet) {
|
||||
transition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
}
|
||||
}
|
||||
|
||||
override val numberOfRootFragments: Int get() = baseFragments.size
|
||||
|
||||
override fun getRootFragment(index: Int) = baseFragments[index].java.newInstance()
|
||||
|
||||
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
||||
val fragmentId = when (fragment) {
|
||||
is HomeFragment -> R.id.magiskFragment
|
||||
is SuperuserFragment -> R.id.superuserFragment
|
||||
is MagiskHideFragment -> R.id.magiskHideFragment
|
||||
is ModulesFragment -> R.id.modulesFragment
|
||||
is ReposFragment -> R.id.reposFragment
|
||||
is LogFragment -> R.id.logFragment
|
||||
is SettingsFragment -> R.id.settings
|
||||
else -> return
|
||||
}
|
||||
binding.navView.setCheckedItem(fragmentId)
|
||||
}
|
||||
|
||||
override fun navigateTo(event: MagiskNavigationEvent) {
|
||||
val directions = event.navDirections
|
||||
|
||||
navigationController?.defaultTransactionOptions = FragNavTransactionOptions.newBuilder()
|
||||
.customAnimations(event.animOptions)
|
||||
.build()
|
||||
|
||||
navigationController?.currentStack
|
||||
?.indexOfFirst { it.javaClass == event.navOptions.popUpTo }
|
||||
?.let { if (it == -1) null else it } // invalidate if class is not found
|
||||
?.let { if (event.navOptions.inclusive) it + 1 else it }
|
||||
?.let { navigationController?.popFragments(it) }
|
||||
|
||||
when (directions.isActivity) {
|
||||
true -> navigateToActivity(event)
|
||||
else -> navigateToFragment(event)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToActivity(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
val options = event.navOptions
|
||||
|
||||
Intent(this, destination)
|
||||
.putExtras(event.navDirections.args)
|
||||
.apply {
|
||||
if (options.singleTop) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
if (options.clearTask) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
}
|
||||
.let { startActivity(it) }
|
||||
}
|
||||
|
||||
private fun navigateToFragment(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
|
||||
when (val index = baseFragments.indexOfFirst { it.java.name == destination.name }) {
|
||||
-1 -> destination.newInstance()
|
||||
.apply { arguments = event.navDirections.args }
|
||||
.let { navigationController?.pushFragment(it) }
|
||||
// When it's desired that fragments of same class are put on top of one another edit this
|
||||
else -> navigationController?.switchTab(index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFragmentTransaction(
|
||||
fragment: Fragment?,
|
||||
transactionType: FragNavController.TransactionType
|
||||
) = Unit
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package com.topjohnwu.magisk.ui
|
||||
|
||||
import android.view.MenuItem
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
|
||||
|
||||
class MainViewModel : MagiskViewModel() {
|
||||
|
@ -1,260 +0,0 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.collection.SparseArrayCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.karumi.dexter.Dexter
|
||||
import com.karumi.dexter.MultiplePermissionsReport
|
||||
import com.karumi.dexter.PermissionToken
|
||||
import com.karumi.dexter.listener.PermissionRequest
|
||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||
import com.ncapdevi.fragnav.FragNavController
|
||||
import com.ncapdevi.fragnav.FragNavTransactionOptions
|
||||
import com.topjohnwu.magisk.model.events.EventHandler
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.extensions.set
|
||||
import com.topjohnwu.magisk.extensions.snackbar
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
||||
import com.topjohnwu.magisk.model.navigation.Navigator
|
||||
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
|
||||
import com.topjohnwu.magisk.utils.LocaleManager
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.magisk.utils.currentLocale
|
||||
import timber.log.Timber
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
typealias RequestCallback = MagiskActivity<*, *>.(Int, Intent?) -> Unit
|
||||
|
||||
abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
AppCompatActivity(), FragNavController.RootFragmentListener, EventHandler,
|
||||
Navigator, FragNavController.TransactionListener {
|
||||
|
||||
protected lateinit var binding: Binding
|
||||
protected abstract val layoutRes: Int
|
||||
protected abstract val viewModel: ViewModel
|
||||
protected open val snackbarView get() = binding.root
|
||||
protected open val navHostId: Int = 0
|
||||
private val viewEventObserver = ViewEventObserver {
|
||||
onEventDispatched(it)
|
||||
if (it is SimpleViewEvent) {
|
||||
onSimpleEventDispatched(it.event)
|
||||
}
|
||||
}
|
||||
|
||||
private val resultCallbacks = SparseArrayCompat<RequestCallback>()
|
||||
|
||||
protected open val defaultPosition: Int = 0
|
||||
|
||||
private val navigationController get() = if (navHostId == 0) null else _navigationController
|
||||
private val _navigationController by lazy {
|
||||
if (navHostId == 0) throw IllegalStateException("Did you forget to override \"navHostId\"?")
|
||||
FragNavController(supportFragmentManager, navHostId)
|
||||
}
|
||||
|
||||
private val isRootFragment
|
||||
get() = navigationController?.let { it.currentStackIndex != defaultPosition } ?: false
|
||||
|
||||
override val numberOfRootFragments: Int get() = baseFragments.size
|
||||
override val baseFragments: List<KClass<out Fragment>> = listOf()
|
||||
|
||||
init {
|
||||
val theme = if (Config.darkTheme) {
|
||||
AppCompatDelegate.MODE_NIGHT_YES
|
||||
} else {
|
||||
AppCompatDelegate.MODE_NIGHT_NO
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(theme)
|
||||
}
|
||||
|
||||
override fun applyOverrideConfiguration(config: Configuration?) {
|
||||
// Force applying our preferred local
|
||||
config?.setLocale(currentLocale)
|
||||
super.applyOverrideConfiguration(config)
|
||||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(LocaleManager.getLocaleContext(base))
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = DataBindingUtil.setContentView<Binding>(this, layoutRes).apply {
|
||||
setVariable(BR.viewModel, viewModel)
|
||||
lifecycleOwner = this@MagiskActivity
|
||||
}
|
||||
|
||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
||||
|
||||
navigationController?.apply {
|
||||
rootFragmentListener = this@MagiskActivity
|
||||
transactionListener = this@MagiskActivity
|
||||
initialize(defaultPosition, savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
navigationController?.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is SnackbarEvent -> snackbar(snackbarView, event.message(this), event.length, event.f)
|
||||
is BackPressEvent -> onBackPressed()
|
||||
is MagiskNavigationEvent -> navigateTo(event)
|
||||
is ViewActionEvent -> event.action(this)
|
||||
is PermissionEvent -> withPermissions(*event.permissions.toTypedArray()) {
|
||||
onSuccess { event.callback.onNext(true) }
|
||||
onFailure {
|
||||
event.callback.onNext(false)
|
||||
event.callback.onError(SecurityException("User refused permissions"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRootFragment(index: Int) = baseFragments[index].java.newInstance()
|
||||
|
||||
override fun navigateTo(event: MagiskNavigationEvent) {
|
||||
val directions = event.navDirections
|
||||
|
||||
navigationController?.defaultTransactionOptions = FragNavTransactionOptions.newBuilder()
|
||||
.customAnimations(event.animOptions)
|
||||
.build()
|
||||
|
||||
navigationController?.currentStack
|
||||
?.indexOfFirst { it.javaClass == event.navOptions.popUpTo }
|
||||
?.let { if (it == -1) null else it } // invalidate if class is not found
|
||||
?.let { if (event.navOptions.inclusive) it + 1 else it }
|
||||
?.let { navigationController?.popFragments(it) }
|
||||
|
||||
when (directions.isActivity) {
|
||||
true -> navigateToActivity(event)
|
||||
else -> navigateToFragment(event)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToActivity(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
val options = event.navOptions
|
||||
|
||||
Intent(this, destination)
|
||||
.putExtras(event.navDirections.args)
|
||||
.apply {
|
||||
if (options.singleTop) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
if (options.clearTask) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
}
|
||||
.let { startActivity(it) }
|
||||
}
|
||||
|
||||
private fun navigateToFragment(event: MagiskNavigationEvent) {
|
||||
val destination = event.navDirections.destination?.java ?: let {
|
||||
Timber.e("Cannot navigate to null destination")
|
||||
return
|
||||
}
|
||||
|
||||
when (val index = baseFragments.indexOfFirst { it.java.name == destination.name }) {
|
||||
-1 -> destination.newInstance()
|
||||
.apply { arguments = event.navDirections.args }
|
||||
.let { navigationController?.pushFragment(it) }
|
||||
// When it's desired that fragments of same class are put on top of one another edit this
|
||||
else -> navigationController?.switchTab(index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
val fragment = navigationController?.currentFrag as? MagiskFragment<*, *>
|
||||
|
||||
if (fragment?.onBackPressed() == true) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
navigationController?.popFragment() ?: throw UnsupportedOperationException()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
when {
|
||||
isRootFragment -> {
|
||||
val options = FragNavTransactionOptions.newBuilder()
|
||||
.transition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
|
||||
.build()
|
||||
navigationController?.switchTab(defaultPosition, options)
|
||||
}
|
||||
else -> super.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFragmentTransaction(
|
||||
fragment: Fragment?,
|
||||
transactionType: FragNavController.TransactionType
|
||||
) = Unit
|
||||
|
||||
override fun onTabTransaction(fragment: Fragment?, index: Int) = Unit
|
||||
|
||||
fun openUrl(url: String) = Utils.openLink(this, url.toUri())
|
||||
|
||||
fun withPermissions(vararg permissions: String, builder: PermissionRequestBuilder.() -> Unit) {
|
||||
val request = PermissionRequestBuilder().apply(builder).build()
|
||||
Dexter.withActivity(this)
|
||||
.withPermissions(*permissions)
|
||||
.withListener(object : MultiplePermissionsListener {
|
||||
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
|
||||
if (report.areAllPermissionsGranted()) {
|
||||
request.onSuccess()
|
||||
} else {
|
||||
request.onFailure()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionRationaleShouldBeShown(
|
||||
permissions: MutableList<PermissionRequest>,
|
||||
token: PermissionToken
|
||||
) = token.continuePermissionRequest()
|
||||
}).check()
|
||||
}
|
||||
|
||||
fun withExternalRW(builder: PermissionRequestBuilder.() -> Unit) {
|
||||
withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, builder = builder)
|
||||
}
|
||||
|
||||
private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) =
|
||||
customAnimations(options.enter, options.exit, options.popEnter, options.popExit).apply {
|
||||
if (!options.anySet) {
|
||||
transition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
resultCallbacks[requestCode]?.apply {
|
||||
resultCallbacks.remove(requestCode)
|
||||
invoke(this@MagiskActivity, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
fun startActivityForResult(intent: Intent, requestCode: Int, listener: RequestCallback) {
|
||||
resultCallbacks[requestCode] = listener
|
||||
startActivityForResult(intent, requestCode)
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.findNavController
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.extensions.snackbar
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
|
||||
import com.topjohnwu.magisk.model.navigation.Navigator
|
||||
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class MagiskFragment<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
Fragment(), Navigator, EventHandler {
|
||||
|
||||
protected val activity get() = requireActivity() as MagiskActivity<*, *>
|
||||
protected lateinit var binding: Binding
|
||||
protected abstract val layoutRes: Int
|
||||
protected abstract val viewModel: ViewModel
|
||||
protected open val snackbarView get() = binding.root
|
||||
protected val navController get() = binding.root.findNavController()
|
||||
private val viewEventObserver = ViewEventObserver {
|
||||
onEventDispatched(it)
|
||||
if (it is SimpleViewEvent) {
|
||||
onSimpleEventDispatched(it.event)
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need nested fragments
|
||||
override val baseFragments: List<KClass<Fragment>> = listOf()
|
||||
|
||||
override fun navigateTo(event: MagiskNavigationEvent) = activity.navigateTo(event)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
viewModel.viewEvents.observe(this, viewEventObserver)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = DataBindingUtil.inflate<Binding>(inflater, layoutRes, container, false).apply {
|
||||
setVariable(BR.viewModel, viewModel)
|
||||
lifecycleOwner = this@MagiskFragment
|
||||
}
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is SnackbarEvent -> snackbar(snackbarView, event.message(requireContext()), event.length, event.f)
|
||||
is BackPressEvent -> activity.onBackPressed()
|
||||
is MagiskNavigationEvent -> navigateTo(event)
|
||||
is ViewActionEvent -> event.action(requireActivity())
|
||||
is PermissionEvent -> activity.withPermissions(*event.permissions.toTypedArray()) {
|
||||
onSuccess { event.callback.onNext(true) }
|
||||
onFailure {
|
||||
event.callback.onNext(false)
|
||||
event.callback.onError(SecurityException("User refused permissions"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun withPermissions(vararg permissions: String, builder: PermissionRequestBuilder.() -> Unit) {
|
||||
activity.withPermissions(*permissions, builder = builder)
|
||||
}
|
||||
|
||||
fun openLink(url: String) = activity.openUrl(url)
|
||||
|
||||
open fun onBackPressed(): Boolean = false
|
||||
|
||||
}
|
@ -9,8 +9,8 @@ import androidx.core.net.toUri
|
||||
import com.topjohnwu.magisk.ClassMap
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.databinding.ActivityFlashBinding
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import java.io.File
|
||||
|
@ -11,6 +11,7 @@ import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.*
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleRvItem
|
||||
@ -18,7 +19,6 @@ import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.flash.FlashResultListener
|
||||
import com.topjohnwu.magisk.model.flash.Flashing
|
||||
import com.topjohnwu.magisk.model.flash.Patching
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.topjohnwu.magisk.ui.hide
|
||||
|
||||
import android.content.pm.ApplicationInfo
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
@ -13,9 +13,9 @@ import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.HideRvItem
|
||||
import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
||||
import com.topjohnwu.magisk.model.events.HideProcessEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -6,8 +6,8 @@ import android.view.MenuItem
|
||||
import android.widget.SearchView
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.FragmentMagiskHideBinding
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
class MagiskHideFragment : MagiskFragment<HideViewModel, FragmentMagiskHideBinding>(),
|
||||
|
@ -1,19 +1,18 @@
|
||||
package com.topjohnwu.magisk.ui.home
|
||||
|
||||
import android.content.Context
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.Info
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||
import com.topjohnwu.magisk.databinding.FragmentMagiskBinding
|
||||
import com.topjohnwu.magisk.extensions.inject
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.extensions.writeTo
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.utils.DynamicClassLoader
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
@ -39,7 +38,7 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is OpenLinkEvent -> openLink(event.url)
|
||||
is OpenLinkEvent -> activity.openUrl(event.url)
|
||||
is ManagerInstallEvent -> installManager()
|
||||
is MagiskInstallEvent -> installMagisk()
|
||||
is UninstallEvent -> uninstall()
|
||||
|
@ -2,11 +2,11 @@ package com.topjohnwu.magisk.ui.home
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import com.topjohnwu.magisk.*
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||
import com.topjohnwu.magisk.extensions.*
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.observer.Observer
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -6,11 +6,11 @@ import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.FragmentLogBinding
|
||||
import com.topjohnwu.magisk.model.events.PageChangedEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
class LogFragment : MagiskFragment<LogViewModel, FragmentLogBinding>() {
|
||||
|
@ -1,11 +1,11 @@
|
||||
package com.topjohnwu.magisk.ui.log
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
@ -17,7 +17,7 @@ import com.topjohnwu.magisk.model.entity.recycler.LogItemRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.LogRvItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.MagiskLogRvItem
|
||||
import com.topjohnwu.magisk.model.events.PageChangedEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.module
|
||||
import android.content.res.Resources
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.database.RepoDao
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.*
|
||||
@ -14,7 +15,6 @@ import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
||||
import com.topjohnwu.magisk.tasks.RepoUpdater
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import io.reactivex.Single
|
||||
|
@ -8,14 +8,14 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.ClassMap
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.FragmentModulesBinding
|
||||
import com.topjohnwu.magisk.extensions.reboot
|
||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.ui.flash.FlashActivity
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
@ -6,9 +6,9 @@ import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.widget.SearchView
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.FragmentReposBinding
|
||||
import com.topjohnwu.magisk.model.download.DownloadService
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
@ -16,7 +16,7 @@ import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.entity.module.Repo
|
||||
import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
@ -17,6 +17,7 @@ import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.BasePreferenceFragment
|
||||
import com.topjohnwu.magisk.data.database.RepoDao
|
||||
import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
@ -26,7 +27,6 @@ import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.observer.Observer
|
||||
import com.topjohnwu.magisk.net.Networking
|
||||
import com.topjohnwu.magisk.ui.base.BasePreferenceFragment
|
||||
import com.topjohnwu.magisk.utils.*
|
||||
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.topjohnwu.magisk.ui.superuser
|
||||
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskFragment
|
||||
import com.topjohnwu.magisk.databinding.FragmentSuperuserBinding
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
class SuperuserFragment :
|
||||
|
@ -2,10 +2,9 @@ package com.topjohnwu.magisk.ui.superuser
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.database.PolicyDao
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.applySchedulers
|
||||
@ -15,9 +14,10 @@ import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
||||
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
||||
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.FingerprintHelper
|
||||
import com.topjohnwu.magisk.utils.RxBus
|
||||
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog
|
||||
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
||||
import io.reactivex.Single
|
||||
|
@ -5,13 +5,13 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.Window
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
||||
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.events.DieEvent
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.model.receiver.GeneralReceiver
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.utils.SuLogger
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
|
@ -12,6 +12,7 @@ import android.text.TextUtils
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||
import com.topjohnwu.magisk.data.database.PolicyDao
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
||||
@ -20,7 +21,6 @@ import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem
|
||||
import com.topjohnwu.magisk.model.entity.toPolicy
|
||||
import com.topjohnwu.magisk.model.events.DieEvent
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.FingerprintHelper
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
|
@ -7,10 +7,10 @@ import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
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.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
|
||||
internal class InstallMethodDialog(activity: MagiskActivity<*, *>, options: List<String>) :
|
||||
|
@ -3,7 +3,7 @@ package com.topjohnwu.magisk.view.dialogs
|
||||
import android.net.Uri
|
||||
import com.topjohnwu.magisk.Info
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.base.MagiskActivity
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.superuser.Shell
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.topjohnwu.magisk.viewmodel.LoadingViewModel.State" />
|
||||
<import type="com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State" />
|
||||
|
||||
<import type="com.topjohnwu.magisk.ui.home.SafetyNetState" />
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user