Guard env state behind cached objects

This commit is contained in:
topjohnwu 2019-10-22 15:37:55 -04:00
parent 9656878ef3
commit a18c552ddf
9 changed files with 68 additions and 28 deletions

View File

@ -1,26 +1,37 @@
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
} }
} }
} }

View File

@ -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()

View File

@ -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 {

View File

@ -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
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 =

View File

@ -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() {
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)

View File

@ -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(
} }
} }
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(
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(
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(
} }
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

View File

@ -0,0 +1,24 @@
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
}
}
}

View File

@ -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))
} }

View File

@ -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 {
.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)