Commit a18c552d authored by topjohnwu's avatar topjohnwu

Guard env state behind cached objects

parent 9656878e
package com.topjohnwu.magisk package com.topjohnwu.magisk
import com.topjohnwu.magisk.model.entity.UpdateInfo import com.topjohnwu.magisk.model.entity.UpdateInfo
import com.topjohnwu.magisk.utils.CachedValue
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
object Info { object Info {
var magiskVersionCode = -1 val envRef = CachedValue { loadState() }
var magiskVersionString = "" val env by envRef // Local
var remote = UpdateInfo() // Remote
var remote = UpdateInfo()
var keepVerity = false var keepVerity = false
var keepEnc = false var keepEnc = false
var recovery = false var recovery = false
fun loadMagiskInfo() { private fun loadState() = runCatching {
runCatching { val str = ShellUtils.fastCmd("magisk -v").split(":".toRegex())[0]
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":".toRegex())[0] val code = ShellUtils.fastCmd("magisk -V").toInt()
magiskVersionCode = ShellUtils.fastCmd("magisk -V").toInt() val hide = Shell.su("magiskhide --status").exec().isSuccess
Config.magiskHide = Shell.su("magiskhide --status").exec().isSuccess Env(code, str, hide)
}.getOrElse { Env() }
class Env(
val magiskVersionCode: Int = -1,
val magiskVersionString: String = "",
hide: Boolean = false
) {
val magiskHide get() = Config.magiskHide
init {
Config.magiskHide = hide
} }
} }
} }
...@@ -29,7 +29,7 @@ class MagiskRepository( ...@@ -29,7 +29,7 @@ class MagiskRepository(
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
}.flatMap { }.flatMap {
// If remote version is lower than current installed, try switching to beta // If remote version is lower than current installed, try switching to beta
if (it.magisk.versionCode < Info.magiskVersionCode if (it.magisk.versionCode < Info.env.magiskVersionCode
&& Config.updateChannel == Config.Value.DEFAULT_CHANNEL) { && Config.updateChannel == Config.Value.DEFAULT_CHANNEL) {
Config.updateChannel = Config.Value.BETA_CHANNEL Config.updateChannel = Config.Value.BETA_CHANNEL
apiRaw.fetchBetaUpdate() apiRaw.fetchBetaUpdate()
......
...@@ -20,7 +20,7 @@ class UpdateCheckService : DelegateWorker() { ...@@ -20,7 +20,7 @@ class UpdateCheckService : DelegateWorker() {
magiskRepo.fetchUpdate().blockingGet() magiskRepo.fetchUpdate().blockingGet()
if (BuildConfig.VERSION_CODE < Info.remote.app.versionCode) if (BuildConfig.VERSION_CODE < Info.remote.app.versionCode)
Notifications.managerUpdate(applicationContext) Notifications.managerUpdate(applicationContext)
else if (Info.magiskVersionCode < Info.remote.magisk.versionCode) else if (Info.env.magiskVersionCode < Info.remote.magisk.versionCode)
Notifications.magiskUpdate(applicationContext) Notifications.magiskUpdate(applicationContext)
ListenableWorker.Result.success() ListenableWorker.Result.success()
}.getOrElse { }.getOrElse {
......
...@@ -7,13 +7,15 @@ import androidx.fragment.app.Fragment ...@@ -7,13 +7,15 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import com.ncapdevi.fragnav.FragNavController import com.ncapdevi.fragnav.FragNavController
import com.ncapdevi.fragnav.FragNavTransactionOptions import com.ncapdevi.fragnav.FragNavTransactionOptions
import com.topjohnwu.magisk.*
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.R
import com.topjohnwu.magisk.base.BaseActivity import com.topjohnwu.magisk.base.BaseActivity
import com.topjohnwu.magisk.base.BaseFragment import com.topjohnwu.magisk.base.BaseFragment
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.extensions.snackbar
import com.topjohnwu.magisk.intent
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
...@@ -152,11 +154,11 @@ open class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(), Na ...@@ -152,11 +154,11 @@ open class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(), Na
private fun checkHideSection() { private fun checkHideSection() {
val menu = binding.navView.menu val menu = binding.navView.menu
menu.findItem(R.id.magiskHideFragment).isVisible = menu.findItem(R.id.magiskHideFragment).isVisible =
Shell.rootAccess() && Config.magiskHide Shell.rootAccess() && Info.env.magiskHide
menu.findItem(R.id.modulesFragment).isVisible = menu.findItem(R.id.modulesFragment).isVisible =
Shell.rootAccess() && Info.magiskVersionCode >= 0 Shell.rootAccess() && Info.env.magiskVersionCode >= 0
menu.findItem(R.id.reposFragment).isVisible = menu.findItem(R.id.reposFragment).isVisible =
(viewModel.isConnected.value && Shell.rootAccess() && Info.magiskVersionCode >= 0) (viewModel.isConnected.value && Shell.rootAccess() && Info.env.magiskVersionCode >= 0)
menu.findItem(R.id.logFragment).isVisible = menu.findItem(R.id.logFragment).isVisible =
Shell.rootAccess() Shell.rootAccess()
menu.findItem(R.id.superuserFragment).isVisible = menu.findItem(R.id.superuserFragment).isVisible =
......
...@@ -7,7 +7,6 @@ import android.text.TextUtils ...@@ -7,7 +7,6 @@ import android.text.TextUtils
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.topjohnwu.magisk.* import com.topjohnwu.magisk.*
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.wrap
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
...@@ -22,7 +21,7 @@ open class SplashActivity : Activity() { ...@@ -22,7 +21,7 @@ open class SplashActivity : Activity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Shell.getShell { Shell.getShell {
if (Info.magiskVersionCode > 0 && Info.magiskVersionCode < Const.MagiskVersion.MIN_SUPPORT) { if (Info.env.magiskVersionCode > 0 && Info.env.magiskVersionCode < Const.MagiskVersion.MIN_SUPPORT) {
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setTitle(R.string.unsupport_magisk_title) .setTitle(R.string.unsupport_magisk_title)
.setMessage(R.string.unsupport_magisk_message) .setMessage(R.string.unsupport_magisk_message)
......
...@@ -107,10 +107,10 @@ class HomeViewModel( ...@@ -107,10 +107,10 @@ class HomeViewModel(
Info.recovery = it ?: return@addOnPropertyChangedCallback Info.recovery = it ?: return@addOnPropertyChangedCallback
} }
isConnected.addOnPropertyChangedCallback { isConnected.addOnPropertyChangedCallback {
if (it == true) refresh() if (it == true) refresh(false)
} }
refresh() refresh(false)
} }
fun paypalPressed() = OpenLinkEvent(Const.Url.PAYPAL_URL).publish() fun paypalPressed() = OpenLinkEvent(Const.Url.PAYPAL_URL).publish()
...@@ -170,7 +170,11 @@ class HomeViewModel( ...@@ -170,7 +170,11 @@ class HomeViewModel(
} }
} }
fun refresh() { @JvmOverloads
fun refresh(invalidate: Boolean = true) {
if (invalidate)
Info.envRef.invalidate()
hasRoot.value = Shell.rootAccess() hasRoot.value = Shell.rootAccess()
val fetchUpdate = if (isConnected.value) val fetchUpdate = if (isConnected.value)
...@@ -179,7 +183,8 @@ class HomeViewModel( ...@@ -179,7 +183,8 @@ class HomeViewModel(
Completable.complete() Completable.complete()
Completable.fromAction { Completable.fromAction {
Info.loadMagiskInfo() // Ensure value is ready
Info.env
}.andThen(fetchUpdate) }.andThen(fetchUpdate)
.applyViewModel(this) .applyViewModel(this)
.doOnSubscribeUi { .doOnSubscribeUi {
...@@ -197,7 +202,7 @@ class HomeViewModel( ...@@ -197,7 +202,7 @@ class HomeViewModel(
private fun refreshVersions() { private fun refreshVersions() {
magiskCurrentVersion.value = if (magiskState.value != MagiskState.NOT_INSTALLED) { magiskCurrentVersion.value = if (magiskState.value != MagiskState.NOT_INSTALLED) {
version.format(Info.magiskVersionString, Info.magiskVersionCode) version.format(Info.env.magiskVersionString, Info.env.magiskVersionCode)
} else { } else {
"" ""
} }
...@@ -207,7 +212,7 @@ class HomeViewModel( ...@@ -207,7 +212,7 @@ class HomeViewModel(
} }
private fun updateSelf() { private fun updateSelf() {
magiskState.value = when (Info.magiskVersionCode) { magiskState.value = when (Info.env.magiskVersionCode) {
in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED
!in Info.remote.magisk.versionCode..Int.MAX_VALUE -> MagiskState.OBSOLETE !in Info.remote.magisk.versionCode..Int.MAX_VALUE -> MagiskState.OBSOLETE
else -> MagiskState.UP_TO_DATE else -> MagiskState.UP_TO_DATE
......
package com.topjohnwu.magisk.utils
class CachedValue<T>(private val factory: () -> T) : Lazy<T> {
private var _val : T? = null
override val value: T
get() {
val local = _val
return local ?: synchronized(this) {
val newInstance = factory()
_val = newInstance
newInstance
}
}
override fun isInitialized() = _val != null
fun invalidate() {
synchronized(this) {
_val = null
}
}
}
...@@ -22,7 +22,6 @@ class RootInit : Shell.Initializer() { ...@@ -22,7 +22,6 @@ class RootInit : Shell.Initializer() {
job.add(context.rawResource(R.raw.util_functions)) job.add(context.rawResource(R.raw.util_functions))
.add(context.rawResource(R.raw.utils)) .add(context.rawResource(R.raw.utils))
Const.MAGISK_DISABLE_FILE = SuFile("/cache/.disable_magisk") Const.MAGISK_DISABLE_FILE = SuFile("/cache/.disable_magisk")
Info.loadMagiskInfo()
} else { } else {
job.add(context.rawResource(R.raw.nonroot_utils)) job.add(context.rawResource(R.raw.nonroot_utils))
} }
......
...@@ -38,7 +38,7 @@ object Shortcuts { ...@@ -38,7 +38,7 @@ object Shortcuts {
.setRank(0) .setRank(0)
.build()) .build())
} }
if (root && Config.magiskHide) { if (root && Info.env.magiskHide) {
shortCuts.add(ShortcutInfo.Builder(context, "magiskhide") shortCuts.add(ShortcutInfo.Builder(context, "magiskhide")
.setShortLabel(context.getString(R.string.magiskhide)) .setShortLabel(context.getString(R.string.magiskhide))
.setIntent(Intent(intent) .setIntent(Intent(intent)
...@@ -49,7 +49,7 @@ object Shortcuts { ...@@ -49,7 +49,7 @@ object Shortcuts {
.setRank(1) .setRank(1)
.build()) .build())
} }
if (!Config.coreOnly && root && Info.magiskVersionCode >= 0) { if (!Config.coreOnly && root && Info.env.magiskVersionCode >= 0) {
shortCuts.add(ShortcutInfo.Builder(context, "modules") shortCuts.add(ShortcutInfo.Builder(context, "modules")
.setShortLabel(context.getString(R.string.modules)) .setShortLabel(context.getString(R.string.modules))
.setIntent(Intent(intent) .setIntent(Intent(intent)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment