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
1060dd29
Commit
1060dd29
authored
Jan 23, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Random refactoring
parent
2e0f7a82
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
62 additions
and
89 deletions
+62
-89
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
+37
-54
BaseActivity.kt
.../main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt
+1
-1
Locales.kt
app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt
+13
-17
ApplicationModule.kt
...rc/main/java/com/topjohnwu/magisk/di/ApplicationModule.kt
+5
-11
XAndroid.kt
app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt
+2
-2
MarkwonImagePlugin.kt
...ain/java/com/topjohnwu/magisk/utils/MarkwonImagePlugin.kt
+3
-3
No files found.
app/src/main/java/com/topjohnwu/magisk/core/App.kt
View file @
1060dd29
...
...
@@ -73,7 +73,7 @@ open class App() : Application() {
androidContext
(
wrapped
)
modules
(
koinModules
)
}
ResMgr
.
init
(
impl
)
AssetHack
.
init
(
impl
)
app
.
registerActivityLifecycleCallbacks
(
ForegroundTracker
)
WorkManager
.
initialize
(
impl
.
wrapJob
(),
androidx
.
work
.
Configuration
.
Builder
().
build
())
}
...
...
app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt
View file @
1060dd29
...
...
@@ -14,6 +14,7 @@ import android.content.Intent
import
android.content.res.AssetManager
import
android.content.res.Configuration
import
android.content.res.Resources
import
android.util.DisplayMetrics
import
androidx.annotation.RequiresApi
import
com.topjohnwu.magisk.DynAPK
import
com.topjohnwu.magisk.R
...
...
@@ -27,23 +28,22 @@ fun AssetManager.addAssetPath(path: String) {
DynAPK
.
addAssetPath
(
this
,
path
)
}
fun
Context
.
wrap
(
global
:
Boolean
=
tru
e
):
Context
=
if
(
global
)
GlobalResContext
(
this
)
else
Res
Context
(
this
)
fun
Context
.
wrap
(
inject
:
Boolean
=
fals
e
):
Context
=
if
(
inject
)
ReInjectedContext
(
this
)
else
Injected
Context
(
this
)
fun
Context
.
wrapJob
():
Context
=
object
:
GlobalRes
Context
(
this
)
{
fun
Context
.
wrapJob
():
Context
=
object
:
Injected
Context
(
this
)
{
override
fun
getApplicationContext
():
Context
{
return
this
}
override
fun
getApplicationContext
()
=
this
@SuppressLint
(
"NewApi"
)
override
fun
getSystemService
(
name
:
String
):
Any
?
{
return
if
(!
isRunningAsStub
)
super
.
getSystemService
(
name
)
else
when
(
name
)
{
Context
.
JOB_SCHEDULER_SERVICE
->
JobSchedulerWrapper
(
super
.
getSystemService
(
name
)
as
JobScheduler
)
else
->
super
.
getSystemService
(
name
)
return
super
.
getSystemService
(
name
).
let
{
when
{
!
isRunningAsStub
->
it
name
==
JOB_SCHEDULER_SERVICE
->
JobSchedulerWrapper
(
it
as
JobScheduler
)
else
->
it
}
}
}
}
...
...
@@ -58,34 +58,27 @@ inline fun <reified T> Activity.redirect() = Intent(intent)
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
()
=
ResMgr
.
resource
override
fun
getResources
():
Resources
{
return
mRes
}
override
fun
getClassLoader
():
ClassLoader
{
return
javaClass
.
classLoader
!!
}
private
open
class
InjectedContext
(
base
:
Context
)
:
ContextWrapper
(
base
)
{
open
val
res
:
Resources
get
()
=
AssetHack
.
resource
override
fun
getAssets
():
AssetManager
=
res
.
assets
override
fun
getResources
()
=
res
override
fun
getClassLoader
()
=
javaClass
.
classLoader
!!
override
fun
createConfigurationContext
(
config
:
Configuration
):
Context
{
return
ResContext
(
super
.
createConfigurationContext
(
config
)
)
return
super
.
createConfigurationContext
(
config
).
wrap
(
true
)
}
}
private
class
ResContext
(
base
:
Context
)
:
GlobalResContext
(
base
)
{
override
val
mRes
by
lazy
{
base
.
resources
.
patch
()
}
private
class
ReInjectedContext
(
base
:
Context
)
:
InjectedContext
(
base
)
{
override
val
res
by
lazy
{
base
.
resources
.
patch
()
}
private
fun
Resources
.
patch
():
Resources
{
updateConfig
()
if
(
isRunningAsStub
)
assets
.
addAssetPath
(
ResMgr
.
apk
)
assets
.
addAssetPath
(
AssetHack
.
apk
)
return
this
}
}
object
ResMgr
{
object
AssetHack
{
lateinit
var
resource
:
Resources
lateinit
var
apk
:
String
...
...
@@ -100,37 +93,27 @@ object ResMgr {
apk
=
context
.
packageResourcePath
}
}
fun
newResource
():
Resources
{
val
asset
=
AssetManager
::
class
.
java
.
newInstance
()
asset
.
addAssetPath
(
apk
)
val
config
=
Configuration
(
resource
.
configuration
)
val
metrics
=
DisplayMetrics
()
metrics
.
setTo
(
resource
.
displayMetrics
)
return
Resources
(
asset
,
metrics
,
config
)
}
}
@RequiresApi
(
28
)
private
class
JobSchedulerWrapper
(
private
val
base
:
JobScheduler
)
:
JobScheduler
()
{
override
fun
schedule
(
job
:
JobInfo
):
Int
{
return
base
.
schedule
(
job
.
patch
())
}
override
fun
enqueue
(
job
:
JobInfo
,
work
:
JobWorkItem
):
Int
{
return
base
.
enqueue
(
job
.
patch
(),
work
)
}
override
fun
cancel
(
jobId
:
Int
)
{
base
.
cancel
(
jobId
)
}
override
fun
cancelAll
()
{
base
.
cancelAll
()
}
override
fun
getAllPendingJobs
():
List
<
JobInfo
>
{
return
base
.
allPendingJobs
}
override
fun
getPendingJob
(
jobId
:
Int
):
JobInfo
?
{
return
base
.
getPendingJob
(
jobId
)
}
override
fun
schedule
(
job
:
JobInfo
)
=
base
.
schedule
(
job
.
patch
())
override
fun
enqueue
(
job
:
JobInfo
,
work
:
JobWorkItem
)
=
base
.
enqueue
(
job
.
patch
(),
work
)
override
fun
cancel
(
jobId
:
Int
)
=
base
.
cancel
(
jobId
)
override
fun
cancelAll
()
=
base
.
cancelAll
()
override
fun
getAllPendingJobs
():
List
<
JobInfo
>
=
base
.
allPendingJobs
override
fun
getPendingJob
(
jobId
:
Int
)
=
base
.
getPendingJob
(
jobId
)
private
fun
JobInfo
.
patch
():
JobInfo
{
//
We need to s
wap out the service of JobInfo
//
S
wap out the service of JobInfo
val
name
=
service
.
className
val
component
=
ComponentName
(
service
.
packageName
,
...
...
app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt
View file @
1060dd29
...
...
@@ -34,7 +34,7 @@ abstract class BaseActivity : AppCompatActivity() {
}
override
fun
attachBaseContext
(
base
:
Context
)
{
super
.
attachBaseContext
(
base
.
wrap
(
fals
e
))
super
.
attachBaseContext
(
base
.
wrap
(
tru
e
))
}
fun
withPermission
(
permission
:
String
,
builder
:
PermissionRequestBuilder
.()
->
Unit
)
{
...
...
app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt
View file @
1060dd29
...
...
@@ -3,20 +3,16 @@
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.AssetHack
import
com.topjohnwu.magisk.core.Config
import
com.topjohnwu.magisk.core.ResMgr
import
com.topjohnwu.magisk.core.addAssetPath
import
com.topjohnwu.magisk.ktx.langTagToLocale
import
com.topjohnwu.magisk.ktx.toLangTag
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
java.util.*
import
kotlin.Comparator
import
kotlin.collections.ArrayList
var
currentLocale
:
Locale
=
Locale
.
getDefault
()
...
...
@@ -30,11 +26,8 @@ suspend fun availableLocales() = cachedLocales ?:
withContext
(
Dispatchers
.
Default
)
{
val
compareId
=
R
.
string
.
app_changelog
// 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
)
// Create a completely new resource to prevent cross talk over active configs
val
res
=
AssetHack
.
newResource
()
val
locales
=
ArrayList
<
String
>().
apply
{
// Add default locale
...
...
@@ -49,15 +42,13 @@ withContext(Dispatchers.Default) {
}.
map
{
it
.
langTagToLocale
()
}.
distinctBy
{
config
.
setLocale
(
it
)
res
.
updateConfiguration
(
config
,
metrics
)
res
.
updateLocale
(
it
)
res
.
getString
(
compareId
)
}.
sortedWith
(
Comparator
{
a
,
b
->
}.
sortedWith
{
a
,
b
->
a
.
getDisplayName
(
a
).
compareTo
(
b
.
getDisplayName
(
b
),
true
)
}
)
}
config
.
setLocale
(
defaultLocale
)
res
.
updateConfiguration
(
config
,
metrics
)
res
.
updateLocale
(
defaultLocale
)
val
defName
=
res
.
getString
(
R
.
string
.
system_default
)
val
names
=
ArrayList
<
String
>(
locales
.
size
+
1
)
...
...
@@ -79,6 +70,11 @@ fun Resources.updateConfig(config: Configuration = configuration) {
updateConfiguration
(
config
,
displayMetrics
)
}
fun
Resources
.
updateLocale
(
locale
:
Locale
)
{
configuration
.
setLocale
(
locale
)
updateConfiguration
(
configuration
,
displayMetrics
)
}
fun
refreshLocale
()
{
val
localeConfig
=
Config
.
locale
currentLocale
=
when
{
...
...
@@ -86,5 +82,5 @@ fun refreshLocale() {
else
->
localeConfig
.
langTagToLocale
()
}
Locale
.
setDefault
(
currentLocale
)
ResMgr
.
resource
.
updateConfig
()
AssetHack
.
resource
.
updateConfig
()
}
app/src/main/java/com/topjohnwu/magisk/di/ApplicationModule.kt
View file @
1060dd29
package
com.topjohnwu.magisk.di
import
android.content.Context
import
android.os.Build
import
androidx.preference.PreferenceManager
import
com.topjohnwu.magisk.core.ResMgr
import
com.topjohnwu.magisk.core.AssetHack
import
com.topjohnwu.magisk.ktx.deviceProtectedContext
import
org.koin.core.qualifier.named
import
org.koin.dsl.module
...
...
@@ -11,15 +11,9 @@ val SUTimeout = named("su_timeout")
val
Protected
=
named
(
"protected"
)
val
applicationModule
=
module
{
factory
{
ResMgr
.
resource
}
factory
{
AssetHack
.
resource
}
factory
{
get
<
Context
>().
packageManager
}
factory
(
Protected
)
{
createDEContext
(
get
())
}
factory
(
Protected
)
{
get
<
Context
>().
deviceProtectedContext
}
single
(
SUTimeout
)
{
get
<
Context
>(
Protected
).
getSharedPreferences
(
"su_timeout"
,
0
)
}
single
{
PreferenceManager
.
getDefaultSharedPreferences
(
get
<
Context
>(
Protected
))
}
}
private
fun
createDEContext
(
context
:
Context
):
Context
{
return
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
context
.
createDeviceProtectedStorageContext
()
else
context
single
{
PreferenceManager
.
getDefaultSharedPreferences
(
get
(
Protected
))
}
}
app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt
View file @
1060dd29
...
...
@@ -46,7 +46,7 @@ import androidx.transition.AutoTransition
import
androidx.transition.TransitionManager
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.Const
import
com.topjohnwu.magisk.core.
ResMgr
import
com.topjohnwu.magisk.core.
AssetHack
import
com.topjohnwu.magisk.core.utils.currentLocale
import
com.topjohnwu.magisk.utils.DynamicClassLoader
import
com.topjohnwu.magisk.utils.Utils
...
...
@@ -366,6 +366,6 @@ var TextView.precomputedText: CharSequence
}
fun
Int
.
dpInPx
():
Int
{
val
scale
=
ResMgr
.
resource
.
displayMetrics
.
density
val
scale
=
AssetHack
.
resource
.
displayMetrics
.
density
return
(
this
*
scale
+
0.5
).
toInt
()
}
app/src/main/java/com/topjohnwu/magisk/utils/MarkwonImagePlugin.kt
View file @
1060dd29
...
...
@@ -15,7 +15,7 @@ import android.widget.TextView
import
androidx.annotation.WorkerThread
import
com.caverock.androidsvg.SVG
import
com.caverock.androidsvg.SVGParseException
import
com.topjohnwu.magisk.core.
ResMgr
import
com.topjohnwu.magisk.core.
AssetHack
import
com.topjohnwu.superuser.internal.WaitRunnable
import
io.noties.markwon.AbstractMarkwonPlugin
import
io.noties.markwon.MarkwonSpansFactory
...
...
@@ -216,7 +216,7 @@ class MarkwonImagePlugin(okHttp: OkHttpClient) : AbstractMarkwonPlugin() {
return
PictureDrawable
(
picture
)
}
val
density
:
Float
=
ResMgr
.
resource
.
displayMetrics
.
density
val
density
:
Float
=
AssetHack
.
resource
.
displayMetrics
.
density
val
width
=
(
w
*
density
+
.
5f
).
toInt
()
val
height
=
(
h
*
density
+
.
5f
).
toInt
()
...
...
@@ -226,7 +226,7 @@ class MarkwonImagePlugin(okHttp: OkHttpClient) : AbstractMarkwonPlugin() {
canvas
.
scale
(
density
,
density
)
svg
.
renderToCanvas
(
canvas
)
return
BitmapDrawable
(
ResMgr
.
resource
,
bitmap
)
return
BitmapDrawable
(
AssetHack
.
resource
,
bitmap
)
}
}
...
...
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