You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Update busybox; Improve environment setup
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user