diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/IBaseLeanback.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/IBaseLeanback.kt new file mode 100644 index 000000000..2a1a7ba14 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/IBaseLeanback.kt @@ -0,0 +1,15 @@ +package com.topjohnwu.magisk.ui.base + +import android.content.Intent + +interface IBaseLeanback { + + fun runWithExternalRW(callback: Runnable) + fun runWithPermissions(vararg permissions: String, callback: Runnable) + fun startActivityForResult( + intent: Intent, + requestCode: Int, + listener: BaseActivity.ActivityResultListener + ) + +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt index d9b0a8c16..1e5688f4a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt @@ -2,12 +2,11 @@ package com.topjohnwu.magisk.ui.base import androidx.core.net.toUri import androidx.databinding.ViewDataBinding -import com.skoumal.teanity.view.TeanityActivity import com.topjohnwu.magisk.utils.Utils abstract class MagiskActivity : - TeanityActivity() { + MagiskLeanbackActivity() { fun openUrl(url: String) = Utils.openLink(this, url.toUri()) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskLeanbackActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskLeanbackActivity.kt new file mode 100644 index 000000000..8ad249173 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskLeanbackActivity.kt @@ -0,0 +1,61 @@ +package com.topjohnwu.magisk.ui.base + +import android.Manifest +import android.content.Intent +import androidx.collection.SparseArrayCompat +import androidx.databinding.ViewDataBinding +import com.karumi.dexter.Dexter +import com.karumi.dexter.MultiplePermissionsReport +import com.karumi.dexter.PermissionToken +import com.karumi.dexter.listener.PermissionRequest +import com.karumi.dexter.listener.multi.MultiplePermissionsListener +import com.skoumal.teanity.view.TeanityActivity +import com.topjohnwu.magisk.Const + +abstract class MagiskLeanbackActivity : + TeanityActivity(), IBaseLeanback { + + private val resultListeners = SparseArrayCompat() + + @Deprecated("Permissions will be checked in a different streamlined way") + override fun runWithExternalRW(callback: Runnable) { + runWithPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, callback = callback) + } + + @Deprecated("Permissions will be checked in a different streamlined way") + override fun runWithPermissions(vararg permissions: String, callback: Runnable) { + Dexter.withActivity(this) + .withPermissions(*permissions) + .withListener(object : MultiplePermissionsListener { + override fun onPermissionsChecked(report: MultiplePermissionsReport?) { + if (report?.areAllPermissionsGranted() == true) { + Const.EXTERNAL_PATH.mkdirs() + callback.run() + } + } + + override fun onPermissionRationaleShouldBeShown( + permissions: MutableList?, + token: PermissionToken? + ) = Unit + }) + .check() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + resultListeners.get(requestCode)?.apply { + resultListeners.remove(requestCode) + onActivityResult(resultCode, data) + } + } + + override fun startActivityForResult( + intent: Intent, + requestCode: Int, + listener: BaseActivity.ActivityResultListener + ) { + resultListeners.put(requestCode, listener) + startActivityForResult(intent, requestCode) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt index 2a262c488..1725b082e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt @@ -7,14 +7,12 @@ import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.R import com.topjohnwu.magisk.databinding.FragmentMagiskBinding import com.topjohnwu.magisk.model.events.* +import com.topjohnwu.magisk.ui.base.MagiskActivity import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.view.MarkDownWindow import com.topjohnwu.magisk.view.SafetyNet import com.topjohnwu.magisk.view.SafetyNet.EXT_APK -import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog -import com.topjohnwu.magisk.view.dialogs.EnvFixDialog -import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog -import com.topjohnwu.magisk.view.dialogs.UninstallDialog +import com.topjohnwu.magisk.view.dialogs.* import com.topjohnwu.net.Networking import com.topjohnwu.superuser.Shell import org.koin.androidx.viewmodel.ext.android.viewModel @@ -47,8 +45,8 @@ class MagiskFragment : NewMagiskFragment() installManager() return } - //FIXME dialog requires old base - //MagiskInstallDialog(requireActivity()).show() + + MagiskInstallDialog(requireActivity() as MagiskActivity<*, *>).show() } private fun installManager() = ManagerInstallDialog(requireActivity()).show() diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java b/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java index f7e3b3dae..f6da7a795 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java +++ b/app/src/main/java/com/topjohnwu/magisk/view/MarkDownWindow.java @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.view; -import android.app.Activity; +import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -19,11 +19,11 @@ import ru.noties.markwon.image.svg.SvgPlugin; public class MarkDownWindow { - public static void show(Activity activity, String title, String url) { + public static void show(Context activity, String title, String url) { Networking.get(url).getAsString(new Listener(activity, title)); } - public static void show (Activity activity, String title, InputStream is) { + public static void show(Context activity, String title, InputStream is) { try (Scanner s = new Scanner(is, "UTF-8")) { s.useDelimiter("\\A"); new Listener(activity, title).onResponse(s.next()); @@ -32,10 +32,10 @@ public class MarkDownWindow { static class Listener implements ResponseListener { - Activity activity; + Context activity; String title; - Listener(Activity a, String t) { + Listener(Context a, String t) { activity = a; title = t; } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java index 4c6919a33..2425f0e0c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java +++ b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/CustomAlertDialog.java @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.view.dialogs; -import android.app.Activity; +import android.content.Context; import android.content.DialogInterface; import android.view.LayoutInflater; import android.view.View; @@ -52,11 +52,11 @@ public class CustomAlertDialog extends AlertDialog.Builder { } - public CustomAlertDialog(@NonNull Activity context) { + public CustomAlertDialog(@NonNull Context context) { super(context); } - public CustomAlertDialog(@NonNull Activity context, @StyleRes int themeResId) { + public CustomAlertDialog(@NonNull Context context, @StyleRes int themeResId) { super(context, themeResId); } @@ -88,7 +88,7 @@ public class CustomAlertDialog extends AlertDialog.Builder { vh.positive.setVisibility(View.VISIBLE); vh.positive.setText(text); positiveListener = listener; - vh.positive.setOnClickListener((v) -> { + vh.positive.setOnClickListener(v -> { if (positiveListener != null) { positiveListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE); } @@ -108,7 +108,7 @@ public class CustomAlertDialog extends AlertDialog.Builder { vh.negative.setVisibility(View.VISIBLE); vh.negative.setText(text); negativeListener = listener; - vh.negative.setOnClickListener((v) -> { + vh.negative.setOnClickListener(v -> { if (negativeListener != null) { negativeListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE); } @@ -128,7 +128,7 @@ public class CustomAlertDialog extends AlertDialog.Builder { vh.neutral.setVisibility(View.VISIBLE); vh.neutral.setText(text); neutralListener = listener; - vh.neutral.setOnClickListener((v) -> { + vh.neutral.setOnClickListener(v -> { if (neutralListener != null) { neutralListener.onClick(dialog, DialogInterface.BUTTON_NEUTRAL); } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java index 6b2970c1f..4faea6bd9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java +++ b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/InstallMethodDialog.java @@ -9,7 +9,7 @@ import com.topjohnwu.magisk.ClassMap; import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.ui.base.BaseActivity; +import com.topjohnwu.magisk.ui.base.IBaseLeanback; import com.topjohnwu.magisk.ui.flash.FlashActivity; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.view.ProgressNotification; @@ -23,7 +23,7 @@ import androidx.appcompat.app.AlertDialog; class InstallMethodDialog extends AlertDialog.Builder { - InstallMethodDialog(BaseActivity activity, List options) { + InstallMethodDialog(Ctxt activity, List options) { super(activity); setTitle(R.string.select_method); setItems(options.toArray(new String[0]), (dialog, idx) -> { @@ -48,7 +48,7 @@ class InstallMethodDialog extends AlertDialog.Builder { }); } - private void patchBoot(BaseActivity activity) { + private void patchBoot(Ctxt activity) { activity.runWithExternalRW(() -> { Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG); Intent intent = new Intent(Intent.ACTION_GET_CONTENT) @@ -66,7 +66,7 @@ class InstallMethodDialog extends AlertDialog.Builder { }); } - private void downloadOnly(BaseActivity activity) { + private void downloadOnly(Ctxt activity) { activity.runWithExternalRW(() -> { String filename = Utils.fmt("Magisk-v%s(%d).zip", Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode); @@ -74,7 +74,7 @@ class InstallMethodDialog extends AlertDialog.Builder { ProgressNotification progress = new ProgressNotification(filename); Networking.get(Config.magiskLink) .setDownloadProgressListener(progress) - .setErrorHandler(((conn, e) -> progress.dlFail())) + .setErrorHandler((conn, e) -> progress.dlFail()) .getAsFile(zip, f -> { progress.dlDone(); SnackbarMaker.make(activity, @@ -84,7 +84,7 @@ class InstallMethodDialog extends AlertDialog.Builder { }); } - private void installInactiveSlot(BaseActivity activity) { + private void installInactiveSlot(Ctxt activity) { new CustomAlertDialog(activity) .setTitle(R.string.warning) .setMessage(R.string.install_inactive_slot_msg) diff --git a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.java b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.java index 64426c656..e1198a92f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.java +++ b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/MagiskInstallDialog.java @@ -1,11 +1,12 @@ package com.topjohnwu.magisk.view.dialogs; +import android.app.Activity; import android.net.Uri; import android.text.TextUtils; import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.ui.base.BaseActivity; +import com.topjohnwu.magisk.ui.base.IBaseLeanback; import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.view.MarkDownWindow; import com.topjohnwu.superuser.Shell; @@ -15,7 +16,7 @@ import java.util.ArrayList; import java.util.List; public class MagiskInstallDialog extends CustomAlertDialog { - public MagiskInstallDialog(BaseActivity a) { + public MagiskInstallDialog(Ctxt a) { super(a); String filename = Utils.fmt("Magisk-v%s(%d).zip", Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode);