Added leanback activity that implements several functions which custom dialogs depend on
This commit is contained in:
parent
ffec64d209
commit
9a968e0584
@ -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
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
@ -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())
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user