diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt index f739f3bad..e038d0bd7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt @@ -46,13 +46,7 @@ object Const { } object ID { - const val FETCH_ZIP = 2 - const val SELECT_FILE = 3 - const val UNINSTALL_APP = 4 - const val MAX_ACTIVITY_RESULT = 10 - // notifications - const val MAGISK_UPDATE_NOTIFICATION_ID = 4 const val APK_UPDATE_NOTIFICATION_ID = 5 const val UPDATE_NOTIFICATION_CHANNEL = "update" const val PROGRESS_NOTIFICATION_CHANNEL = "progress" diff --git a/app/src/main/java/com/topjohnwu/magisk/core/SplashActivity.kt b/app/src/main/java/com/topjohnwu/magisk/core/SplashActivity.kt index 06b62c68c..61d6c46fd 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/SplashActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/SplashActivity.kt @@ -1,21 +1,23 @@ package com.topjohnwu.magisk.core -import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID 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.ktx.get import com.topjohnwu.magisk.ui.MainActivity +import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.superuser.Shell import java.util.concurrent.CountDownLatch -open class SplashActivity : Activity() { +open class SplashActivity : BaseActivity() { private val latch = CountDownLatch(1) @@ -41,12 +43,27 @@ open class SplashActivity : Activity() { if (Config.suManager.isNotEmpty()) Config.suManager = "" pkg ?: return - val uninstall = Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec() - if (!uninstall.isSuccess) uninstallApp(pkg) + if (!Shell.su("(pm uninstall $pkg)& >/dev/null 2>&1").exec().isSuccess) + uninstallApp(pkg) } } 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) Config.load(prevPkg) @@ -59,8 +76,7 @@ open class SplashActivity : Activity() { get() DONE = true - - redirect().also { startActivity(it) } + startActivity(redirect()) finish() } @@ -69,16 +85,12 @@ open class SplashActivity : Activity() { val uri = Uri.Builder().scheme("package").opaquePart(pkg).build() val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, uri) intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) - startActivityForResult(intent, Const.ID.UNINSTALL_APP) + startActivityForResult(intent) { _, _ -> + latch.countDown() + } 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 { var DONE = false } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt index 64e88b325..af62f8fab 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt @@ -14,7 +14,6 @@ import androidx.collection.SparseArrayCompat import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.wrap import com.topjohnwu.magisk.ktx.set @@ -26,6 +25,13 @@ typealias ActivityResultCallback = BaseActivity.(Int, Intent?) -> Unit abstract class BaseActivity : AppCompatActivity() { private val resultCallbacks by lazy { SparseArrayCompat() } + 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?) { // Force applying our preferred local @@ -49,10 +55,7 @@ abstract class BaseActivity : AppCompatActivity() { if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { request.onSuccess() } else { - var requestCode: Int - do { - requestCode = Random.nextInt(Const.ID.MAX_ACTIVITY_RESULT + 1, 1 shl 15) - } while (resultCallbacks.containsKey(requestCode)) + val requestCode = newRequestCode resultCallbacks[requestCode] = { result, _ -> if (result > 0) 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 try { startActivityForResult(intent, requestCode) diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt index 338ed5aa1..14f2bd2a3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt @@ -31,6 +31,8 @@ class BusyBoxInit : BaseShellInit() { val localBB: File if (isRunningAsStub) { + if (!shell.isRoot) + return true val jar = JarFile(DynAPK.current(context)) val bb = jar.getJarEntry("lib/${Const.CPU_ABI_32}/libbusybox.so") localBB = context.deviceProtectedContext.cachedFile("busybox") diff --git a/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt b/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt index 50c6f3b17..8476a7bc3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt @@ -80,7 +80,7 @@ class MagiskInstallFileEvent(private val callback: ActivityResultCallback) override fun invoke(activity: BaseUIActivity<*, *>) { val intent = Intent(Intent.ACTION_GET_CONTENT).setType("*/*") try { - activity.startActivityForResult(intent, Const.ID.SELECT_FILE, callback) + activity.startActivityForResult(intent, callback) Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG) } catch (e: ActivityNotFoundException) { 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") try { fragment.apply { - activity.startActivityForResult(intent, Const.ID.FETCH_ZIP) { code, intent -> + activity.startActivityForResult(intent) { code, intent -> if (code == Activity.RESULT_OK && intent != null) { intent.data?.also { MainDirections.actionFlashFragment(Const.Value.FLASH_ZIP, it).navigate() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt index e7a616611..d319bf7f0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt @@ -18,7 +18,6 @@ import com.topjohnwu.magisk.arch.BaseUIActivity import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.ReselectionTarget import com.topjohnwu.magisk.core.* -import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding import com.topjohnwu.magisk.ktx.startAnimations 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.view.MagiskDialog import com.topjohnwu.magisk.view.Shortcuts -import com.topjohnwu.superuser.Shell import org.koin.androidx.viewmodel.ext.android.viewModel import java.io.File @@ -196,12 +194,12 @@ open class MainActivity : BaseUIActivity( .reveal() } - if (Info.env.isActive && System.getenv("PATH") + if (!Info.isEmulator && Info.env.isActive && System.getenv("PATH") ?.split(':') ?.filterNot { File("$it/magisk").exists() } ?.any { File("$it/su").exists() } == true) { MagiskDialog(this) - .applyTitle(R.string.unsupport_other_su_title) + .applyTitle(R.string.unsupport_general_title) .applyMessage(R.string.unsupport_other_su_msg) .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .cancellable(false) @@ -210,7 +208,7 @@ open class MainActivity : BaseUIActivity( if (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) { MagiskDialog(this) - .applyTitle(R.string.unsupport_system_app_title) + .applyTitle(R.string.unsupport_general_title) .applyMessage(R.string.unsupport_system_app_msg) .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .cancellable(false) @@ -219,25 +217,13 @@ open class MainActivity : BaseUIActivity( if (applicationInfo.flags and ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0) { MagiskDialog(this) - .applyTitle(R.string.unsupport_external_storage_title) + .applyTitle(R.string.unsupport_general_title) .applyMessage(R.string.unsupport_external_storage_msg) .applyButton(MagiskDialog.ButtonType.POSITIVE) { titleRes = android.R.string.ok } .cancellable(false) .reveal() } - - 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() - } - } + }g private fun askForHomeShortcut() { if (isRunningAsStub && !Config.askedHome && diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt index 7ba8f7708..2cf96a371 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt @@ -47,7 +47,8 @@ class MagiskDialog( super.onCreate(savedInstanceState) 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) materialShapeDrawable.initializeElevationOverlay(context) materialShapeDrawable.fillColor = ColorStateList.valueOf(surfaceColor) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9482cefe9..65d47a125 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -230,14 +230,12 @@ Authenticate Unsupported Magisk Version 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. - Other su found on this device - The existence of other su may cause Magisk to run abnormally and MagiskHide to be invalid. Please remove other su. - Unsupported run as system app - Magisk does not support run as system app, which breaks its hidden feature. Please revert to user app. - Unsupported installed on external storage - Magisk is installed to a non-standard location. Please move app to internal storage. + Abnormal State + Running this app as a system app is not supported. Please revert the app to a user app. + An \"su\" command that does not belong to Magisk is detected. Please remove the other unsupported su. + Magisk is installed to external storage. Please move the app to internal storage. + The app cannot continue to work in the hidden state as root was lost. Please restore it back to the original APK. @string/settings_restore_app_title - Root is lost, the application can not continue to work in the hidden state, please restore it back to the original APK. Grant storage permission to enable this functionality Add shortcut to home screen 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? diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 28aca4db0..5bc16dee5 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -17,12 +17,12 @@ - @@ -38,4 +38,4 @@