Only allow hide/restore app if connected
This commit is contained in:
parent
d010cb7e42
commit
0b5fd3ee76
@ -1,7 +1,11 @@
|
||||
package com.topjohnwu.magisk
|
||||
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.topjohnwu.magisk.extensions.get
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.model.entity.UpdateInfo
|
||||
import com.topjohnwu.magisk.utils.CachedValue
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.topjohnwu.superuser.ShellUtils
|
||||
|
||||
@ -16,13 +20,27 @@ object Info {
|
||||
var keepEnc = false
|
||||
var recovery = false
|
||||
|
||||
val isConnected by lazy {
|
||||
KObservableField(false).also { field ->
|
||||
ReactiveNetwork.observeNetworkConnectivity(get())
|
||||
.subscribeK {
|
||||
field.value = it.available()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadState() = runCatching {
|
||||
val str = ShellUtils.fastCmd("magisk -v").split(":".toRegex())[0]
|
||||
val code = ShellUtils.fastCmd("magisk -V").toInt()
|
||||
val hide = Shell.su("magiskhide --status").exec().isSuccess
|
||||
var mode = Int.MAX_VALUE
|
||||
if (code >= Const.Version.CONNECT_MODE)
|
||||
var mode = -1
|
||||
if (code >= Const.Version.CONNECT_MODE) {
|
||||
mode = Shell.su("magisk --connect-mode").exec().code
|
||||
if (mode == 0) {
|
||||
// Manually trigger broadcast test
|
||||
Shell.su("magisk --broadcast-test").exec()
|
||||
}
|
||||
}
|
||||
Env(code, str, hide, mode)
|
||||
}.getOrElse { Env() }
|
||||
|
||||
@ -30,7 +48,7 @@ object Info {
|
||||
val magiskVersionCode: Int = -1,
|
||||
val magiskVersionString: String = "",
|
||||
hide: Boolean = false,
|
||||
var connectionMode: Int = Int.MAX_VALUE
|
||||
var connectionMode: Int = -1
|
||||
) {
|
||||
val magiskHide get() = Config.magiskHide
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.topjohnwu.magisk.base.viewmodel
|
||||
|
||||
import android.app.Activity
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.topjohnwu.magisk.Info.isConnected as gIsConnected
|
||||
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
|
||||
import com.topjohnwu.magisk.extensions.get
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.model.events.BackPressEvent
|
||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||
import com.topjohnwu.magisk.model.events.ViewActionEvent
|
||||
@ -17,12 +15,10 @@ abstract class BaseViewModel(
|
||||
initialState: State = State.LOADING
|
||||
) : LoadingViewModel(initialState) {
|
||||
|
||||
val isConnected = KObservableField(false)
|
||||
|
||||
init {
|
||||
ReactiveNetwork.observeNetworkConnectivity(get())
|
||||
.subscribeK { isConnected.value = it.available() }
|
||||
.add()
|
||||
val isConnected = object : KObservableField<Boolean>(gIsConnected.value, gIsConnected) {
|
||||
override fun get(): Boolean {
|
||||
return gIsConnected.value
|
||||
}
|
||||
}
|
||||
|
||||
fun withView(action: Activity.() -> Unit) {
|
||||
|
@ -24,7 +24,6 @@ import com.topjohnwu.magisk.model.download.DownloadService
|
||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.observer.Observer
|
||||
import com.topjohnwu.magisk.net.Networking
|
||||
import com.topjohnwu.magisk.utils.*
|
||||
import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
|
||||
import com.topjohnwu.superuser.Shell
|
||||
@ -54,6 +53,7 @@ class SettingsFragment : BasePreferenceFragment() {
|
||||
preferenceManager.setStorageDeviceProtected()
|
||||
setPreferencesFromResource(R.xml.app_settings, rootKey)
|
||||
|
||||
// Get preferences
|
||||
updateChannel = findPreference(Config.Key.UPDATE_CHANNEL)!!
|
||||
rootConfig = findPreference(Config.Key.ROOT_ACCESS)!!
|
||||
autoRes = findPreference(Config.Key.SU_AUTO_RESPONSE)!!
|
||||
@ -67,19 +67,68 @@ class SettingsFragment : BasePreferenceFragment() {
|
||||
val magiskCategory = findPreference<PreferenceCategory>("magisk")!!
|
||||
val suCategory = findPreference<PreferenceCategory>("superuser")!!
|
||||
val hideManager = findPreference<Preference>("hide")!!
|
||||
hideManager.setOnPreferenceClickListener {
|
||||
showManagerNameDialog {
|
||||
PatchAPK.hideManager(requireContext(), it)
|
||||
}
|
||||
true
|
||||
val restoreManager = findPreference<Preference>("restore")!!
|
||||
|
||||
// Remove/Disable entries
|
||||
|
||||
// Only show canary channels if user is already on canary channel
|
||||
// or the user have already chosen canary channel
|
||||
if (!Utils.isCanary && Config.updateChannel < Config.Value.CANARY_CHANNEL) {
|
||||
// Remove the last 2 entries
|
||||
val entries = updateChannel.entries
|
||||
updateChannel.entries = entries.copyOf(entries.size - 2)
|
||||
}
|
||||
val restoreManager = findPreference<Preference>("restore")
|
||||
restoreManager?.setOnPreferenceClickListener {
|
||||
DownloadService(requireContext()) {
|
||||
subject = DownloadSubject.Manager(Configuration.APK.Restore)
|
||||
}
|
||||
true
|
||||
|
||||
// Remove dangerous settings in secondary user
|
||||
if (Const.USER_ID > 0) {
|
||||
suCategory.removePreference(multiuserConfig)
|
||||
}
|
||||
|
||||
// Remove re-authentication option on Android O, it will not work
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
suCategory.removePreference(reauth)
|
||||
}
|
||||
|
||||
// Disable fingerprint option if not possible
|
||||
if (!FingerprintHelper.canUseFingerprint()) {
|
||||
fingerprint.isEnabled = false
|
||||
fingerprint.isChecked = false
|
||||
fingerprint.setSummary(R.string.disable_fingerprint)
|
||||
}
|
||||
|
||||
if (Const.USER_ID == 0 && Info.isConnected.value && Shell.rootAccess()) {
|
||||
if (activity.packageName == BuildConfig.APPLICATION_ID) {
|
||||
generalCatagory.removePreference(restoreManager)
|
||||
hideManager.setOnPreferenceClickListener {
|
||||
showManagerNameDialog {
|
||||
PatchAPK.hideManager(requireContext(), it)
|
||||
}
|
||||
true
|
||||
}
|
||||
} else {
|
||||
generalCatagory.removePreference(hideManager)
|
||||
restoreManager.setOnPreferenceClickListener {
|
||||
DownloadService(requireContext()) {
|
||||
subject = DownloadSubject.Manager(Configuration.APK.Restore)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove if not primary user, no connection, or no root
|
||||
generalCatagory.removePreference(restoreManager)
|
||||
generalCatagory.removePreference(hideManager)
|
||||
}
|
||||
|
||||
if (!Utils.showSuperUser()) {
|
||||
preferenceScreen.removePreference(suCategory)
|
||||
}
|
||||
|
||||
if (!Shell.rootAccess()) {
|
||||
preferenceScreen.removePreference(magiskCategory)
|
||||
generalCatagory.removePreference(hideManager)
|
||||
}
|
||||
|
||||
findPreference<Preference>("clear")?.setOnPreferenceClickListener {
|
||||
Completable.fromAction { repoDB.clear() }.subscribeK {
|
||||
Utils.toast(R.string.repo_cache_cleared, Toast.LENGTH_SHORT)
|
||||
@ -123,58 +172,7 @@ class SettingsFragment : BasePreferenceFragment() {
|
||||
|
||||
setLocalePreference(findPreference(Config.Key.LOCALE)!!)
|
||||
|
||||
/* We only show canary channels if user is already on canary channel
|
||||
* or the user have already chosen canary channel */
|
||||
if (!Utils.isCanary && Config.updateChannel < Config.Value.CANARY_CHANNEL) {
|
||||
// Remove the last 2 entries
|
||||
val entries = updateChannel.entries
|
||||
updateChannel.entries = entries.copyOf(entries.size - 2)
|
||||
|
||||
}
|
||||
|
||||
setSummary()
|
||||
|
||||
// Disable dangerous settings in secondary user
|
||||
if (Const.USER_ID > 0) {
|
||||
suCategory.removePreference(multiuserConfig)
|
||||
}
|
||||
|
||||
// Disable re-authentication option on Android O, it will not work
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
reauth.isEnabled = false
|
||||
reauth.isChecked = false
|
||||
reauth.setSummary(R.string.android_o_not_support)
|
||||
}
|
||||
|
||||
// Disable fingerprint option if not possible
|
||||
if (!FingerprintHelper.canUseFingerprint()) {
|
||||
fingerprint.isEnabled = false
|
||||
fingerprint.isChecked = false
|
||||
fingerprint.setSummary(R.string.disable_fingerprint)
|
||||
}
|
||||
|
||||
if (Shell.rootAccess() && Const.USER_ID == 0) {
|
||||
if (activity.packageName == BuildConfig.APPLICATION_ID) {
|
||||
generalCatagory.removePreference(restoreManager)
|
||||
} else {
|
||||
if (!Networking.checkNetworkStatus(requireContext())) {
|
||||
generalCatagory.removePreference(restoreManager)
|
||||
}
|
||||
generalCatagory.removePreference(hideManager)
|
||||
}
|
||||
} else {
|
||||
generalCatagory.removePreference(restoreManager)
|
||||
generalCatagory.removePreference(hideManager)
|
||||
}
|
||||
|
||||
if (!Utils.showSuperUser()) {
|
||||
preferenceScreen.removePreference(suCategory)
|
||||
}
|
||||
|
||||
if (!Shell.rootAccess()) {
|
||||
preferenceScreen.removePreference(magiskCategory)
|
||||
generalCatagory.removePreference(hideManager)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String) {
|
||||
|
@ -9,15 +9,11 @@ import java.io.Serializable
|
||||
* You can define if wrapped type is Nullable or not.
|
||||
* You can use kotlin get/set syntax for value
|
||||
*/
|
||||
class KObservableField<T> : ObservableField<T>, Serializable {
|
||||
open class KObservableField<T> : ObservableField<T>, Serializable {
|
||||
|
||||
var value: T
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
notifyChange()
|
||||
}
|
||||
}
|
||||
get() = get()
|
||||
set(value) { set(value) }
|
||||
|
||||
constructor(init: T) {
|
||||
value = init
|
||||
@ -27,23 +23,8 @@ class KObservableField<T> : ObservableField<T>, Serializable {
|
||||
value = init
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Needed for data binding, use KObservableField.value syntax from code",
|
||||
replaceWith = ReplaceWith("value")
|
||||
)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun get(): T {
|
||||
return value
|
||||
return super.get() as T
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Needed for data binding, use KObservableField.value = ... syntax from code",
|
||||
replaceWith = ReplaceWith("value = newValue")
|
||||
)
|
||||
override fun set(newValue: T) {
|
||||
value = newValue
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "KObservableField(value=$value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,11 +39,6 @@ class RootInit : Shell.Initializer() {
|
||||
Info.keepEnc = ShellUtils.fastCmd("echo \$KEEPFORCEENCRYPT").toBoolean()
|
||||
Info.recovery = ShellUtils.fastCmd("echo \$RECOVERYMODE").toBoolean()
|
||||
|
||||
if (Info.env.connectionMode == 0) {
|
||||
// Manually trigger broadcast test
|
||||
Shell.su("magisk --broadcast-test").exec()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user