parent
0f34457a10
commit
10ce11d671
@ -16,6 +16,7 @@ import com.topjohnwu.magisk.di.koinModules
|
|||||||
import com.topjohnwu.magisk.extensions.get
|
import com.topjohnwu.magisk.extensions.get
|
||||||
import com.topjohnwu.magisk.extensions.unwrap
|
import com.topjohnwu.magisk.extensions.unwrap
|
||||||
import com.topjohnwu.magisk.utils.RootInit
|
import com.topjohnwu.magisk.utils.RootInit
|
||||||
|
import com.topjohnwu.magisk.utils.updateConfig
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.core.context.startKoin
|
import org.koin.core.context.startKoin
|
||||||
@ -58,15 +59,15 @@ open class App() : Application() {
|
|||||||
app = this
|
app = this
|
||||||
impl = base
|
impl = base
|
||||||
}
|
}
|
||||||
ResourceMgr.init(impl)
|
val wrapped = impl.wrap()
|
||||||
super.attachBaseContext(impl.wrap())
|
super.attachBaseContext(wrapped)
|
||||||
|
|
||||||
// Normal startup
|
// Normal startup
|
||||||
startKoin {
|
startKoin {
|
||||||
androidContext(baseContext)
|
androidContext(wrapped)
|
||||||
modules(koinModules)
|
modules(koinModules)
|
||||||
}
|
}
|
||||||
ResourceMgr.reload()
|
ResourceMgr.init(impl)
|
||||||
app.registerActivityLifecycleCallbacks(get<ActivityTracker>())
|
app.registerActivityLifecycleCallbacks(get<ActivityTracker>())
|
||||||
WorkManager.initialize(impl.wrapJob(), androidx.work.Configuration.Builder().build())
|
WorkManager.initialize(impl.wrapJob(), androidx.work.Configuration.Builder().build())
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ open class App() : Application() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
ResourceMgr.reload(newConfig)
|
resources.updateConfig(newConfig)
|
||||||
if (!isRunningAsStub)
|
if (!isRunningAsStub)
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ import com.topjohnwu.magisk.ui.flash.FlashActivity
|
|||||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||||
import com.topjohnwu.magisk.utils.currentLocale
|
import com.topjohnwu.magisk.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.utils.defaultLocale
|
import com.topjohnwu.magisk.utils.defaultLocale
|
||||||
|
import com.topjohnwu.magisk.utils.refreshLocale
|
||||||
|
import com.topjohnwu.magisk.utils.updateConfig
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun AssetManager.addAssetPath(path: String) {
|
fun AssetManager.addAssetPath(path: String) {
|
||||||
@ -51,15 +53,6 @@ fun Context.wrapJob(): Context = object : GlobalResContext(this) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override locale and inject resources from dynamic APK
|
|
||||||
private fun Resources.patch(config: Configuration = Configuration(configuration)): Resources {
|
|
||||||
config.setLocale(currentLocale)
|
|
||||||
updateConfiguration(config, displayMetrics)
|
|
||||||
if (isRunningAsStub)
|
|
||||||
assets.addAssetPath(ResourceMgr.resApk)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Class<*>.cmp(pkg: String = BuildConfig.APPLICATION_ID): ComponentName {
|
fun Class<*>.cmp(pkg: String = BuildConfig.APPLICATION_ID): ComponentName {
|
||||||
val name = ClassMap[this].name
|
val name = ClassMap[this].name
|
||||||
return ComponentName(pkg, Info.stub?.componentMap?.get(name) ?: name)
|
return ComponentName(pkg, Info.stub?.componentMap?.get(name) ?: name)
|
||||||
@ -92,35 +85,28 @@ private open class GlobalResContext(base: Context) : ContextWrapper(base) {
|
|||||||
|
|
||||||
private class ResContext(base: Context) : GlobalResContext(base) {
|
private class ResContext(base: Context) : GlobalResContext(base) {
|
||||||
override val mRes by lazy { base.resources.patch() }
|
override val mRes by lazy { base.resources.patch() }
|
||||||
|
|
||||||
|
private fun Resources.patch(): Resources {
|
||||||
|
updateConfig()
|
||||||
|
if (isRunningAsStub)
|
||||||
|
assets.addAssetPath(ResourceMgr.resApk)
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ResourceMgr {
|
object ResourceMgr {
|
||||||
|
|
||||||
internal lateinit var resource: Resources
|
lateinit var resource: Resources
|
||||||
internal lateinit var resApk: String
|
lateinit var resApk: String
|
||||||
|
|
||||||
fun init(context: Context) {
|
fun init(context: Context) {
|
||||||
resource = context.resources
|
resource = context.resources
|
||||||
if (isRunningAsStub)
|
refreshLocale()
|
||||||
|
if (isRunningAsStub) {
|
||||||
resApk = DynAPK.current(context).path
|
resApk = DynAPK.current(context).path
|
||||||
}
|
resource.assets.addAssetPath(resApk)
|
||||||
|
|
||||||
fun reload(config: Configuration = Configuration(resource.configuration)) {
|
|
||||||
val localeConfig = Config.locale
|
|
||||||
currentLocale = when {
|
|
||||||
localeConfig.isEmpty() -> defaultLocale
|
|
||||||
else -> localeConfig.langTagToLocale()
|
|
||||||
}
|
}
|
||||||
Locale.setDefault(currentLocale)
|
|
||||||
resource.patch(config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getString(locale: Locale, @StringRes id: Int): String {
|
|
||||||
val config = Configuration()
|
|
||||||
config.setLocale(locale)
|
|
||||||
return Resources(resource.assets, resource.displayMetrics, config).getString(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = 28)
|
@RequiresApi(api = 28)
|
||||||
|
@ -19,7 +19,6 @@ import com.topjohnwu.magisk.data.database.RepoDao
|
|||||||
import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
|
import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
|
||||||
import com.topjohnwu.magisk.databinding.DialogCustomNameBinding
|
import com.topjohnwu.magisk.databinding.DialogCustomNameBinding
|
||||||
import com.topjohnwu.magisk.extensions.subscribeK
|
import com.topjohnwu.magisk.extensions.subscribeK
|
||||||
import com.topjohnwu.magisk.extensions.toLangTag
|
|
||||||
import com.topjohnwu.magisk.model.download.DownloadService
|
import com.topjohnwu.magisk.model.download.DownloadService
|
||||||
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
import com.topjohnwu.magisk.model.entity.internal.Configuration
|
||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||||
@ -199,7 +198,7 @@ class SettingsFragment : BasePreferenceFragment() {
|
|||||||
Shell.su("magiskhide --disable").submit()
|
Shell.su("magiskhide --disable").submit()
|
||||||
}
|
}
|
||||||
Config.Key.LOCALE -> {
|
Config.Key.LOCALE -> {
|
||||||
ResourceMgr.reload()
|
refreshLocale()
|
||||||
activity.recreate()
|
activity.recreate()
|
||||||
}
|
}
|
||||||
Config.Key.CHECK_UPDATES -> Utils.scheduleUpdateCheck(activity)
|
Config.Key.CHECK_UPDATES -> Utils.scheduleUpdateCheck(activity)
|
||||||
@ -223,22 +222,7 @@ class SettingsFragment : BasePreferenceFragment() {
|
|||||||
|
|
||||||
private fun setLocalePreference(lp: ListPreference) {
|
private fun setLocalePreference(lp: ListPreference) {
|
||||||
lp.isEnabled = false
|
lp.isEnabled = false
|
||||||
availableLocales.map {
|
availableLocales.subscribeK { (names, values) ->
|
||||||
val names = mutableListOf<String>()
|
|
||||||
val values = mutableListOf<String>()
|
|
||||||
|
|
||||||
names.add(
|
|
||||||
ResourceMgr.getString(defaultLocale, R.string.system_default)
|
|
||||||
)
|
|
||||||
values.add("")
|
|
||||||
|
|
||||||
it.forEach { locale ->
|
|
||||||
names.add(locale.getDisplayName(locale))
|
|
||||||
values.add(locale.toLangTag())
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair(names.toTypedArray(), values.toTypedArray())
|
|
||||||
}.subscribeK { (names, values) ->
|
|
||||||
lp.isEnabled = true
|
lp.isEnabled = true
|
||||||
lp.entries = names
|
lp.entries = names
|
||||||
lp.entryValues = values
|
lp.entryValues = values
|
||||||
|
@ -1,24 +1,32 @@
|
|||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package com.topjohnwu.magisk.utils
|
package com.topjohnwu.magisk.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
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.Config
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.ResourceMgr
|
import com.topjohnwu.magisk.ResourceMgr
|
||||||
import com.topjohnwu.magisk.extensions.langTagToLocale
|
import com.topjohnwu.magisk.extensions.langTagToLocale
|
||||||
|
import com.topjohnwu.magisk.extensions.toLangTag
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.Comparator
|
import kotlin.Comparator
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
var currentLocale: Locale = Locale.getDefault()
|
var currentLocale: Locale = Locale.getDefault()
|
||||||
|
|
||||||
@SuppressLint("ConstantLocale")
|
@SuppressLint("ConstantLocale")
|
||||||
val defaultLocale: Locale = Locale.getDefault()
|
val defaultLocale: Locale = Locale.getDefault()
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
val availableLocales = Single.fromCallable {
|
val availableLocales = Single.fromCallable {
|
||||||
val compareId = R.string.app_changelog
|
val compareId = R.string.app_changelog
|
||||||
mutableListOf<Locale>().apply {
|
val config = ResourceMgr.resource.configuration
|
||||||
|
val metrics = ResourceMgr.resource.displayMetrics
|
||||||
|
val res = Resources(ResourceMgr.resource.assets, metrics, config)
|
||||||
|
|
||||||
|
val locales = mutableListOf<Locale>().apply {
|
||||||
// Add default locale
|
// Add default locale
|
||||||
add(Locale.ENGLISH)
|
add(Locale.ENGLISH)
|
||||||
|
|
||||||
@ -26,24 +34,56 @@ val availableLocales = Single.fromCallable {
|
|||||||
add(Locale.TAIWAN)
|
add(Locale.TAIWAN)
|
||||||
add(Locale("pt", "BR"))
|
add(Locale("pt", "BR"))
|
||||||
|
|
||||||
val config = Configuration()
|
|
||||||
val metrics = ResourceMgr.resource.displayMetrics
|
|
||||||
val res = Resources(ResourceMgr.resource.assets, metrics, config)
|
|
||||||
|
|
||||||
// Other locales
|
// Other locales
|
||||||
val otherLocales = ResourceMgr.resource.assets.locales
|
val otherLocales = ResourceMgr.resource.assets.locales
|
||||||
.map { it.langTagToLocale() }
|
.map { it.langTagToLocale() }
|
||||||
.distinctBy {
|
.distinctBy {
|
||||||
config.setLocale(it)
|
config.setLocale(it)
|
||||||
res.updateConfiguration(config, metrics)
|
res.updateConfiguration(config, metrics)
|
||||||
res.getString(compareId)
|
res.getString(compareId)
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf("", "").toTypedArray()
|
|
||||||
|
|
||||||
addAll(otherLocales)
|
addAll(otherLocales)
|
||||||
}.sortedWith(Comparator { a, b ->
|
}.sortedWith(Comparator { a, b ->
|
||||||
a.getDisplayName(a).toLowerCase(a)
|
a.getDisplayName(a).toLowerCase(a)
|
||||||
.compareTo(b.getDisplayName(b).toLowerCase(b))
|
.compareTo(b.getDisplayName(b).toLowerCase(b))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
config.setLocale(defaultLocale)
|
||||||
|
res.updateConfiguration(config, metrics)
|
||||||
|
val defName = res.getString(R.string.system_default)
|
||||||
|
|
||||||
|
// Restore back to current locale
|
||||||
|
config.setLocale(currentLocale)
|
||||||
|
res.updateConfiguration(config, metrics)
|
||||||
|
|
||||||
|
Pair(locales, defName)
|
||||||
|
}.map { (locales, defName) ->
|
||||||
|
val names = ArrayList<String>(locales.size + 1)
|
||||||
|
val values = ArrayList<String>(locales.size + 1)
|
||||||
|
|
||||||
|
names.add(defName)
|
||||||
|
values.add("")
|
||||||
|
|
||||||
|
locales.forEach { locale ->
|
||||||
|
names.add(locale.getDisplayName(locale))
|
||||||
|
values.add(locale.toLangTag())
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair(names.toTypedArray(), values.toTypedArray())
|
||||||
}.cache()!!
|
}.cache()!!
|
||||||
|
|
||||||
|
fun Resources.updateConfig(config: Configuration = configuration) {
|
||||||
|
config.setLocale(currentLocale)
|
||||||
|
updateConfiguration(config, displayMetrics)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refreshLocale() {
|
||||||
|
val localeConfig = Config.locale
|
||||||
|
currentLocale = when {
|
||||||
|
localeConfig.isEmpty() -> defaultLocale
|
||||||
|
else -> localeConfig.langTagToLocale()
|
||||||
|
}
|
||||||
|
Locale.setDefault(currentLocale)
|
||||||
|
ResourceMgr.resource.updateConfig()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user