Simplify context hacks

This commit is contained in:
topjohnwu 2022-06-02 04:22:25 -07:00
parent 9ab7550970
commit 5c6a7ffa6f
12 changed files with 61 additions and 67 deletions

View File

@ -2,10 +2,8 @@
package com.topjohnwu.magisk.core
import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.res.AssetManager
import android.content.res.Configuration
@ -20,13 +18,9 @@ lateinit var AppApkPath: String
fun Resources.addAssetPath(path: String) = StubApk.addAssetPath(this, path)
fun Context.wrap(): Context = if (this is PatchedContext) this else PatchedContext(this)
private class PatchedContext(base: Context) : ContextWrapper(base) {
init { base.resources.patch() }
override fun getClassLoader() = javaClass.classLoader!!
override fun createConfigurationContext(config: Configuration) =
super.createConfigurationContext(config).wrap()
fun Context.patch(): Context {
resources.patch()
return this
}
fun Resources.patch(): Resources {
@ -49,10 +43,6 @@ fun createNewResources(): Resources {
fun Class<*>.cmp(pkg: String) =
ComponentName(pkg, Info.stub?.classToComponent?.get(name) ?: name)
inline fun <reified T> Activity.redirect() = Intent(intent)
.setComponent(T::class.java.cmp(packageName))
.setFlags(0)
inline fun <reified T> Context.intent() = Intent().setComponent(T::class.java.cmp(packageName))
// Keep a reference to these resources to prevent it from

View File

@ -1,22 +1,14 @@
package com.topjohnwu.magisk.core
import android.content.ContentProvider
import android.content.ContentValues
import android.content.Context
import android.content.pm.ProviderInfo
import android.database.Cursor
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 java.io.File
class Provider : ContentProvider() {
override fun attachInfo(context: Context, info: ProviderInfo) {
super.attachInfo(context.wrap(), info)
}
class Provider : BaseProvider() {
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
SuCallbackHandler.run(context!!, method, extras)
@ -38,11 +30,4 @@ class Provider : ContentProvider() {
fun PREFS_URI(pkg: String) =
Uri.Builder().scheme("content").authority("$pkg.provider").path("prefs_file").build()
}
override fun onCreate() = true
override fun getType(uri: Uri): String? = null
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?) = 0
override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?) = 0
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? = null
}

View File

@ -1,7 +1,7 @@
package com.topjohnwu.magisk.core
import android.annotation.SuppressLint
import android.content.ContextWrapper
import android.content.Context
import android.content.Intent
import com.topjohnwu.magisk.core.base.BaseReceiver
import com.topjohnwu.magisk.core.di.ServiceLocator
@ -26,8 +26,9 @@ open class Receiver : BaseReceiver() {
return if (uid == -1) null else uid
}
override fun onReceive(context: ContextWrapper, intent: Intent?) {
override fun onReceive(context: Context, intent: Intent?) {
intent ?: return
super.onReceive(context, intent)
fun rmPolicy(uid: Int) = GlobalScope.launch {
policyDB.delete(uid)

View File

@ -18,10 +18,9 @@ import androidx.annotation.WorkerThread
import androidx.appcompat.app.AppCompatActivity
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.isRunningAsStub
import com.topjohnwu.magisk.core.patch
import com.topjohnwu.magisk.core.utils.RequestInstall
import com.topjohnwu.magisk.core.utils.UninstallPackage
import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.ktx.reflectField
import com.topjohnwu.magisk.utils.Utils
import java.util.concurrent.CountDownLatch
@ -56,14 +55,12 @@ abstract class BaseActivity : AppCompatActivity() {
uninstallLatch.countDown()
}
override fun applyOverrideConfiguration(config: Configuration?) {
// Force applying our preferred local
config?.setLocale(currentLocale)
super.applyOverrideConfiguration(config)
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.patch())
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap())
override fun createConfigurationContext(config: Configuration): Context {
return super.createConfigurationContext(config).patch()
}
override fun onCreate(savedInstanceState: Bundle?) {

View File

@ -2,10 +2,10 @@ package com.topjohnwu.magisk.core.base
import android.app.job.JobService
import android.content.Context
import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.core.patch
abstract class BaseJobService : JobService() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap())
super.attachBaseContext(base.patch())
}
}

View File

@ -0,0 +1,21 @@
package com.topjohnwu.magisk.core.base
import android.content.ContentProvider
import android.content.ContentValues
import android.content.Context
import android.content.pm.ProviderInfo
import android.database.Cursor
import android.net.Uri
import com.topjohnwu.magisk.core.patch
open class BaseProvider : ContentProvider() {
override fun attachInfo(context: Context, info: ProviderInfo) {
super.attachInfo(context.patch(), info)
}
override fun onCreate() = true
override fun getType(uri: Uri): String? = null
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?) = 0
override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?) = 0
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? = null
}

View File

@ -2,15 +2,13 @@ package com.topjohnwu.magisk.core.base
import android.content.BroadcastReceiver
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import com.topjohnwu.magisk.core.wrap
import androidx.annotation.CallSuper
import com.topjohnwu.magisk.core.patch
abstract class BaseReceiver : BroadcastReceiver() {
final override fun onReceive(context: Context, intent: Intent?) {
onReceive(context.wrap() as ContextWrapper, intent)
@CallSuper
override fun onReceive(context: Context, intent: Intent?) {
context.patch()
}
abstract fun onReceive(context: ContextWrapper, intent: Intent?)
}

View File

@ -2,10 +2,13 @@ package com.topjohnwu.magisk.core.base
import android.app.Service
import android.content.Context
import com.topjohnwu.magisk.core.wrap
import android.content.Intent
import android.os.IBinder
import com.topjohnwu.magisk.core.patch
abstract class BaseService : Service() {
open class BaseService : Service() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap())
super.attachBaseContext(base.patch())
}
override fun onBind(intent: Intent?): IBinder? = null
}

View File

@ -2,7 +2,6 @@ package com.topjohnwu.magisk.core.download
import android.app.Notification
import android.content.Intent
import android.os.IBinder
import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseService
@ -20,8 +19,6 @@ open class NotificationService : BaseService() {
protected val service get() = ServiceLocator.networkService
override fun onBind(intent: Intent?): IBinder? = null
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
notifications.forEach { Notifications.mgr.cancel(it.key) }

View File

@ -6,6 +6,7 @@ import android.annotation.SuppressLint
import android.content.res.Configuration
import android.content.res.Resources
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ActivityTracker
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.createNewResources
import com.topjohnwu.magisk.core.di.AppContext
@ -27,6 +28,11 @@ withContext(Dispatchers.Default) {
// Create a completely new resource to prevent cross talk over active configs
val res = createNewResources()
fun changeLocale(locale: Locale) {
res.configuration.setLocale(locale)
res.updateConfiguration(res.configuration, res.displayMetrics)
}
val locales = ArrayList<String>().apply {
// Add default locale
add("en")
@ -40,13 +46,13 @@ withContext(Dispatchers.Default) {
}.map {
Locale.forLanguageTag(it)
}.distinctBy {
res.setLocale(it)
changeLocale(it)
res.getString(compareId)
}.sortedWith { a, b ->
a.getDisplayName(a).compareTo(b.getDisplayName(b), true)
}
res.setLocale(defaultLocale)
changeLocale(defaultLocale)
val defName = res.getString(R.string.system_default)
val names = ArrayList<String>(locales.size + 1)
@ -70,11 +76,6 @@ fun Resources.setConfig(config: Configuration) {
fun Resources.syncLocale() = setConfig(configuration)
fun Resources.setLocale(locale: Locale) {
configuration.setLocale(locale)
updateConfiguration(configuration, displayMetrics)
}
fun refreshLocale() {
val localeConfig = Config.locale
currentLocale = when {
@ -83,4 +84,5 @@ fun refreshLocale() {
}
Locale.setDefault(currentLocale)
AppContext.resources.syncLocale()
ActivityTracker.foreground?.recreate()
}

View File

@ -37,9 +37,10 @@ object Customization : BaseSettingsItem.Section() {
}
object Language : BaseSettingsItem.Selector() {
override var value = -1
override var value
get() = index
set(value) {
field = value
index = value
Config.locale = entryValues[value]
}
@ -47,6 +48,7 @@ object Language : BaseSettingsItem.Selector() {
private var entries = emptyArray<String>()
private var entryValues = emptyArray<String>()
private var index = -1
override fun entries(res: Resources) = entries
override fun descriptions(res: Resources) = entries
@ -62,7 +64,7 @@ object Language : BaseSettingsItem.Selector() {
entries = names
entryValues = values
val selectedLocale = currentLocale.getDisplayName(currentLocale)
value = names.indexOfFirst { it == selectedLocale }.let { if (it == -1) 0 else it }
index = names.indexOfFirst { it == selectedLocale }.let { if (it == -1) 0 else it }
notifyPropertyChanged(BR.description)
}
}

View File

@ -17,7 +17,6 @@ import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.adapterOf
import com.topjohnwu.magisk.databinding.itemBindingOf
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.RecreateEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ktx.activity
@ -108,7 +107,6 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
override fun onItemAction(view: View, item: BaseSettingsItem) {
when (item) {
Language -> RecreateEvent().publish()
UpdateChannel -> openUrlIfNecessary(view)
is Hide -> viewModelScope.launch { HideAPK.hide(view.activity, item.value) }
Restore -> viewModelScope.launch { HideAPK.restore(view.activity) }