Update busybox; Improve environment setup

This commit is contained in:
topjohnwu
2016-09-25 21:31:38 +08:00
parent dac85757b3
commit 89932b325d
17 changed files with 169 additions and 204 deletions
@@ -35,6 +35,32 @@ import java.util.List;
public class Async {
public static class BusyboxEnv extends AsyncTask<Void, Void, Void> {
Context mContext;
public BusyboxEnv(Context context) {
mContext = context;
}
@Override
protected Void doInBackground(Void... voids) {
String toolPath = mContext.getApplicationInfo().dataDir + "/busybox";
String busybox = mContext.getApplicationInfo().dataDir + "/lib/libbusybox.so";
if (Shell.rootAccess() && !Utils.commandExists("unzip") && !Utils.itemExist(toolPath)) {
Shell.su(true,
"mkdir " + toolPath,
"chmod 755 " + toolPath,
"ln -s " + busybox + " " + toolPath + "/busybox",
"for tool in $(" + toolPath + "/busybox --list); do",
"ln -s " + busybox + " " + toolPath + "/$tool",
"done"
);
}
return null;
}
}
public static class CheckUpdates extends AsyncTask<Void, Void, Void> {
private Context mContext;
@@ -100,7 +126,7 @@ public class Async {
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
@Override
public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute();
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
};
break;
@@ -110,7 +136,7 @@ public class Async {
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
@Override
public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute();
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
};
break;
@@ -127,7 +153,7 @@ public class Async {
protected void done() {
Utils.downloadAndReceive(temp, rootReceiver, link, filename);
}
}.execute();
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
};
Utils.downloadAndReceive(mContext, magiskReceiver, Utils.magiskLink, "latest_magisk.zip");
@@ -150,7 +176,7 @@ public class Async {
new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
@Override
public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute();
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
},
Utils.phhLink, "phhsu.zip");
@@ -161,7 +187,7 @@ public class Async {
new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
@Override
public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute();
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
},
Utils.supersuLink, "supersu.zip");
@@ -186,17 +212,17 @@ public class Async {
@Override
protected Void doInBackground(Void... voids) {
ModulesFragment.listModules.clear();
Logger.dh("Loading modules");
List<String> magisk = Utils.getModList(Utils.MAGISK_PATH);
Log.d("Magisk", "Utils: Reload called, loading modules");
List<String> magiskCache = Utils.getModList(Utils.MAGISK_CACHE_PATH);
for (String mod : magisk) {
Log.d("Magisk", "Utils: Adding module from string " + mod);
Logger.dh("Adding modules from " + mod);
ModulesFragment.listModules.add(new Module(mContext, mod));
}
for (String mod : magiskCache) {
Log.d("Magisk", "Utils: Adding cache module from string " + mod);
Logger.dh("Adding cache modules from " + mod);
Module cacheMod = new Module(mContext, mod);
// Prevent people forgot to change module.prop
cacheMod.setCache();
@@ -205,6 +231,8 @@ public class Async {
Collections.sort(ModulesFragment.listModules, new Utils.ModuleComparator());
Logger.dh("Module load done");
return null;
}
@@ -68,23 +68,6 @@ public class Shell {
return rootStatus > 0;
}
public static boolean GetRootStatus() {
if (Shell.sh("which su").contains("su")) {
Shell.su(("setprop magisk.root 0"));
}
try {
String rootStatus = Shell.su("getprop magisk.root").toString();
return Integer.valueOf(rootStatus).equals(1);
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
public static List<String> sh(String... commands) {
List<String> res = Collections.synchronizedList(new ArrayList<String>());
@@ -126,46 +109,92 @@ public class Shell {
return res;
}
// Run with the same shell by default
public static List<String> su(String... commands) {
return su(false, commands);
}
if(!Shell.rootAccess()) return null;
public static List<String> su(boolean newShell, String... commands) {
List<String> res;
Process process;
DataOutputStream STDIN;
StreamGobbler STDOUT;
rootOutList.clear();
if (newShell) {
res = Collections.synchronizedList(new ArrayList<String>());
try {
process = Runtime.getRuntime().exec(sh("getprop magisk.supath").get(0) + "/su");
STDIN = new DataOutputStream(process.getOutputStream());
STDOUT = new StreamGobbler(process.getInputStream(), res);
} catch (IOException e) {
try {
// Improper root
process = Runtime.getRuntime().exec("su");
STDIN = new DataOutputStream(process.getOutputStream());
STDOUT = new StreamGobbler(process.getInputStream(), res);
} catch (IOException err) {
return null;
}
}
STDOUT.start();
} else {
process = rootShell;
STDIN = rootSTDIN;
STDOUT = rootSTDOUT;
res = rootOutList;
res.clear();
}
try {
for (String write : commands) {
rootSTDIN.write((write + "\n").getBytes("UTF-8"));
rootSTDIN.flush();
STDIN.write((write + "\n").getBytes("UTF-8"));
STDIN.flush();
}
if (newShell) {
STDIN.write("exit\n".getBytes("UTF-8"));
STDIN.flush();
process.waitFor();
try {
STDIN.close();
} catch (IOException ignore) {
// might be closed already
}
STDOUT.join();
process.destroy();
} else {
STDIN.write(("echo \' \'\n").getBytes("UTF-8"));
STDIN.flush();
STDIN.write(("echo \'-done-\'\n").getBytes("UTF-8"));
STDIN.flush();
while (true) {
try {
// Process terminated, it means the interactive shell has some issues
process.exitValue();
return null;
} catch (IllegalThreadStateException e) {
// Process still running, gobble output until done
int end = res.size() - 1;
if (end > 0) {
if (res.get(end).equals("-done-")) {
res.remove(end);
res.remove(end - 1);
break;
}
}
try { STDOUT.join(100); } catch (InterruptedException err) { return null; }
}
}
}
rootSTDIN.write(("echo \' \'\n").getBytes("UTF-8"));
rootSTDIN.flush();
rootSTDIN.write(("echo \'-done-\'\n").getBytes("UTF-8"));
rootSTDIN.flush();
} catch (IOException e) {
if (!e.getMessage().contains("EPIPE")) {
return null;
}
} catch(InterruptedException e) {
return null;
}
while (true) {
try {
// Process terminated, it means the interactive shell cannot be initialized
rootShell.exitValue();
return null;
} catch (IllegalThreadStateException e) {
// Process still running, gobble output until done
int end = rootOutList.size() - 1;
if (rootOutList != null && end > 0) {
if (rootOutList.get(end).equals("-done-")) {
rootOutList.remove(end);
rootOutList.remove(end - 1);
break;
}
}
try { rootSTDOUT.join(100); } catch (InterruptedException err) { return null; }
}
}
return new ArrayList<>(rootOutList);
return new ArrayList<>(res);
}
}
@@ -69,20 +69,13 @@ public class Utils {
} else {
magiskVersion = Integer.parseInt(ret.get(0));
}
if (!Shell.rootAccess()) {
Snackbar.make(((Activity) context).findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show();
}
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("keep_root_off", false)) {
Utils.toggleRoot(false, context);
}
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enable_quicktile", false)) {
Utils.SetupQuickSettingsTile(context);
}
String toolPath = context.getApplicationInfo().dataDir + "/busybox";
Shell.su("PATH=$PATH:" + toolPath);
}
public static boolean fileExist(String path) {
public static boolean itemExist(String path) {
List<String> ret;
String command = "if [ -f " + path + " ]; then echo true; else echo false; fi";
String command = "if [ -e " + path + " ]; then echo true; else echo false; fi";
if (Shell.rootAccess()) {
ret = Shell.su(command);
} else {
@@ -91,22 +84,15 @@ public class Utils {
return Boolean.parseBoolean(ret.get(0));
}
public static boolean busyboxInstalled() {
public static boolean commandExists(String s) {
List<String> ret;
String command = "if [ -d /data/busybox ]; then echo true; else echo false; fi";
if (Shell.rootAccess()) {
ret = Shell.su(command);
} else {
ret = Shell.sh(command);
}
String command = "if [ -z $(which " + s + ") ]; then echo false; else echo true; fi";
ret = Shell.sh(command);
return Boolean.parseBoolean(ret.get(0));
}
public static boolean rootEnabled() {
List<String> ret;
String command = "if [ -z $(which su) ]; then echo false; else echo true; fi";
ret = Shell.sh(command);
return Boolean.parseBoolean(ret.get(0));
return commandExists("su");
}
public static boolean autoToggleEnabled(Context context) {
@@ -33,14 +33,12 @@ public class WebRequest {
* @requestmethod - http request method
*/
public static String makeWebServiceCall(String url, int requestmethod) {
Log.d("Magisk","WebRequest: Service call received for URL " + url);
return makeWebServiceCall(url, requestmethod, null, false);
}
public static String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) {
Log.d("Magisk","WebRequest: Service call(bool) received for URL " + url);
return makeWebServiceCall(url, requestmethod, null, addNewLines);
}
@@ -54,6 +52,7 @@ public class WebRequest {
*/
public static String makeWebServiceCall(String urladdress, int requestmethod,
HashMap<String, String> params, boolean addNewLines) {
Logger.dh("WebRequest: Service call " + urladdress);
URL url;
String response = "";
try {