Optimize root shell and startups
This commit is contained in:
parent
0886dca385
commit
b3b2149ebb
@ -13,6 +13,7 @@ import com.topjohnwu.magisk.utils.Shell;
|
|||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ValueSortedMap;
|
import com.topjohnwu.magisk.utils.ValueSortedMap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Global {
|
public class Global {
|
||||||
@ -37,13 +38,6 @@ public class Global {
|
|||||||
public static List<String> blockList;
|
public static List<String> blockList;
|
||||||
public static List<ApplicationInfo> appList;
|
public static List<ApplicationInfo> appList;
|
||||||
public static List<String> magiskHideList;
|
public static List<String> magiskHideList;
|
||||||
public static void clear() {
|
|
||||||
repoMap = null;
|
|
||||||
moduleMap = null;
|
|
||||||
blockList = null;
|
|
||||||
appList = null;
|
|
||||||
magiskHideList = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static class Events {
|
public static class Events {
|
||||||
public static final CallbackHandler.Event blockDetectionDone = new CallbackHandler.Event();
|
public static final CallbackHandler.Event blockDetectionDone = new CallbackHandler.Event();
|
||||||
@ -67,6 +61,29 @@ public class Global {
|
|||||||
public static int suNotificationType;
|
public static int suNotificationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void init(Context context) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
Configs.isDarkTheme = prefs.getBoolean("dark_theme", false);
|
||||||
|
Configs.devLogging = prefs.getBoolean("developer_logging", false);
|
||||||
|
Configs.shellLogging = prefs.getBoolean("shell_logging", false);
|
||||||
|
Configs.magiskHide = prefs.getBoolean("magiskhide", false);
|
||||||
|
updateMagiskInfo();
|
||||||
|
initSuAccess();
|
||||||
|
initSuConfigs(context);
|
||||||
|
// Initialize prefs
|
||||||
|
prefs.edit()
|
||||||
|
.putBoolean("dark_theme", Configs.isDarkTheme)
|
||||||
|
.putBoolean("magiskhide", Configs.magiskHide)
|
||||||
|
.putBoolean("busybox", Utils.commandExists("busybox"))
|
||||||
|
.putBoolean("hosts", new File("/magisk/.core/hosts").exists())
|
||||||
|
.putBoolean("disable", Utils.itemExist(MAGISK_DISABLE_FILE))
|
||||||
|
.putString("su_request_timeout", String.valueOf(Configs.suRequestTimeout))
|
||||||
|
.putString("su_auto_response", String.valueOf(Configs.suResponseType))
|
||||||
|
.putString("su_notification", String.valueOf(Configs.suNotificationType))
|
||||||
|
.putString("su_access", String.valueOf(Configs.suAccessState))
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
public static void initSuConfigs(Context context) {
|
public static void initSuConfigs(Context context) {
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
Configs.suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
|
Configs.suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
|
||||||
@ -85,7 +102,7 @@ public class Global {
|
|||||||
if (Utils.isValidShellResponse(ret))
|
if (Utils.isValidShellResponse(ret))
|
||||||
Configs.suAccessState = Integer.parseInt(ret.get(0));
|
Configs.suAccessState = Integer.parseInt(ret.get(0));
|
||||||
else {
|
else {
|
||||||
Shell.su("setprop persist.sys.root_access 3");
|
Shell.su(true, "setprop persist.sys.root_access 3");
|
||||||
Configs.suAccessState = 3;
|
Configs.suAccessState = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,8 +122,12 @@ public class Global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = Shell.sh("getprop ro.magisk.disable");
|
ret = Shell.sh("getprop ro.magisk.disable");
|
||||||
if (Utils.isValidShellResponse(ret))
|
try {
|
||||||
Info.disabled = Integer.parseInt(ret.get(0)) != 0;
|
Info.disabled = Utils.isValidShellResponse(ret) && Integer.parseInt(ret.get(0)) != 0;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Info.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,15 @@ public class SplashActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// Start all async tasks
|
// Init the info and configs and root shell
|
||||||
new Async.InitConfigs(getApplicationContext()){
|
Global.init(getApplicationContext());
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void v) {
|
// Start MagiskHide if not started at boot
|
||||||
// Start main activity only after configs are loaded
|
if (Global.Configs.magiskHide && !Global.Info.disabled && Global.Info.magiskVersion > 10.3)
|
||||||
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
new Async.MagiskHide().enable();
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
// Now fire all async tasks
|
||||||
}
|
new Async.LoadApps(getPackageManager()).exec();
|
||||||
}.exec();
|
|
||||||
new Async.GetBootBlocks().exec();
|
new Async.GetBootBlocks().exec();
|
||||||
new Async.CheckUpdates().exec();
|
new Async.CheckUpdates().exec();
|
||||||
new Async.LoadModules() {
|
new Async.LoadModules() {
|
||||||
@ -32,6 +31,10 @@ public class SplashActivity extends AppCompatActivity {
|
|||||||
new Async.LoadRepos(getApplicationContext()).exec();
|
new Async.LoadRepos(getApplicationContext()).exec();
|
||||||
}
|
}
|
||||||
}.exec();
|
}.exec();
|
||||||
new Async.LoadApps(getPackageManager()).exec();
|
|
||||||
|
// Preparation done, now start main activity
|
||||||
|
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,15 @@ import com.topjohnwu.magisk.R;
|
|||||||
import com.topjohnwu.magisk.utils.Async;
|
import com.topjohnwu.magisk.utils.Async;
|
||||||
|
|
||||||
public class BootReceiver extends BroadcastReceiver {
|
public class BootReceiver extends BroadcastReceiver {
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
new Async.RootTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
Global.initSuAccess();
|
|
||||||
Global.updateMagiskInfo();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void v) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Global.initSuAccess();
|
||||||
|
Global.updateMagiskInfo();
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
if (prefs.getBoolean("magiskhide", false) && !Global.Info.disabled && Global.Info.magiskVersion >= 11) {
|
if (prefs.getBoolean("magiskhide", false) && !Global.Info.disabled && Global.Info.magiskVersion > 10.3) {
|
||||||
Toast.makeText(context, R.string.start_magiskhide, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.start_magiskhide, Toast.LENGTH_SHORT).show();
|
||||||
new Async.MagiskHide().enable();
|
new Async.MagiskHide(true).enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.exec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,11 @@ package com.topjohnwu.magisk.utils;
|
|||||||
|
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -51,40 +49,6 @@ public class Async {
|
|||||||
public static final String MAGISK_HIDE_PATH = "/magisk/.core/magiskhide/";
|
public static final String MAGISK_HIDE_PATH = "/magisk/.core/magiskhide/";
|
||||||
public static final String TMP_FOLDER_PATH = "/dev/tmp";
|
public static final String TMP_FOLDER_PATH = "/dev/tmp";
|
||||||
|
|
||||||
public static class InitConfigs extends RootTask<Void, Void, Void> {
|
|
||||||
|
|
||||||
Context mContext;
|
|
||||||
|
|
||||||
public InitConfigs(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
|
||||||
Global.Configs.isDarkTheme = prefs.getBoolean("dark_theme", false);
|
|
||||||
Global.Configs.devLogging = prefs.getBoolean("developer_logging", false);
|
|
||||||
Global.Configs.shellLogging = prefs.getBoolean("shell_logging", false);
|
|
||||||
Global.Configs.magiskHide = prefs.getBoolean("magiskhide", false);
|
|
||||||
Global.updateMagiskInfo();
|
|
||||||
Global.initSuAccess();
|
|
||||||
Global.initSuConfigs(mContext);
|
|
||||||
// Initialize prefs
|
|
||||||
prefs.edit()
|
|
||||||
.putBoolean("dark_theme", Global.Configs.isDarkTheme)
|
|
||||||
.putBoolean("magiskhide", Global.Configs.magiskHide)
|
|
||||||
.putBoolean("busybox", Utils.commandExists("busybox"))
|
|
||||||
.putBoolean("hosts", Utils.itemExist(false, "/magisk/.core/hosts"))
|
|
||||||
.putBoolean("disable", Utils.itemExist(Global.MAGISK_DISABLE_FILE))
|
|
||||||
.putString("su_request_timeout", String.valueOf(Global.Configs.suRequestTimeout))
|
|
||||||
.putString("su_auto_response", String.valueOf(Global.Configs.suResponseType))
|
|
||||||
.putString("su_notification", String.valueOf(Global.Configs.suNotificationType))
|
|
||||||
.putString("su_access", String.valueOf(Global.Configs.suAccessState))
|
|
||||||
.apply();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CheckUpdates extends NormalTask<Void, Void, Void> {
|
public static class CheckUpdates extends NormalTask<Void, Void, Void> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -327,10 +291,19 @@ public class Async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class MagiskHide extends RootTask<Object, Void, Void> {
|
public static class MagiskHide extends RootTask<Object, Void, Void> {
|
||||||
|
|
||||||
|
private boolean newShell = false;
|
||||||
|
|
||||||
|
public MagiskHide() {}
|
||||||
|
|
||||||
|
public MagiskHide(boolean b) {
|
||||||
|
newShell = b;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Object... params) {
|
protected Void doInBackground(Object... params) {
|
||||||
String command = (String) params[0];
|
String command = (String) params[0];
|
||||||
Shell.su(MAGISK_HIDE_PATH + command);
|
Shell.su(newShell, MAGISK_HIDE_PATH + command);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,16 +15,15 @@ public class Shell {
|
|||||||
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
|
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
|
||||||
public static int rootStatus;
|
public static int rootStatus;
|
||||||
|
|
||||||
|
private static boolean isInit = false;
|
||||||
private static Process rootShell;
|
private static Process rootShell;
|
||||||
private static DataOutputStream rootSTDIN;
|
private static DataOutputStream rootSTDIN;
|
||||||
private static StreamGobbler rootSTDOUT;
|
private static StreamGobbler rootSTDOUT;
|
||||||
private static List<String> rootOutList = new ArrayList<>();
|
private static List<String> rootOutList = Collections.synchronizedList(new ArrayList<String>());
|
||||||
|
|
||||||
static {
|
public static void init() {
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void init() {
|
isInit = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rootShell = Runtime.getRuntime().exec("su");
|
rootShell = Runtime.getRuntime().exec("su");
|
||||||
@ -64,7 +63,7 @@ public class Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean rootAccess() {
|
public static boolean rootAccess() {
|
||||||
return rootStatus > 0;
|
return isInit && rootStatus > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> sh(String... commands) {
|
public static List<String> sh(String... commands) {
|
||||||
@ -120,9 +119,12 @@ public class Shell {
|
|||||||
DataOutputStream STDIN;
|
DataOutputStream STDIN;
|
||||||
StreamGobbler STDOUT;
|
StreamGobbler STDOUT;
|
||||||
|
|
||||||
if (!rootAccess()) {
|
// Create the default shell if not init
|
||||||
|
if (!newShell && !isInit)
|
||||||
|
init();
|
||||||
|
|
||||||
|
if (!newShell && !rootAccess())
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
if (newShell) {
|
if (newShell) {
|
||||||
res = Collections.synchronizedList(new ArrayList<String>());
|
res = Collections.synchronizedList(new ArrayList<String>());
|
||||||
|
@ -25,18 +25,9 @@ public class Utils {
|
|||||||
public static boolean isDownloading = false;
|
public static boolean isDownloading = false;
|
||||||
|
|
||||||
public static boolean itemExist(String path) {
|
public static boolean itemExist(String path) {
|
||||||
return itemExist(true, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean itemExist(boolean root, String path) {
|
|
||||||
String command = "if [ -e " + path + " ]; then echo true; else echo false; fi";
|
String command = "if [ -e " + path + " ]; then echo true; else echo false; fi";
|
||||||
List<String> ret;
|
List<String> ret = Shell.su(command);
|
||||||
if (Shell.rootAccess() && root) {
|
|
||||||
ret = Shell.su(command);
|
|
||||||
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
||||||
} else {
|
|
||||||
return new File(path).exists();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean commandExists(String s) {
|
public static boolean commandExists(String s) {
|
||||||
@ -59,10 +50,8 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getModList(String path) {
|
public static List<String> getModList(String path) {
|
||||||
List<String> ret;
|
|
||||||
String command = "find " + path + " -type d -maxdepth 1 ! -name \"*.core\" ! -name \"*lost+found\" ! -name \"*magisk\"";
|
String command = "find " + path + " -type d -maxdepth 1 ! -name \"*.core\" ! -name \"*lost+found\" ! -name \"*magisk\"";
|
||||||
ret = Shell.su(command);
|
return Shell.su(command);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> readFile(String path) {
|
public static List<String> readFile(String path) {
|
||||||
@ -151,4 +140,13 @@ public class Utils {
|
|||||||
return Integer.parseInt(prefs.getString(key, String.valueOf(def)));
|
return Integer.parseInt(prefs.getString(key, String.valueOf(def)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkAndStartMagiskHide() {
|
||||||
|
String command = "ps | grep magiskhide >/dev/null; echo $?";
|
||||||
|
List<String> ret = Shell.su(command);
|
||||||
|
if (!isValidShellResponse(ret))
|
||||||
|
return;
|
||||||
|
if (Integer.parseInt(ret.get(0)) != 0)
|
||||||
|
new Async.MagiskHide().enable();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user