From 480198dcd003277d7f4908a476c87116bbac577b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 11 Jul 2024 15:50:40 -0700 Subject: [PATCH] Improve package migration --- .../com/topjohnwu/magisk/ui/SplashActivity.kt | 21 ++--- .../java/com/topjohnwu/magisk/core/Config.kt | 58 +++++++----- .../java/com/topjohnwu/magisk/core/Const.kt | 2 +- .../com/topjohnwu/magisk/core/Provider.kt | 15 --- .../magisk/core/base/BaseActivity.kt | 14 ++- .../core/repository/PreferenceConfig.kt | 91 ------------------- .../topjohnwu/magisk/core/tasks/HideAPK.kt | 14 +-- 7 files changed, 58 insertions(+), 157 deletions(-) diff --git a/app/apk/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt b/app/apk/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt index 8693e54ef..80ecb8c32 100644 --- a/app/apk/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt +++ b/app/apk/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt @@ -17,7 +17,7 @@ import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.JobService -import com.topjohnwu.magisk.core.base.realCallingPackage +import com.topjohnwu.magisk.core.base.launchPackage import com.topjohnwu.magisk.core.base.relaunch import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.isRunningAsStub @@ -113,15 +113,11 @@ abstract class SplashActivity : NavigationActivity : NavigationActivity/dev/null 2>&1").exec() } } else { - if (Config.suManager.isNotEmpty()) + if (Config.suManager.isNotEmpty()) { Config.suManager = "" - if (prevPkg != null) { + } + if (isPackageMigration) { Shell.cmd("(pm uninstall $prevPkg)& >/dev/null 2>&1").exec() } } - if (prevPkg != null) { + if (isPackageMigration) { runOnUiThread { // Relaunch the process after package migration StubApk.restartProcess(this) diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/Config.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/Config.kt index 0f976ddc4..332be0f88 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/Config.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/Config.kt @@ -1,17 +1,12 @@ package com.topjohnwu.magisk.core -import android.annotation.SuppressLint +import android.os.Bundle import androidx.core.content.edit import com.topjohnwu.magisk.core.di.ServiceLocator -import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.repository.DBConfig import com.topjohnwu.magisk.core.repository.PreferenceConfig import com.topjohnwu.magisk.core.utils.LocaleSetting -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.runBlocking -import java.io.File -import java.io.IOException object Config : PreferenceConfig, DBConfig { @@ -20,14 +15,6 @@ object Config : PreferenceConfig, DBConfig { override val context get() = ServiceLocator.deContext override val coroutineScope get() = GlobalScope - private val prefsFile = File("${context.filesDir.parent}/shared_prefs", "${fileName}.xml") - - @SuppressLint("ApplySharedPref") - fun getPrefsFile(): File { - prefs.edit().remove(Key.ASKED_HOME).commit() - return prefsFile - } - object Key { // db configs const val ROOT_ACCESS = "root_access" @@ -56,6 +43,9 @@ object Config : PreferenceConfig, DBConfig { const val ASKED_HOME = "asked_home" const val DOH = "doh" const val RAND_NAME = "rand_name" + + val NO_MIGRATION = setOf(ASKED_HOME, SU_REQUEST_TIMEOUT, + SU_AUTO_RESPONSE, SU_REAUTH, SU_TAPJACK) } object Value { @@ -159,17 +149,37 @@ object Config : PreferenceConfig, DBConfig { private const val SU_FINGERPRINT = "su_fingerprint" - fun load(pkg: String?) { - // Only try to load prefs when fresh install and a previous package name is set - if (pkg != null && prefs.all.isEmpty()) { - runBlocking { - try { - context.contentResolver - .openInputStream(Provider.preferencesUri(pkg)) - ?.writeTo(prefsFile, dispatcher = Dispatchers.Unconfined) - } catch (ignored: IOException) {} + fun toBundle(): Bundle { + val map = prefs.all - Key.NO_MIGRATION + return Bundle().apply { + for ((key, value) in map) { + when (value) { + is String -> putString(key, value) + is Int -> putInt(key, value) + is Boolean -> putBoolean(key, value) + } } - return + } + } + + @Suppress("DEPRECATION") + private fun fromBundle(bundle: Bundle) { + val keys = bundle.keySet().apply { removeAll(Key.NO_MIGRATION) } + prefs.edit { + for (key in keys) { + when (val value = bundle.get(key)) { + is String -> putString(key, value) + is Int -> putInt(key, value) + is Boolean -> putBoolean(key, value) + } + } + } + } + + fun init(bundle: Bundle?) { + // Only try to load prefs when fresh install + if (bundle != null && prefs.all.isEmpty()) { + fromBundle(bundle) } prefs.edit { diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/Const.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/Const.kt index 4b071c86e..2ac6a40c5 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/Const.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/Const.kt @@ -54,7 +54,7 @@ object Const { object Key { // intents const val OPEN_SECTION = "section" - const val PREV_PKG = "prev_pkg" + const val PREV_CONFIG = "prev_config" } object Value { diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/Provider.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/Provider.kt index c634ffe24..ef69615cd 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/Provider.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/Provider.kt @@ -1,9 +1,6 @@ package com.topjohnwu.magisk.core -import android.net.Uri import android.os.Bundle -import android.os.ParcelFileDescriptor -import android.os.ParcelFileDescriptor.MODE_READ_ONLY import com.topjohnwu.magisk.core.base.BaseProvider import com.topjohnwu.magisk.core.su.SuCallbackHandler import com.topjohnwu.magisk.core.su.TestHandler @@ -19,16 +16,4 @@ class Provider : BaseProvider() { else -> TestHandler.run(method) } } - - override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? { - return when (uri.encodedPath ?: return null) { - "/prefs_file" -> ParcelFileDescriptor.open(Config.getPrefsFile(), MODE_READ_ONLY) - else -> super.openFile(uri, mode) - } - } - - companion object { - fun preferencesUri(pkg: String): Uri = - Uri.Builder().scheme("content").authority("$pkg.provider").path("prefs_file").build() - } } diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt index fcdec33e2..7bd9e4440 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt @@ -125,14 +125,12 @@ class ActivityExtension(private val activity: ComponentActivity) { } } -private val mReferrerField by lazy(LazyThreadSafetyMode.NONE) { - Activity::class.java.reflectField("mReferrer") -} - -val Activity.realCallingPackage: String? get() { - callingPackage?.let { return it } - mReferrerField.get(this)?.let { return it as String } - return null +val Activity.launchPackage: String? get() { + return if (Build.VERSION.SDK_INT >= 34) { + launchedFromPackage + } else { + Activity::class.java.reflectField("mReferrer").get(this) as String? + } } fun Activity.relaunch() { diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/repository/PreferenceConfig.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/repository/PreferenceConfig.kt index 1005619ec..de1f0382f 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/repository/PreferenceConfig.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/repository/PreferenceConfig.kt @@ -35,36 +35,17 @@ interface PreferenceConfig { commit: Boolean = false ) = BooleanProperty(name, default, commit) - fun preference( - name: String, - default: Float, - commit: Boolean = false - ) = FloatProperty(name, default, commit) - fun preference( name: String, default: Int, commit: Boolean = false ) = IntProperty(name, default, commit) - fun preference( - name: String, - default: Long, - commit: Boolean = false - ) = LongProperty(name, default, commit) - fun preference( name: String, default: String, commit: Boolean = false ) = StringProperty(name, default, commit) - - fun preference( - name: String, - default: Set, - commit: Boolean = false - ) = StringSetProperty(name, default, commit) - } abstract class PreferenceProperty { @@ -109,30 +90,6 @@ class BooleanProperty( } } -class FloatProperty( - private val name: String, - private val default: Float, - private val commit: Boolean -) : PreferenceProperty(), ReadWriteProperty { - - override operator fun getValue( - thisRef: PreferenceConfig, - property: KProperty<*> - ): Float { - val prefName = name.ifBlank { property.name } - return thisRef.prefs.get(prefName, default) - } - - override operator fun setValue( - thisRef: PreferenceConfig, - property: KProperty<*>, - value: Float - ) { - val prefName = name.ifBlank { property.name } - thisRef.prefs.edit(commit) { put(prefName, value) } - } -} - class IntProperty( private val name: String, private val default: Int, @@ -157,30 +114,6 @@ class IntProperty( } } -class LongProperty( - private val name: String, - private val default: Long, - private val commit: Boolean -) : PreferenceProperty(), ReadWriteProperty { - - override operator fun getValue( - thisRef: PreferenceConfig, - property: KProperty<*> - ): Long { - val prefName = name.ifBlank { property.name } - return thisRef.prefs.get(prefName, default) - } - - override operator fun setValue( - thisRef: PreferenceConfig, - property: KProperty<*>, - value: Long - ) { - val prefName = name.ifBlank { property.name } - thisRef.prefs.edit(commit) { put(prefName, value) } - } -} - class StringProperty( private val name: String, private val default: String, @@ -204,27 +137,3 @@ class StringProperty( thisRef.prefs.edit(commit) { put(prefName, value) } } } - -class StringSetProperty( - private val name: String, - private val default: Set, - private val commit: Boolean -) : PreferenceProperty(), ReadWriteProperty> { - - override operator fun getValue( - thisRef: PreferenceConfig, - property: KProperty<*> - ): Set { - val prefName = name.ifBlank { property.name } - return thisRef.prefs.get(prefName, default) - } - - override operator fun setValue( - thisRef: PreferenceConfig, - property: KProperty<*>, - value: Set - ) { - val prefName = name.ifBlank { property.name } - thisRef.prefs.edit(commit) { put(prefName, value) } - } -} diff --git a/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt b/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt index 53bb1b21a..d3bca3986 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt @@ -1,15 +1,16 @@ package com.topjohnwu.magisk.core.tasks import android.app.Activity +import android.app.ActivityOptions import android.content.Context import android.content.Intent +import android.os.Build import android.widget.Toast import androidx.annotation.WorkerThread import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.BuildConfig.APP_PACKAGE_NAME import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const -import com.topjohnwu.magisk.core.Provider import com.topjohnwu.magisk.core.R import com.topjohnwu.magisk.core.ktx.await import com.topjohnwu.magisk.core.ktx.copyAndClose @@ -161,11 +162,12 @@ object HideAPK { private fun launchApp(activity: Activity, pkg: String) { val intent = activity.packageManager.getLaunchIntentForPackage(pkg) ?: return - val self = activity.packageName - val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION - activity.grantUriPermission(pkg, Provider.preferencesUri(self), flag) - intent.putExtra(Const.Key.PREV_PKG, self) - activity.startActivity(intent) + intent.putExtra(Const.Key.PREV_CONFIG, Config.toBundle()) + val options = ActivityOptions.makeBasic() + if (Build.VERSION.SDK_INT >= 34) { + options.setShareIdentityEnabled(true) + } + activity.startActivity(intent, options.toBundle()) activity.finish() }