mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 07:57:39 +00:00
Improve package migration
This commit is contained in:
parent
4ab7bc0d97
commit
480198dcd0
@ -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<Binding : ViewDataBinding> : NavigationActivity<Bi
|
||||
}
|
||||
|
||||
private fun initialize(savedState: Bundle?) {
|
||||
val prevPkg = intent.getStringExtra(Const.Key.PREV_PKG)?.let {
|
||||
// Make sure the calling package matches (prevent DoS)
|
||||
if (it == realCallingPackage)
|
||||
it
|
||||
else
|
||||
null
|
||||
}
|
||||
val prevPkg = launchPackage
|
||||
val prevConfig = intent.getBundleExtra(Const.Key.PREV_CONFIG)
|
||||
val isPackageMigration = prevPkg != null && prevConfig != null
|
||||
|
||||
Config.load(prevPkg)
|
||||
Config.init(prevConfig)
|
||||
|
||||
if (packageName != APP_PACKAGE_NAME) {
|
||||
runCatching {
|
||||
@ -130,14 +126,15 @@ abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Bi
|
||||
Shell.cmd("(pm uninstall $APP_PACKAGE_NAME)& >/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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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<String>,
|
||||
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<PreferenceConfig, Float> {
|
||||
|
||||
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<PreferenceConfig, Long> {
|
||||
|
||||
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<String>,
|
||||
private val commit: Boolean
|
||||
) : PreferenceProperty(), ReadWriteProperty<PreferenceConfig, Set<String>> {
|
||||
|
||||
override operator fun getValue(
|
||||
thisRef: PreferenceConfig,
|
||||
property: KProperty<*>
|
||||
): Set<String> {
|
||||
val prefName = name.ifBlank { property.name }
|
||||
return thisRef.prefs.get(prefName, default)
|
||||
}
|
||||
|
||||
override operator fun setValue(
|
||||
thisRef: PreferenceConfig,
|
||||
property: KProperty<*>,
|
||||
value: Set<String>
|
||||
) {
|
||||
val prefName = name.ifBlank { property.name }
|
||||
thisRef.prefs.edit(commit) { put(prefName, value) }
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user