package com.fox2code.mmm.utils; import android.app.Dialog; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityOptionsCompat; import androidx.core.util.Supplier; import com.fox2code.mmm.Constants; import com.topjohnwu.superuser.internal.UiThreadHandler; import java.util.List; import timber.log.Timber; public final class ExternalHelper { public static final ExternalHelper INSTANCE = new ExternalHelper(); private static final boolean TEST_MODE = false; private static final String FOX_MMM_OPEN_EXTERNAL = "com.fox2code.mmm.utils.intent.action.OPEN_EXTERNAL"; private static final String FOX_MMM_EXTRA_REPO_ID = "extra_repo_id"; private ComponentName fallback; private CharSequence label; private boolean multi; private ExternalHelper() { } public void refreshHelper(Context context) { Intent intent = new Intent(FOX_MMM_OPEN_EXTERNAL, Uri.parse("https://fox2code.com/module.zip")); List resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER); if (resolveInfos.isEmpty()) { Timber.i("No external provider installed!"); label = TEST_MODE ? "External" : null; multi = TEST_MODE; fallback = null; } else { ResolveInfo resolveInfo = resolveInfos.get(0); Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName); fallback = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); label = resolveInfo.loadLabel(context.getPackageManager()); multi = resolveInfos.size() >= 2; } } public boolean openExternal(Context context, Uri uri, String repoId) { if (label == null) return false; Bundle param = ActivityOptionsCompat.makeCustomAnimation(context, android.R.anim.fade_in, android.R.anim.fade_out).toBundle(); Intent intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri); intent.setFlags(IntentHelper.FLAG_GRANT_URI_PERMISSION); intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId); if (multi) { intent = Intent.createChooser(intent, label); } else { intent.putExtra(Constants.EXTRA_FADE_OUT, true); } try { if (multi) { context.startActivity(intent); } else { context.startActivity(intent, param); } return true; } catch ( ActivityNotFoundException e) { Timber.e(e); } if (fallback != null) { if (multi) { intent = new Intent(FOX_MMM_OPEN_EXTERNAL, uri); intent.putExtra(FOX_MMM_EXTRA_REPO_ID, repoId); intent.putExtra(Constants.EXTRA_FADE_OUT, true); } intent.setComponent(fallback); try { context.startActivity(intent, param); return true; } catch ( ActivityNotFoundException e) { Timber.e(e); } } return false; } public void injectButton(AlertDialog.Builder builder, Supplier uriSupplier, String repoId) { if (label == null) return; builder.setNeutralButton(label, (dialog, button) -> { Context context = ((Dialog) dialog).getContext(); new Thread("Async downloader") { @Override public void run() { final Uri uri = uriSupplier.get(); if (uri == null) return; UiThreadHandler.run(() -> { if (!openExternal(context, uri, repoId)) { Toast.makeText(context, "Failed to launch external activity", Toast.LENGTH_SHORT).show(); } }); } }.start(); }); } }