Merge branch 'remote-master' into development

# Conflicts:
#	app/src/main/java/com/topjohnwu/magisk/di/ViewModelsModule.kt
#	app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt
#	app/src/main/java/com/topjohnwu/magisk/utils/XString.kt
This commit is contained in:
Viktor De Pasquale 2019-05-10 16:43:37 +02:00
commit 58a449d437
12 changed files with 82 additions and 58 deletions

View File

@ -9,12 +9,11 @@ import org.koin.dsl.module
val applicationModule = module { val applicationModule = module {
single { RxBus() } single { RxBus() }
single { get<Context>().resources } factory { get<Context>().resources }
single { get<Context>() as App } factory { get<Context>() as App }
single { get<Context>().packageManager } factory { get<Context>().packageManager }
single(SUTimeout) { single(SUTimeout) {
get<App>().protectedContext get<App>().protectedContext.getSharedPreferences("su_timeout", 0)
.getSharedPreferences("su_timeout", 0)
} }
single { PreferenceManager.getDefaultSharedPreferences(get<App>().protectedContext) } single { PreferenceManager.getDefaultSharedPreferences(get<App>().protectedContext) }
} }

View File

@ -15,7 +15,7 @@ import org.koin.dsl.module
val viewModelModules = module { val viewModelModules = module {
viewModel { MainViewModel() } viewModel { MainViewModel() }
viewModel { HomeViewModel(get(), get(), get()) } viewModel { HomeViewModel(get(), get()) }
viewModel { SuperuserViewModel(get(), get(), get(), get()) } viewModel { SuperuserViewModel(get(), get(), get(), get()) }
viewModel { HideViewModel(get(), get()) } viewModel { HideViewModel(get(), get()) }
viewModel { ModuleViewModel(get(), get()) } viewModel { ModuleViewModel(get(), get()) }

View File

@ -1,6 +1,7 @@
package com.topjohnwu.magisk.ui.base package com.topjohnwu.magisk.ui.base
import android.content.Intent import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
@ -24,6 +25,7 @@ import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
import com.topjohnwu.magisk.model.navigation.Navigator 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.Utils import com.topjohnwu.magisk.utils.Utils
import timber.log.Timber import timber.log.Timber
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -58,6 +60,12 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
} }
override fun applyOverrideConfiguration(config: Configuration?) {
// Force applying our preferred local
config?.setLocale(LocaleManager.locale)
super.applyOverrideConfiguration(config)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
navigationController?.apply { navigationController?.apply {

View File

@ -1,23 +1,28 @@
package com.topjohnwu.magisk.ui.home package com.topjohnwu.magisk.ui.home
import android.content.res.Resources import android.content.Context
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
import com.skoumal.teanity.extensions.doOnSubscribeUi import com.skoumal.teanity.extensions.doOnSubscribeUi
import com.skoumal.teanity.extensions.subscribeK import com.skoumal.teanity.extensions.subscribeK
import com.skoumal.teanity.util.KObservableField import com.skoumal.teanity.util.KObservableField
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.* import com.topjohnwu.magisk.*
import com.topjohnwu.magisk.data.repository.MagiskRepository import com.topjohnwu.magisk.data.repository.MagiskRepository
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.ui.base.MagiskViewModel import com.topjohnwu.magisk.ui.base.MagiskViewModel
import com.topjohnwu.magisk.utils.*
import com.topjohnwu.net.Networking
import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.utils.ISafetyNetHelper
import com.topjohnwu.magisk.utils.toggle import com.topjohnwu.magisk.utils.toggle
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
class HomeViewModel( class HomeViewModel(
private val resources: Resources, private val context: Context,
private val app: App,
private val magiskRepo: MagiskRepository private val magiskRepo: MagiskRepository
) : MagiskViewModel() { ) : MagiskViewModel() {
@ -30,17 +35,17 @@ class HomeViewModel(
val magiskStateText = Observer(magiskState) { val magiskStateText = Observer(magiskState) {
when (magiskState.value) { when (magiskState.value) {
MagiskState.NO_ROOT -> TODO() MagiskState.NO_ROOT -> TODO()
MagiskState.NOT_INSTALLED -> resources.getString(R.string.magisk_version_error) MagiskState.NOT_INSTALLED -> R.string.magisk_version_error.res()
MagiskState.UP_TO_DATE -> resources.getString(R.string.magisk_up_to_date) MagiskState.UP_TO_DATE -> R.string.magisk_up_to_date.res()
MagiskState.LOADING -> resources.getString(R.string.checking_for_updates) MagiskState.LOADING -> R.string.checking_for_updates.res()
MagiskState.OBSOLETE -> resources.getString(R.string.magisk_update_title) MagiskState.OBSOLETE -> R.string.magisk_update_title.res()
} }
} }
val magiskCurrentVersion = KObservableField("") val magiskCurrentVersion = KObservableField("")
val magiskLatestVersion = KObservableField("") val magiskLatestVersion = KObservableField("")
val magiskAdditionalInfo = Observer(magiskState) { val magiskAdditionalInfo = Observer(magiskState) {
if (Config.get<Boolean>(Config.Key.COREONLY)) if (Config.get<Boolean>(Config.Key.COREONLY))
resources.getString(R.string.core_only_enabled) R.string.core_only_enabled.res()
else else
"" ""
} }
@ -49,22 +54,22 @@ class HomeViewModel(
val managerStateText = Observer(managerState) { val managerStateText = Observer(managerState) {
when (managerState.value) { when (managerState.value) {
MagiskState.NO_ROOT -> "wtf" MagiskState.NO_ROOT -> "wtf"
MagiskState.NOT_INSTALLED -> resources.getString(R.string.invalid_update_channel) MagiskState.NOT_INSTALLED -> R.string.invalid_update_channel.res()
MagiskState.UP_TO_DATE -> resources.getString(R.string.manager_up_to_date) MagiskState.UP_TO_DATE -> R.string.manager_up_to_date.res()
MagiskState.LOADING -> resources.getString(R.string.checking_for_updates) MagiskState.LOADING -> R.string.checking_for_updates.res()
MagiskState.OBSOLETE -> resources.getString(R.string.manager_update_title) MagiskState.OBSOLETE -> R.string.manager_update_title.res()
} }
} }
val managerCurrentVersion = KObservableField("") val managerCurrentVersion = KObservableField("")
val managerLatestVersion = KObservableField("") val managerLatestVersion = KObservableField("")
val managerAdditionalInfo = Observer(managerState) { val managerAdditionalInfo = Observer(managerState) {
if (app.packageName != BuildConfig.APPLICATION_ID) if (packageName != BuildConfig.APPLICATION_ID)
"(${app.packageName})" "($packageName)"
else else
"" ""
} }
val safetyNetTitle = KObservableField(resources.getString(R.string.safetyNet_check_text)) val safetyNetTitle = KObservableField(R.string.safetyNet_check_text.res())
val ctsState = KObservableField(SafetyNetState.IDLE) val ctsState = KObservableField(SafetyNetState.IDLE)
val basicIntegrityState = KObservableField(SafetyNetState.IDLE) val basicIntegrityState = KObservableField(SafetyNetState.IDLE)
val safetyNetState = Observer(ctsState, basicIntegrityState) { val safetyNetState = Observer(ctsState, basicIntegrityState) {
@ -82,8 +87,6 @@ class HomeViewModel(
val hasRoot = KObservableField(false) val hasRoot = KObservableField(false)
private var shownDialog = false private var shownDialog = false
private val current = resources.getString(R.string.current_installed)
private val latest = resources.getString(R.string.latest_version)
init { init {
isForceEncryption.addOnPropertyChangedCallback { isForceEncryption.addOnPropertyChangedCallback {
@ -118,7 +121,7 @@ class HomeViewModel(
fun safetyNetPressed() { fun safetyNetPressed() {
ctsState.value = SafetyNetState.LOADING ctsState.value = SafetyNetState.LOADING
basicIntegrityState.value = SafetyNetState.LOADING basicIntegrityState.value = SafetyNetState.LOADING
safetyNetTitle.value = resources.getString(R.string.checking_safetyNet_status) safetyNetTitle.value = R.string.checking_safetyNet_status.res()
UpdateSafetyNetEvent().publish() UpdateSafetyNetEvent().publish()
} }
@ -127,7 +130,7 @@ class HomeViewModel(
response and 0x0F == 0 -> { response and 0x0F == 0 -> {
val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0 val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0
val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0 val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0
safetyNetTitle.value = resources.getString(R.string.safetyNet_check_success) safetyNetTitle.value = R.string.safetyNet_check_success.res()
ctsState.value = if (hasCtsPassed) { ctsState.value = if (hasCtsPassed) {
SafetyNetState.PASS SafetyNetState.PASS
} else { } else {
@ -146,11 +149,10 @@ class HomeViewModel(
else -> { else -> {
ctsState.value = SafetyNetState.IDLE ctsState.value = SafetyNetState.IDLE
basicIntegrityState.value = SafetyNetState.IDLE basicIntegrityState.value = SafetyNetState.IDLE
val errorString = when (response) { safetyNetTitle.value = when (response) {
ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid
else -> R.string.safetyNet_api_error else -> R.string.safetyNet_api_error
} }.res()
safetyNetTitle.value = resources.getString(errorString)
} }
} }
@ -185,16 +187,14 @@ class HomeViewModel(
else -> MagiskState.UP_TO_DATE else -> MagiskState.UP_TO_DATE
} }
if (magiskState.value != MagiskState.NOT_INSTALLED) { magiskCurrentVersion.value = if (magiskState.value != MagiskState.NOT_INSTALLED) {
magiskCurrentVersion.value = version version.format(Config.magiskVersionString, Config.magiskVersionCode)
.format(Config.magiskVersionString, Config.magiskVersionCode)
.let { current.format(it) }
} else { } else {
magiskCurrentVersion.value = "" ""
} }
magiskLatestVersion.value = version magiskLatestVersion.value = version
.format(Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode) .format(Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode)
.let { latest.format(it) }
managerState.value = when (Config.remoteManagerVersionCode) { managerState.value = when (Config.remoteManagerVersionCode) {
in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED //wrong update channel in Int.MIN_VALUE until 0 -> MagiskState.NOT_INSTALLED //wrong update channel
@ -204,10 +204,9 @@ class HomeViewModel(
managerCurrentVersion.value = version managerCurrentVersion.value = version
.format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE) .format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
.let { current.format(it) }
managerLatestVersion.value = version managerLatestVersion.value = version
.format(Config.remoteManagerVersionString, Config.remoteManagerVersionCode) .format(Config.remoteManagerVersionString, Config.remoteManagerVersionCode)
.let { latest.format(it) }
} }
private fun ensureEnv() { private fun ensureEnv() {

View File

@ -13,6 +13,12 @@ import com.topjohnwu.magisk.App
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
val packageName: String
get() {
val app: App by inject()
return app.packageName
}
val PackageInfo.processes val PackageInfo.processes
get() = activities?.processNames.orEmpty() + get() = activities?.processNames.orEmpty() +
services?.processNames.orEmpty() + services?.processNames.orEmpty() +

View File

@ -1,5 +1,7 @@
package com.topjohnwu.magisk.utils package com.topjohnwu.magisk.utils
import android.content.res.Resources
val specialChars = arrayOf('!', '@', '#', '$', '%', '&', '?') val specialChars = arrayOf('!', '@', '#', '$', '%', '&', '?')
fun String.replaceRandomWithSpecial(): String { fun String.replaceRandomWithSpecial(): String {
@ -12,3 +14,8 @@ fun String.replaceRandomWithSpecial(): String {
fun StringBuilder.appendIf(condition: Boolean, builder: StringBuilder.() -> Unit) = fun StringBuilder.appendIf(condition: Boolean, builder: StringBuilder.() -> Unit) =
if (condition) apply(builder) else this if (condition) apply(builder) else this
fun Int.res(vararg args: Any): String {
val resources: Resources by inject()
return resources.getString(this, *args)
}

View File

@ -110,7 +110,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1" android:maxLines="1"
android:text="@{state != MagiskState.LOADING ? currentVersion : @string/checking_for_updates}" android:text="@{state != MagiskState.LOADING ? @string/current_installed(currentVersion) : @string/checking_for_updates}"
app:autoSizeMinTextSize="1sp" app:autoSizeMinTextSize="1sp"
app:autoSizeTextType="uniform" app:autoSizeTextType="uniform"
app:layout_constraintBottom_toTopOf="@+id/latest_version" app:layout_constraintBottom_toTopOf="@+id/latest_version"
@ -125,7 +125,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1" android:maxLines="1"
android:text="@{state != MagiskState.LOADING ? latestVersion : @string/checking_for_updates}" android:text="@{state != MagiskState.LOADING ? @string/latest_version(latestVersion) : @string/checking_for_updates}"
app:autoSizeMinTextSize="1sp" app:autoSizeMinTextSize="1sp"
app:autoSizeTextType="uniform" app:autoSizeTextType="uniform"
app:layout_constraintBottom_toTopOf="@+id/additional" app:layout_constraintBottom_toTopOf="@+id/additional"

View File

@ -55,6 +55,7 @@ restore_imgs() {
local STOCKDTBO=/data/stock_dtbo.img.gz local STOCKDTBO=/data/stock_dtbo.img.gz
[ -f $STOCKBOOT ] || return 1 [ -f $STOCKBOOT ] || return 1
get_flags
find_boot_image find_boot_image
find_dtbo_image find_dtbo_image

View File

@ -46,7 +46,7 @@ subprojects {
getPlugins().hasPlugin('com.android.application')) { getPlugins().hasPlugin('com.android.application')) {
android { android {
compileSdkVersion 'android-Q' compileSdkVersion 'android-Q'
buildToolsVersion '29.0.0-rc2' buildToolsVersion '29.0.0-rc3'
defaultConfig { defaultConfig {
if (minSdkVersion == null) if (minSdkVersion == null)

View File

@ -374,7 +374,7 @@ static bool magisk_env() {
mount_mirror(system, MS_RDONLY); mount_mirror(system, MS_RDONLY);
} else if (str_contains(line, " /vendor ")) { } else if (str_contains(line, " /vendor ")) {
mount_mirror(vendor, MS_RDONLY); mount_mirror(vendor, MS_RDONLY);
} else if (str_contains(line, " /data ")) { } else if (str_contains(line, " /data ") && !str_contains(line, "tmpfs")) {
mount_mirror(data, 0); mount_mirror(data, 0);
} else if (SDK_INT >= 24 && } else if (SDK_INT >= 24 &&
str_contains(line, " /proc ") && !str_contains(line, "hidepid=2")) { str_contains(line, " /proc ") && !str_contains(line, "hidepid=2")) {

View File

@ -74,7 +74,7 @@ static void usage(char *arg0) {
" test\n" " test\n"
" Check if fstab has verity/avb flags\n" " Check if fstab has verity/avb flags\n"
" Return values:\n" " Return values:\n"
" 0:no flags 1:flag exists\n" " 0:flag exists 1:no flags\n"
" patch\n" " patch\n"
" Search for fstab and remove verity/avb\n" " Search for fstab and remove verity/avb\n"
"\n" "\n"

View File

@ -55,6 +55,7 @@ $BOOTMODE || recovery_actions
# Uninstall # Uninstall
########################################################################################## ##########################################################################################
get_flags
find_boot_image find_boot_image
find_dtbo_image find_dtbo_image
@ -67,36 +68,35 @@ cd $MAGISKBIN
CHROMEOS=false CHROMEOS=false
ui_print "- Unpacking boot image" ui_print "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE" ./magiskboot unpack "$BOOTIMAGE"
case $? in case $? in
1 ) 1 )
abort "! Unable to unpack boot image" abort "! Unsupported/Unknown image format"
;; ;;
2 ) 2 )
ui_print "- ChromeOS boot image detected" ui_print "- ChromeOS boot image detected"
CHROMEOS=true CHROMEOS=true
;; ;;
3 )
ui_print "! Sony ELF32 format detected"
abort "! Please use BootBridge from @AdrianDC"
;;
4 )
ui_print "! Sony ELF64 format detected"
abort "! Stock kernel cannot be patched, please use a custom kernel"
esac esac
# Detect boot image state # Detect boot image state
ui_print "- Checking ramdisk status" ui_print "- Checking ramdisk status"
./magiskboot --cpio ramdisk.cpio test if [ -e ramdisk.cpio ]; then
case $? in ./magiskboot cpio ramdisk.cpio test
STATUS=$?
else
# Stock A only system-as-root
STATUS=0
fi
case $((STATUS & 3)) in
0 ) # Stock boot 0 ) # Stock boot
ui_print "- Stock boot image detected" ui_print "- Stock boot image detected"
;; ;;
1 ) # Magisk patched 1 ) # Magisk patched
ui_print "- Magisk patched image detected" ui_print "- Magisk patched image detected"
# Find SHA1 of stock boot image # Find SHA1 of stock boot image
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null` [ -z $SHA1 ] && SHA1=`./magiskboot cpio ramdisk.cpio sha1 2>/dev/null`
STOCKBOOT=/data/stock_boot_${SHA1}.img.gz STOCKBOOT=/data/stock_boot_${SHA1}.img.gz
STOCKDTBO=/data/stock_dtbo.img.gz STOCKDTBO=/data/stock_dtbo.img.gz
if [ -f $STOCKBOOT ]; then if [ -f $STOCKBOOT ]; then
@ -109,16 +109,20 @@ case $? in
else else
ui_print "! Boot image backup unavailable" ui_print "! Boot image backup unavailable"
ui_print "- Restoring ramdisk with internal backup" ui_print "- Restoring ramdisk with internal backup"
./magiskboot --cpio ramdisk.cpio restore ./magiskboot cpio ramdisk.cpio restore
./magiskboot --repack $BOOTIMAGE if ! ./magiskboot cpio ramdisk.cpio "exists init.rc"; then
# A only system-as-root
rm -f ramdisk.cpio
fi
./magiskboot repack $BOOTIMAGE
# Sign chromeos boot # Sign chromeos boot
$CHROMEOS && sign_chromeos $CHROMEOS && sign_chromeos
ui_print "- Flashing restored boot image" ui_print "- Flashing restored boot image"
flash_image new-boot.img $BOOTIMAGE || abort "! Insufficient partition size" flash_image new-boot.img $BOOTIMAGE || abort "! Insufficient partition size"
fi fi
;; ;;
2 ) # Other patched 2 ) # Unsupported
ui_print "! Boot image patched by other programs" ui_print "! Boot image patched by unsupported programs"
abort "! Cannot uninstall" abort "! Cannot uninstall"
;; ;;
esac esac