Update to libsu 1.1.0 with su I/O
This commit is contained in:
parent
9d6886d367
commit
691dc1d49e
@ -8,7 +8,7 @@ android {
|
|||||||
applicationId "com.topjohnwu.magisk"
|
applicationId "com.topjohnwu.magisk"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 94
|
versionCode 96
|
||||||
versionName "5.5.5"
|
versionName "5.5.5"
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
@ -46,7 +46,7 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation project(':utils')
|
implementation project(':utils')
|
||||||
implementation 'com.github.topjohnwu:libsu:1.0.1'
|
implementation 'com.github.topjohnwu:libsu:1.1.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'
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
### v5.5.5 (93)
|
### v5.5.5 (96)
|
||||||
- Remove JNI requirement, Magisk Manager is now pure Java
|
- Remove JNI requirement, Magisk Manager is now pure Java
|
||||||
- Update the method to handle global su database (v15+), should fix root request not saving issue
|
- Update the method handling su database (v15+), may fix the issue that root requests won't save
|
||||||
on many devices
|
|
||||||
|
@ -8,6 +8,7 @@ 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.support.annotation.NonNull;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
@ -16,8 +17,10 @@ import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
|||||||
import com.topjohnwu.magisk.utils.Const;
|
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.BusyBox;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -86,7 +89,14 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
|
|
||||||
public MagiskManager() {
|
public MagiskManager() {
|
||||||
weakSelf = new WeakReference<>(this);
|
weakSelf = new WeakReference<>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
|
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
|
||||||
|
BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH);
|
||||||
Shell.setInitializer(new Shell.Initializer() {
|
Shell.setInitializer(new Shell.Initializer() {
|
||||||
@Override
|
@Override
|
||||||
public void onRootShellInit(@NonNull Shell shell) {
|
public void onRootShellInit(@NonNull Shell shell) {
|
||||||
@ -96,16 +106,11 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
shell.run(null, null,
|
shell.run(null, null,
|
||||||
"export PATH=" + Const.BUSYBOX_PATH + ":$PATH",
|
|
||||||
"mount_partitions",
|
"mount_partitions",
|
||||||
"run_migrations");
|
"run_migrations");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
// Handle duplicate package
|
// Handle duplicate package
|
||||||
@ -163,8 +168,8 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
prefs.edit()
|
prefs.edit()
|
||||||
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
|
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
|
||||||
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
|
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
|
||||||
.putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE()))
|
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE().exists())
|
||||||
.putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE))
|
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
|
||||||
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
|
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
|
||||||
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
|
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
|
||||||
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
|
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
|
||||||
@ -188,64 +193,22 @@ public class MagiskManager extends Shell.ContainerApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadMagiskInfo() {
|
public void loadMagiskInfo() {
|
||||||
List<String> ret;
|
|
||||||
ret = Shell.Sync.sh("magisk -v");
|
|
||||||
if (!Utils.isValidShellResponse(ret)) {
|
|
||||||
ret = Shell.Sync.sh("getprop magisk.version");
|
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
|
||||||
try {
|
try {
|
||||||
magiskVersionString = ret.get(0);
|
magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
|
||||||
magiskVersionCode = (int) Double.parseDouble(ret.get(0)) * 10;
|
magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
|
||||||
} catch (NumberFormatException ignored) {}
|
String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ") + Const.MAGISKHIDE_PROP);
|
||||||
}
|
magiskHide = s == null || Integer.parseInt(s) != 0;
|
||||||
} else {
|
} catch (Exception ignored) {}
|
||||||
magiskVersionString = ret.get(0).split(":")[0];
|
|
||||||
ret = Shell.Sync.sh("magisk -V");
|
|
||||||
try {
|
|
||||||
magiskVersionCode = Integer.parseInt(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
|
||||||
if (magiskVersionCode > 1435) {
|
|
||||||
ret = Shell.Sync.su("resetprop -p " + Const.MAGISKHIDE_PROP);
|
|
||||||
} else {
|
|
||||||
ret = Shell.Sync.sh("getprop " + Const.MAGISKHIDE_PROP);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
magiskHide = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = Shell.Sync.su("echo \"$BOOTIMAGE\"");
|
bootBlock = Utils.cmd("echo \"$BOOTIMAGE\"");
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
bootBlock = ret.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getDefaultInstallFlags() {
|
public void getDefaultInstallFlags() {
|
||||||
List<String> ret;
|
keepVerity = Boolean.parseBoolean(Utils.cmd("getvar KEEPVERITY; echo $KEEPVERITY")) ||
|
||||||
ret = Shell.Sync.su("echo \"$DTBOIMAGE\"");
|
Utils.cmd("echo \"$DTBOIMAGE\"") != null;
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepVerity = true;
|
|
||||||
|
|
||||||
ret = Shell.Sync.su(
|
keepEnc = Boolean.parseBoolean(Utils.cmd("getvar KEEPFORCEENCRYPT; echo $KEEPFORCEENCRYPT")) ||
|
||||||
"getvar KEEPVERITY",
|
TextUtils.equals("encrypted", Utils.cmd("getprop ro.crypto.state"));
|
||||||
"echo $KEEPVERITY");
|
|
||||||
try {
|
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepVerity = Boolean.parseBoolean(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
|
|
||||||
ret = Shell.Sync.sh("getprop ro.crypto.state");
|
|
||||||
if (Utils.isValidShellResponse(ret) && ret.get(0).equals("encrypted"))
|
|
||||||
keepEnc = true;
|
|
||||||
|
|
||||||
ret = Shell.Sync.su(
|
|
||||||
"getvar KEEPFORCEENCRYPT",
|
|
||||||
"echo $KEEPFORCEENCRYPT");
|
|
||||||
try {
|
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepEnc = Boolean.parseBoolean(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermissionGrantCallback(Runnable callback) {
|
public void setPermissionGrantCallback(Runnable callback) {
|
||||||
|
@ -27,6 +27,7 @@ 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 java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
@ -223,9 +224,11 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
break;
|
break;
|
||||||
case Const.Key.COREONLY:
|
case Const.Key.COREONLY:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
Utils.createFile(Const.MAGISK_DISABLE_FILE);
|
try {
|
||||||
|
Const.MAGISK_DISABLE_FILE.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
} else {
|
} else {
|
||||||
Utils.removeItem(Const.MAGISK_DISABLE_FILE);
|
Const.MAGISK_DISABLE_FILE.delete();
|
||||||
}
|
}
|
||||||
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
|
||||||
break;
|
break;
|
||||||
|
@ -4,9 +4,9 @@ import android.app.Activity;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -38,7 +38,7 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
|||||||
try (
|
try (
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
||||||
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
}
|
}
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import com.topjohnwu.magisk.utils.Const;
|
|||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -38,8 +39,8 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
|
|
||||||
private boolean unzipAndCheck() throws Exception {
|
private boolean unzipAndCheck() throws Exception {
|
||||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
||||||
List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script"));
|
String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script"));
|
||||||
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
return s != null && s.contains("#MAGISK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,7 +56,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
) {
|
) {
|
||||||
if (in == null) throw new FileNotFoundException();
|
if (in == null) throw new FileNotFoundException();
|
||||||
InputStream buf= new BufferedInputStream(in);
|
InputStream buf= new BufferedInputStream(in);
|
||||||
Utils.inToOut(buf, out);
|
ShellUtils.pump(buf, out);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Invalid Uri");
|
console.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@ -65,7 +66,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
}
|
}
|
||||||
if (!unzipAndCheck()) return 0;
|
if (!unzipAndCheck()) return 0;
|
||||||
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
||||||
Shell.getShell().run(console, logs,
|
Shell.Sync.su(console, logs,
|
||||||
"cd " + mCachedFile.getParent(),
|
"cd " + mCachedFile.getParent(),
|
||||||
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
|
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
|
||||||
);
|
);
|
||||||
|
@ -10,12 +10,12 @@ import com.topjohnwu.magisk.utils.Const;
|
|||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
import com.topjohnwu.utils.JarMap;
|
import com.topjohnwu.utils.JarMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
|
|
||||||
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
||||||
@ -130,12 +130,11 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install the application
|
// Install the application
|
||||||
|
if (ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack))
|
||||||
List<String> ret = Shell.Sync.su(Utils.fmt("pm install %s >/dev/null && echo true || echo false", repack));
|
|
||||||
repack.delete();
|
|
||||||
if (!Utils.isValidShellResponse(ret) || !Boolean.parseBoolean(ret.get(0)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
repack.delete();
|
||||||
|
|
||||||
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
||||||
Utils.dumpPrefs();
|
Utils.dumpPrefs();
|
||||||
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -14,6 +13,9 @@ import com.topjohnwu.magisk.utils.Const;
|
|||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||||
import com.topjohnwu.utils.SignBoot;
|
import com.topjohnwu.utils.SignBoot;
|
||||||
|
|
||||||
import org.kamranzafar.jtar.TarInputStream;
|
import org.kamranzafar.jtar.TarInputStream;
|
||||||
@ -28,7 +30,6 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
mm.createDeviceProtectedStorageContext() :
|
mm.createDeviceProtectedStorageContext() :
|
||||||
mm).getFilesDir().getParent()
|
mm).getFilesDir().getParent()
|
||||||
, "install");
|
, "install");
|
||||||
Shell.Async.sh("rm -rf " + install);
|
Shell.Sync.sh("rm -rf " + install);
|
||||||
|
|
||||||
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||||
String arch;
|
String arch;
|
||||||
@ -108,10 +109,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
boolean highCompression = false;
|
boolean highCompression = false;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PATCH_MODE:
|
case PATCH_MODE:
|
||||||
console.add("- Use boot/ramdisk image: " + boot);
|
|
||||||
// Copy boot image to local
|
// Copy boot image to local
|
||||||
try (
|
try (InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
||||||
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
|
||||||
OutputStream out = new FileOutputStream(boot)
|
OutputStream out = new FileOutputStream(boot)
|
||||||
) {
|
) {
|
||||||
InputStream source;
|
InputStream source;
|
||||||
@ -130,7 +129,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
// Direct copy raw image
|
// Direct copy raw image
|
||||||
source = new BufferedInputStream(in);
|
source = new BufferedInputStream(in);
|
||||||
}
|
}
|
||||||
Utils.inToOut(source, out);
|
ShellUtils.pump(source, out);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Invalid Uri");
|
console.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@ -140,19 +139,14 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
console.add("- Use boot/ramdisk image: " + mBootLocation);
|
console.add("- Patch boot/ramdisk image: " + mBootLocation);
|
||||||
if (mm.remoteMagiskVersionCode >= 1463) {
|
if (mm.remoteMagiskVersionCode >= 1463) {
|
||||||
List<String> ret = new ArrayList<>();
|
highCompression = Integer.parseInt(Utils.cmd(Utils.fmt(
|
||||||
Shell.getShell().run(ret, logs,
|
"%s/magiskboot --parse %s; echo $?",
|
||||||
install + "/magiskboot --parse " + mBootLocation,
|
install, mBootLocation))) == 2;
|
||||||
"echo $?"
|
|
||||||
);
|
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
|
||||||
highCompression = Integer.parseInt(ret.get(ret.size() - 1)) == 2;
|
|
||||||
if (highCompression)
|
if (highCompression)
|
||||||
console.add("! Insufficient boot partition size detected");
|
console.add("! Insufficient boot partition size detected");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (boot.createNewFile()) {
|
if (boot.createNewFile()) {
|
||||||
Shell.Sync.su("cat " + mBootLocation + " > " + boot);
|
Shell.Sync.su("cat " + mBootLocation + " > " + boot);
|
||||||
} else {
|
} else {
|
||||||
@ -175,15 +169,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force non-root shell
|
|
||||||
Shell shell;
|
|
||||||
if (Shell.rootAccess())
|
|
||||||
shell = Shell.newInstance("sh");
|
|
||||||
else
|
|
||||||
shell = Shell.getShell();
|
|
||||||
|
|
||||||
// Patch boot image
|
// Patch boot image
|
||||||
shell.run(console, logs,
|
Shell.Sync.sh(console, logs,
|
||||||
"cd " + install,
|
"cd " + install,
|
||||||
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
|
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
|
||||||
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
|
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
|
||||||
@ -192,24 +179,22 @@ 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(null, null, "mv -f new-boot.img ../",
|
Shell.Sync.sh("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 /");
|
||||||
|
|
||||||
File patched_boot = new File(install.getParent(), "new-boot.img");
|
SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
|
||||||
|
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
console.add("- Signing boot image with test keys");
|
console.add("- Signing boot image with test keys");
|
||||||
File signed = new File(install.getParent(), "signed.img");
|
File signed = new File(install.getParent(), "signed.img");
|
||||||
AssetManager assets = mm.getAssets();
|
try (InputStream in = new SuFileInputStream(patched_boot);
|
||||||
try (
|
|
||||||
InputStream in = new FileInputStream(patched_boot);
|
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
|
||||||
) {
|
) {
|
||||||
SignBoot.doSignature("/boot", in, out, null, null);
|
SignBoot.doSignature("/boot", in, out, null, null);
|
||||||
}
|
}
|
||||||
shell.run(null, null, "mv -f " + signed + " " + patched_boot);
|
Shell.Sync.sh("mv -f " + signed + " " + patched_boot);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@ -227,8 +212,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
out = new BufferedOutputStream(new FileOutputStream(dest));
|
out = new BufferedOutputStream(new FileOutputStream(dest));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try (InputStream in = new BufferedInputStream(new FileInputStream(patched_boot))) {
|
try (InputStream in = new SuFileInputStream(patched_boot)) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
console.add("");
|
console.add("");
|
||||||
@ -239,7 +224,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
|
String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
|
||||||
Shell.getShell().run(console, logs,
|
Shell.Sync.su(console, logs,
|
||||||
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
||||||
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
|
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
|
||||||
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),
|
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),
|
||||||
|
@ -6,8 +6,8 @@ import android.webkit.WebView;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
import org.commonmark.parser.Parser;
|
import org.commonmark.parser.Parser;
|
||||||
@ -44,7 +44,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
|
|||||||
md = WebService.getString(mUrl);
|
md = WebService.getString(mUrl);
|
||||||
} else {
|
} else {
|
||||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||||
Utils.inToOut(is, out);
|
ShellUtils.pump(is, out);
|
||||||
md = out.toString();
|
md = out.toString();
|
||||||
is.close();
|
is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -57,7 +57,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
|
|||||||
InputStream in = mm.getAssets().open(mm.isDarkTheme ? "dark.css" : "light.css");
|
InputStream in = mm.getAssets().open(mm.isDarkTheme ? "dark.css" : "light.css");
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
||||||
) {
|
) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
css = out.toString();
|
css = out.toString();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -17,6 +17,7 @@ import com.topjohnwu.magisk.utils.Utils;
|
|||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -68,7 +69,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
out.putNextEntry(new JarEntry(path));
|
out.putNextEntry(new JarEntry(path));
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,7 +108,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
|
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
|
||||||
) {
|
) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
|
@ -6,27 +6,22 @@ import com.topjohnwu.magisk.MagiskManager;
|
|||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
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.ShellUtils;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
|
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... voids) {
|
protected Boolean doInBackground(Void... voids) {
|
||||||
String sha1;
|
String sha1;
|
||||||
List<String> ret = Utils.readFile("/.backup/.sha1");
|
sha1 = Utils.cmd("cat /.backup/.sha1");
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
if (sha1 == null) {
|
||||||
sha1 = ret.get(0);
|
sha1 = Utils.cmd("cat /init.magisk.rc | grep STOCKSHA1");
|
||||||
} else {
|
if (sha1 == null)
|
||||||
ret = Shell.Sync.su("cat /init.magisk.rc | grep STOCKSHA1");
|
|
||||||
if (!Utils.isValidShellResponse(ret))
|
|
||||||
return false;
|
return false;
|
||||||
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
|
sha1 = sha1.substring(sha1.indexOf('=') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = Shell.Sync.su("restore_imgs " + sha1 + " && echo true || echo false");
|
return ShellUtils.fastCmdResult(Shell.getShell(), "restore_imgs " + sha1);
|
||||||
|
|
||||||
return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
package com.topjohnwu.magisk.container;
|
package com.topjohnwu.magisk.container;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Module extends BaseModule {
|
public class Module extends BaseModule {
|
||||||
|
|
||||||
private String mRemoveFile, mDisableFile, mUpdateFile;
|
private SuFile mRemoveFile, mDisableFile, mUpdateFile;
|
||||||
private boolean mEnable, mRemove, mUpdated;
|
private boolean mEnable, mRemove, mUpdated;
|
||||||
|
|
||||||
public Module(String path) {
|
public Module(String path) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parseProps(Utils.readFile(path + "/module.prop"));
|
parseProps(Shell.Sync.su("cat " + path + "/module.prop"));
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException ignored) {}
|
||||||
|
|
||||||
mRemoveFile = path + "/remove";
|
mRemoveFile = new SuFile(path + "/remove", true);
|
||||||
mDisableFile = path + "/disable";
|
mDisableFile = new SuFile(path + "/disable", true);
|
||||||
mUpdateFile = path + "/update";
|
mUpdateFile = new SuFile(path + "/update", true);
|
||||||
|
|
||||||
if (getId() == null) {
|
if (getId() == null) {
|
||||||
int sep = path.lastIndexOf('/');
|
int sep = path.lastIndexOf('/');
|
||||||
@ -26,19 +29,21 @@ public class Module extends BaseModule {
|
|||||||
setName(getId());
|
setName(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
mEnable = !Utils.itemExist(mDisableFile);
|
mEnable = !mDisableFile.exists();
|
||||||
mRemove = Utils.itemExist(mRemoveFile);
|
mRemove = mRemoveFile.exists();
|
||||||
mUpdated = Utils.itemExist(mUpdateFile);
|
mUpdated = mUpdateFile.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createDisableFile() {
|
public void createDisableFile() {
|
||||||
mEnable = false;
|
mEnable = false;
|
||||||
Utils.createFile(mDisableFile);
|
try {
|
||||||
|
mDisableFile.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeDisableFile() {
|
public void removeDisableFile() {
|
||||||
mEnable = true;
|
mEnable = true;
|
||||||
Utils.removeItem(mDisableFile);
|
mDisableFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
@ -47,12 +52,14 @@ public class Module extends BaseModule {
|
|||||||
|
|
||||||
public void createRemoveFile() {
|
public void createRemoveFile() {
|
||||||
mRemove = true;
|
mRemove = true;
|
||||||
Utils.createFile(mRemoveFile);
|
try {
|
||||||
|
mRemoveFile.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteRemoveFile() {
|
public void deleteRemoveFile() {
|
||||||
mRemove = false;
|
mRemove = false;
|
||||||
Utils.removeItem(mRemoveFile);
|
mRemoveFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean willBeRemoved() {
|
public boolean willBeRemoved() {
|
||||||
|
@ -4,6 +4,7 @@ import android.os.Environment;
|
|||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -24,8 +25,8 @@ 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;
|
private static SuFile MAGISK_PATH = null;
|
||||||
public static final String MAGISK_DISABLE_FILE = "/cache/.disable_magisk";
|
public static final SuFile MAGISK_DISABLE_FILE = new SuFile("/cache/.disable_magisk", true);
|
||||||
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";
|
||||||
public static final String MAGISK_LOG = "/cache/magisk.log";
|
public static final String MAGISK_LOG = "/cache/magisk.log";
|
||||||
@ -37,21 +38,23 @@ 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 synchronized static String MAGISK_PATH() {
|
public synchronized static SuFile MAGISK_PATH() {
|
||||||
|
SuFile file;
|
||||||
if (MAGISK_PATH == null) {
|
if (MAGISK_PATH == null) {
|
||||||
if (Utils.itemExist("/sbin/.core/img")) {
|
file = new SuFile("/sbin/.core/img", true);
|
||||||
MAGISK_PATH = "/sbin/.core/img";
|
if (file.exists()) {
|
||||||
} else if (Utils.itemExist("/dev/magisk/img")) {
|
MAGISK_PATH = file;
|
||||||
MAGISK_PATH = "/dev/magisk/img";
|
} else if ((file = new SuFile("/dev/magisk/img", true)).exists()) {
|
||||||
|
MAGISK_PATH = file;
|
||||||
} else {
|
} else {
|
||||||
MAGISK_PATH = "/magisk";
|
MAGISK_PATH = new SuFile("/magisk", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MAGISK_PATH;
|
return MAGISK_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String MAGISK_HOST_FILE() {
|
public static SuFile MAGISK_HOST_FILE() {
|
||||||
return MAGISK_PATH() + "/.core/hosts";
|
return new SuFile(MAGISK_PATH() + "/.core/hosts");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A list of apps that should not be shown as hide-able */
|
/* A list of apps that should not be shown as hide-able */
|
||||||
|
@ -23,6 +23,7 @@ import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
|||||||
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
||||||
import com.topjohnwu.magisk.receivers.RebootReceiver;
|
import com.topjohnwu.magisk.receivers.RebootReceiver;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -111,11 +112,11 @@ 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.Sync.su("echo $SLOT");
|
String s = Utils.cmd("echo $SLOT");
|
||||||
if (Utils.isValidShellResponse(res)) {
|
if (s != null) {
|
||||||
options.add(mm.getString(R.string.install_second_slot));
|
options.add(mm.getString(R.string.install_second_slot));
|
||||||
}
|
}
|
||||||
char[] slot = Utils.isValidShellResponse(res) ? res.get(0).toCharArray() : null;
|
char[] slot = s == null ? null : s.toCharArray();
|
||||||
new AlertDialog.Builder(activity)
|
new AlertDialog.Builder(activity)
|
||||||
.setTitle(R.string.select_method)
|
.setTitle(R.string.select_method)
|
||||||
.setItems(
|
.setItems(
|
||||||
@ -185,12 +186,11 @@ 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.Sync.su(
|
boot = Utils.cmd(
|
||||||
"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;
|
|
||||||
Shell.Async.su("mount_partitions");
|
Shell.Async.su("mount_partitions");
|
||||||
if (boot == null)
|
if (boot == null)
|
||||||
return;
|
return;
|
||||||
@ -253,14 +253,14 @@ public class ShowUI {
|
|||||||
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
.setPositiveButton(R.string.complete_uninstall, (d, i) -> {
|
||||||
ByteArrayOutputStream uninstaller = new ByteArrayOutputStream();
|
ByteArrayOutputStream uninstaller = new ByteArrayOutputStream();
|
||||||
try (InputStream in = mm.getAssets().open(Const.UNINSTALLER)) {
|
try (InputStream in = mm.getAssets().open(Const.UNINSTALLER)) {
|
||||||
Utils.inToOut(in, uninstaller);
|
ShellUtils.pump(in, uninstaller);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ByteArrayOutputStream utils = new ByteArrayOutputStream();
|
ByteArrayOutputStream utils = new ByteArrayOutputStream();
|
||||||
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
|
try (InputStream in = mm.getAssets().open(Const.UTIL_FUNCTIONS)) {
|
||||||
Utils.inToOut(in, utils);
|
ShellUtils.pump(in, utils);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
|
@ -19,7 +19,6 @@ import android.support.annotation.StringRes;
|
|||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@ -31,11 +30,10 @@ import com.topjohnwu.magisk.components.SnackbarMaker;
|
|||||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -47,37 +45,8 @@ public class Utils {
|
|||||||
|
|
||||||
public static boolean isDownloading = false;
|
public static boolean isDownloading = false;
|
||||||
|
|
||||||
public static boolean itemExist(Object path) {
|
public static String cmd(String cmd) {
|
||||||
List<String> ret = Shell.Sync.su(fmt("[ -e %s ] && echo true || echo false", path));
|
return ShellUtils.fastCmd(Shell.getShell(), cmd);
|
||||||
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createFile(Object 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) {
|
|
||||||
path.getParentFile().mkdirs();
|
|
||||||
try {
|
|
||||||
path.createNewFile();
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeItem(Object path) {
|
|
||||||
Shell.Async.su(fmt("rm -rf %s 2>/dev/null", path));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> readFile(Object path) {
|
|
||||||
return Shell.Sync.su(fmt("cat %s | sed '$a\\ ' | sed '$d'", path));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String checkInode(Object path) {
|
|
||||||
List<String> ret = Shell.Sync.su(fmt("ls -i %s", path));
|
|
||||||
return isValidShellResponse(ret) ? ret.get(0).trim().split("\\s+")[0] : path.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uninstallPkg(String pkg) {
|
public static void uninstallPkg(String pkg) {
|
||||||
@ -118,16 +87,6 @@ public class Utils {
|
|||||||
.replace("\\", "_");
|
.replace("\\", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isValidShellResponse(List<String> list) {
|
|
||||||
if (list != null && list.size() != 0) {
|
|
||||||
// Check if all empty
|
|
||||||
for (String res : list) {
|
|
||||||
if (!TextUtils.isEmpty(res)) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getPrefsInt(SharedPreferences prefs, String key, int def) {
|
public static int getPrefsInt(SharedPreferences prefs, String key, int def) {
|
||||||
return Integer.parseInt(prefs.getString(key, String.valueOf(def)));
|
return Integer.parseInt(prefs.getString(key, String.valueOf(def)));
|
||||||
}
|
}
|
||||||
@ -230,14 +189,6 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getDB(String dbName) {
|
|
||||||
return getDB(MagiskManager.get(), dbName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static File getDB(Context context, String dbName) {
|
|
||||||
return new File(context.getFilesDir().getParent() + "/databases", dbName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetManager getAssets(String apk) {
|
public static AssetManager getAssets(String apk) {
|
||||||
try {
|
try {
|
||||||
AssetManager asset = AssetManager.class.newInstance();
|
AssetManager asset = AssetManager.class.newInstance();
|
||||||
@ -249,22 +200,10 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int inToOut(InputStream in, OutputStream out) throws IOException {
|
|
||||||
int read, total = 0;
|
|
||||||
byte buffer[] = new byte[4096];
|
|
||||||
while ((read = in.read(buffer)) > 0) {
|
|
||||||
out.write(buffer, 0, read);
|
|
||||||
total += read;
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.Sync.su("patch_dtbo_image && echo true || echo false");
|
if (ShellUtils.fastCmdResult(Shell.getShell(), "patch_dtbo_image")) {
|
||||||
if (Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1))) {
|
|
||||||
ShowUI.dtboPatchedNotification();
|
ShowUI.dtboPatchedNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,9 +224,9 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadPrefs() {
|
public static void loadPrefs() {
|
||||||
String config = fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS);
|
SuFile config = new SuFile(fmt("/data/user/%d/%s", Const.USER_ID, Const.MANAGER_CONFIGS), true);
|
||||||
List<String> ret = readFile(config);
|
List<String> ret = Shell.Sync.su("cat " + config);
|
||||||
if (isValidShellResponse(ret)) {
|
if (ShellUtils.isValidOutput(ret)) {
|
||||||
SharedPreferences.Editor editor = MagiskManager.get().prefs.edit();
|
SharedPreferences.Editor editor = MagiskManager.get().prefs.edit();
|
||||||
String json = ret.get(0);
|
String json = ret.get(0);
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
@ -306,7 +245,7 @@ public class Utils {
|
|||||||
editor.remove(Const.Key.ETAG_KEY);
|
editor.remove(Const.Key.ETAG_KEY);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
MagiskManager.get().loadConfig();
|
MagiskManager.get().loadConfig();
|
||||||
removeItem(config);
|
config.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.utils;
|
package com.topjohnwu.magisk.utils;
|
||||||
|
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
import com.topjohnwu.utils.JarMap;
|
import com.topjohnwu.utils.JarMap;
|
||||||
import com.topjohnwu.utils.SignAPK;
|
import com.topjohnwu.utils.SignAPK;
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ public class ZipUtils {
|
|||||||
File dest = new File(folder, name);
|
File dest = new File(folder, name);
|
||||||
dest.getParentFile().mkdirs();
|
dest.getParentFile().mkdirs();
|
||||||
try (FileOutputStream out = new FileOutputStream(dest)) {
|
try (FileOutputStream out = new FileOutputStream(dest)) {
|
||||||
Utils.inToOut(zipfile, out);
|
ShellUtils.pump(zipfile, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user