Update to libsu 1.0.0

This commit is contained in:
topjohnwu 2018-01-25 18:43:30 +08:00
parent 00d655f346
commit 40082d4571
19 changed files with 97 additions and 127 deletions

View File

@ -55,7 +55,7 @@ repositories {
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':crypto') implementation project(':crypto')
implementation 'com.github.topjohnwu:libsu:0.1.0' implementation 'com.github.topjohnwu:libsu:1.0.0'
implementation 'com.android.support:recyclerview-v7:27.0.2' implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.android.support:cardview-v7:27.0.2' implementation 'com.android.support:cardview-v7:27.0.2'
implementation 'com.android.support:design:27.0.2' implementation 'com.android.support:design:27.0.2'

View File

@ -17,8 +17,8 @@ import com.topjohnwu.magisk.asyncs.FlashZip;
import com.topjohnwu.magisk.asyncs.InstallMagisk; import com.topjohnwu.magisk.asyncs.InstallMagisk;
import com.topjohnwu.magisk.components.Activity; import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.utils.Const; import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellCallbackVector;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -49,7 +49,7 @@ public class FlashActivity extends Activity {
@OnClick(R.id.reboot) @OnClick(R.id.reboot)
void reboot() { void reboot() {
Shell.su_raw("/system/bin/reboot"); Shell.Async.su("/system/bin/reboot");
} }
@OnClick(R.id.save_logs) @OnClick(R.id.save_logs)
@ -96,9 +96,9 @@ public class FlashActivity extends Activity {
reboot.setVisibility(View.GONE); reboot.setVisibility(View.GONE);
logs = new ArrayList<>(); logs = new ArrayList<>();
ShellCallbackVector console = new ShellCallbackVector() { CallbackList console = new CallbackList<String>(new ArrayList<>()) {
@Override @Override
public void onShellOutput(String s) { public void onAddElement(String s) {
logs.add(s); logs.add(s);
flashLogs.setText(TextUtils.join("\n", this)); flashLogs.setText(TextUtils.join("\n", this));
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10); sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);

View File

@ -22,8 +22,8 @@ import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.components.SnackbarMaker; import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Const; import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.CallbackList;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellCallback;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -114,12 +114,18 @@ public class MagiskLogFragment extends Fragment {
mode = (int) params[0]; mode = (int) params[0];
switch (mode) { switch (mode) {
case 0: case 0:
StringBuildingList logList = new StringBuildingList(); StringBuilder builder = new StringBuilder();
Shell.su(logList, "cat " + Const.MAGISK_LOG + " | tail -n 5000"); CallbackList<String> logs = new CallbackList<String>() {
return logList.getCharSequence(); @Override
public void onAddElement(String s) {
builder.append(s).append('\n');
}
};
Shell.Sync.su(logs, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
return builder;
case 1: case 1:
Shell.su_raw("echo -n > " + Const.MAGISK_LOG); Shell.Async.su("echo -n > " + Const.MAGISK_LOG);
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show(); SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
return ""; return "";
@ -139,8 +145,16 @@ public class MagiskLogFragment extends Fragment {
} }
try (FileWriter out = new FileWriter(targetFile)) { try (FileWriter out = new FileWriter(targetFile)) {
FileWritingList fileWritingList = new FileWritingList(out); CallbackList<String> list = new CallbackList<String>() {
Shell.su(fileWritingList, "cat " + Const.MAGISK_LOG); @Override
public void onAddElement(String s) {
try {
out.write(s);
out.write("\n");
} catch (IOException ignored) {}
}
};
Shell.Sync.su(list, "cat " + Const.MAGISK_LOG);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return false; return false;
@ -188,39 +202,4 @@ public class MagiskLogFragment extends Fragment {
exec(2); exec(2);
} }
} }
private static class StringBuildingList extends ShellCallback {
StringBuilder builder;
StringBuildingList() {
builder = new StringBuilder();
}
public CharSequence getCharSequence() {
return builder;
}
@Override
public void onShellOutput(String s) {
builder.append(s).append("\n");
}
}
private static class FileWritingList extends ShellCallback {
private FileWriter writer;
FileWritingList(FileWriter out) {
writer = out;
}
@Override
public void onShellOutput(String s) {
try {
writer.write(s + "\n");
} catch (IOException ignored) {}
}
}
} }

View File

@ -1,6 +1,5 @@
package com.topjohnwu.magisk; package com.topjohnwu.magisk;
import android.app.Application;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -8,6 +7,7 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.container.Module; import com.topjohnwu.magisk.container.Module;
@ -17,8 +17,6 @@ import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellContainer;
import com.topjohnwu.superuser.ShellInitializer;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -27,7 +25,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
public class MagiskManager extends Application implements ShellContainer { public class MagiskManager extends Shell.ContainerApp {
// Global weak reference to self // Global weak reference to self
private static WeakReference<MagiskManager> weakSelf; private static WeakReference<MagiskManager> weakSelf;
@ -82,7 +80,6 @@ public class MagiskManager extends Application implements ShellContainer {
public SharedPreferences prefs; public SharedPreferences prefs;
public SuDatabaseHelper suDB; public SuDatabaseHelper suDB;
public RepoDatabaseHelper repoDB; public RepoDatabaseHelper repoDB;
public Shell shell;
public Runnable permissionGrantCallback = null; public Runnable permissionGrantCallback = null;
private static Handler mHandler = new Handler(); private static Handler mHandler = new Handler();
@ -90,16 +87,16 @@ public class MagiskManager extends Application implements ShellContainer {
public MagiskManager() { public MagiskManager() {
weakSelf = new WeakReference<>(this); weakSelf = new WeakReference<>(this);
Shell.setFlags(Shell.FLAG_MOUNT_MASTER); Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
Shell.setGlobalContainer(this); Shell.setInitializer(new Shell.Initializer() {
Shell.setInitializer(new ShellInitializer() {
@Override @Override
public void onRootShellInit(Shell shell) { public void onRootShellInit(@NonNull Shell shell) {
try (InputStream in = MagiskManager.get().getAssets().open(Const.UTIL_FUNCTIONS)) { try (InputStream in = MagiskManager.get().getAssets().open(Const.UTIL_FUNCTIONS)) {
shell.loadInputStream(in); shell.loadInputStream(null, null, in);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
shell.run_raw("export PATH=" + Const.BUSYBOX_PATH + ":$PATH", shell.run(null, null,
"export PATH=" + Const.BUSYBOX_PATH + ":$PATH",
"mount_partitions", "mount_partitions",
"run_migrations"); "run_migrations");
} }
@ -129,16 +126,6 @@ public class MagiskManager extends Application implements ShellContainer {
loadConfig(); loadConfig();
} }
@Override
public Shell getShell() {
return shell;
}
@Override
public void setShell(Shell shell) {
this.shell = shell;
}
public static MagiskManager get() { public static MagiskManager get() {
return weakSelf.get(); return weakSelf.get();
} }
@ -202,9 +189,9 @@ public class MagiskManager extends Application implements ShellContainer {
public void loadMagiskInfo() { public void loadMagiskInfo() {
List<String> ret; List<String> ret;
ret = Shell.sh("magisk -v"); ret = Shell.Sync.sh("magisk -v");
if (!Utils.isValidShellResponse(ret)) { if (!Utils.isValidShellResponse(ret)) {
ret = Shell.sh("getprop magisk.version"); ret = Shell.Sync.sh("getprop magisk.version");
if (Utils.isValidShellResponse(ret)) { if (Utils.isValidShellResponse(ret)) {
try { try {
magiskVersionString = ret.get(0); magiskVersionString = ret.get(0);
@ -213,15 +200,15 @@ public class MagiskManager extends Application implements ShellContainer {
} }
} else { } else {
magiskVersionString = ret.get(0).split(":")[0]; magiskVersionString = ret.get(0).split(":")[0];
ret = Shell.sh("magisk -V"); ret = Shell.Sync.sh("magisk -V");
try { try {
magiskVersionCode = Integer.parseInt(ret.get(0)); magiskVersionCode = Integer.parseInt(ret.get(0));
} catch (NumberFormatException ignored) {} } catch (NumberFormatException ignored) {}
} }
if (magiskVersionCode > 1435) { if (magiskVersionCode > 1435) {
ret = Shell.su("resetprop -p " + Const.MAGISKHIDE_PROP); ret = Shell.Sync.su("resetprop -p " + Const.MAGISKHIDE_PROP);
} else { } else {
ret = Shell.sh("getprop " + Const.MAGISKHIDE_PROP); ret = Shell.Sync.sh("getprop " + Const.MAGISKHIDE_PROP);
} }
try { try {
magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0; magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0;
@ -229,7 +216,7 @@ public class MagiskManager extends Application implements ShellContainer {
magiskHide = true; magiskHide = true;
} }
ret = Shell.su("echo \"$BOOTIMAGE\""); ret = Shell.Sync.su("echo \"$BOOTIMAGE\"");
if (Utils.isValidShellResponse(ret)) if (Utils.isValidShellResponse(ret))
bootBlock = ret.get(0); bootBlock = ret.get(0);
@ -241,11 +228,11 @@ public class MagiskManager extends Application implements ShellContainer {
public void getDefaultInstallFlags() { public void getDefaultInstallFlags() {
List<String> ret; List<String> ret;
ret = Shell.su("echo \"$DTBOIMAGE\""); ret = Shell.Sync.su("echo \"$DTBOIMAGE\"");
if (Utils.isValidShellResponse(ret)) if (Utils.isValidShellResponse(ret))
keepVerity = true; keepVerity = true;
ret = Shell.su( ret = Shell.Sync.su(
"getvar KEEPVERITY", "getvar KEEPVERITY",
"echo $KEEPVERITY"); "echo $KEEPVERITY");
try { try {
@ -253,11 +240,11 @@ public class MagiskManager extends Application implements ShellContainer {
keepVerity = Boolean.parseBoolean(ret.get(0)); keepVerity = Boolean.parseBoolean(ret.get(0));
} catch (NumberFormatException ignored) {} } catch (NumberFormatException ignored) {}
ret = Shell.sh("getprop ro.crypto.state"); ret = Shell.Sync.sh("getprop ro.crypto.state");
if (Utils.isValidShellResponse(ret) && ret.get(0).equals("encrypted")) if (Utils.isValidShellResponse(ret) && ret.get(0).equals("encrypted"))
keepEnc = true; keepEnc = true;
ret = Shell.su( ret = Shell.Sync.su(
"getvar KEEPFORCEENCRYPT", "getvar KEEPFORCEENCRYPT",
"echo $KEEPFORCEENCRYPT"); "echo $KEEPFORCEENCRYPT");
try { try {

View File

@ -113,16 +113,16 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.reboot: case R.id.reboot:
Shell.su_raw("/system/bin/reboot"); Shell.Async.su("/system/bin/reboot");
return true; return true;
case R.id.reboot_recovery: case R.id.reboot_recovery:
Shell.su_raw("/system/bin/reboot recovery"); Shell.Async.su("/system/bin/reboot recovery");
return true; return true;
case R.id.reboot_bootloader: case R.id.reboot_bootloader:
Shell.su_raw("/system/bin/reboot bootloader"); Shell.Async.su("/system/bin/reboot bootloader");
return true; return true;
case R.id.reboot_download: case R.id.reboot_download:
Shell.su_raw("/system/bin/reboot download"); Shell.Async.su("/system/bin/reboot download");
return true; return true;
default: default:
return false; return false;

View File

@ -231,18 +231,18 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
break; break;
case Const.Key.MAGISKHIDE: case Const.Key.MAGISKHIDE:
if (prefs.getBoolean(key, false)) { if (prefs.getBoolean(key, false)) {
Shell.su_raw("magiskhide --enable"); Shell.Async.su("magiskhide --enable");
} else { } else {
Shell.su_raw("magiskhide --disable"); Shell.Async.su("magiskhide --disable");
} }
break; break;
case Const.Key.HOSTS: case Const.Key.HOSTS:
if (prefs.getBoolean(key, false)) { if (prefs.getBoolean(key, false)) {
Shell.su_raw( Shell.Async.su(
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(), "cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(),
"mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts"); "mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts");
} else { } else {
Shell.su_raw( Shell.Async.su(
"umount -l /system/etc/hosts", "umount -l /system/etc/hosts",
"rm -f " + Const.MAGISK_HOST_FILE()); "rm -f " + Const.MAGISK_HOST_FILE());
} }

View File

@ -81,10 +81,10 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
holder.checkBox.setChecked(mHideList.contains(info.packageName)); holder.checkBox.setChecked(mHideList.contains(info.packageName));
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> { holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
if (isChecked) { if (isChecked) {
Shell.su_raw("magiskhide --add " + info.packageName); Shell.Async.su("magiskhide --add " + info.packageName);
mHideList.add(info.packageName); mHideList.add(info.packageName);
} else { } else {
Shell.su_raw("magiskhide --rm " + info.packageName); Shell.Async.su("magiskhide --rm " + info.packageName);
mHideList.remove(info.packageName); mHideList.remove(info.packageName);
} }
}); });
@ -155,7 +155,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
} }
Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase() Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
.compareTo(b.loadLabel(pm).toString().toLowerCase())); .compareTo(b.loadLabel(pm).toString().toLowerCase()));
mHideList = Shell.su("magiskhide --ls"); mHideList = Shell.Sync.su("magiskhide --ls");
return null; return null;
} }

View File

@ -32,7 +32,7 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
} }
private void dlSnet() throws IOException { private void dlSnet() throws IOException {
Shell.sh("rm -rf " + dexPath.getParent()); Shell.Sync.sh("rm -rf " + dexPath.getParent());
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null); HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
dexPath.getParentFile().mkdir(); dexPath.getParentFile().mkdir();
try ( try (

View File

@ -85,7 +85,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
@Override @Override
protected void onPostExecute(Integer result) { protected void onPostExecute(Integer result) {
FlashActivity activity = (FlashActivity) getActivity(); FlashActivity activity = (FlashActivity) getActivity();
Shell.su_raw( Shell.Async.su(
"rm -rf " + mCachedFile.getParent(), "rm -rf " + mCachedFile.getParent(),
"rm -rf " + Const.TMP_FOLDER_PATH "rm -rf " + Const.TMP_FOLDER_PATH
); );

View File

@ -131,7 +131,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
// Install the application // Install the application
List<String> ret = Shell.su(Utils.fmt("pm install %s >/dev/null && echo true || echo false", repack)); List<String> ret = Shell.Sync.su(Utils.fmt("pm install %s >/dev/null && echo true || echo false", repack));
repack.delete(); repack.delete();
if (!Utils.isValidShellResponse(ret) || !Boolean.parseBoolean(ret.get(0))) if (!Utils.isValidShellResponse(ret) || !Boolean.parseBoolean(ret.get(0)))
return false; return false;

View File

@ -70,7 +70,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
mm.createDeviceProtectedStorageContext() : mm.createDeviceProtectedStorageContext() :
mm).getFilesDir().getParent() mm).getFilesDir().getParent()
, "install"); , "install");
Shell.sh_raw("rm -rf " + install); Shell.Async.sh("rm -rf " + install);
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS); List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
String arch; String arch;
@ -102,7 +102,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
console.add("! Cannot unzip zip"); console.add("! Cannot unzip zip");
throw e; throw e;
} }
Shell.sh("chmod 755 " + install + "/*"); Shell.Sync.sh("chmod 755 " + install + "/*");
File boot = new File(install, "boot.img"); File boot = new File(install, "boot.img");
boolean highCompression = false; boolean highCompression = false;
@ -154,7 +154,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
} }
} }
if (boot.createNewFile()) { if (boot.createNewFile()) {
Shell.su("cat " + mBootLocation + " > " + boot); Shell.Sync.su("cat " + mBootLocation + " > " + boot);
} else { } else {
console.add("! Dump boot image failed"); console.add("! Dump boot image failed");
return false; return false;
@ -178,7 +178,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
// Force non-root shell // Force non-root shell
Shell shell; Shell shell;
if (Shell.rootAccess()) if (Shell.rootAccess())
shell = Shell.newShell("sh"); shell = Shell.newInstance("sh");
else else
shell = Shell.getShell(); shell = Shell.getShell();
@ -192,7 +192,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
if (TextUtils.equals(console.get(console.size() - 1), "Failed!")) if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
return false; return false;
shell.run("mv -f new-boot.img ../", shell.run(null, null, "mv -f new-boot.img ../",
"mv bin/busybox busybox", "mv bin/busybox busybox",
"rm -rf bin *.img update-binary", "rm -rf bin *.img update-binary",
"cd /"); "cd /");
@ -211,7 +211,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
) { ) {
SignBoot.doSignature("/boot", in, out, keyIn, certIn); SignBoot.doSignature("/boot", in, out, keyIn, certIn);
} }
shell.run_raw("mv -f " + signed + " " + patched_boot); shell.run(null, null, "mv -f " + signed + " " + patched_boot);
} }
switch (mode) { switch (mode) {

View File

@ -12,7 +12,7 @@ public class LoadModules extends ParallelTask<Void, Void, Void> {
private List<String> getModList() { private List<String> getModList() {
String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found"; String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found";
return Shell.su(command); return Shell.Sync.su(command);
} }
@Override @Override

View File

@ -18,13 +18,13 @@ public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
if (Utils.isValidShellResponse(ret)) { if (Utils.isValidShellResponse(ret)) {
sha1 = ret.get(0); sha1 = ret.get(0);
} else { } else {
ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1"); ret = Shell.Sync.su("cat /init.magisk.rc | grep STOCKSHA1");
if (!Utils.isValidShellResponse(ret)) if (!Utils.isValidShellResponse(ret))
return false; return false;
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1); sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
} }
ret = Shell.su("restore_imgs " + sha1 + " && echo true || echo false"); ret = Shell.Sync.su("restore_imgs " + sha1 + " && echo true || echo false");
return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1)); return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1));
} }

View File

@ -42,7 +42,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
private SQLiteDatabase mDb; private SQLiteDatabase mDb;
private static void unmntDB() { private static void unmntDB() {
Shell.su(Utils.fmt("umount -l /data/user*/*/%s/*/*.db", MagiskManager.get().getPackageName())); Shell.Sync.su(Utils.fmt("umount -l /data/user*/*/%s/*/*.db", MagiskManager.get().getPackageName()));
} }
private static Context initDB(boolean verify) { private static Context initDB(boolean verify) {
@ -100,22 +100,22 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
if (!verified) { if (!verified) {
context.deleteDatabase(DB_NAME); context.deleteDatabase(DB_NAME);
db.getParentFile().mkdirs(); db.getParentFile().mkdirs();
Shell.su(Utils.fmt("magisk --clone-attr %s %s; chmod 600 %s; ln %s %s", Shell.Sync.su(Utils.fmt("magisk --clone-attr %s %s; chmod 600 %s; ln %s %s",
context.getFilesDir(), OLD_GLOBAL_DB, OLD_GLOBAL_DB, OLD_GLOBAL_DB, db)); context.getFilesDir(), OLD_GLOBAL_DB, OLD_GLOBAL_DB, OLD_GLOBAL_DB, db));
verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db)); verified = TextUtils.equals(Utils.checkInode(OLD_GLOBAL_DB), Utils.checkInode(db));
} }
} else if (ce.magiskVersionCode >= 1464) { } else if (ce.magiskVersionCode >= 1464) {
// New global su db // New global su db
Shell.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent())); Shell.Sync.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent()));
if (!Utils.itemExist(GLOBAL_DB)) { if (!Utils.itemExist(GLOBAL_DB)) {
context.openOrCreateDatabase(DB_NAME, 0, null).close(); context.openOrCreateDatabase(DB_NAME, 0, null).close();
Shell.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db)); Shell.Sync.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db));
} }
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db)); verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
if (!verified) { if (!verified) {
context.deleteDatabase(DB_NAME); context.deleteDatabase(DB_NAME);
Utils.javaCreateFile(db); Utils.javaCreateFile(db);
Shell.su(Utils.fmt( Shell.Sync.su(Utils.fmt(
"chown 0.0 %s; chmod 666 %s; chcon u:object_r:su_file:s0 %s;" + "chown 0.0 %s; chmod 666 %s; chcon u:object_r:su_file:s0 %s;" +
"mount -o bind %s %s", "mount -o bind %s %s",
GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, db)); GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, GLOBAL_DB, db));
@ -131,7 +131,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
} catch(Exception e) { } catch(Exception e) {
// Try to catch runtime exceptions and remove all db for retry // Try to catch runtime exceptions and remove all db for retry
unmntDB(); unmntDB();
Shell.su(Utils.fmt("rm -rf /data/user*/*/magisk.db /data/adb/magisk.db /data/user*/*/%s/databases", Shell.Sync.su(Utils.fmt("rm -rf /data/user*/*/magisk.db /data/adb/magisk.db /data/user*/*/%s/databases",
MagiskManager.get().getPackageName())); MagiskManager.get().getPackageName()));
e.printStackTrace(); e.printStackTrace();
return new SuDatabaseHelper(initDB(false)); return new SuDatabaseHelper(initDB(false));

View File

@ -25,7 +25,7 @@ public class PackageReceiver extends BroadcastReceiver {
break; break;
case Intent.ACTION_PACKAGE_FULLY_REMOVED: case Intent.ACTION_PACKAGE_FULLY_REMOVED:
mm.suDB.deletePolicy(pkg); mm.suDB.deletePolicy(pkg);
Shell.su_raw("magiskhide --rm " + pkg); Shell.Async.su("magiskhide --rm " + pkg);
break; break;
} }
} }

View File

@ -9,6 +9,6 @@ import com.topjohnwu.superuser.Shell;
public class RebootReceiver extends BroadcastReceiver { public class RebootReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
Shell.su_raw("/system/bin/reboot"); Shell.Async.su("/system/bin/reboot");
} }
} }

View File

@ -26,6 +26,7 @@ public class Const {
public static final String SU_KEYSTORE_KEY = "su_key"; public static final String SU_KEYSTORE_KEY = "su_key";
// Paths // Paths
private static String MAGISK_PATH = null;
public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk"; public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk";
public static final String BUSYBOX_PATH = "/sbin/.core/busybox"; public static final String BUSYBOX_PATH = "/sbin/.core/busybox";
public static final String TMP_FOLDER_PATH = "/dev/tmp"; public static final String TMP_FOLDER_PATH = "/dev/tmp";
@ -38,14 +39,17 @@ public class Const {
public static final int SNET_VER = 7; public static final int SNET_VER = 7;
public static final int MIN_MODULE_VER = 1400; public static final int MIN_MODULE_VER = 1400;
public static String MAGISK_PATH() { public synchronized static String MAGISK_PATH() {
if (Utils.itemExist("/sbin/.core/img")) { if (MAGISK_PATH == null) {
return "/sbin/.core/img"; if (Utils.itemExist("/sbin/.core/img")) {
} else if (Utils.itemExist("/dev/magisk/img")) { MAGISK_PATH = "/sbin/.core/img";
return "/dev/magisk/img"; } else if (Utils.itemExist("/dev/magisk/img")) {
} else { MAGISK_PATH = "/dev/magisk/img";
return "/magisk"; } else {
MAGISK_PATH = "/magisk";
}
} }
return MAGISK_PATH;
} }
public static String MAGISK_HOST_FILE() { public static String MAGISK_HOST_FILE() {

View File

@ -111,7 +111,7 @@ public class ShowUI {
if (Shell.rootAccess()) { if (Shell.rootAccess()) {
options.add(mm.getString(R.string.direct_install)); options.add(mm.getString(R.string.direct_install));
} }
List<String> res = Shell.su("echo $SLOT"); List<String> res = Shell.Sync.su("echo $SLOT");
if (Utils.isValidShellResponse(res)) { if (Utils.isValidShellResponse(res)) {
options.add(mm.getString(R.string.install_second_slot)); options.add(mm.getString(R.string.install_second_slot));
} }
@ -185,13 +185,13 @@ public class ShowUI {
if (slot[1] == 'a') slot[1] = 'b'; if (slot[1] == 'a') slot[1] = 'b';
else slot[1] = 'a'; else slot[1] = 'a';
// Then find the boot image again // Then find the boot image again
List<String> ret = Shell.su( List<String> ret = Shell.Sync.su(
"SLOT=" + String.valueOf(slot), "SLOT=" + String.valueOf(slot),
"find_boot_image", "find_boot_image",
"echo \"$BOOTIMAGE\"" "echo \"$BOOTIMAGE\""
); );
boot = Utils.isValidShellResponse(ret) ? ret.get(ret.size() - 1) : null; boot = Utils.isValidShellResponse(ret) ? ret.get(ret.size() - 1) : null;
Shell.su_raw("mount_partitions"); Shell.Async.su("mount_partitions");
if (boot == null) if (boot == null)
return; return;
receiver = new DownloadReceiver() { receiver = new DownloadReceiver() {
@ -266,7 +266,7 @@ public class ShowUI {
return; return;
} }
Shell.su( Shell.Sync.su(
Utils.fmt("echo '%s' > /cache/%s", uninstaller.toString().replace("'", "'\\''"), Const.UNINSTALLER), Utils.fmt("echo '%s' > /cache/%s", uninstaller.toString().replace("'", "'\\''"), Const.UNINSTALLER),
Utils.fmt("echo '%s' > %s/%s", utils.toString().replace("'", "'\\''"), Utils.fmt("echo '%s' > %s/%s", utils.toString().replace("'", "'\\''"),
mm.magiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk", Const.UTIL_FUNCTIONS) mm.magiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk", Const.UTIL_FUNCTIONS)

View File

@ -47,12 +47,12 @@ public class Utils {
public static boolean isDownloading = false; public static boolean isDownloading = false;
public static boolean itemExist(Object path) { public static boolean itemExist(Object path) {
List<String> ret = Shell.su(fmt("[ -e %s ] && echo true || echo false", path)); List<String> ret = Shell.Sync.su(fmt("[ -e %s ] && echo true || echo false", path));
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0)); return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
} }
public static void createFile(Object path) { public static void createFile(Object path) {
Shell.su_raw(fmt("mkdir -p `dirname '%s'` 2>/dev/null; touch '%s' 2>/dev/null", path, path)); Shell.Async.su(fmt("mkdir -p `dirname '%s'` 2>/dev/null; touch '%s' 2>/dev/null", path, path));
} }
public static boolean javaCreateFile(File path) { public static boolean javaCreateFile(File path) {
@ -67,20 +67,20 @@ public class Utils {
} }
public static void removeItem(Object path) { public static void removeItem(Object path) {
Shell.su_raw(fmt("rm -rf %s 2>/dev/null", path)); Shell.Async.su(fmt("rm -rf %s 2>/dev/null", path));
} }
public static List<String> readFile(Object path) { public static List<String> readFile(Object path) {
return Shell.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path)); return Shell.Sync.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path));
} }
public static String checkInode(Object path) { public static String checkInode(Object path) {
List<String> ret = Shell.su(fmt("ls -i %s", path)); List<String> ret = Shell.Sync.su(fmt("ls -i %s", path));
return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : path.toString(); return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : path.toString();
} }
public static void uninstallPkg(String pkg) { public static void uninstallPkg(String pkg) {
Shell.su(fmt("umount -l /data/user*/*/%s/*/*.db 2>/dev/null; pm uninstall %s", pkg, pkg)); Shell.Sync.su(fmt("umount -l /data/user*/*/%s/*/*.db 2>/dev/null; pm uninstall %s", pkg, pkg));
} }
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) { public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
@ -260,7 +260,7 @@ public class Utils {
public static void patchDTBO() { public static void patchDTBO() {
MagiskManager mm = MagiskManager.get(); MagiskManager mm = MagiskManager.get();
if (mm.magiskVersionCode >= 1446 && !mm.keepVerity) { if (mm.magiskVersionCode >= 1446 && !mm.keepVerity) {
List<String> ret = Shell.su("patch_dtbo_image && echo true || echo false"); List<String> ret = Shell.Sync.su("patch_dtbo_image && echo true || echo false");
if (Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1))) { if (Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1))) {
ShowUI.dtboPatchedNotification(); ShowUI.dtboPatchedNotification();
} }
@ -278,7 +278,7 @@ public class Utils {
Map<String, ?> prefs = MagiskManager.get().prefs.getAll(); Map<String, ?> prefs = MagiskManager.get().prefs.getAll();
prefs.remove("App Restrictions"); prefs.remove("App Restrictions");
String json = gson.toJson(prefs, new TypeToken<Map<String, ?>>(){}.getType()); String json = gson.toJson(prefs, new TypeToken<Map<String, ?>>(){}.getType());
Shell.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS)); Shell.Sync.su(fmt("for usr in /data/user/*; do echo '%s' > ${usr}/%s; done", json, Const.MANAGER_CONFIGS));
} }
public static void loadPrefs() { public static void loadPrefs() {