Commit 5c6a7ffa authored by topjohnwu's avatar topjohnwu

Simplify context hacks

parent 9ab75509
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.app.Activity
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import android.content.res.AssetManager import android.content.res.AssetManager
import android.content.res.Configuration import android.content.res.Configuration
...@@ -20,13 +18,9 @@ lateinit var AppApkPath: String ...@@ -20,13 +18,9 @@ lateinit var AppApkPath: String
fun Resources.addAssetPath(path: String) = StubApk.addAssetPath(this, path) fun Resources.addAssetPath(path: String) = StubApk.addAssetPath(this, path)
fun Context.wrap(): Context = if (this is PatchedContext) this else PatchedContext(this) fun Context.patch(): Context {
resources.patch()
private class PatchedContext(base: Context) : ContextWrapper(base) { return this
init { base.resources.patch() }
override fun getClassLoader() = javaClass.classLoader!!
override fun createConfigurationContext(config: Configuration) =
super.createConfigurationContext(config).wrap()
} }
fun Resources.patch(): Resources { fun Resources.patch(): Resources {
...@@ -49,10 +43,6 @@ fun createNewResources(): Resources { ...@@ -49,10 +43,6 @@ fun createNewResources(): Resources {
fun Class<*>.cmp(pkg: String) = fun Class<*>.cmp(pkg: String) =
ComponentName(pkg, Info.stub?.classToComponent?.get(name) ?: name) 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)) inline fun <reified T> Context.intent() = Intent().setComponent(T::class.java.cmp(packageName))
// Keep a reference to these resources to prevent it from // Keep a reference to these resources to prevent it from
......
package com.topjohnwu.magisk.core 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.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import android.os.ParcelFileDescriptor.MODE_READ_ONLY 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.SuCallbackHandler
import java.io.File import java.io.File
class Provider : ContentProvider() { class Provider : BaseProvider() {
override fun attachInfo(context: Context, info: ProviderInfo) {
super.attachInfo(context.wrap(), info)
}
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? { override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
SuCallbackHandler.run(context!!, method, extras) SuCallbackHandler.run(context!!, method, extras)
...@@ -38,11 +30,4 @@ class Provider : ContentProvider() { ...@@ -38,11 +30,4 @@ class Provider : ContentProvider() {
fun PREFS_URI(pkg: String) = fun PREFS_URI(pkg: String) =
Uri.Builder().scheme("content").authority("$pkg.provider").path("prefs_file").build() 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
} }
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContextWrapper import android.content.Context
import android.content.Intent import android.content.Intent
import com.topjohnwu.magisk.core.base.BaseReceiver import com.topjohnwu.magisk.core.base.BaseReceiver
import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.di.ServiceLocator
...@@ -26,8 +26,9 @@ open class Receiver : BaseReceiver() { ...@@ -26,8 +26,9 @@ open class Receiver : BaseReceiver() {
return if (uid == -1) null else uid return if (uid == -1) null else uid
} }
override fun onReceive(context: ContextWrapper, intent: Intent?) { override fun onReceive(context: Context, intent: Intent?) {
intent ?: return intent ?: return
super.onReceive(context, intent)
fun rmPolicy(uid: Int) = GlobalScope.launch { fun rmPolicy(uid: Int) = GlobalScope.launch {
policyDB.delete(uid) policyDB.delete(uid)
......
...@@ -18,10 +18,9 @@ import androidx.annotation.WorkerThread ...@@ -18,10 +18,9 @@ import androidx.annotation.WorkerThread
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.isRunningAsStub 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.RequestInstall
import com.topjohnwu.magisk.core.utils.UninstallPackage 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.ktx.reflectField
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
...@@ -56,14 +55,12 @@ abstract class BaseActivity : AppCompatActivity() { ...@@ -56,14 +55,12 @@ abstract class BaseActivity : AppCompatActivity() {
uninstallLatch.countDown() uninstallLatch.countDown()
} }
override fun applyOverrideConfiguration(config: Configuration?) { override fun attachBaseContext(base: Context) {
// Force applying our preferred local super.attachBaseContext(base.patch())
config?.setLocale(currentLocale)
super.applyOverrideConfiguration(config)
} }
override fun attachBaseContext(base: Context) { override fun createConfigurationContext(config: Configuration): Context {
super.attachBaseContext(base.wrap()) return super.createConfigurationContext(config).patch()
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
......
...@@ -2,10 +2,10 @@ package com.topjohnwu.magisk.core.base ...@@ -2,10 +2,10 @@ package com.topjohnwu.magisk.core.base
import android.app.job.JobService import android.app.job.JobService
import android.content.Context import android.content.Context
import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.core.patch
abstract class BaseJobService : JobService() { abstract class BaseJobService : JobService() {
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap()) super.attachBaseContext(base.patch())
} }
} }
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
}
...@@ -2,15 +2,13 @@ package com.topjohnwu.magisk.core.base ...@@ -2,15 +2,13 @@ package com.topjohnwu.magisk.core.base
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.ContextWrapper
import android.content.Intent import android.content.Intent
import com.topjohnwu.magisk.core.wrap import androidx.annotation.CallSuper
import com.topjohnwu.magisk.core.patch
abstract class BaseReceiver : BroadcastReceiver() { abstract class BaseReceiver : BroadcastReceiver() {
@CallSuper
final override fun onReceive(context: Context, intent: Intent?) { override fun onReceive(context: Context, intent: Intent?) {
onReceive(context.wrap() as ContextWrapper, intent) context.patch()
} }
abstract fun onReceive(context: ContextWrapper, intent: Intent?)
} }
...@@ -2,10 +2,13 @@ package com.topjohnwu.magisk.core.base ...@@ -2,10 +2,13 @@ package com.topjohnwu.magisk.core.base
import android.app.Service import android.app.Service
import android.content.Context 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) { override fun attachBaseContext(base: Context) {
super.attachBaseContext(base.wrap()) super.attachBaseContext(base.patch())
} }
override fun onBind(intent: Intent?): IBinder? = null
} }
...@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.core.download ...@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.core.download
import android.app.Notification import android.app.Notification
import android.content.Intent import android.content.Intent
import android.os.IBinder
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseService import com.topjohnwu.magisk.core.base.BaseService
...@@ -20,8 +19,6 @@ open class NotificationService : BaseService() { ...@@ -20,8 +19,6 @@ open class NotificationService : BaseService() {
protected val service get() = ServiceLocator.networkService protected val service get() = ServiceLocator.networkService
override fun onBind(intent: Intent?): IBinder? = null
override fun onTaskRemoved(rootIntent: Intent?) { override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent) super.onTaskRemoved(rootIntent)
notifications.forEach { Notifications.mgr.cancel(it.key) } notifications.forEach { Notifications.mgr.cancel(it.key) }
......
...@@ -6,6 +6,7 @@ import android.annotation.SuppressLint ...@@ -6,6 +6,7 @@ import android.annotation.SuppressLint
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.ActivityTracker
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.createNewResources import com.topjohnwu.magisk.core.createNewResources
import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.di.AppContext
...@@ -27,6 +28,11 @@ withContext(Dispatchers.Default) { ...@@ -27,6 +28,11 @@ withContext(Dispatchers.Default) {
// Create a completely new resource to prevent cross talk over active configs // Create a completely new resource to prevent cross talk over active configs
val res = createNewResources() val res = createNewResources()
fun changeLocale(locale: Locale) {
res.configuration.setLocale(locale)
res.updateConfiguration(res.configuration, res.displayMetrics)
}
val locales = ArrayList<String>().apply { val locales = ArrayList<String>().apply {
// Add default locale // Add default locale
add("en") add("en")
...@@ -40,13 +46,13 @@ withContext(Dispatchers.Default) { ...@@ -40,13 +46,13 @@ withContext(Dispatchers.Default) {
}.map { }.map {
Locale.forLanguageTag(it) Locale.forLanguageTag(it)
}.distinctBy { }.distinctBy {
res.setLocale(it) changeLocale(it)
res.getString(compareId) res.getString(compareId)
}.sortedWith { a, b -> }.sortedWith { a, b ->
a.getDisplayName(a).compareTo(b.getDisplayName(b), true) a.getDisplayName(a).compareTo(b.getDisplayName(b), true)
} }
res.setLocale(defaultLocale) changeLocale(defaultLocale)
val defName = res.getString(R.string.system_default) val defName = res.getString(R.string.system_default)
val names = ArrayList<String>(locales.size + 1) val names = ArrayList<String>(locales.size + 1)
...@@ -70,11 +76,6 @@ fun Resources.setConfig(config: Configuration) { ...@@ -70,11 +76,6 @@ fun Resources.setConfig(config: Configuration) {
fun Resources.syncLocale() = setConfig(configuration) fun Resources.syncLocale() = setConfig(configuration)
fun Resources.setLocale(locale: Locale) {
configuration.setLocale(locale)
updateConfiguration(configuration, displayMetrics)
}
fun refreshLocale() { fun refreshLocale() {
val localeConfig = Config.locale val localeConfig = Config.locale
currentLocale = when { currentLocale = when {
...@@ -83,4 +84,5 @@ fun refreshLocale() { ...@@ -83,4 +84,5 @@ fun refreshLocale() {
} }
Locale.setDefault(currentLocale) Locale.setDefault(currentLocale)
AppContext.resources.syncLocale() AppContext.resources.syncLocale()
ActivityTracker.foreground?.recreate()
} }
...@@ -37,9 +37,10 @@ object Customization : BaseSettingsItem.Section() { ...@@ -37,9 +37,10 @@ object Customization : BaseSettingsItem.Section() {
} }
object Language : BaseSettingsItem.Selector() { object Language : BaseSettingsItem.Selector() {
override var value = -1 override var value
get() = index
set(value) { set(value) {
field = value index = value
Config.locale = entryValues[value] Config.locale = entryValues[value]
} }
...@@ -47,6 +48,7 @@ object Language : BaseSettingsItem.Selector() { ...@@ -47,6 +48,7 @@ object Language : BaseSettingsItem.Selector() {
private var entries = emptyArray<String>() private var entries = emptyArray<String>()
private var entryValues = emptyArray<String>() private var entryValues = emptyArray<String>()
private var index = -1
override fun entries(res: Resources) = entries override fun entries(res: Resources) = entries
override fun descriptions(res: Resources) = entries override fun descriptions(res: Resources) = entries
...@@ -62,7 +64,7 @@ object Language : BaseSettingsItem.Selector() { ...@@ -62,7 +64,7 @@ object Language : BaseSettingsItem.Selector() {
entries = names entries = names
entryValues = values entryValues = values
val selectedLocale = currentLocale.getDisplayName(currentLocale) 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) notifyPropertyChanged(BR.description)
} }
} }
......
...@@ -17,7 +17,6 @@ import com.topjohnwu.magisk.core.tasks.HideAPK ...@@ -17,7 +17,6 @@ import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.adapterOf import com.topjohnwu.magisk.databinding.adapterOf
import com.topjohnwu.magisk.databinding.itemBindingOf import com.topjohnwu.magisk.databinding.itemBindingOf
import com.topjohnwu.magisk.events.AddHomeIconEvent import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.RecreateEvent
import com.topjohnwu.magisk.events.SnackbarEvent import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ktx.activity import com.topjohnwu.magisk.ktx.activity
...@@ -108,7 +107,6 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler { ...@@ -108,7 +107,6 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
override fun onItemAction(view: View, item: BaseSettingsItem) { override fun onItemAction(view: View, item: BaseSettingsItem) {
when (item) { when (item) {
Language -> RecreateEvent().publish()
UpdateChannel -> openUrlIfNecessary(view) UpdateChannel -> openUrlIfNecessary(view)
is Hide -> viewModelScope.launch { HideAPK.hide(view.activity, item.value) } is Hide -> viewModelScope.launch { HideAPK.hide(view.activity, item.value) }
Restore -> viewModelScope.launch { HideAPK.restore(view.activity) } Restore -> viewModelScope.launch { HideAPK.restore(view.activity) }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment