Optimize root shell and startups

This commit is contained in:
topjohnwu 2017-02-05 22:02:14 +08:00
parent 0886dca385
commit b3b2149ebb
6 changed files with 85 additions and 97 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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>());

View File

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