Several changes

- Change error message strings
- Move non-root stub error to SplashActivity
- Skip shell init in non-root stub
This commit is contained in:
topjohnwu 2021-02-22 03:05:49 -08:00
parent a4fb1297b0
commit 68090943f4
9 changed files with 54 additions and 57 deletions

View File

@ -46,13 +46,7 @@ object Const {
} }
object ID { object ID {
const val FETCH_ZIP = 2
const val SELECT_FILE = 3
const val UNINSTALL_APP = 4
const val MAX_ACTIVITY_RESULT = 10
// notifications // notifications
const val MAGISK_UPDATE_NOTIFICATION_ID = 4
const val APK_UPDATE_NOTIFICATION_ID = 5 const val APK_UPDATE_NOTIFICATION_ID = 5
const val UPDATE_NOTIFICATION_CHANNEL = "update" const val UPDATE_NOTIFICATION_CHANNEL = "update"
const val PROGRESS_NOTIFICATION_CHANNEL = "progress" const val PROGRESS_NOTIFICATION_CHANNEL = "progress"

View File

@ -1,21 +1,23 @@
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.base.BaseActivity
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.data.repository.NetworkService import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.ktx.get import com.topjohnwu.magisk.ktx.get
import com.topjohnwu.magisk.ui.MainActivity import com.topjohnwu.magisk.ui.MainActivity
import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
open class SplashActivity : Activity() { open class SplashActivity : BaseActivity() {
private val latch = CountDownLatch(1) private val latch = CountDownLatch(1)
@ -41,12 +43,27 @@ open class SplashActivity : Activity() {
if (Config.suManager.isNotEmpty()) if (Config.suManager.isNotEmpty())
Config.suManager = "" Config.suManager = ""
pkg ?: return pkg ?: return
val uninstall = Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec() if (!Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec().isSuccess)
if (!uninstall.isSuccess) uninstallApp(pkg) uninstallApp(pkg)
} }
} }
private fun initAndStart() { private fun initAndStart() {
if (isRunningAsStub && !Shell.rootAccess()) {
runOnUiThread {
MagiskDialog(this)
.applyTitle(R.string.unsupport_nonroot_stub_title)
.applyMessage(R.string.unsupport_nonroot_stub_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.install
onClick { HideAPK.restore(this@SplashActivity) }
}
.cancellable(false)
.reveal()
}
return
}
val prevPkg = intent.getStringExtra(Const.Key.PREV_PKG) val prevPkg = intent.getStringExtra(Const.Key.PREV_PKG)
Config.load(prevPkg) Config.load(prevPkg)
@ -59,8 +76,7 @@ open class SplashActivity : Activity() {
get<NetworkService>() get<NetworkService>()
DONE = true DONE = true
startActivity(redirect<MainActivity>())
redirect<MainActivity>().also { startActivity(it) }
finish() finish()
} }
@ -69,16 +85,12 @@ open class SplashActivity : Activity() {
val uri = Uri.Builder().scheme("package").opaquePart(pkg).build() val uri = Uri.Builder().scheme("package").opaquePart(pkg).build()
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, uri) val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, uri)
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
startActivityForResult(intent, Const.ID.UNINSTALL_APP) startActivityForResult(intent) { _, _ ->
latch.countDown()
}
latch.await() latch.await()
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == Const.ID.UNINSTALL_APP) {
if (resultCode != RESULT_CANCELED) latch.countDown()
} else super.onActivityResult(requestCode, resultCode, data)
}
companion object { companion object {
var DONE = false var DONE = false
} }

View File

@ -14,7 +14,6 @@ import androidx.collection.SparseArrayCompat
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.core.wrap
import com.topjohnwu.magisk.ktx.set import com.topjohnwu.magisk.ktx.set
@ -26,6 +25,13 @@ typealias ActivityResultCallback = BaseActivity.(Int, Intent?) -> Unit
abstract class BaseActivity : AppCompatActivity() { abstract class BaseActivity : AppCompatActivity() {
private val resultCallbacks by lazy { SparseArrayCompat<ActivityResultCallback>() } private val resultCallbacks by lazy { SparseArrayCompat<ActivityResultCallback>() }
private val newRequestCode: Int get() {
var requestCode: Int
do {
requestCode = Random.nextInt(0, 1 shl 15)
} while (resultCallbacks.containsKey(requestCode))
return requestCode
}
override fun applyOverrideConfiguration(config: Configuration?) { override fun applyOverrideConfiguration(config: Configuration?) {
// Force applying our preferred local // Force applying our preferred local
@ -49,10 +55,7 @@ abstract class BaseActivity : AppCompatActivity() {
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
request.onSuccess() request.onSuccess()
} else { } else {
var requestCode: Int val requestCode = newRequestCode
do {
requestCode = Random.nextInt(Const.ID.MAX_ACTIVITY_RESULT + 1, 1 shl 15)
} while (resultCallbacks.containsKey(requestCode))
resultCallbacks[requestCode] = { result, _ -> resultCallbacks[requestCode] = { result, _ ->
if (result > 0) if (result > 0)
request.onSuccess() request.onSuccess()
@ -92,7 +95,8 @@ abstract class BaseActivity : AppCompatActivity() {
} }
} }
fun startActivityForResult(intent: Intent, requestCode: Int, callback: ActivityResultCallback) { fun startActivityForResult(intent: Intent, callback: ActivityResultCallback) {
val requestCode = newRequestCode
resultCallbacks[requestCode] = callback resultCallbacks[requestCode] = callback
try { try {
startActivityForResult(intent, requestCode) startActivityForResult(intent, requestCode)

View File

@ -31,6 +31,8 @@ class BusyBoxInit : BaseShellInit() {
val localBB: File val localBB: File
if (isRunningAsStub) { if (isRunningAsStub) {
if (!shell.isRoot)
return true
val jar = JarFile(DynAPK.current(context)) val jar = JarFile(DynAPK.current(context))
val bb = jar.getJarEntry("lib/${Const.CPU_ABI_32}/libbusybox.so") val bb = jar.getJarEntry("lib/${Const.CPU_ABI_32}/libbusybox.so")
localBB = context.deviceProtectedContext.cachedFile("busybox") localBB = context.deviceProtectedContext.cachedFile("busybox")

View File

@ -80,7 +80,7 @@ class MagiskInstallFileEvent(private val callback: ActivityResultCallback)
override fun invoke(activity: BaseUIActivity<*, *>) { override fun invoke(activity: BaseUIActivity<*, *>) {
val intent = Intent(Intent.ACTION_GET_CONTENT).setType("*/*") val intent = Intent(Intent.ACTION_GET_CONTENT).setType("*/*")
try { try {
activity.startActivityForResult(intent, Const.ID.SELECT_FILE, callback) activity.startActivityForResult(intent, callback)
Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG) Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT) Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT)
@ -109,7 +109,7 @@ class SelectModuleEvent : ViewEvent(), FragmentExecutor {
val intent = Intent(Intent.ACTION_GET_CONTENT).setType("application/zip") val intent = Intent(Intent.ACTION_GET_CONTENT).setType("application/zip")
try { try {
fragment.apply { fragment.apply {
activity.startActivityForResult(intent, Const.ID.FETCH_ZIP) { code, intent -> activity.startActivityForResult(intent) { code, intent ->
if (code == Activity.RESULT_OK && intent != null) { if (code == Activity.RESULT_OK && intent != null) {
intent.data?.also { intent.data?.also {
MainDirections.actionFlashFragment(Const.Value.FLASH_ZIP, it).navigate() MainDirections.actionFlashFragment(Const.Value.FLASH_ZIP, it).navigate()

View File

@ -18,7 +18,6 @@ import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.ReselectionTarget import com.topjohnwu.magisk.arch.ReselectionTarget
import com.topjohnwu.magisk.core.* import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.tasks.HideAPK
import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding
import com.topjohnwu.magisk.ktx.startAnimations import com.topjohnwu.magisk.ktx.startAnimations
import com.topjohnwu.magisk.ui.home.HomeFragmentDirections import com.topjohnwu.magisk.ui.home.HomeFragmentDirections
@ -26,7 +25,6 @@ import com.topjohnwu.magisk.utils.HideableBehavior
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import java.io.File import java.io.File
@ -196,12 +194,12 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
.reveal() .reveal()
} }
if (Info.env.isActive && System.getenv("PATH") if (!Info.isEmulator && Info.env.isActive && System.getenv("PATH")
?.split(':') ?.split(':')
?.filterNot { File("$it/magisk").exists() } ?.filterNot { File("$it/magisk").exists() }
?.any { File("$it/su").exists() } == true) { ?.any { File("$it/su").exists() } == true) {
MagiskDialog(this) MagiskDialog(this)
.applyTitle(R.string.unsupport_other_su_title) .applyTitle(R.string.unsupport_general_title)
.applyMessage(R.string.unsupport_other_su_msg) .applyMessage(R.string.unsupport_other_su_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok }
.cancellable(false) .cancellable(false)
@ -210,7 +208,7 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
if (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) { if (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
MagiskDialog(this) MagiskDialog(this)
.applyTitle(R.string.unsupport_system_app_title) .applyTitle(R.string.unsupport_general_title)
.applyMessage(R.string.unsupport_system_app_msg) .applyMessage(R.string.unsupport_system_app_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok }
.cancellable(false) .cancellable(false)
@ -219,25 +217,13 @@ open class MainActivity : BaseUIActivity<MainViewModel, ActivityMainMd2Binding>(
if (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0) { if (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0) {
MagiskDialog(this) MagiskDialog(this)
.applyTitle(R.string.unsupport_external_storage_title) .applyTitle(R.string.unsupport_general_title)
.applyMessage(R.string.unsupport_external_storage_msg) .applyMessage(R.string.unsupport_external_storage_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok }
.cancellable(false) .cancellable(false)
.reveal() .reveal()
} }
}g
if (isRunningAsStub && !Shell.rootAccess()) {
MagiskDialog(this)
.applyTitle(R.string.unsupport_nonroot_stub_title)
.applyMessage(R.string.unsupport_nonroot_stub_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) {
titleRes = R.string.install
onClick { HideAPK.restore(this@MainActivity) }
}
.cancellable(false)
.reveal()
}
}
private fun askForHomeShortcut() { private fun askForHomeShortcut() {
if (isRunningAsStub && !Config.askedHome && if (isRunningAsStub && !Config.askedHome &&

View File

@ -47,7 +47,8 @@ class MagiskDialog(
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
super.setContentView(binding.root) super.setContentView(binding.root)
val surfaceColor = MaterialColors.getColor(context, R.attr.colorSurfaceSurfaceVariant, javaClass.canonicalName) val default = MaterialColors.getColor(context, R.attr.colorSurface, javaClass.canonicalName)
val surfaceColor = MaterialColors.getColor(context, R.attr.colorSurfaceSurfaceVariant, default)
val materialShapeDrawable = MaterialShapeDrawable(context, null, R.attr.alertDialogStyle, R.style.MaterialAlertDialog_MaterialComponents) val materialShapeDrawable = MaterialShapeDrawable(context, null, R.attr.alertDialogStyle, R.style.MaterialAlertDialog_MaterialComponents)
materialShapeDrawable.initializeElevationOverlay(context) materialShapeDrawable.initializeElevationOverlay(context)
materialShapeDrawable.fillColor = ColorStateList.valueOf(surfaceColor) materialShapeDrawable.fillColor = ColorStateList.valueOf(surfaceColor)

View File

@ -230,14 +230,12 @@
<string name="authenticate">Authenticate</string> <string name="authenticate">Authenticate</string>
<string name="unsupport_magisk_title">Unsupported Magisk Version</string> <string name="unsupport_magisk_title">Unsupported Magisk Version</string>
<string name="unsupport_magisk_msg">This version of the app does not support Magisk version lower than %1$s.\n\nThe app will behave as if no Magisk is installed, please upgrade Magisk as soon as possible.</string> <string name="unsupport_magisk_msg">This version of the app does not support Magisk version lower than %1$s.\n\nThe app will behave as if no Magisk is installed, please upgrade Magisk as soon as possible.</string>
<string name="unsupport_other_su_title">Other su found on this device</string> <string name="unsupport_general_title">Abnormal State</string>
<string name="unsupport_other_su_msg">The existence of other su may cause Magisk to run abnormally and MagiskHide to be invalid. Please remove other su.</string> <string name="unsupport_system_app_msg">Running this app as a system app is not supported. Please revert the app to a user app.</string>
<string name="unsupport_system_app_title">Unsupported run as system app</string> <string name="unsupport_other_su_msg">An \"su\" command that does not belong to Magisk is detected. Please remove the other unsupported su.</string>
<string name="unsupport_system_app_msg">Magisk does not support run as system app, which breaks its hidden feature. Please revert to user app.</string> <string name="unsupport_external_storage_msg">Magisk is installed to external storage. Please move the app to internal storage.</string>
<string name="unsupport_external_storage_title">Unsupported installed on external storage</string> <string name="unsupport_nonroot_stub_msg">The app cannot continue to work in the hidden state as root was lost. Please restore it back to the original APK.</string>
<string name="unsupport_external_storage_msg">Magisk is installed to a non-standard location. Please move app to internal storage.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string> <string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="unsupport_nonroot_stub_msg">Root is lost, the application can not continue to work in the hidden state, please restore it back to the original APK.</string>
<string name="external_rw_permission_denied">Grant storage permission to enable this functionality</string> <string name="external_rw_permission_denied">Grant storage permission to enable this functionality</string>
<string name="add_shortcut_title">Add shortcut to home screen</string> <string name="add_shortcut_title">Add shortcut to home screen</string>
<string name="add_shortcut_msg">After hiding this app, its name and icon might become difficult to recognize. Do you want to add a pretty shortcut to the home screen?</string> <string name="add_shortcut_msg">After hiding this app, its name and icon might become difficult to recognize. Do you want to add a pretty shortcut to the home screen?</string>

View File

@ -17,12 +17,12 @@
<style name="Theme.Foundation" parent="Base.V17.Theme.Foundation" /> <style name="Theme.Foundation" parent="Base.V17.Theme.Foundation" />
<style name="Base.V17.Theme.Splash.Light" parent="android:Theme.DeviceDefault.Light.NoActionBar"> <style name="Base.V17.Theme.Splash.Light" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowBackground">@drawable/ic_splash_activity</item> <item name="android:windowBackground">@drawable/ic_splash_activity</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
</style> </style>
<style name="Base.V17.Theme.Splash" parent="android:Theme.DeviceDefault.NoActionBar"> <style name="Base.V17.Theme.Splash" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:windowBackground">@drawable/ic_splash_activity</item> <item name="android:windowBackground">@drawable/ic_splash_activity</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:windowContentOverlay">@null</item>
</style> </style>
@ -38,4 +38,4 @@
<style name="ThemeOverlay.Foundation.Dialog" parent="Base.V17.ThemeOverlay.Foundation.Dialog" /> <style name="ThemeOverlay.Foundation.Dialog" parent="Base.V17.ThemeOverlay.Foundation.Dialog" />
</resources> </resources>