Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
0d7474cc
Commit
0d7474cc
authored
Feb 18, 2020
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix all locale issues
parent
1e7e06d1
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
66 additions
and
63 deletions
+66
-63
App.kt
app/src/main/java/com/topjohnwu/magisk/core/App.kt
+1
-1
Hacks.kt
app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt
+9
-10
Locales.kt
app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt
+25
-26
ApplicationModule.kt
...rc/main/java/com/topjohnwu/magisk/di/ApplicationModule.kt
+2
-2
SettingsItem.kt
...om/topjohnwu/magisk/model/entity/recycler/SettingsItem.kt
+9
-2
SettingsItems.kt
...in/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt
+20
-22
No files found.
app/src/main/java/com/topjohnwu/magisk/core/App.kt
View file @
0d7474cc
...
...
@@ -82,7 +82,7 @@ open class App() : Application() {
androidContext
(
wrapped
)
modules
(
koinModules
)
}
Res
ource
Mgr
.
init
(
impl
)
ResMgr
.
init
(
impl
)
app
.
registerActivityLifecycleCallbacks
(
get
<
ActivityTracker
>())
WorkManager
.
initialize
(
impl
.
wrapJob
(),
androidx
.
work
.
Configuration
.
Builder
().
build
())
}
...
...
app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt
View file @
0d7474cc
...
...
@@ -57,7 +57,7 @@ fun Class<*>.cmp(pkg: String): ComponentName {
inline
fun
<
reified
T
>
Context
.
intent
()
=
Intent
().
setComponent
(
T
::
class
.
java
.
cmp
(
packageName
))
private
open
class
GlobalResContext
(
base
:
Context
)
:
ContextWrapper
(
base
)
{
open
val
mRes
:
Resources
get
()
=
Res
ource
Mgr
.
resource
open
val
mRes
:
Resources
get
()
=
ResMgr
.
resource
override
fun
getResources
():
Resources
{
return
mRes
...
...
@@ -78,22 +78,24 @@ private class ResContext(base: Context) : GlobalResContext(base) {
private
fun
Resources
.
patch
():
Resources
{
updateConfig
()
if
(
isRunningAsStub
)
assets
.
addAssetPath
(
Res
ourceMgr
.
resA
pk
)
assets
.
addAssetPath
(
Res
Mgr
.
a
pk
)
return
this
}
}
object
Res
ource
Mgr
{
object
ResMgr
{
lateinit
var
resource
:
Resources
lateinit
var
resA
pk
:
String
lateinit
var
a
pk
:
String
fun
init
(
context
:
Context
)
{
resource
=
context
.
resources
refreshLocale
()
if
(
isRunningAsStub
)
{
resApk
=
DynAPK
.
current
(
context
).
path
resource
.
assets
.
addAssetPath
(
resApk
)
apk
=
DynAPK
.
current
(
context
).
path
resource
.
assets
.
addAssetPath
(
apk
)
}
else
{
apk
=
context
.
packageResourcePath
}
}
}
...
...
@@ -169,8 +171,5 @@ val shouldKeepResources = listOf(
R
.
string
.
unsupport_magisk_title
,
R
.
string
.
install_inactive_slot_msg
,
R
.
string
.
invalid_update_channel
,
R
.
string
.
update_available
,
/* Android Studio is dumb and cannot detect following usages in databinding */
R
.
menu
.
menu_reboot
R
.
string
.
update_available
)
app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt
View file @
0d7474cc
...
...
@@ -3,11 +3,14 @@
package
com.topjohnwu.magisk.core.utils
import
android.annotation.SuppressLint
import
android.content.res.AssetManager
import
android.content.res.Configuration
import
android.content.res.Resources
import
android.util.DisplayMetrics
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.ResourceMgr
import
com.topjohnwu.magisk.core.ResMgr
import
com.topjohnwu.magisk.core.addAssetPath
import
com.topjohnwu.magisk.extensions.langTagToLocale
import
com.topjohnwu.magisk.extensions.toLangTag
import
io.reactivex.Single
...
...
@@ -22,41 +25,37 @@ val defaultLocale: Locale = Locale.getDefault()
val
availableLocales
=
Single
.
fromCallable
{
val
compareId
=
R
.
string
.
app_changelog
val
config
=
ResourceMgr
.
resource
.
configuration
val
metrics
=
ResourceMgr
.
resource
.
displayMetrics
val
res
=
Resources
(
ResourceMgr
.
resource
.
assets
,
metrics
,
config
)
val
locales
=
mutableListOf
<
Locale
>().
apply
{
// Create a completely new resource to prevent cross talk over app's configs
val
asset
=
AssetManager
::
class
.
java
.
newInstance
().
apply
{
addAssetPath
(
ResMgr
.
apk
)
}
val
config
=
Configuration
(
ResMgr
.
resource
.
configuration
)
val
metrics
=
DisplayMetrics
().
apply
{
setTo
(
ResMgr
.
resource
.
displayMetrics
)
}
val
res
=
Resources
(
asset
,
metrics
,
config
)
val
locales
=
ArrayList
<
String
>().
apply
{
// Add default locale
add
(
Locale
.
ENGLISH
)
add
(
"en"
)
// Add some special locales
add
(
Locale
.
TAIWAN
)
add
(
Locale
(
"pt"
,
"BR"
))
// Other locales
val
otherLocales
=
ResourceMgr
.
resource
.
assets
.
locales
.
map
{
it
.
langTagToLocale
()
}
.
distinctBy
{
add
(
"zh-TW"
)
add
(
"pt-BR"
)
// Then add all supported locales
addAll
(
res
.
assets
.
locales
)
}.
map
{
it
.
langTagToLocale
()
}.
distinctBy
{
config
.
setLocale
(
it
)
res
.
updateConfiguration
(
config
,
metrics
)
res
.
getString
(
compareId
)
}
addAll
(
otherLocales
)
}.
sortedWith
(
Comparator
{
a
,
b
->
a
.
getDisplayName
(
a
).
toLowerCase
(
a
)
.
compareTo
(
b
.
getDisplayName
(
b
).
toLowerCase
(
b
))
a
.
getDisplayName
(
a
).
compareTo
(
b
.
getDisplayName
(
b
),
true
)
})
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
)
...
...
@@ -85,5 +84,5 @@ fun refreshLocale() {
else
->
localeConfig
.
langTagToLocale
()
}
Locale
.
setDefault
(
currentLocale
)
Res
ource
Mgr
.
resource
.
updateConfig
()
ResMgr
.
resource
.
updateConfig
()
}
app/src/main/java/com/topjohnwu/magisk/di/ApplicationModule.kt
View file @
0d7474cc
...
...
@@ -8,7 +8,7 @@ import android.os.Build
import
android.os.Bundle
import
androidx.localbroadcastmanager.content.LocalBroadcastManager
import
androidx.preference.PreferenceManager
import
com.topjohnwu.magisk.core.Res
ource
Mgr
import
com.topjohnwu.magisk.core.ResMgr
import
com.topjohnwu.magisk.utils.RxBus
import
org.koin.core.qualifier.named
import
org.koin.dsl.module
...
...
@@ -18,7 +18,7 @@ val Protected = named("protected")
val
applicationModule
=
module
{
single
{
RxBus
()
}
factory
{
Res
ource
Mgr
.
resource
}
factory
{
ResMgr
.
resource
}
factory
{
get
<
Context
>().
packageManager
}
factory
(
Protected
)
{
createDEContext
(
get
())
}
single
(
SUTimeout
)
{
get
<
Context
>(
Protected
).
getSharedPreferences
(
"su_timeout"
,
0
)
}
...
...
app/src/main/java/com/topjohnwu/magisk/model/entity/recycler/SettingsItem.kt
View file @
0d7474cc
...
...
@@ -4,6 +4,7 @@ import android.content.Context
import
android.content.res.Resources
import
android.view.MotionEvent
import
android.view.View
import
androidx.annotation.ArrayRes
import
androidx.annotation.CallSuper
import
androidx.databinding.Bindable
import
androidx.databinding.ViewDataBinding
...
...
@@ -145,13 +146,19 @@ sealed class SettingsItem : ObservableItem<SettingsItem>() {
protected
val
resources
get
()
=
get
<
Resources
>()
abstract
val
entries
:
Array
<
out
CharSequence
>
abstract
val
entryValues
:
Array
<
out
CharSequence
>
@ArrayRes
open
val
entryRes
=
-
1
@ArrayRes
open
val
entryValRes
=
-
1
open
val
entries
get
()
=
resources
.
getArrayOrEmpty
(
entryRes
)
open
val
entryValues
get
()
=
resources
.
getArrayOrEmpty
(
entryValRes
)
@get
:
Bindable
val
selectedEntry
get
()
=
entries
.
getOrNull
(
value
)
private
fun
Resources
.
getArrayOrEmpty
(
id
:
Int
):
Array
<
String
>
=
runCatching
{
getStringArray
(
id
)
}.
getOrDefault
(
emptyArray
())
override
fun
onPressed
(
view
:
View
,
callback
:
Callback
)
{
if
(
entries
.
isEmpty
()
||
entryValues
.
isEmpty
())
return
callback
.
onItemPressed
(
view
,
this
)
...
...
app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt
View file @
0d7474cc
...
...
@@ -39,8 +39,8 @@ object Language : SettingsItem.Selector() {
}
override
val
title
=
R
.
string
.
language
.
asTransitive
()
override
var
entries
=
arrayOf
<
String
>()
override
var
entryValues
=
arrayOf
<
String
>()
override
var
entries
=
emptyArray
<
String
>()
override
var
entryValues
=
emptyArray
<
String
>()
init
{
availableLocales
.
subscribeK
{
(
names
,
values
)
->
...
...
@@ -132,19 +132,19 @@ object GridSize : SettingsItem.Selector() {
override
val
title
=
R
.
string
.
settings_grid_column_count_title
.
asTransitive
()
override
val
description
=
R
.
string
.
settings_grid_column_count_summary
.
asTransitive
()
override
val
entr
ies
=
resources
.
getStringArray
(
R
.
array
.
span_count
)
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
override
val
entr
yRes
=
R
.
array
.
span_count
override
val
entryVal
Res
=
R
.
array
.
value_array
}
object
UpdateChannel
:
SettingsItem
.
Selector
()
{
override
var
value
by
bindableValue
(
Config
.
updateChannel
)
{
Config
.
updateChannel
=
it
}
override
val
title
=
R
.
string
.
settings_update_channel_title
.
asTransitive
()
override
val
entries
=
resources
.
getStringArray
(
R
.
array
.
update_channel
).
let
{
override
val
entries
get
()
=
resources
.
getStringArray
(
R
.
array
.
update_channel
).
let
{
if
(!
isCanaryVersion
&&
Config
.
updateChannel
<
Config
.
Value
.
CANARY_CHANNEL
)
it
.
take
(
it
.
size
-
2
).
toTypedArray
()
else
it
}
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
override
val
entryVal
Res
=
R
.
array
.
value_array
}
object
UpdateChannelUrl
:
SettingsItem
.
Input
()
{
...
...
@@ -247,8 +247,8 @@ object Superuser : SettingsItem.Section() {
object
AccessMode
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
superuser_access
.
asTransitive
()
override
val
entr
ies
=
resources
.
getStringArray
(
R
.
array
.
su_access
)
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
override
val
entr
yRes
=
R
.
array
.
su_access
override
val
entryVal
Res
=
R
.
array
.
value_array
override
var
value
by
bindableValue
(
Config
.
rootMode
)
{
Config
.
rootMode
=
entryValues
[
it
].
toInt
()
...
...
@@ -257,16 +257,15 @@ object AccessMode : SettingsItem.Selector() {
object
MultiuserMode
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
multiuser_mode
.
asTransitive
()
override
val
entries
=
resources
.
getStringArray
(
R
.
array
.
multiuser_mode
)
override
val
entryValues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
private
val
descArray
=
resources
.
getStringArray
(
R
.
array
.
multiuser_summary
)
override
val
entryRes
=
R
.
array
.
multiuser_mode
override
val
entryValRes
=
R
.
array
.
value_array
override
var
value
by
bindableValue
(
Config
.
suMultiuserMode
)
{
Config
.
suMultiuserMode
=
entryValues
[
it
].
toInt
()
}
override
val
description
get
()
=
descArray
[
value
].
asTransitive
()
get
()
=
resources
.
getStringArray
(
R
.
array
.
multiuser_summary
)
[
value
].
asTransitive
()
override
fun
refresh
()
{
isEnabled
=
Const
.
USER_ID
==
0
...
...
@@ -275,22 +274,21 @@ object MultiuserMode : SettingsItem.Selector() {
object
MountNamespaceMode
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
mount_namespace_mode
.
asTransitive
()
override
val
entries
=
resources
.
getStringArray
(
R
.
array
.
namespace
)
override
val
entryValues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
private
val
descArray
=
resources
.
getStringArray
(
R
.
array
.
namespace_summary
)
override
val
entryRes
=
R
.
array
.
namespace
override
val
entryValRes
=
R
.
array
.
value_array
override
var
value
by
bindableValue
(
Config
.
suMntNamespaceMode
)
{
Config
.
suMntNamespaceMode
=
entryValues
[
it
].
toInt
()
}
override
val
description
get
()
=
descArray
[
value
].
asTransitive
()
get
()
=
resources
.
getStringArray
(
R
.
array
.
namespace_summary
)
[
value
].
asTransitive
()
}
object
AutomaticResponse
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
auto_response
.
asTransitive
()
override
val
entr
ies
=
resources
.
getStringArray
(
R
.
array
.
auto_response
)
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
override
val
entr
yRes
=
R
.
array
.
auto_response
override
val
entryVal
Res
=
R
.
array
.
value_array
override
var
value
by
bindableValue
(
Config
.
suAutoReponse
)
{
Config
.
suAutoReponse
=
entryValues
[
it
].
toInt
()
...
...
@@ -299,8 +297,8 @@ object AutomaticResponse : SettingsItem.Selector() {
object
RequestTimeout
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
request_timeout
.
asTransitive
()
override
val
entr
ies
=
resources
.
getStringArray
(
R
.
array
.
request_timeout
)
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
request_timeout_value
)
override
val
entr
yRes
=
R
.
array
.
request_timeout
override
val
entryVal
Res
=
R
.
array
.
request_timeout_value
override
var
value
by
bindableValue
(
selected
)
{
Config
.
suDefaultTimeout
=
entryValues
[
it
].
toInt
()
...
...
@@ -312,8 +310,8 @@ object RequestTimeout : SettingsItem.Selector() {
object
SUNotification
:
SettingsItem
.
Selector
()
{
override
val
title
=
R
.
string
.
superuser_notification
.
asTransitive
()
override
val
entr
ies
=
resources
.
getStringArray
(
R
.
array
.
su_notification
)
override
val
entryVal
ues
=
resources
.
getStringArray
(
R
.
array
.
value_array
)
override
val
entr
yRes
=
R
.
array
.
su_notification
override
val
entryVal
Res
=
R
.
array
.
value_array
override
var
value
by
bindableValue
(
Config
.
suNotification
)
{
Config
.
suNotification
=
entryValues
[
it
].
toInt
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment