diff --git a/app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java b/app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java index 4ca386078..c4fa756be 100644 --- a/app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java +++ b/app/shared/src/main/java/com/topjohnwu/magisk/utils/APKInstall.java @@ -40,11 +40,12 @@ public final class APKInstall { } public static Session startSession(Context context) { - return startSession(context, null, null); + return startSession(context, null, null, null); } - public static Session startSession(Context context, String pkg, Runnable onSuccess) { - var receiver = new InstallReceiver(pkg, onSuccess); + public static Session startSession(Context context, String pkg, + Runnable onFailure, Runnable onSuccess) { + var receiver = new InstallReceiver(pkg, onSuccess, onFailure); context = context.getApplicationContext(); if (pkg != null) { // If pkg is not null, look for package added event @@ -68,14 +69,16 @@ public final class APKInstall { private static class InstallReceiver extends BroadcastReceiver implements Session { private final String packageName; private final Runnable onSuccess; + private final Runnable onFailure; private final CountDownLatch latch = new CountDownLatch(1); private Intent userAction = null; final String sessionId = UUID.randomUUID().toString(); - private InstallReceiver(String packageName, Runnable onSuccess) { + private InstallReceiver(String packageName, Runnable onSuccess, Runnable onFailure) { this.packageName = packageName; this.onSuccess = onSuccess; + this.onFailure = onFailure; } @Override @@ -108,6 +111,10 @@ public final class APKInstall { installer.abandonSession(info.getSessionId()); } } + if (onFailure != null) { + onFailure.run(); + } + context.getApplicationContext().unregisterReceiver(this); } latch.countDown(); } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt index f86e40fd4..3ec7ecc66 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt @@ -22,6 +22,7 @@ import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Runnable import kotlinx.coroutines.withContext import timber.log.Timber import java.io.File @@ -102,7 +103,7 @@ object HideAPK { activity.finish() } - private suspend fun patchAndHide(activity: Activity, label: String): Boolean { + private suspend fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean { val stub = File(activity.cacheDir, "stub.apk") try { svc.fetchFile(Info.remote.stub.link).byteStream().writeTo(stub) @@ -123,7 +124,7 @@ object HideAPK { return false // Install and auto launch app - val session = APKInstall.startSession(activity, pkg) { + val session = APKInstall.startSession(activity, pkg, onFailure) { launchApp(activity, pkg) } try { @@ -132,7 +133,7 @@ object HideAPK { Timber.e(e) return false } - session.waitIntent()?.let { activity.startActivity(it) } + session.waitIntent()?.let { activity.startActivity(it) } ?: return false return true } @@ -144,13 +145,14 @@ object HideAPK { setCancelable(false) show() } - val result = withContext(Dispatchers.IO) { - patchAndHide(activity, label) - } - if (!result) { + val onFailure = Runnable { dialog.dismiss() Utils.toast(R.string.failure, Toast.LENGTH_LONG) } + val success = withContext(Dispatchers.IO) { + patchAndHide(activity, label, onFailure) + } + if (!success) onFailure.run() } @Suppress("DEPRECATION") @@ -161,19 +163,25 @@ object HideAPK { setCancelable(false) show() } + val onFailure = Runnable { + dialog.dismiss() + Utils.toast(R.string.failure, Toast.LENGTH_LONG) + } val apk = StubApk.current(activity) - val session = APKInstall.startSession(activity, APPLICATION_ID) { + val session = APKInstall.startSession(activity, APPLICATION_ID, onFailure) { launchApp(activity, APPLICATION_ID) dialog.dismiss() } - withContext(Dispatchers.IO) { + val success = withContext(Dispatchers.IO) { try { session.install(activity, apk) } catch (e: IOException) { Timber.e(e) - return@withContext + return@withContext false } - session.waitIntent()?.let { activity.startActivity(it) } + session.waitIntent()?.let { activity.startActivity(it) } ?: return@withContext false + return@withContext true } + if (!success) onFailure.run() } }