diff --git a/app/src/main/java/com/topjohnwu/magisk/components/GeneralReceiver.java b/app/src/main/java/com/topjohnwu/magisk/components/GeneralReceiver.java index 2310c5aaf..8d7523e18 100644 --- a/app/src/main/java/com/topjohnwu/magisk/components/GeneralReceiver.java +++ b/app/src/main/java/com/topjohnwu/magisk/components/GeneralReceiver.java @@ -3,6 +3,7 @@ package com.topjohnwu.magisk.components; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Build; import com.topjohnwu.magisk.App; import com.topjohnwu.magisk.ClassMap; @@ -14,6 +15,7 @@ import com.topjohnwu.magisk.container.Policy; import com.topjohnwu.magisk.uicomponents.Notifications; import com.topjohnwu.magisk.uicomponents.Shortcuts; import com.topjohnwu.magisk.utils.DownloadApp; +import com.topjohnwu.magisk.utils.RootUtils; import com.topjohnwu.magisk.utils.SuLogger; import com.topjohnwu.superuser.Shell; @@ -42,15 +44,19 @@ public class GeneralReceiver extends BroadcastReceiver { switch (action) { case Intent.ACTION_REBOOT: case Intent.ACTION_BOOT_COMPLETED: - String realAction = intent.getStringExtra("action"); - if (realAction == null) - realAction = "boot_complete"; - switch (realAction) { + action = intent.getStringExtra("action"); + if (action == null) + action = "boot_complete"; + switch (action) { case "request": Intent i = new Intent(app, ClassMap.get(SuRequestActivity.class)) .putExtra("socket", intent.getStringExtra("socket")) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - app.startActivity(i); + if (Build.VERSION.CODENAME.equals("Q")) { + RootUtils.startActivity(i); + } else { + app.startActivity(i); + } break; case "log": SU_LOGGER.handleLogs(intent); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/RootUtils.java b/app/src/main/java/com/topjohnwu/magisk/utils/RootUtils.java index b11d1ba3e..216c2a3d0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/RootUtils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/RootUtils.java @@ -2,6 +2,9 @@ package com.topjohnwu.magisk.utils; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; import androidx.annotation.NonNull; @@ -13,6 +16,9 @@ import com.topjohnwu.superuser.ShellUtils; import com.topjohnwu.superuser.io.SuFile; import java.io.InputStream; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.List; public class RootUtils extends Shell.Initializer { @@ -24,6 +30,102 @@ public class RootUtils extends Shell.Initializer { Shell.su("/system/bin/reboot" + (Config.recovery ? " recovery" : "")).submit(); } + public static void startActivity(Intent intent) { + if (intent.getComponent() == null) + return; + List args = new ArrayList<>(); + args.add("am"); + args.add("start"); + intentToCommand(intent, args); + Shell.su(Utils.argsToCommand(args)).exec(); + } + + public static void intentToCommand(Intent intent, List args) { + if (intent.getAction() != null) { + args.add("-a"); + args.add(intent.getAction()); + } + if (intent.getComponent() != null) { + args.add("-n"); + args.add(intent.getComponent().flattenToString()); + } + if (intent.getData() != null) { + args.add("-d"); + args.add(intent.getDataString()); + } + if (intent.getCategories() != null) { + for (String cat : intent.getCategories()) { + args.add("-c"); + args.add(cat); + } + } + if (intent.getType() != null) { + args.add("-t"); + args.add(intent.getType()); + } + Bundle extras = intent.getExtras(); + if (extras != null) { + for (String key : extras.keySet()) { + Object val = extras.get(key); + if (val == null) + continue; + Object value = val; + String arg; + if (val instanceof String) arg = "--es"; + else if (val instanceof Boolean) arg = "--ez"; + else if (val instanceof Integer) arg = "--ei"; + else if (val instanceof Long) arg = "--el"; + else if (val instanceof Float) arg = "--ef"; + else if (val instanceof Uri) arg = "--eu"; + else if (val instanceof ComponentName) { + arg = "--ecn"; + value = ((ComponentName) val).flattenToString(); + } else if (val instanceof ArrayList) { + ArrayList arr = (ArrayList) val; + if (arr.size() <= 0) + /* Impossible to know the type due to type erasure */ + continue; + + if (arr.get(0) instanceof Integer) arg = "--eial"; + else if (arr.get(0) instanceof Long) arg = "--elal"; + else if (arr.get(0) instanceof Float) arg = "--efal"; + else if (arr.get(0) instanceof String) arg = "--esal"; + else continue; /* Unsupported */ + StringBuilder sb = new StringBuilder(); + for (Object o : arr) { + sb.append(o.toString().replace(",", "\\,")); + sb.append(','); + } + // Remove trailing comma + sb.deleteCharAt(sb.length() - 1); + value = sb; + } else if (val.getClass().isArray()) { + if (val instanceof int[]) arg = "--eia"; + else if (val instanceof long[]) arg = "--ela"; + else if (val instanceof float[]) arg = "--efa"; + else if (val instanceof String[]) arg = "--esa"; + else continue; /* Unsupported */ + StringBuilder sb = new StringBuilder(); + int len = Array.getLength(val); + for (int i = 0; i < len; ++i) { + sb.append(Array.get(val, i).toString().replace(",", "\\,")); + sb.append(','); + } + // Remove trailing comma + sb.deleteCharAt(sb.length() - 1); + value = sb; + } + else continue; /* Unsupported */ + + args.add(arg); + args.add(key); + args.add(value.toString()); + } + } + args.add("-f"); + args.add(String.valueOf(intent.getFlags())); + } + @Override public boolean onInit(Context context, @NonNull Shell shell) { Shell.Job job = shell.newJob(); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 4da21aab3..9cb213c7a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -32,6 +32,7 @@ import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.internal.UiThreadHandler; import com.topjohnwu.superuser.io.SuFile; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -165,4 +166,19 @@ public class Utils { toast(R.string.open_link_failed_toast, Toast.LENGTH_SHORT); } } + + public static String argsToCommand(List args) { + StringBuilder sb = new StringBuilder(); + for (String s : args) { + if (s.contains(" ")) { + sb.append('"').append(s).append('"'); + } else { + sb.append(s); + } + sb.append(' '); + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + }