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
|
# DelegateWorker
|
||||||
-keep,allowobfuscation class * extends com.topjohnwu.magisk.model.worker.DelegateWorker
|
-keep,allowobfuscation class * extends com.topjohnwu.magisk.base.DelegateWorker
|
||||||
|
|
||||||
# BootSigner
|
# BootSigner
|
||||||
-keepclassmembers class com.topjohnwu.signing.BootSigner { *; }
|
-keepclassmembers class com.topjohnwu.signing.BootSigner { *; }
|
||||||
|
@ -6,7 +6,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.work.Worker;
|
import androidx.work.Worker;
|
||||||
import androidx.work.WorkerParameters;
|
import androidx.work.WorkerParameters;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.model.worker.DelegateWorker;
|
import com.topjohnwu.magisk.base.DelegateWorker;
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
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.annotation.SuppressLint
|
||||||
import android.content.SharedPreferences
|
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.content.Context
|
||||||
import android.net.Network
|
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 androidx.databinding.Bindable
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
@ -13,7 +13,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
|||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
"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
|
DeprecationLevel.WARNING
|
||||||
)
|
)
|
||||||
fun setLoading() {
|
fun setLoading() {
|
||||||
@ -22,7 +22,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
|||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
"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
|
DeprecationLevel.WARNING
|
||||||
)
|
)
|
||||||
fun setLoaded() {
|
fun setLoaded() {
|
||||||
@ -31,7 +31,7 @@ abstract class LoadingViewModel(defaultState: State = State.LOADING) :
|
|||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
|
"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
|
DeprecationLevel.WARNING
|
||||||
)
|
)
|
||||||
fun setLoadingFailed() {
|
fun setLoadingFailed() {
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.ui.base
|
package com.topjohnwu.magisk.base.viewmodel
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
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.PermissionEvent
|
||||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.magisk.viewmodel.LoadingViewModel
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.subjects.PublishSubject
|
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.Observable
|
||||||
import androidx.databinding.PropertyChangeRegistry
|
import androidx.databinding.PropertyChangeRegistry
|
@ -1,4 +1,4 @@
|
|||||||
package com.topjohnwu.magisk.viewmodel
|
package com.topjohnwu.magisk.base.viewmodel
|
||||||
|
|
||||||
abstract class StatefulViewModel<State : Enum<*>>(
|
abstract class StatefulViewModel<State : Enum<*>>(
|
||||||
val defaultState: State
|
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.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
@ -1,6 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.model.entity.recycler
|
||||||
|
|
||||||
import com.topjohnwu.magisk.utils.RxBus
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.model.events.HideProcessEvent
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
|
import com.topjohnwu.magisk.utils.RxBus
|
||||||
|
|
||||||
class HideRvItem(val item: HideAppInfo, targets: List<HideTarget>) :
|
class HideRvItem(val item: HideAppInfo, targets: List<HideTarget>) :
|
||||||
ComparableRvItem<HideRvItem>() {
|
ComparableRvItem<HideRvItem>() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.model.entity.recycler
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import com.topjohnwu.magisk.utils.RxBus
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.PolicyEnableEvent
|
||||||
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
|
import com.topjohnwu.magisk.utils.RxBus
|
||||||
|
|
||||||
class PolicyRvItem(val item: MagiskPolicy, val icon: Drawable) : ComparableRvItem<PolicyRvItem>() {
|
class PolicyRvItem(val item: MagiskPolicy, val icon: Drawable) : ComparableRvItem<PolicyRvItem>() {
|
||||||
|
|
||||||
|
@ -15,4 +15,11 @@ internal interface EventHandler {
|
|||||||
* the way how you handle them.
|
* the way how you handle them.
|
||||||
*/
|
*/
|
||||||
fun onSimpleEventDispatched(event: Int) {}
|
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
|
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.MagiskPolicy
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.HideProcessRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem
|
||||||
|
import com.topjohnwu.magisk.utils.RxBus
|
||||||
|
|
||||||
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
|
class HideProcessEvent(val item: HideProcessRvItem) : RxBus.Event
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.model.events
|
package com.topjohnwu.magisk.model.events
|
||||||
|
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
|
|
||||||
class SimpleViewEvent(
|
class SimpleViewEvent(
|
||||||
val event: Int
|
val event: Int
|
||||||
) : ViewEvent()
|
) : ViewEvent()
|
@ -3,7 +3,6 @@ package com.topjohnwu.magisk.model.events
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
|
|
||||||
class SnackbarEvent private constructor(
|
class SnackbarEvent private constructor(
|
||||||
@StringRes private val messageRes: Int,
|
@StringRes private val messageRes: Int,
|
||||||
|
@ -3,9 +3,9 @@ package com.topjohnwu.magisk.model.update
|
|||||||
import androidx.work.ListenableWorker
|
import androidx.work.ListenableWorker
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
import com.topjohnwu.magisk.Info
|
import com.topjohnwu.magisk.Info
|
||||||
|
import com.topjohnwu.magisk.base.DelegateWorker
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.extensions.inject
|
import com.topjohnwu.magisk.extensions.inject
|
||||||
import com.topjohnwu.magisk.model.worker.DelegateWorker
|
|
||||||
import com.topjohnwu.magisk.view.Notifications
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
|
||||||
|
@ -4,15 +4,24 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.fragment.app.Fragment
|
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.ClassMap
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.Const.Key.OPEN_SECTION
|
import com.topjohnwu.magisk.Const.Key.OPEN_SECTION
|
||||||
import com.topjohnwu.magisk.Info
|
import com.topjohnwu.magisk.Info
|
||||||
import com.topjohnwu.magisk.R
|
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.databinding.ActivityMainBinding
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.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.hide.MagiskHideFragment
|
||||||
import com.topjohnwu.magisk.ui.home.HomeFragment
|
import com.topjohnwu.magisk.ui.home.HomeFragment
|
||||||
import com.topjohnwu.magisk.ui.log.LogFragment
|
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.magisk.utils.Utils
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
import timber.log.Timber
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>(), Navigator,
|
||||||
open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
FragNavController.RootFragmentListener, FragNavController.TransactionListener {
|
||||||
|
|
||||||
override val layoutRes: Int = R.layout.activity_main
|
override val layoutRes: Int = R.layout.activity_main
|
||||||
override val viewModel: MainViewModel by viewModel()
|
override val viewModel: MainViewModel by viewModel()
|
||||||
override val navHostId: Int = R.id.main_nav_host
|
override val navHostId: Int = R.id.main_nav_host
|
||||||
override val defaultPosition: Int = 0
|
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(
|
override val baseFragments: List<KClass<out Fragment>> = listOf(
|
||||||
HomeFragment::class,
|
HomeFragment::class,
|
||||||
SuperuserFragment::class,
|
SuperuserFragment::class,
|
||||||
@ -50,6 +67,13 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
navigationController?.apply {
|
||||||
|
rootFragmentListener = this@MainActivity
|
||||||
|
transactionListener = this@MainActivity
|
||||||
|
initialize(defaultPosition, savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
checkHideSection()
|
checkHideSection()
|
||||||
setSupportActionBar(binding.mainInclude.mainToolbar)
|
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?) {
|
override fun setTitle(title: CharSequence?) {
|
||||||
supportActionBar?.title = title
|
supportActionBar?.title = title
|
||||||
}
|
}
|
||||||
@ -72,21 +101,27 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
|||||||
supportActionBar?.setTitle(titleId)
|
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() {
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (binding.drawerLayout.isDrawerOpen(binding.navView)) {
|
if (binding.drawerLayout.isDrawerOpen(binding.navView)) {
|
||||||
binding.drawerLayout.closeDrawer(binding.navView)
|
binding.drawerLayout.closeDrawer(binding.navView)
|
||||||
} else {
|
} 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) {
|
override fun onSimpleEventDispatched(event: Int) {
|
||||||
super.onSimpleEventDispatched(event)
|
super.onSimpleEventDispatched(event)
|
||||||
when (event) {
|
when (event) {
|
||||||
@ -116,4 +168,84 @@ open class MainActivity : MagiskActivity<MainViewModel, ActivityMainBinding>() {
|
|||||||
menu.findItem(R.id.superuserFragment).isVisible =
|
menu.findItem(R.id.superuserFragment).isVisible =
|
||||||
Utils.showSuperUser()
|
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 android.view.MenuItem
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
|
||||||
|
|
||||||
|
|
||||||
class MainViewModel : 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.ClassMap
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskActivity
|
||||||
import com.topjohnwu.magisk.databinding.ActivityFlashBinding
|
import com.topjohnwu.magisk.databinding.ActivityFlashBinding
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -11,6 +11,7 @@ import com.topjohnwu.magisk.BR
|
|||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.*
|
import com.topjohnwu.magisk.extensions.*
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleRvItem
|
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.FlashResultListener
|
||||||
import com.topjohnwu.magisk.model.flash.Flashing
|
import com.topjohnwu.magisk.model.flash.Flashing
|
||||||
import com.topjohnwu.magisk.model.flash.Patching
|
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.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.topjohnwu.magisk.ui.hide
|
package com.topjohnwu.magisk.ui.hide
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import com.topjohnwu.magisk.utils.RxBus
|
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.recycler.HideRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
import com.topjohnwu.magisk.model.entity.state.IndeterminateState
|
||||||
import com.topjohnwu.magisk.model.events.HideProcessEvent
|
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.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
|
import com.topjohnwu.magisk.utils.RxBus
|
||||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ import android.view.MenuItem
|
|||||||
import android.widget.SearchView
|
import android.widget.SearchView
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskFragment
|
||||||
import com.topjohnwu.magisk.databinding.FragmentMagiskHideBinding
|
import com.topjohnwu.magisk.databinding.FragmentMagiskHideBinding
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class MagiskHideFragment : MagiskFragment<HideViewModel, FragmentMagiskHideBinding>(),
|
class MagiskHideFragment : MagiskFragment<HideViewModel, FragmentMagiskHideBinding>(),
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package com.topjohnwu.magisk.ui.home
|
package com.topjohnwu.magisk.ui.home
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.Info
|
import com.topjohnwu.magisk.Info
|
||||||
import com.topjohnwu.magisk.R
|
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.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.databinding.FragmentMagiskBinding
|
import com.topjohnwu.magisk.databinding.FragmentMagiskBinding
|
||||||
import com.topjohnwu.magisk.extensions.inject
|
import com.topjohnwu.magisk.extensions.inject
|
||||||
import com.topjohnwu.magisk.extensions.subscribeK
|
import com.topjohnwu.magisk.extensions.subscribeK
|
||||||
import com.topjohnwu.magisk.extensions.writeTo
|
import com.topjohnwu.magisk.extensions.writeTo
|
||||||
import com.topjohnwu.magisk.model.events.*
|
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.DynamicClassLoader
|
||||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
@ -39,7 +38,7 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
|
|||||||
override fun onEventDispatched(event: ViewEvent) {
|
override fun onEventDispatched(event: ViewEvent) {
|
||||||
super.onEventDispatched(event)
|
super.onEventDispatched(event)
|
||||||
when (event) {
|
when (event) {
|
||||||
is OpenLinkEvent -> openLink(event.url)
|
is OpenLinkEvent -> activity.openUrl(event.url)
|
||||||
is ManagerInstallEvent -> installManager()
|
is ManagerInstallEvent -> installManager()
|
||||||
is MagiskInstallEvent -> installMagisk()
|
is MagiskInstallEvent -> installMagisk()
|
||||||
is UninstallEvent -> uninstall()
|
is UninstallEvent -> uninstall()
|
||||||
|
@ -2,11 +2,11 @@ package com.topjohnwu.magisk.ui.home
|
|||||||
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import com.topjohnwu.magisk.*
|
import com.topjohnwu.magisk.*
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
import com.topjohnwu.magisk.data.repository.MagiskRepository
|
||||||
import com.topjohnwu.magisk.extensions.*
|
import com.topjohnwu.magisk.extensions.*
|
||||||
import com.topjohnwu.magisk.model.events.*
|
import com.topjohnwu.magisk.model.events.*
|
||||||
import com.topjohnwu.magisk.model.observer.Observer
|
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.KObservableField
|
||||||
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
import com.topjohnwu.magisk.utils.SafetyNetHelper
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -6,11 +6,11 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskFragment
|
||||||
import com.topjohnwu.magisk.databinding.FragmentLogBinding
|
import com.topjohnwu.magisk.databinding.FragmentLogBinding
|
||||||
import com.topjohnwu.magisk.model.events.PageChangedEvent
|
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
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class LogFragment : MagiskFragment<LogViewModel, FragmentLogBinding>() {
|
class LogFragment : MagiskFragment<LogViewModel, FragmentLogBinding>() {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package com.topjohnwu.magisk.ui.log
|
package com.topjohnwu.magisk.ui.log
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.repository.LogRepository
|
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.LogRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.MagiskLogRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.MagiskLogRvItem
|
||||||
import com.topjohnwu.magisk.model.events.PageChangedEvent
|
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.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.module
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.database.RepoDao
|
import com.topjohnwu.magisk.data.database.RepoDao
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.*
|
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.OpenChangelogEvent
|
||||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
||||||
import com.topjohnwu.magisk.tasks.RepoUpdater
|
import com.topjohnwu.magisk.tasks.RepoUpdater
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
|
||||||
import com.topjohnwu.magisk.utils.DiffObservableList
|
import com.topjohnwu.magisk.utils.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
@ -8,14 +8,14 @@ import android.view.MenuInflater
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.ClassMap
|
import com.topjohnwu.magisk.ClassMap
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskFragment
|
||||||
import com.topjohnwu.magisk.databinding.FragmentModulesBinding
|
import com.topjohnwu.magisk.databinding.FragmentModulesBinding
|
||||||
import com.topjohnwu.magisk.extensions.reboot
|
import com.topjohnwu.magisk.extensions.reboot
|
||||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
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.magisk.ui.flash.FlashActivity
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
|
@ -6,9 +6,9 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.SearchView
|
import android.widget.SearchView
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskFragment
|
||||||
import com.topjohnwu.magisk.databinding.FragmentReposBinding
|
import com.topjohnwu.magisk.databinding.FragmentReposBinding
|
||||||
import com.topjohnwu.magisk.model.download.DownloadService
|
import com.topjohnwu.magisk.model.download.DownloadService
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
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.entity.module.Repo
|
||||||
import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
import com.topjohnwu.magisk.model.events.InstallModuleEvent
|
||||||
import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
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.MarkDownWindow
|
||||||
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog
|
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
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.Config
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.BasePreferenceFragment
|
||||||
import com.topjohnwu.magisk.data.database.RepoDao
|
import com.topjohnwu.magisk.data.database.RepoDao
|
||||||
import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
|
import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
|
||||||
import com.topjohnwu.magisk.extensions.subscribeK
|
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.entity.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.observer.Observer
|
import com.topjohnwu.magisk.model.observer.Observer
|
||||||
import com.topjohnwu.magisk.net.Networking
|
import com.topjohnwu.magisk.net.Networking
|
||||||
import com.topjohnwu.magisk.ui.base.BasePreferenceFragment
|
|
||||||
import com.topjohnwu.magisk.utils.*
|
import com.topjohnwu.magisk.utils.*
|
||||||
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.topjohnwu.magisk.ui.superuser
|
package com.topjohnwu.magisk.ui.superuser
|
||||||
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskFragment
|
||||||
import com.topjohnwu.magisk.databinding.FragmentSuperuserBinding
|
import com.topjohnwu.magisk.databinding.FragmentSuperuserBinding
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskFragment
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
class SuperuserFragment :
|
class SuperuserFragment :
|
||||||
|
@ -2,10 +2,9 @@ package com.topjohnwu.magisk.ui.superuser
|
|||||||
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Resources
|
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.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.database.PolicyDao
|
import com.topjohnwu.magisk.data.database.PolicyDao
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.applySchedulers
|
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.entity.recycler.PolicyRvItem
|
||||||
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
import com.topjohnwu.magisk.model.events.PolicyEnableEvent
|
||||||
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
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.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper
|
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.CustomAlertDialog
|
||||||
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
@ -5,13 +5,13 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskActivity
|
||||||
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
import com.topjohnwu.magisk.databinding.ActivityRequestBinding
|
||||||
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||||
import com.topjohnwu.magisk.model.events.DieEvent
|
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.model.receiver.GeneralReceiver
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskActivity
|
|
||||||
import com.topjohnwu.magisk.utils.SuLogger
|
import com.topjohnwu.magisk.utils.SuLogger
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
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.BuildConfig
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.viewmodel.MagiskViewModel
|
||||||
import com.topjohnwu.magisk.data.database.PolicyDao
|
import com.topjohnwu.magisk.data.database.PolicyDao
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
import com.topjohnwu.magisk.extensions.addOnPropertyChangedCallback
|
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.recycler.SpinnerRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.toPolicy
|
import com.topjohnwu.magisk.model.entity.toPolicy
|
||||||
import com.topjohnwu.magisk.model.events.DieEvent
|
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.DiffObservableList
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper
|
import com.topjohnwu.magisk.utils.FingerprintHelper
|
||||||
import com.topjohnwu.magisk.utils.KObservableField
|
import com.topjohnwu.magisk.utils.KObservableField
|
||||||
|
@ -7,10 +7,10 @@ import android.widget.Toast
|
|||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.base.MagiskActivity
|
||||||
import com.topjohnwu.magisk.model.download.DownloadService
|
import com.topjohnwu.magisk.model.download.DownloadService
|
||||||
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.ui.base.MagiskActivity
|
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
|
|
||||||
internal class InstallMethodDialog(activity: MagiskActivity<*, *>, options: List<String>) :
|
internal class InstallMethodDialog(activity: MagiskActivity<*, *>, options: List<String>) :
|
||||||
|
@ -3,7 +3,7 @@ package com.topjohnwu.magisk.view.dialogs
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.topjohnwu.magisk.Info
|
import com.topjohnwu.magisk.Info
|
||||||
import com.topjohnwu.magisk.R
|
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.utils.Utils
|
||||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<data>
|
<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" />
|
<import type="com.topjohnwu.magisk.ui.home.SafetyNetState" />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user