Random small refactoring

This commit is contained in:
topjohnwu 2023-07-24 23:49:20 -07:00
parent 6141bb5bb3
commit cf1bc82537
10 changed files with 21 additions and 132 deletions

View File

@ -8,6 +8,7 @@ import android.os.Bundle
import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.DispatcherExecutor import com.topjohnwu.magisk.core.utils.DispatcherExecutor
import com.topjohnwu.magisk.core.utils.ProcessLifecycle
import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.ShellInit import com.topjohnwu.magisk.core.utils.ShellInit
import com.topjohnwu.magisk.core.utils.refreshLocale import com.topjohnwu.magisk.core.utils.refreshLocale
@ -80,7 +81,7 @@ open class App() : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
ProcessLifecycleAccessor.init(this) ProcessLifecycle.init(this)
} }
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {

View File

@ -12,6 +12,7 @@ import com.topjohnwu.magisk.core.data.magiskdb.StringDao
import com.topjohnwu.magisk.core.ktx.deviceProtectedContext import com.topjohnwu.magisk.core.ktx.deviceProtectedContext
import com.topjohnwu.magisk.core.repository.LogRepository import com.topjohnwu.magisk.core.repository.LogRepository
import com.topjohnwu.magisk.core.repository.NetworkService import com.topjohnwu.magisk.core.repository.NetworkService
import com.topjohnwu.magisk.core.utils.BiometricHelper
import io.noties.markwon.Markwon import io.noties.markwon.Markwon
import io.noties.markwon.utils.NoCopySpannableFactory import io.noties.markwon.utils.NoCopySpannableFactory
@ -23,6 +24,7 @@ object ServiceLocator {
lateinit var context: Context lateinit var context: Context
val deContext by lazy { context.deviceProtectedContext } val deContext by lazy { context.deviceProtectedContext }
val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) } val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) }
val biometrics by lazy { BiometricHelper(context) }
// Database // Database
val policyDB = PolicyDao() val policyDB = PolicyDao()

View File

@ -12,7 +12,6 @@ import android.graphics.Canvas
import android.graphics.drawable.AdaptiveIconDrawable import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Process import android.os.Process
@ -21,16 +20,12 @@ import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.magisk.utils.APKInstall
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler import com.topjohnwu.superuser.internal.UiThreadHandler
import java.io.File import java.io.File
import kotlin.Array
import kotlin.String import kotlin.String
import java.lang.reflect.Array as JArray
fun Context.rawResource(id: Int) = resources.openRawResource(id) fun Context.rawResource(id: Int) = resources.openRawResource(id)
@ -56,110 +51,6 @@ val Context.deviceProtectedContext: Context get() =
createDeviceProtectedStorageContext() createDeviceProtectedStorageContext()
} else { this } } else { this }
fun Intent.startActivityWithRoot() {
val args = mutableListOf("am", "start", "--user", Const.USER_ID.toString())
val cmd = toCommand(args).joinToString(" ")
Shell.cmd(cmd).submit()
}
fun Intent.toCommand(args: MutableList<String> = mutableListOf()): MutableList<String> {
action?.also {
args.add("-a")
args.add(it)
}
component?.also {
args.add("-n")
args.add(it.flattenToString())
}
data?.also {
args.add("-d")
args.add(it.toString())
}
categories?.also {
for (cat in it) {
args.add("-c")
args.add(cat)
}
}
type?.also {
args.add("-t")
args.add(it)
}
extras?.also {
loop@ for (key in it.keySet()) {
val v = it[key] ?: continue
var value: Any = v
val arg: String
when {
v is String -> arg = "--es"
v is Boolean -> arg = "--ez"
v is Int -> arg = "--ei"
v is Long -> arg = "--el"
v is Float -> arg = "--ef"
v is Uri -> arg = "--eu"
v is ComponentName -> {
arg = "--ecn"
value = v.flattenToString()
}
v is List<*> -> {
if (v.isEmpty())
continue@loop
arg = if (v[0] is Int)
"--eial"
else if (v[0] is Long)
"--elal"
else if (v[0] is Float)
"--efal"
else if (v[0] is String)
"--esal"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
for (o in v) {
sb.append(o.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
}
v.javaClass.isArray -> {
arg = if (v is IntArray)
"--eia"
else if (v is LongArray)
"--ela"
else if (v is FloatArray)
"--efa"
else if (v is Array<*> && v.isArrayOf<String>())
"--esa"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
val len = JArray.getLength(v)
for (i in 0 until len) {
sb.append(JArray.get(v, i)!!.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
}
else -> continue@loop
} /* Unsupported */
args.add(arg)
args.add(key)
args.add(value.toString())
}
}
args.add("-f")
args.add(flags.toString())
return args
}
fun Context.cachedFile(name: String) = File(cacheDir, name) fun Context.cachedFile(name: String) = File(cacheDir, name)
fun ApplicationInfo.getLabel(pm: PackageManager): String { fun ApplicationInfo.getLabel(pm: PackageManager): String {

View File

@ -1,8 +1,6 @@
package com.topjohnwu.magisk.core.ktx package com.topjohnwu.magisk.core.ktx
import android.content.Context
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -15,12 +13,4 @@ fun reboot(reason: String = if (Config.recovery) "recovery" else "") {
Shell.cmd("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit() Shell.cmd("/system/bin/svc power reboot $reason || /system/bin/reboot $reason").submit()
} }
fun relaunchApp(context: Context) {
val intent = context.packageManager.getLaunchIntentForPackage(context.packageName) ?: return
val args = mutableListOf("am", "start", "--user", Const.USER_ID.toString())
val cmd = intent.toCommand(args).joinToString(separator = " ")
Shell.cmd("run_delay 1 \"$cmd\"").exec()
Runtime.getRuntime().exit(0)
}
suspend fun Shell.Job.await() = withContext(Dispatchers.IO) { exec() } suspend fun Shell.Job.await() = withContext(Dispatchers.IO) { exec() }

View File

@ -1,18 +1,19 @@
package com.topjohnwu.magisk.core.utils package com.topjohnwu.magisk.core.utils
import android.content.Context
import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.di.AppContext
object BiometricHelper { class BiometricHelper(context: Context) {
private val mgr by lazy { BiometricManager.from(AppContext) } private val mgr = BiometricManager.from(context)
val isSupported get() = when (mgr.canAuthenticate()) { val isSupported get() = when (mgr.canAuthenticate(Authenticators.BIOMETRIC_WEAK)) {
BiometricManager.BIOMETRIC_SUCCESS -> true BiometricManager.BIOMETRIC_SUCCESS -> true
else -> false else -> false
} }
@ -48,7 +49,7 @@ object BiometricHelper {
) )
val info = BiometricPrompt.PromptInfo.Builder() val info = BiometricPrompt.PromptInfo.Builder()
.setConfirmationRequired(true) .setConfirmationRequired(true)
.setDeviceCredentialAllowed(false) .setAllowedAuthenticators(Authenticators.BIOMETRIC_WEAK)
.setTitle(activity.getString(R.string.authenticate)) .setTitle(activity.getString(R.string.authenticate))
.setNegativeButtonText(activity.getString(android.R.string.cancel)) .setNegativeButtonText(activity.getString(android.R.string.cancel))
.build() .build()

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.core; package com.topjohnwu.magisk.core.utils;
import android.content.Context; import android.content.Context;
@ -7,7 +7,7 @@ import androidx.lifecycle.LifecycleDispatcher;
import androidx.lifecycle.ProcessLifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner;
// Use Java to bypass Kotlin internal visibility modifier // Use Java to bypass Kotlin internal visibility modifier
public class ProcessLifecycleAccessor { public class ProcessLifecycle {
public static void init(@NonNull Context context) { public static void init(@NonNull Context context) {
LifecycleDispatcher.init(context); LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init$lifecycle_process_release(context); ProcessLifecycleOwner.init$lifecycle_process_release(context);

View File

@ -3,6 +3,7 @@ package com.topjohnwu.magisk.events
import com.topjohnwu.magisk.arch.ActivityExecutor import com.topjohnwu.magisk.arch.ActivityExecutor
import com.topjohnwu.magisk.arch.UIActivity import com.topjohnwu.magisk.arch.UIActivity
import com.topjohnwu.magisk.arch.ViewEvent import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
class BiometricEvent( class BiometricEvent(
@ -17,7 +18,7 @@ class BiometricEvent(
} }
override fun invoke(activity: UIActivity<*>) { override fun invoke(activity: UIActivity<*>) {
BiometricHelper.authenticate( ServiceLocator.biometrics.authenticate(
activity, activity,
onError = listenerOnFailure, onError = listenerOnFailure,
onSuccess = listenerOnSuccess onSuccess = listenerOnSuccess

View File

@ -12,6 +12,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.activity import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
@ -289,7 +290,7 @@ object Biometrics : BaseSettingsItem.Toggle() {
override var value by Config::suBiometric override var value by Config::suBiometric
override fun refresh() { override fun refresh() {
isEnabled = BiometricHelper.isSupported isEnabled = ServiceLocator.biometrics.isSupported
if (!isEnabled) { if (!isEnabled) {
value = false value = false
description = R.string.no_biometric.asText() description = R.string.no_biometric.asText()

View File

@ -13,6 +13,7 @@ import com.topjohnwu.magisk.arch.AsyncLoadViewModel
import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.getLabel import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
@ -113,7 +114,7 @@ class SuperuserViewModel(
} }
} }
if (BiometricHelper.isEnabled) { if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()
@ -169,7 +170,7 @@ class SuperuserViewModel(
} }
} }
if (BiometricHelper.isEnabled) { if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()

View File

@ -22,6 +22,7 @@ import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.ktx.getLabel import com.topjohnwu.magisk.core.ktx.getLabel
import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
@ -75,7 +76,7 @@ class SuRequestViewModel(
fun grantPressed() { fun grantPressed() {
cancelTimer() cancelTimer()
if (BiometricHelper.isEnabled) { if (ServiceLocator.biometrics.isEnabled) {
BiometricEvent { BiometricEvent {
onSuccess { onSuccess {
respond(ALLOW) respond(ALLOW)