Added leanback activity that implements several functions which custom dialogs depend on

This commit is contained in:
Viktor De Pasquale 2019-04-15 20:26:22 +02:00
parent ffec64d209
commit 9a968e0584
8 changed files with 101 additions and 27 deletions

View File

@ -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
)
}

View File

@ -2,12 +2,11 @@ package com.topjohnwu.magisk.ui.base
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import com.skoumal.teanity.view.TeanityActivity
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> : abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
TeanityActivity<ViewModel, Binding>() { MagiskLeanbackActivity<ViewModel, Binding>() {
fun openUrl(url: String) = Utils.openLink(this, url.toUri()) fun openUrl(url: String) = Utils.openLink(this, url.toUri())

View File

@ -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<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
TeanityActivity<ViewModel, Binding>(), IBaseLeanback {
private val resultListeners = SparseArrayCompat<BaseActivity.ActivityResultListener>()
@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<PermissionRequest>?,
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)
}
}

View File

@ -7,14 +7,12 @@ import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.FragmentMagiskBinding import com.topjohnwu.magisk.databinding.FragmentMagiskBinding
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.ui.base.MagiskActivity
import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.utils.ISafetyNetHelper
import com.topjohnwu.magisk.view.MarkDownWindow import com.topjohnwu.magisk.view.MarkDownWindow
import com.topjohnwu.magisk.view.SafetyNet import com.topjohnwu.magisk.view.SafetyNet
import com.topjohnwu.magisk.view.SafetyNet.EXT_APK import com.topjohnwu.magisk.view.SafetyNet.EXT_APK
import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog import com.topjohnwu.magisk.view.dialogs.*
import com.topjohnwu.magisk.view.dialogs.EnvFixDialog
import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog
import com.topjohnwu.magisk.view.dialogs.UninstallDialog
import com.topjohnwu.net.Networking import com.topjohnwu.net.Networking
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
@ -47,8 +45,8 @@ class MagiskFragment : NewMagiskFragment<HomeViewModel, FragmentMagiskBinding>()
installManager() installManager()
return return
} }
//FIXME dialog requires old base
//MagiskInstallDialog(requireActivity()).show() MagiskInstallDialog(requireActivity() as MagiskActivity<*, *>).show()
} }
private fun installManager() = ManagerInstallDialog(requireActivity()).show() private fun installManager() = ManagerInstallDialog(requireActivity()).show()

View File

@ -1,6 +1,6 @@
package com.topjohnwu.magisk.view; package com.topjohnwu.magisk.view;
import android.app.Activity; import android.content.Context;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -19,11 +19,11 @@ import ru.noties.markwon.image.svg.SvgPlugin;
public class MarkDownWindow { 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)); 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")) { try (Scanner s = new Scanner(is, "UTF-8")) {
s.useDelimiter("\\A"); s.useDelimiter("\\A");
new Listener(activity, title).onResponse(s.next()); new Listener(activity, title).onResponse(s.next());
@ -32,10 +32,10 @@ public class MarkDownWindow {
static class Listener implements ResponseListener<String> { static class Listener implements ResponseListener<String> {
Activity activity; Context activity;
String title; String title;
Listener(Activity a, String t) { Listener(Context a, String t) {
activity = a; activity = a;
title = t; title = t;
} }

View File

@ -1,6 +1,6 @@
package com.topjohnwu.magisk.view.dialogs; package com.topjohnwu.magisk.view.dialogs;
import android.app.Activity; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; 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); super(context);
} }
public CustomAlertDialog(@NonNull Activity context, @StyleRes int themeResId) { public CustomAlertDialog(@NonNull Context context, @StyleRes int themeResId) {
super(context, themeResId); super(context, themeResId);
} }
@ -88,7 +88,7 @@ public class CustomAlertDialog extends AlertDialog.Builder {
vh.positive.setVisibility(View.VISIBLE); vh.positive.setVisibility(View.VISIBLE);
vh.positive.setText(text); vh.positive.setText(text);
positiveListener = listener; positiveListener = listener;
vh.positive.setOnClickListener((v) -> { vh.positive.setOnClickListener(v -> {
if (positiveListener != null) { if (positiveListener != null) {
positiveListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE); positiveListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
} }
@ -108,7 +108,7 @@ public class CustomAlertDialog extends AlertDialog.Builder {
vh.negative.setVisibility(View.VISIBLE); vh.negative.setVisibility(View.VISIBLE);
vh.negative.setText(text); vh.negative.setText(text);
negativeListener = listener; negativeListener = listener;
vh.negative.setOnClickListener((v) -> { vh.negative.setOnClickListener(v -> {
if (negativeListener != null) { if (negativeListener != null) {
negativeListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE); negativeListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
} }
@ -128,7 +128,7 @@ public class CustomAlertDialog extends AlertDialog.Builder {
vh.neutral.setVisibility(View.VISIBLE); vh.neutral.setVisibility(View.VISIBLE);
vh.neutral.setText(text); vh.neutral.setText(text);
neutralListener = listener; neutralListener = listener;
vh.neutral.setOnClickListener((v) -> { vh.neutral.setOnClickListener(v -> {
if (neutralListener != null) { if (neutralListener != null) {
neutralListener.onClick(dialog, DialogInterface.BUTTON_NEUTRAL); neutralListener.onClick(dialog, DialogInterface.BUTTON_NEUTRAL);
} }

View File

@ -9,7 +9,7 @@ import com.topjohnwu.magisk.ClassMap;
import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.Config;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R; 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.ui.flash.FlashActivity;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.view.ProgressNotification; import com.topjohnwu.magisk.view.ProgressNotification;
@ -23,7 +23,7 @@ import androidx.appcompat.app.AlertDialog;
class InstallMethodDialog extends AlertDialog.Builder { class InstallMethodDialog extends AlertDialog.Builder {
InstallMethodDialog(BaseActivity activity, List<String> options) { <Ctxt extends Activity & IBaseLeanback> InstallMethodDialog(Ctxt activity, List<String> options) {
super(activity); super(activity);
setTitle(R.string.select_method); setTitle(R.string.select_method);
setItems(options.toArray(new String[0]), (dialog, idx) -> { setItems(options.toArray(new String[0]), (dialog, idx) -> {
@ -48,7 +48,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
}); });
} }
private void patchBoot(BaseActivity activity) { private <Ctxt extends Activity & IBaseLeanback> void patchBoot(Ctxt activity) {
activity.runWithExternalRW(() -> { activity.runWithExternalRW(() -> {
Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG); Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT) Intent intent = new Intent(Intent.ACTION_GET_CONTENT)
@ -66,7 +66,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
}); });
} }
private void downloadOnly(BaseActivity activity) { private <Ctxt extends Activity & IBaseLeanback> void downloadOnly(Ctxt activity) {
activity.runWithExternalRW(() -> { activity.runWithExternalRW(() -> {
String filename = Utils.fmt("Magisk-v%s(%d).zip", String filename = Utils.fmt("Magisk-v%s(%d).zip",
Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode); Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode);
@ -74,7 +74,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
ProgressNotification progress = new ProgressNotification(filename); ProgressNotification progress = new ProgressNotification(filename);
Networking.get(Config.magiskLink) Networking.get(Config.magiskLink)
.setDownloadProgressListener(progress) .setDownloadProgressListener(progress)
.setErrorHandler(((conn, e) -> progress.dlFail())) .setErrorHandler((conn, e) -> progress.dlFail())
.getAsFile(zip, f -> { .getAsFile(zip, f -> {
progress.dlDone(); progress.dlDone();
SnackbarMaker.make(activity, SnackbarMaker.make(activity,
@ -84,7 +84,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
}); });
} }
private void installInactiveSlot(BaseActivity activity) { private <Ctxt extends Activity & IBaseLeanback> void installInactiveSlot(Ctxt activity) {
new CustomAlertDialog(activity) new CustomAlertDialog(activity)
.setTitle(R.string.warning) .setTitle(R.string.warning)
.setMessage(R.string.install_inactive_slot_msg) .setMessage(R.string.install_inactive_slot_msg)

View File

@ -1,11 +1,12 @@
package com.topjohnwu.magisk.view.dialogs; package com.topjohnwu.magisk.view.dialogs;
import android.app.Activity;
import android.net.Uri; import android.net.Uri;
import android.text.TextUtils; import android.text.TextUtils;
import com.topjohnwu.magisk.Config; import com.topjohnwu.magisk.Config;
import com.topjohnwu.magisk.R; 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.utils.Utils;
import com.topjohnwu.magisk.view.MarkDownWindow; import com.topjohnwu.magisk.view.MarkDownWindow;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
@ -15,7 +16,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MagiskInstallDialog extends CustomAlertDialog { public class MagiskInstallDialog extends CustomAlertDialog {
public MagiskInstallDialog(BaseActivity a) { public <Ctxt extends Activity & IBaseLeanback> MagiskInstallDialog(Ctxt a) {
super(a); super(a);
String filename = Utils.fmt("Magisk-v%s(%d).zip", String filename = Utils.fmt("Magisk-v%s(%d).zip",
Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode); Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode);