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
71d855e8
Commit
71d855e8
authored
Aug 04, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup more code
parent
33b7ab59
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
221 additions
and
306 deletions
+221
-306
App.kt
app/src/main/java/com/topjohnwu/magisk/App.kt
+0
-7
XAndroid.kt
...src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt
+1
-1
XJava.kt
app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt
+62
-0
XTime.kt
app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt
+5
-6
SuLogEntry.java
...in/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java
+0
-56
GeneralReceiver.kt
...va/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt
+1
-1
UpdateCheckService.kt
...a/com/topjohnwu/magisk/model/update/UpdateCheckService.kt
+2
-2
MagiskActivity.kt
.../main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
+3
-2
HomeFragment.kt
...rc/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt
+7
-2
SettingsFragment.kt
...java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt
+6
-11
LocaleManager.kt
...src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt
+32
-100
Utils.kt
app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt
+2
-9
Notifications.java
...rc/main/java/com/topjohnwu/magisk/view/Notifications.java
+0
-109
Notifications.kt
app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt
+100
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/App.kt
View file @
71d855e8
package
com.topjohnwu.magisk
package
com.topjohnwu.magisk
import
android.annotation.SuppressLint
import
android.app.Application
import
android.app.Application
import
android.content.Context
import
android.content.Context
import
android.content.res.Configuration
import
android.content.res.Configuration
...
@@ -39,7 +38,6 @@ open class App : Application() {
...
@@ -39,7 +38,6 @@ open class App : Application() {
}
}
deContext
=
base
deContext
=
base
self
=
this
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
{
deContext
=
base
.
createDeviceProtectedStorageContext
()
deContext
=
base
.
createDeviceProtectedStorageContext
()
...
@@ -61,11 +59,6 @@ open class App : Application() {
...
@@ -61,11 +59,6 @@ open class App : Application() {
companion
object
{
companion
object
{
@SuppressLint
(
"StaticFieldLeak"
)
@Deprecated
(
"Use dependency injection"
)
@JvmStatic
lateinit
var
self
:
App
init
{
init
{
AppCompatDelegate
.
setCompatVectorFromResourcesEnabled
(
true
)
AppCompatDelegate
.
setCompatVectorFromResourcesEnabled
(
true
)
Shell
.
Config
.
setFlags
(
Shell
.
FLAG_MOUNT_MASTER
or
Shell
.
FLAG_USE_MAGISK_BUSYBOX
)
Shell
.
Config
.
setFlags
(
Shell
.
FLAG_MOUNT_MASTER
or
Shell
.
FLAG_USE_MAGISK_BUSYBOX
)
...
...
app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt
View file @
71d855e8
...
@@ -55,7 +55,7 @@ val ApplicationInfo.packageInfo: PackageInfo?
...
@@ -55,7 +55,7 @@ val ApplicationInfo.packageInfo: PackageInfo?
val
Uri
.
fileName
:
String
val
Uri
.
fileName
:
String
get
()
{
get
()
{
var
name
:
String
?
=
null
var
name
:
String
?
=
null
App
.
self
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
)
?.
use
{
c
->
get
<
Context
>()
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
)
?.
use
{
c
->
val
nameIndex
=
c
.
getColumnIndex
(
OpenableColumns
.
DISPLAY_NAME
)
val
nameIndex
=
c
.
getColumnIndex
(
OpenableColumns
.
DISPLAY_NAME
)
if
(
nameIndex
!=
-
1
)
{
if
(
nameIndex
!=
-
1
)
{
c
.
moveToFirst
()
c
.
moveToFirst
()
...
...
app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt
View file @
71d855e8
package
com.topjohnwu.magisk.extensions
package
com.topjohnwu.magisk.extensions
import
android.net.Uri
import
android.net.Uri
import
android.os.Build
import
androidx.core.net.toFile
import
androidx.core.net.toFile
import
java.io.File
import
java.io.File
import
java.io.InputStream
import
java.io.InputStream
import
java.io.OutputStream
import
java.io.OutputStream
import
java.util.*
import
java.util.zip.ZipEntry
import
java.util.zip.ZipEntry
import
java.util.zip.ZipInputStream
import
java.util.zip.ZipInputStream
import
kotlin.NoSuchElementException
fun
ZipInputStream
.
forEach
(
callback
:
(
ZipEntry
)
->
Unit
)
{
fun
ZipInputStream
.
forEach
(
callback
:
(
ZipEntry
)
->
Unit
)
{
var
entry
:
ZipEntry
?
=
nextEntry
var
entry
:
ZipEntry
?
=
nextEntry
...
@@ -38,4 +41,63 @@ inline fun <T, R> List<T>.firstMap(mapper: (T) -> R?): R {
...
@@ -38,4 +41,63 @@ inline fun <T, R> List<T>.firstMap(mapper: (T) -> R?): R {
return
mapper
(
item
)
?:
continue
return
mapper
(
item
)
?:
continue
}
}
throw
NoSuchElementException
(
"Collection contains no element matching the predicate."
)
throw
NoSuchElementException
(
"Collection contains no element matching the predicate."
)
}
fun
String
.
langTagToLocale
():
Locale
{
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
return
Locale
.
forLanguageTag
(
this
)
}
else
{
val
tok
=
split
(
"-"
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
if
(
tok
.
isEmpty
())
{
return
Locale
(
""
)
}
val
language
=
when
(
tok
[
0
])
{
"und"
->
""
// Undefined
"fil"
->
"tl"
// Filipino
else
->
tok
[
0
]
}
if
(
language
.
length
!=
2
&&
language
.
length
!=
3
)
return
Locale
(
""
)
if
(
tok
.
size
==
1
)
return
Locale
(
language
)
val
country
=
tok
[
1
]
return
if
(
country
.
length
!=
2
&&
country
.
length
!=
3
)
Locale
(
language
)
else
Locale
(
language
,
country
)
}
}
fun
Locale
.
toLangTag
():
String
{
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
return
toLanguageTag
()
}
else
{
var
language
=
language
var
country
=
country
var
variant
=
variant
when
{
language
.
isEmpty
()
||
!
language
.
matches
(
"\\p{Alpha}{2,8}"
.
toRegex
())
->
language
=
"und"
// Follow the Locale#toLanguageTag() implementation
language
==
"iw"
->
language
=
"he"
// correct deprecated "Hebrew"
language
==
"in"
->
language
=
"id"
// correct deprecated "Indonesian"
language
==
"ji"
->
language
=
"yi"
// correct deprecated "Yiddish"
}
// ensure valid country code, if not well formed, it's omitted
// variant subtags that begin with a letter must be at least 5 characters long
// ensure valid country code, if not well formed, it's omitted
if
(!
country
.
matches
(
"\\p{Alpha}{2}|\\p{Digit}{3}"
.
toRegex
()))
{
country
=
""
}
// variant subtags that begin with a letter must be at least 5 characters long
if
(!
variant
.
matches
(
"\\p{Alnum}{5,8}|\\p{Digit}\\p{Alnum}{3}"
.
toRegex
()))
{
variant
=
""
}
val
tag
=
StringBuilder
(
language
)
if
(
country
.
isNotEmpty
())
tag
.
append
(
'-'
).
append
(
country
)
if
(
variant
.
isNotEmpty
())
tag
.
append
(
'-'
).
append
(
variant
)
return
tag
.
toString
()
}
}
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt
View file @
71d855e8
package
com.topjohnwu.magisk.extensions
package
com.topjohnwu.magisk.extensions
import
com.topjohnwu.magisk.utils.
LocaleManager
import
com.topjohnwu.magisk.utils.
currentLocale
import
java.text.DateFormat
import
java.text.DateFormat
import
java.text.ParseException
import
java.text.ParseException
import
java.text.SimpleDateFormat
import
java.text.SimpleDateFormat
...
@@ -14,8 +14,7 @@ fun String.toTime(format: DateFormat) = try {
...
@@ -14,8 +14,7 @@ fun String.toTime(format: DateFormat) = try {
-
1L
-
1L
}
}
private
val
locale
get
()
=
LocaleManager
.
locale
val
timeFormatFull
by
lazy
{
SimpleDateFormat
(
"yyyy/MM/dd_HH:mm:ss"
,
currentLocale
)
}
val
timeFormatFull
by
lazy
{
SimpleDateFormat
(
"yyyy/MM/dd_HH:mm:ss"
,
locale
)
}
val
timeFormatStandard
by
lazy
{
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
,
currentLocale
)
}
val
timeFormatStandard
by
lazy
{
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss'Z'"
,
locale
)
}
val
timeFormatMedium
by
lazy
{
DateFormat
.
getDateInstance
(
DateFormat
.
MEDIUM
,
currentLocale
)
}
val
timeFormatMedium
by
lazy
{
DateFormat
.
getDateInstance
(
DateFormat
.
MEDIUM
,
LocaleManager
.
locale
)
}
val
timeFormatTime
by
lazy
{
SimpleDateFormat
(
"h:mm a"
,
currentLocale
)
}
val
timeFormatTime
by
lazy
{
SimpleDateFormat
(
"h:mm a"
,
LocaleManager
.
locale
)
}
\ No newline at end of file
app/src/main/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java
deleted
100644 → 0
View file @
33b7ab59
package
com
.
topjohnwu
.
magisk
.
model
.
entity
;
import
android.content.ContentValues
;
import
com.topjohnwu.magisk.utils.LocaleManager
;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
public
class
SuLogEntry
{
public
int
fromUid
,
toUid
,
fromPid
;
public
String
packageName
,
appName
,
command
;
public
boolean
action
;
public
Date
date
;
public
SuLogEntry
(
MagiskPolicy
policy
)
{
fromUid
=
policy
.
getUid
();
packageName
=
policy
.
getPackageName
();
appName
=
policy
.
getAppName
();
action
=
policy
.
getPolicy
()
==
Policy
.
ALLOW
;
}
public
SuLogEntry
(
ContentValues
values
)
{
fromUid
=
values
.
getAsInteger
(
"from_uid"
);
packageName
=
values
.
getAsString
(
"package_name"
);
appName
=
values
.
getAsString
(
"app_name"
);
fromPid
=
values
.
getAsInteger
(
"from_pid"
);
command
=
values
.
getAsString
(
"command"
);
toUid
=
values
.
getAsInteger
(
"to_uid"
);
action
=
values
.
getAsInteger
(
"action"
)
!=
0
;
date
=
new
Date
(
values
.
getAsLong
(
"time"
));
}
public
ContentValues
getContentValues
()
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
"from_uid"
,
fromUid
);
values
.
put
(
"package_name"
,
packageName
);
values
.
put
(
"app_name"
,
appName
);
values
.
put
(
"from_pid"
,
fromPid
);
values
.
put
(
"command"
,
command
);
values
.
put
(
"to_uid"
,
toUid
);
values
.
put
(
"action"
,
action
?
1
:
0
);
values
.
put
(
"time"
,
date
.
getTime
());
return
values
;
}
public
String
getDateString
()
{
return
DateFormat
.
getDateInstance
(
DateFormat
.
MEDIUM
,
LocaleManager
.
getLocale
()).
format
(
date
);
}
public
String
getTimeString
()
{
return
new
SimpleDateFormat
(
"h:mm a"
,
LocaleManager
.
getLocale
()).
format
(
date
);
}
}
app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt
View file @
71d855e8
...
@@ -47,7 +47,7 @@ open class GeneralReceiver : BroadcastReceiver() {
...
@@ -47,7 +47,7 @@ open class GeneralReceiver : BroadcastReceiver() {
// Actual boot completed event
// Actual boot completed event
Shell
.
su
(
"mm_patch_dtbo"
).
submit
{
result
->
Shell
.
su
(
"mm_patch_dtbo"
).
submit
{
result
->
if
(
result
.
isSuccess
)
if
(
result
.
isSuccess
)
Notifications
.
dtboPatched
()
Notifications
.
dtboPatched
(
context
)
}
}
return
return
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/model/update/UpdateCheckService.kt
View file @
71d855e8
...
@@ -19,9 +19,9 @@ class UpdateCheckService : DelegateWorker() {
...
@@ -19,9 +19,9 @@ class UpdateCheckService : DelegateWorker() {
return
runCatching
{
return
runCatching
{
magiskRepo
.
fetchUpdate
().
blockingGet
()
magiskRepo
.
fetchUpdate
().
blockingGet
()
if
(
BuildConfig
.
VERSION_CODE
<
Info
.
remote
.
app
.
versionCode
)
if
(
BuildConfig
.
VERSION_CODE
<
Info
.
remote
.
app
.
versionCode
)
Notifications
.
managerUpdate
()
Notifications
.
managerUpdate
(
applicationContext
)
else
if
(
Info
.
magiskVersionCode
<
Info
.
remote
.
magisk
.
versionCode
)
else
if
(
Info
.
magiskVersionCode
<
Info
.
remote
.
magisk
.
versionCode
)
Notifications
.
magiskUpdate
()
Notifications
.
magiskUpdate
(
applicationContext
)
ListenableWorker
.
Result
.
success
()
ListenableWorker
.
Result
.
success
()
}.
getOrElse
{
}.
getOrElse
{
ListenableWorker
.
Result
.
failure
()
ListenableWorker
.
Result
.
failure
()
...
...
app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt
View file @
71d855e8
...
@@ -32,6 +32,7 @@ import com.topjohnwu.magisk.model.navigation.Navigator
...
@@ -32,6 +32,7 @@ import com.topjohnwu.magisk.model.navigation.Navigator
import
com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import
com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import
com.topjohnwu.magisk.utils.LocaleManager
import
com.topjohnwu.magisk.utils.LocaleManager
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.utils.currentLocale
import
timber.log.Timber
import
timber.log.Timber
import
kotlin.reflect.KClass
import
kotlin.reflect.KClass
...
@@ -68,12 +69,12 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
...
@@ -68,12 +69,12 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
override
fun
applyOverrideConfiguration
(
config
:
Configuration
?)
{
override
fun
applyOverrideConfiguration
(
config
:
Configuration
?)
{
// Force applying our preferred local
// Force applying our preferred local
config
?.
setLocale
(
LocaleManager
.
l
ocale
)
config
?.
setLocale
(
currentL
ocale
)
super
.
applyOverrideConfiguration
(
config
)
super
.
applyOverrideConfiguration
(
config
)
}
}
override
fun
attachBaseContext
(
base
:
Context
)
{
override
fun
attachBaseContext
(
base
:
Context
)
{
super
.
attachBaseContext
(
LocaleManager
.
getLocaleContext
(
base
,
LocaleManager
.
locale
))
super
.
attachBaseContext
(
LocaleManager
.
getLocaleContext
(
base
))
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
...
...
app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt
View file @
71d855e8
package
com.topjohnwu.magisk.ui.home
package
com.topjohnwu.magisk.ui.home
import
android.app.Activity
import
android.app.Activity
import
android.content.Context
import
android.os.Bundle
import
android.os.Bundle
import
com.skoumal.teanity.extensions.subscribeK
import
com.skoumal.teanity.extensions.subscribeK
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.skoumal.teanity.viewevents.ViewEvent
import
com.topjohnwu.magisk.*
import
com.topjohnwu.magisk.BuildConfig
import
com.topjohnwu.magisk.Const
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.databinding.FragmentMagiskBinding
import
com.topjohnwu.magisk.databinding.FragmentMagiskBinding
import
com.topjohnwu.magisk.extensions.get
import
com.topjohnwu.magisk.extensions.inject
import
com.topjohnwu.magisk.extensions.inject
import
com.topjohnwu.magisk.extensions.writeTo
import
com.topjohnwu.magisk.extensions.writeTo
import
com.topjohnwu.magisk.model.events.*
import
com.topjohnwu.magisk.model.events.*
...
@@ -114,7 +119,7 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
...
@@ -114,7 +119,7 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
}
}
companion
object
{
companion
object
{
val
EXT_APK
=
File
(
"${App.self.filesDir.parent}/snet"
,
"snet.apk"
)
val
EXT_APK
by
lazy
{
File
(
"${get<Context>().filesDir.parent}/snet"
,
"snet.apk"
)
}
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt
View file @
71d855e8
...
@@ -21,15 +21,13 @@ import com.topjohnwu.magisk.Const
...
@@ -21,15 +21,13 @@ import com.topjohnwu.magisk.Const
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.data.database.RepoDao
import
com.topjohnwu.magisk.data.database.RepoDao
import
com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
import
com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding
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
import
com.topjohnwu.magisk.model.observer.Observer
import
com.topjohnwu.magisk.model.observer.Observer
import
com.topjohnwu.magisk.ui.base.BasePreferenceFragment
import
com.topjohnwu.magisk.ui.base.BasePreferenceFragment
import
com.topjohnwu.magisk.utils.FingerprintHelper
import
com.topjohnwu.magisk.utils.*
import
com.topjohnwu.magisk.utils.LocaleManager
import
com.topjohnwu.magisk.utils.PatchAPK
import
com.topjohnwu.magisk.utils.Utils
import
com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
import
com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog
import
com.topjohnwu.net.Networking
import
com.topjohnwu.net.Networking
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.Shell
...
@@ -226,21 +224,18 @@ class SettingsFragment : BasePreferenceFragment() {
...
@@ -226,21 +224,18 @@ class SettingsFragment : BasePreferenceFragment() {
private
fun
setLocalePreference
(
lp
:
ListPreference
)
{
private
fun
setLocalePreference
(
lp
:
ListPreference
)
{
lp
.
isEnabled
=
false
lp
.
isEnabled
=
false
LocaleManager
.
availableLocales
availableLocales
.
map
{
.
map
{
val
names
=
mutableListOf
<
String
>()
val
names
=
mutableListOf
<
String
>()
val
values
=
mutableListOf
<
String
>()
val
values
=
mutableListOf
<
String
>()
names
.
add
(
names
.
add
(
LocaleManager
.
getString
(
LocaleManager
.
getString
(
defaultLocale
,
R
.
string
.
system_default
)
LocaleManager
.
defaultLocale
,
R
.
string
.
system_default
)
)
)
values
.
add
(
""
)
values
.
add
(
""
)
it
.
forEach
{
locale
->
it
.
forEach
{
locale
->
names
.
add
(
locale
.
getDisplayName
(
locale
))
names
.
add
(
locale
.
getDisplayName
(
locale
))
values
.
add
(
LocaleManager
.
toLanguageTag
(
locale
))
values
.
add
(
locale
.
toLangTag
(
))
}
}
Pair
(
names
.
toTypedArray
(),
values
.
toTypedArray
())
Pair
(
names
.
toTypedArray
(),
values
.
toTypedArray
())
...
@@ -248,7 +243,7 @@ class SettingsFragment : BasePreferenceFragment() {
...
@@ -248,7 +243,7 @@ class SettingsFragment : BasePreferenceFragment() {
lp
.
isEnabled
=
true
lp
.
isEnabled
=
true
lp
.
entries
=
names
lp
.
entries
=
names
lp
.
entryValues
=
values
lp
.
entryValues
=
values
lp
.
summary
=
LocaleManager
.
locale
.
getDisplayName
(
LocaleManager
.
l
ocale
)
lp
.
summary
=
currentLocale
.
getDisplayName
(
currentL
ocale
)
}
}
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt
View file @
71d855e8
...
@@ -4,133 +4,65 @@ import android.content.Context
...
@@ -4,133 +4,65 @@ import android.content.Context
import
android.content.ContextWrapper
import
android.content.ContextWrapper
import
android.content.res.Configuration
import
android.content.res.Configuration
import
android.content.res.Resources
import
android.content.res.Resources
import
android.os.Build
import
androidx.annotation.StringRes
import
androidx.annotation.StringRes
import
com.topjohnwu.magisk.App
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.Config
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.extensions.get
import
com.topjohnwu.magisk.extensions.inject
import
com.topjohnwu.magisk.extensions.inject
import
com.topjohnwu.magisk.extensions.langTagToLocale
import
com.topjohnwu.superuser.internal.InternalUtils
import
com.topjohnwu.superuser.internal.InternalUtils
import
io.reactivex.Single
import
io.reactivex.Single
import
java.util.*
import
java.util.*
object
LocaleManager
{
var
currentLocale
=
Locale
.
getDefault
()
!!
@JvmStatic
private
set
var
locale
=
Locale
.
getDefault
()
@JvmStatic
val
defaultLocale
=
Locale
.
getDefault
()
@JvmStatic
val
availableLocales
=
Single
.
fromCallable
{
val
compareId
=
R
.
string
.
app_changelog
val
res
:
Resources
by
inject
()
mutableListOf
<
Locale
>().
apply
{
// Add default locale
add
(
Locale
.
ENGLISH
)
// Add some special locales
val
defaultLocale
=
Locale
.
getDefault
()
!!
add
(
Locale
.
TAIWAN
)
add
(
Locale
(
"pt"
,
"BR"
))
// Other locales
val
availableLocales
=
Single
.
fromCallable
{
val
otherLocales
=
res
.
assets
.
locales
val
compareId
=
R
.
string
.
app_changelog
.
map
{
forLanguageTag
(
it
)
}
val
res
:
Resources
by
inject
()
.
distinctBy
{
getString
(
it
,
compareId
)
}
mutableListOf
<
Locale
>().
apply
{
// Add default locale
add
(
Locale
.
ENGLISH
)
listOf
(
""
,
""
).
toTypedArray
()
// Add some special locales
add
(
Locale
.
TAIWAN
)
addAll
(
otherLocales
)
add
(
Locale
(
"pt"
,
"BR"
))
}.
sortedWith
(
Comparator
{
a
,
b
->
a
.
getDisplayName
(
a
).
toLowerCase
(
a
)
.
compareTo
(
b
.
getDisplayName
(
b
).
toLowerCase
(
b
))
})
}.
cache
()
private
fun
forLanguageTag
(
tag
:
String
):
Locale
{
// Other locales
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
val
otherLocales
=
res
.
assets
.
locales
return
Locale
.
forLanguageTag
(
tag
)
.
map
{
it
.
langTagToLocale
()
}
}
else
{
.
distinctBy
{
LocaleManager
.
getString
(
it
,
compareId
)
}
val
tok
=
tag
.
split
(
"-"
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
if
(
tok
.
isEmpty
())
{
return
Locale
(
""
)
}
val
language
=
when
(
tok
[
0
])
{
"und"
->
""
// Undefined
"fil"
->
"tl"
// Filipino
else
->
tok
[
0
]
}
if
(
language
.
length
!=
2
&&
language
.
length
!=
3
)
return
Locale
(
""
)
if
(
tok
.
size
==
1
)
return
Locale
(
language
)
val
country
=
tok
[
1
]
return
if
(
country
.
length
!=
2
&&
country
.
length
!=
3
)
Locale
(
language
)
else
Locale
(
language
,
country
)
}
}
@JvmStatic
listOf
(
""
,
""
).
toTypedArray
()
fun
toLanguageTag
(
loc
:
Locale
):
String
{
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
{
return
loc
.
toLanguageTag
()
}
else
{
var
language
=
loc
.
language
var
country
=
loc
.
country
var
variant
=
loc
.
variant
when
{
language
.
isEmpty
()
||
!
language
.
matches
(
"\\p{Alpha}{2,8}"
.
toRegex
())
->
language
=
"und"
// Follow the Locale#toLanguageTag() implementation
language
==
"iw"
->
language
=
"he"
// correct deprecated "Hebrew"
language
==
"in"
->
language
=
"id"
// correct deprecated "Indonesian"
language
==
"ji"
->
language
=
"yi"
// correct deprecated "Yiddish"
}
// ensure valid country code, if not well formed, it's omitted
// variant subtags that begin with a letter must be at least 5 characters long
addAll
(
otherLocales
)
// ensure valid country code, if not well formed, it's omitted
}.
sortedWith
(
Comparator
{
a
,
b
->
if
(!
country
.
matches
(
"\\p{Alpha}{2}|\\p{Digit}{3}"
.
toRegex
()))
{
a
.
getDisplayName
(
a
).
toLowerCase
(
a
)
country
=
""
.
compareTo
(
b
.
getDisplayName
(
b
).
toLowerCase
(
b
))
}
})
}.
cache
()
!!
// variant subtags that begin with a letter must be at least 5 characters long
object
LocaleManager
{
if
(!
variant
.
matches
(
"\\p{Alnum}{5,8}|\\p{Digit}\\p{Alnum}{3}"
.
toRegex
()))
{
variant
=
""
}
val
tag
=
StringBuilder
(
language
)
if
(
country
.
isNotEmpty
())
tag
.
append
(
'-'
).
append
(
country
)
if
(
variant
.
isNotEmpty
())
tag
.
append
(
'-'
).
append
(
variant
)
return
tag
.
toString
()
}
}
@JvmStatic
fun
setLocale
(
wrapper
:
ContextWrapper
)
{
fun
setLocale
(
wrapper
:
ContextWrapper
)
{
val
localeConfig
=
Config
.
locale
val
localeConfig
=
Config
.
locale
l
ocale
=
when
{
currentL
ocale
=
when
{
localeConfig
.
isEmpty
()
->
defaultLocale
localeConfig
.
isEmpty
()
->
defaultLocale
else
->
forLanguageTag
(
localeConfig
)
else
->
localeConfig
.
langTagToLocale
(
)
}
}
Locale
.
setDefault
(
l
ocale
)
Locale
.
setDefault
(
currentL
ocale
)
InternalUtils
.
replaceBaseContext
(
wrapper
,
getLocaleContext
(
l
ocale
))
InternalUtils
.
replaceBaseContext
(
wrapper
,
getLocaleContext
(
wrapper
,
currentL
ocale
))
}
}
@JvmStatic
fun
getLocaleContext
(
context
:
Context
,
locale
:
Locale
=
currentLocale
):
Context
{
fun
getLocaleContext
(
context
:
Context
,
locale
:
Locale
):
Context
{
val
config
=
Configuration
(
context
.
resources
.
configuration
)
val
config
=
Configuration
(
context
.
resources
.
configuration
)
config
.
setLocale
(
locale
)
config
.
setLocale
(
locale
)
return
context
.
createConfigurationContext
(
config
)
return
context
.
createConfigurationContext
(
config
)
}
}
@JvmStatic
fun
getLocaleContext
(
locale
:
Locale
):
Context
{
return
getLocaleContext
(
App
.
self
.
baseContext
,
locale
)
}
@JvmStatic
fun
getString
(
locale
:
Locale
,
@StringRes
id
:
Int
):
String
{
fun
getString
(
locale
:
Locale
,
@StringRes
id
:
Int
):
String
{
return
getLocaleContext
(
locale
).
getString
(
id
)
return
getLocaleContext
(
get
(),
locale
).
getString
(
id
)
}
}
}
}
app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt
View file @
71d855e8
...
@@ -15,7 +15,6 @@ import com.topjohnwu.magisk.*
...
@@ -15,7 +15,6 @@ import com.topjohnwu.magisk.*
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.extensions.get
import
com.topjohnwu.magisk.extensions.get
import
com.topjohnwu.magisk.model.update.UpdateCheckService
import
com.topjohnwu.magisk.model.update.UpdateCheckService
import
com.topjohnwu.net.Networking
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.Shell
import
com.topjohnwu.superuser.internal.UiThreadHandler
import
com.topjohnwu.superuser.internal.UiThreadHandler
import
java.io.File
import
java.io.File
...
@@ -24,8 +23,7 @@ import java.util.concurrent.TimeUnit
...
@@ -24,8 +23,7 @@ import java.util.concurrent.TimeUnit
object
Utils
{
object
Utils
{
val
isCanary
:
Boolean
val
isCanary
:
Boolean
=
BuildConfig
.
VERSION_NAME
.
contains
(
"-"
)
get
()
=
BuildConfig
.
VERSION_NAME
.
contains
(
"-"
)
fun
toast
(
msg
:
CharSequence
,
duration
:
Int
)
{
fun
toast
(
msg
:
CharSequence
,
duration
:
Int
)
{
UiThreadHandler
.
run
{
Toast
.
makeText
(
get
(),
msg
,
duration
).
show
()
}
UiThreadHandler
.
run
{
Toast
.
makeText
(
get
(),
msg
,
duration
).
show
()
}
...
@@ -35,11 +33,6 @@ object Utils {
...
@@ -35,11 +33,6 @@ object Utils {
UiThreadHandler
.
run
{
Toast
.
makeText
(
get
(),
resId
,
duration
).
show
()
}
UiThreadHandler
.
run
{
Toast
.
makeText
(
get
(),
resId
,
duration
).
show
()
}
}
}
fun
dlString
(
url
:
String
):
String
{
val
s
=
Networking
.
get
(
url
).
execForString
().
result
return
s
?:
""
}
fun
getPrefsInt
(
prefs
:
SharedPreferences
,
key
:
String
,
def
:
Int
=
0
):
Int
{
fun
getPrefsInt
(
prefs
:
SharedPreferences
,
key
:
String
,
def
:
Int
=
0
):
Int
{
return
prefs
.
getString
(
key
,
def
.
toString
())
!!
.
toInt
()
return
prefs
.
getString
(
key
,
def
.
toString
())
!!
.
toInt
()
}
}
...
@@ -58,7 +51,7 @@ object Utils {
...
@@ -58,7 +51,7 @@ object Utils {
if
(
info
.
labelRes
>
0
)
{
if
(
info
.
labelRes
>
0
)
{
val
res
=
pm
.
getResourcesForApplication
(
info
)
val
res
=
pm
.
getResourcesForApplication
(
info
)
val
config
=
Configuration
()
val
config
=
Configuration
()
config
.
setLocale
(
LocaleManager
.
l
ocale
)
config
.
setLocale
(
currentL
ocale
)
res
.
updateConfiguration
(
config
,
res
.
displayMetrics
)
res
.
updateConfiguration
(
config
,
res
.
displayMetrics
)
return
res
.
getString
(
info
.
labelRes
)
return
res
.
getString
(
info
.
labelRes
)
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/view/Notifications.java
deleted
100644 → 0
View file @
33b7ab59
package
com
.
topjohnwu
.
magisk
.
view
;
import
android.app.NotificationChannel
;
import
android.app.NotificationManager
;
import
android.app.PendingIntent
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Build
;
import
androidx.core.app.NotificationCompat
;
import
androidx.core.app.NotificationManagerCompat
;
import
androidx.core.app.TaskStackBuilder
;
import
com.topjohnwu.magisk.App
;
import
com.topjohnwu.magisk.ClassMap
;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.Info
;
import
com.topjohnwu.magisk.R
;
import
com.topjohnwu.magisk.model.receiver.GeneralReceiver
;
import
com.topjohnwu.magisk.ui.SplashActivity
;
public
class
Notifications
{
public
static
NotificationManagerCompat
mgr
=
NotificationManagerCompat
.
from
(
App
.
self
);
public
static
void
setup
(
Context
c
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
mgr
.
deleteNotificationChannel
(
"magisk_notification"
);
NotificationChannel
channel
=
new
NotificationChannel
(
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
,
c
.
getString
(
R
.
string
.
update_channel
),
NotificationManager
.
IMPORTANCE_DEFAULT
);
mgr
.
createNotificationChannel
(
channel
);
channel
=
new
NotificationChannel
(
Const
.
ID
.
PROGRESS_NOTIFICATION_CHANNEL
,
c
.
getString
(
R
.
string
.
progress_channel
),
NotificationManager
.
IMPORTANCE_LOW
);
mgr
.
createNotificationChannel
(
channel
);
}
}
public
static
void
magiskUpdate
()
{
App
app
=
App
.
self
;
Intent
intent
=
new
Intent
(
app
,
ClassMap
.
get
(
SplashActivity
.
class
));
intent
.
putExtra
(
Const
.
Key
.
OPEN_SECTION
,
"magisk"
);
TaskStackBuilder
stackBuilder
=
TaskStackBuilder
.
create
(
app
);
stackBuilder
.
addParentStack
(
ClassMap
.
get
(
SplashActivity
.
class
));
stackBuilder
.
addNextIntent
(
intent
);
PendingIntent
pendingIntent
=
stackBuilder
.
getPendingIntent
(
Const
.
ID
.
MAGISK_UPDATE_NOTIFICATION_ID
,
PendingIntent
.
FLAG_UPDATE_CURRENT
);
NotificationCompat
.
Builder
builder
=
new
NotificationCompat
.
Builder
(
app
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
);
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
app
.
getString
(
R
.
string
.
magisk_update_title
))
.
setContentText
(
app
.
getString
(
R
.
string
.
manager_download_install
))
.
setVibrate
(
new
long
[]{
0
,
100
,
100
,
100
})
.
setAutoCancel
(
true
)
.
setContentIntent
(
pendingIntent
);
mgr
.
notify
(
Const
.
ID
.
MAGISK_UPDATE_NOTIFICATION_ID
,
builder
.
build
());
}
public
static
void
managerUpdate
()
{
App
app
=
App
.
self
;
Intent
intent
=
new
Intent
(
app
,
ClassMap
.
get
(
GeneralReceiver
.
class
));
intent
.
setAction
(
Const
.
Key
.
BROADCAST_MANAGER_UPDATE
);
intent
.
putExtra
(
Const
.
Key
.
INTENT_SET_APP
,
Info
.
remote
.
getApp
());
PendingIntent
pendingIntent
=
PendingIntent
.
getBroadcast
(
app
,
Const
.
ID
.
APK_UPDATE_NOTIFICATION_ID
,
intent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
);
NotificationCompat
.
Builder
builder
=
new
NotificationCompat
.
Builder
(
app
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
);
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
app
.
getString
(
R
.
string
.
manager_update_title
))
.
setContentText
(
app
.
getString
(
R
.
string
.
manager_download_install
))
.
setVibrate
(
new
long
[]{
0
,
100
,
100
,
100
})
.
setAutoCancel
(
true
)
.
setContentIntent
(
pendingIntent
);
mgr
.
notify
(
Const
.
ID
.
APK_UPDATE_NOTIFICATION_ID
,
builder
.
build
());
}
public
static
void
dtboPatched
()
{
App
app
=
App
.
self
;
Intent
intent
=
new
Intent
(
app
,
ClassMap
.
get
(
GeneralReceiver
.
class
))
.
setAction
(
Const
.
Key
.
BROADCAST_REBOOT
);
PendingIntent
pendingIntent
=
PendingIntent
.
getBroadcast
(
app
,
Const
.
ID
.
DTBO_NOTIFICATION_ID
,
intent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
);
NotificationCompat
.
Builder
builder
=
new
NotificationCompat
.
Builder
(
app
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
);
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
app
.
getString
(
R
.
string
.
dtbo_patched_title
))
.
setContentText
(
app
.
getString
(
R
.
string
.
dtbo_patched_reboot
))
.
setVibrate
(
new
long
[]{
0
,
100
,
100
,
100
})
.
addAction
(
R
.
drawable
.
ic_refresh
,
app
.
getString
(
R
.
string
.
reboot
),
pendingIntent
);
mgr
.
notify
(
Const
.
ID
.
DTBO_NOTIFICATION_ID
,
builder
.
build
());
}
public
static
NotificationCompat
.
Builder
progress
(
Context
context
,
CharSequence
title
)
{
NotificationCompat
.
Builder
builder
=
new
NotificationCompat
.
Builder
(
context
,
Const
.
ID
.
PROGRESS_NOTIFICATION_CHANNEL
);
builder
.
setPriority
(
NotificationCompat
.
PRIORITY_LOW
)
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download
)
.
setContentTitle
(
title
)
.
setProgress
(
0
,
0
,
true
)
.
setOngoing
(
true
);
return
builder
;
}
}
app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt
0 → 100644
View file @
71d855e8
package
com.topjohnwu.magisk.view
import
android.app.NotificationChannel
import
android.app.NotificationManager
import
android.app.PendingIntent
import
android.content.Context
import
android.content.Intent
import
android.os.Build
import
androidx.core.app.NotificationCompat
import
androidx.core.app.NotificationManagerCompat
import
androidx.core.app.TaskStackBuilder
import
com.topjohnwu.magisk.ClassMap
import
com.topjohnwu.magisk.Const
import
com.topjohnwu.magisk.Info
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.extensions.get
import
com.topjohnwu.magisk.model.receiver.GeneralReceiver
import
com.topjohnwu.magisk.ui.SplashActivity
object
Notifications
{
val
mgr
by
lazy
{
NotificationManagerCompat
.
from
(
get
())
}
fun
setup
(
context
:
Context
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
mgr
.
deleteNotificationChannel
(
"magisk_notification"
)
var
channel
=
NotificationChannel
(
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
,
context
.
getString
(
R
.
string
.
update_channel
),
NotificationManager
.
IMPORTANCE_DEFAULT
)
mgr
.
createNotificationChannel
(
channel
)
channel
=
NotificationChannel
(
Const
.
ID
.
PROGRESS_NOTIFICATION_CHANNEL
,
context
.
getString
(
R
.
string
.
progress_channel
),
NotificationManager
.
IMPORTANCE_LOW
)
mgr
.
createNotificationChannel
(
channel
)
}
}
fun
magiskUpdate
(
context
:
Context
)
{
val
intent
=
Intent
(
context
,
ClassMap
[
SplashActivity
::
class
.
java
])
intent
.
putExtra
(
Const
.
Key
.
OPEN_SECTION
,
"magisk"
)
val
stackBuilder
=
TaskStackBuilder
.
create
(
context
)
stackBuilder
.
addParentStack
(
ClassMap
.
get
<
Class
<*>>(
SplashActivity
::
class
.
java
))
stackBuilder
.
addNextIntent
(
intent
)
val
pendingIntent
=
stackBuilder
.
getPendingIntent
(
Const
.
ID
.
MAGISK_UPDATE_NOTIFICATION_ID
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
)
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
context
.
getString
(
R
.
string
.
magisk_update_title
))
.
setContentText
(
context
.
getString
(
R
.
string
.
manager_download_install
))
.
setVibrate
(
longArrayOf
(
0
,
100
,
100
,
100
))
.
setAutoCancel
(
true
)
.
setContentIntent
(
pendingIntent
)
mgr
.
notify
(
Const
.
ID
.
MAGISK_UPDATE_NOTIFICATION_ID
,
builder
.
build
())
}
fun
managerUpdate
(
context
:
Context
)
{
val
intent
=
Intent
(
context
,
ClassMap
[
GeneralReceiver
::
class
.
java
])
intent
.
action
=
Const
.
Key
.
BROADCAST_MANAGER_UPDATE
intent
.
putExtra
(
Const
.
Key
.
INTENT_SET_APP
,
Info
.
remote
.
app
)
val
pendingIntent
=
PendingIntent
.
getBroadcast
(
context
,
Const
.
ID
.
APK_UPDATE_NOTIFICATION_ID
,
intent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
)
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
context
.
getString
(
R
.
string
.
manager_update_title
))
.
setContentText
(
context
.
getString
(
R
.
string
.
manager_download_install
))
.
setVibrate
(
longArrayOf
(
0
,
100
,
100
,
100
))
.
setAutoCancel
(
true
)
.
setContentIntent
(
pendingIntent
)
mgr
.
notify
(
Const
.
ID
.
APK_UPDATE_NOTIFICATION_ID
,
builder
.
build
())
}
fun
dtboPatched
(
context
:
Context
)
{
val
intent
=
Intent
(
context
,
ClassMap
[
GeneralReceiver
::
class
.
java
])
.
setAction
(
Const
.
Key
.
BROADCAST_REBOOT
)
val
pendingIntent
=
PendingIntent
.
getBroadcast
(
context
,
Const
.
ID
.
DTBO_NOTIFICATION_ID
,
intent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
val
builder
=
NotificationCompat
.
Builder
(
context
,
Const
.
ID
.
UPDATE_NOTIFICATION_CHANNEL
)
builder
.
setSmallIcon
(
R
.
drawable
.
ic_magisk_outline
)
.
setContentTitle
(
context
.
getString
(
R
.
string
.
dtbo_patched_title
))
.
setContentText
(
context
.
getString
(
R
.
string
.
dtbo_patched_reboot
))
.
setVibrate
(
longArrayOf
(
0
,
100
,
100
,
100
))
.
addAction
(
R
.
drawable
.
ic_refresh
,
context
.
getString
(
R
.
string
.
reboot
),
pendingIntent
)
mgr
.
notify
(
Const
.
ID
.
DTBO_NOTIFICATION_ID
,
builder
.
build
())
}
fun
progress
(
context
:
Context
,
title
:
CharSequence
):
NotificationCompat
.
Builder
{
val
builder
=
NotificationCompat
.
Builder
(
context
,
Const
.
ID
.
PROGRESS_NOTIFICATION_CHANNEL
)
builder
.
setPriority
(
NotificationCompat
.
PRIORITY_LOW
)
.
setSmallIcon
(
android
.
R
.
drawable
.
stat_sys_download
)
.
setContentTitle
(
title
)
.
setProgress
(
0
,
0
,
true
)
.
setOngoing
(
true
)
return
builder
}
}
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