From 630f2b7d199808d54b57f22ae0d7794baed51590 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 13 May 2018 18:14:10 +0800 Subject: [PATCH] Support fixing Magisk environment --- build.gradle | 4 +- .../com/topjohnwu/magisk/MagiskFragment.java | 15 +- .../com/topjohnwu/magisk/MagiskManager.java | 9 +- .../magisk/asyncs/InstallMagisk.java | 415 +++++++++++------- .../com/topjohnwu/magisk/utils/Const.java | 1 + .../com/topjohnwu/magisk/utils/ShowUI.java | 21 + .../com/topjohnwu/magisk/utils/Utils.java | 4 + .../com/topjohnwu/magisk/utils/ZipUtils.java | 14 +- src/main/res/raw/{magiskdb.sh => utils.sh} | 7 + src/main/res/values/strings.xml | 4 + 10 files changed, 308 insertions(+), 186 deletions(-) rename src/main/res/raw/{magiskdb.sh => utils.sh} (84%) diff --git a/build.gradle b/build.gradle index c8b455b0e..046a64e52 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ android { applicationId "com.topjohnwu.magisk" minSdkVersion 21 targetSdkVersion rootProject.ext.compileSdkVersion - versionCode 115 + versionCode 117 versionName "5.7.0" javaCompileOptions { annotationProcessorOptions { @@ -46,7 +46,7 @@ dependencies { implementation "com.android.support:design:${rootProject.ext.supportLibVersion}" implementation "com.android.support:support-v4:${rootProject.ext.supportLibVersion}" implementation 'com.jakewharton:butterknife:8.8.1' - implementation 'com.atlassian.commonmark:commonmark:0.10.0' + implementation 'com.atlassian.commonmark:commonmark:0.11.0' implementation 'org.kamranzafar:jtar:2.3' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' } diff --git a/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/src/main/java/com/topjohnwu/magisk/MagiskFragment.java index 14c743c64..0f121d61d 100644 --- a/src/main/java/com/topjohnwu/magisk/MagiskFragment.java +++ b/src/main/java/com/topjohnwu/magisk/MagiskFragment.java @@ -259,17 +259,22 @@ public class MagiskFragment extends Fragment } } - if (!shownDialog && (mm.remoteMagiskVersionCode > mm.magiskVersionCode - || mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE)) { - install(); - } - magiskUpdateIcon.setImageResource(image); magiskUpdateIcon.setColorFilter(color); magiskUpdateIcon.setVisibility(View.VISIBLE); magiskUpdateProgress.setVisibility(View.GONE); mSwipeRefreshLayout.setRefreshing(false); + + if (!shownDialog) { + if (mm.remoteMagiskVersionCode > mm.magiskVersionCode + || mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) { + install(); + } else if (mm.remoteMagiskVersionCode >= Const.MAGISK_VER.FIX_ENV && + !Utils.cmdResult("env_check")) { + ShowUI.envFixDialog(getActivity()); + } + } } private void updateSafetyNetUI(int response) { diff --git a/src/main/java/com/topjohnwu/magisk/MagiskManager.java b/src/main/java/com/topjohnwu/magisk/MagiskManager.java index 70c55d7bc..6ca391d1c 100644 --- a/src/main/java/com/topjohnwu/magisk/MagiskManager.java +++ b/src/main/java/com/topjohnwu/magisk/MagiskManager.java @@ -105,10 +105,11 @@ public class MagiskManager extends Shell.ContainerApp { Shell.setInitializer(new Shell.Initializer() { @Override public void onRootShellInit(@NonNull Shell shell) { - try (InputStream utils = getAssets().open(Const.UTIL_FUNCTIONS); - InputStream magiskDB = getResources().openRawResource(R.raw.magiskdb)) { - shell.loadInputStream(null, null, utils); - shell.loadInputStream(null, null, magiskDB); + try (InputStream magiskUtils = getAssets().open(Const.UTIL_FUNCTIONS); + InputStream managerUtils = getResources().openRawResource(R.raw.utils) + ) { + shell.loadInputStream(null, null, magiskUtils); + shell.loadInputStream(null, null, managerUtils); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java b/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java index ab7547265..44f0c0c41 100644 --- a/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java +++ b/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java @@ -1,13 +1,16 @@ package com.topjohnwu.magisk.asyncs; import android.app.Activity; +import android.app.ProgressDialog; import android.net.Uri; import android.os.Build; import android.text.TextUtils; import android.view.View; +import android.widget.Toast; import com.topjohnwu.magisk.FlashActivity; import com.topjohnwu.magisk.MagiskManager; +import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.container.TarEntry; import com.topjohnwu.magisk.utils.Const; import com.topjohnwu.magisk.utils.Utils; @@ -30,6 +33,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.AbstractList; import java.util.Arrays; import java.util.List; @@ -37,42 +41,228 @@ public class InstallMagisk extends ParallelTask { private static final int PATCH_MODE = 0; private static final int DIRECT_MODE = 1; + private static final int FIX_ENV_MODE = 2; private Uri mBootImg, mZip; private List console, logs; private String mBootLocation; private int mode; private File install; + private ProgressDialog dialog; + private boolean highCompression; - private InstallMagisk(Activity context, List console, List logs, Uri zip) { + public InstallMagisk(Activity context, Uri zip) { super(context); - this.console = console; - this.logs = logs; mZip = zip; + mode = FIX_ENV_MODE; } - public InstallMagisk(Activity context, List console, List logs, Uri zip, Uri boot) { + private InstallMagisk(Activity context, List console, List logs, Uri zip) { + this(context, zip); + this.console = console; + this.logs = logs; + } + + public InstallMagisk(FlashActivity context, List console, List logs, Uri zip, Uri boot) { this(context, console, logs, zip); mBootImg = boot; + highCompression = false; mode = PATCH_MODE; } - public InstallMagisk(Activity context, List console, List logs, Uri zip, String boot) { + public InstallMagisk(FlashActivity context, List console, List logs, Uri zip, String boot) { this(context, console, logs, zip); mBootLocation = boot; mode = DIRECT_MODE; } + @Override + protected void onPreExecute() { + if (mode == FIX_ENV_MODE) { + dialog = ProgressDialog.show(getActivity(), + "Additional Setup", "Running environment setup..."); + console = new NOPList<>(); + } + } + + private void extractFiles(String arch) throws IOException { + MagiskManager mm = MagiskManager.get(); + console.add("- Extracting files"); + try (InputStream in = mm.getContentResolver().openInputStream(mZip)) { + if (in == null) throw new FileNotFoundException(); + BufferedInputStream buf = new BufferedInputStream(in); + buf.mark(Integer.MAX_VALUE); + ZipUtils.unzip(buf, install, arch + "/", true); + buf.reset(); + ZipUtils.unzip(buf, install, "common/", true); + buf.reset(); + ZipUtils.unzip(buf, install, "chromeos/", false); + buf.reset(); + ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true); + buf.close(); + } catch (FileNotFoundException e) { + console.add("! Invalid Uri"); + throw e; + } catch (IOException e) { + console.add("! Cannot unzip zip"); + throw e; + } + Shell.Sync.sh(Utils.fmt("chmod -R 755 %s/*; %s/magiskinit -x magisk %s/magisk", + install, install, install)); + } + + private boolean dumpBoot(File boot) throws IOException { + MagiskManager mm = MagiskManager.get(); + switch (mode) { + case PATCH_MODE: + // Copy boot image to local + try (InputStream in = mm.getContentResolver().openInputStream(mBootImg); + OutputStream out = new FileOutputStream(boot) + ) { + InputStream source; + if (in == null) throw new FileNotFoundException(); + + if (Utils.getNameFromUri(mm, mBootImg).endsWith(".tar")) { + // Extract boot.img from tar + TarInputStream tar = new TarInputStream(new BufferedInputStream(in)); + org.kamranzafar.jtar.TarEntry entry; + while ((entry = tar.getNextEntry()) != null) { + if (entry.getName().equals("boot.img")) + break; + } + source = tar; + } else { + // Direct copy raw image + source = new BufferedInputStream(in); + } + ShellUtils.pump(source, out); + } catch (FileNotFoundException e) { + console.add("! Invalid Uri"); + throw e; + } catch (IOException e) { + console.add("! Copy failed"); + throw e; + } + break; + case DIRECT_MODE: + console.add("- Patch boot/ramdisk image: " + mBootLocation); + if (mm.remoteMagiskVersionCode >= 1463) { + highCompression = Integer.parseInt(Utils.cmd(Utils.fmt( + "%s/magiskboot --parse %s; echo $?", + install, mBootLocation))) == 2; + if (highCompression) + console.add("! Insufficient boot partition size detected"); + } + if (boot.createNewFile()) { + Shell.Sync.su("cat " + mBootLocation + " > " + boot); + } else { + console.add("! Dump boot image failed"); + return false; + } + break; + default: + return false; + } + return true; + } + + private boolean patchBoot(File boot, SuFile patched_boot) throws IOException { + MagiskManager mm = MagiskManager.get(); + + boolean isSigned; + try (InputStream in = new FileInputStream(boot)) { + isSigned = SignBoot.verifySignature(in, null); + if (isSigned) { + console.add("- Boot image is signed with AVB 1.0"); + } + } catch (IOException e) { + console.add("! Unable to check signature"); + throw e; + } + + // Patch boot image + Shell.Sync.sh(console, logs, + "cd " + install, + Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " + + "sh update-binary indep boot_patch.sh %s || echo 'Failed!'", + mm.keepEnc, mm.keepVerity, highCompression, boot)); + + if (TextUtils.equals(console.get(console.size() - 1), "Failed!")) + return false; + + Shell.Sync.sh("mv -f new-boot.img ../", + "mv bin/busybox busybox", + "rm -rf magisk.apk bin *.img update-binary", + "cd /"); + + if (isSigned) { + console.add("- Signing boot image with test keys"); + File signed = new File(install.getParent(), "signed.img"); + try (InputStream in = new SuFileInputStream(patched_boot); + OutputStream out = new BufferedOutputStream(new FileOutputStream(signed)) + ) { + SignBoot.doSignature("/boot", in, out, null, null); + } + Shell.Sync.sh("mv -f " + signed + " " + patched_boot); + } + return true; + } + + private void outputBoot(SuFile patched_boot) throws IOException { + MagiskManager mm = MagiskManager.get(); + + switch (mode) { + case PATCH_MODE: + File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat); + dest.getParentFile().mkdirs(); + OutputStream out; + switch (mm.bootFormat) { + case ".img.tar": + out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest))); + ((TarOutputStream) out).putNextEntry(new TarEntry(patched_boot, "boot.img")); + break; + default: + case ".img": + out = new BufferedOutputStream(new FileOutputStream(dest)); + break; + } + try (InputStream in = new SuFileInputStream(patched_boot)) { + ShellUtils.pump(in, out); + out.close(); + } + console.add(""); + console.add("*********************************"); + console.add(" Patched Boot Image is placed in "); + console.add(" " + dest + " "); + console.add("*********************************"); + break; + case DIRECT_MODE: + String binPath = mm.remoteMagiskVersionCode >= Const.MAGISK_VER.HIDDEN_PATH ? "/data/adb/magisk" : "/data/magisk"; + Shell.Sync.su(console, logs, + 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("flash_boot_image %s %s", patched_boot, mBootLocation), + mm.keepVerity ? "" : "patch_dtbo_image"); + break; + } + patched_boot.delete(); + } + @Override protected Boolean doInBackground(Void... voids) { MagiskManager mm = MagiskManager.get(); - install = new File( - (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? - mm.createDeviceProtectedStorageContext() : mm) - .getFilesDir().getParent() - , "install"); - Shell.Sync.sh("rm -rf " + install); + if (mode == FIX_ENV_MODE) { + install = new File("/data/adb/magisk"); + Shell.Sync.sh("rm -rf " + install + "/*"); + } else { + install = new File( + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? + mm.createDeviceProtectedStorageContext() : mm) + .getFilesDir().getParent() + , "install"); + Shell.Sync.sh("rm -rf " + install); + } List abis = Arrays.asList(Build.SUPPORTED_ABIS); String arch; @@ -91,162 +281,26 @@ public class InstallMagisk extends ParallelTask { console.add("- Device platform: " + Build.SUPPORTED_ABIS[0]); try { - // Unzip files - console.add("- Extracting files"); - try (InputStream in = mm.getContentResolver().openInputStream(mZip)) { - if (in == null) throw new FileNotFoundException(); - BufferedInputStream buf = new BufferedInputStream(in); - buf.mark(Integer.MAX_VALUE); - ZipUtils.unzip(buf, install, arch + "/", true); - buf.reset(); - ZipUtils.unzip(buf, install, "common/", true); - buf.reset(); - ZipUtils.unzip(buf, install, "chromeos/", false); - buf.reset(); - ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true); - buf.close(); - } catch (FileNotFoundException e) { - console.add("! Invalid Uri"); - throw e; - } catch (Exception e) { - console.add("! Cannot unzip zip"); - throw e; - } - Shell.Sync.sh("chmod 755 " + install + "/*"); + extractFiles(arch); + if (mode == FIX_ENV_MODE) { + Shell.Sync.sh( + "cd " + install, + "sh update-binary extract", + "rm -f update-binary magisk.apk", + "cd /", + "rm -rf /sbin/.core/busybox/*", + "/sbin/.core/mirror/bin/busybox --install -s /sbin/.core/busybox" + ); + } else { + File boot = new File(install, "boot.img"); + SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img"); - File boot = new File(install, "boot.img"); - boolean highCompression = false; - switch (mode) { - case PATCH_MODE: - // Copy boot image to local - try (InputStream in = mm.getContentResolver().openInputStream(mBootImg); - OutputStream out = new FileOutputStream(boot) - ) { - InputStream source; - if (in == null) throw new FileNotFoundException(); - - if (Utils.getNameFromUri(mm, mBootImg).endsWith(".tar")) { - // Extract boot.img from tar - TarInputStream tar = new TarInputStream(new BufferedInputStream(in)); - org.kamranzafar.jtar.TarEntry entry; - while ((entry = tar.getNextEntry()) != null) { - if (entry.getName().equals("boot.img")) - break; - } - source = tar; - } else { - // Direct copy raw image - source = new BufferedInputStream(in); - } - ShellUtils.pump(source, out); - } catch (FileNotFoundException e) { - console.add("! Invalid Uri"); - throw e; - } catch (IOException e) { - console.add("! Copy failed"); - throw e; - } - break; - case DIRECT_MODE: - console.add("- Patch boot/ramdisk image: " + mBootLocation); - if (mm.remoteMagiskVersionCode >= 1463) { - highCompression = Integer.parseInt(Utils.cmd(Utils.fmt( - "%s/magiskboot --parse %s; echo $?", - install, mBootLocation))) == 2; - if (highCompression) - console.add("! Insufficient boot partition size detected"); - } - if (boot.createNewFile()) { - Shell.Sync.su("cat " + mBootLocation + " > " + boot); - } else { - console.add("! Dump boot image failed"); - return false; - } - break; - default: + if (!dumpBoot(boot) || !patchBoot(boot, patched_boot)) return false; + outputBoot(patched_boot); + + console.add("- All done!"); } - - boolean isSigned; - try (InputStream in = new FileInputStream(boot)) { - isSigned = SignBoot.verifySignature(in, null); - if (isSigned) { - console.add("- Boot image is signed with AVB 1.0"); - } - } catch (Exception e) { - console.add("! Unable to check signature"); - throw e; - } - - // Patch boot image - Shell.Sync.sh(console, logs, - "cd " + install, - Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " + - "sh update-binary indep boot_patch.sh %s || echo 'Failed!'", - mm.keepEnc, mm.keepVerity, highCompression, boot)); - - if (TextUtils.equals(console.get(console.size() - 1), "Failed!")) - return false; - - Shell.Sync.sh("mv -f new-boot.img ../", - "mv bin/busybox busybox", - "rm -rf magisk.apk bin *.img update-binary", - "cd /"); - - SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img"); - - if (isSigned) { - console.add("- Signing boot image with test keys"); - File signed = new File(install.getParent(), "signed.img"); - try (InputStream in = new SuFileInputStream(patched_boot); - OutputStream out = new BufferedOutputStream(new FileOutputStream(signed)) - ) { - SignBoot.doSignature("/boot", in, out, null, null); - } - Shell.Sync.sh("mv -f " + signed + " " + patched_boot); - } - - switch (mode) { - case PATCH_MODE: - File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat); - dest.getParentFile().mkdirs(); - OutputStream out; - switch (mm.bootFormat) { - case ".img.tar": - out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest))); - ((TarOutputStream) out).putNextEntry(new TarEntry(patched_boot, "boot.img")); - break; - default: - case ".img": - out = new BufferedOutputStream(new FileOutputStream(dest)); - break; - } - try (InputStream in = new SuFileInputStream(patched_boot)) { - ShellUtils.pump(in, out); - out.close(); - } - console.add(""); - console.add("*********************************"); - console.add(" Patched Boot Image is placed in "); - console.add(" " + dest + " "); - console.add("*********************************"); - break; - case DIRECT_MODE: - String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk"; - Shell.Sync.su(console, logs, - 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("flash_boot_image %s %s", patched_boot, mBootLocation), - mm.remoteMagiskVersionCode >= 1464 ? "[ -L /data/magisk.img ] || cp /data/magisk.img /data/adb/magisk.img" : "", - mm.keepVerity ? "" : "patch_dtbo_image"); - break; - default: - return false; - } - - patched_boot.delete(); - - console.add("- All done!"); } catch (Exception e) { e.printStackTrace(); return false; @@ -256,12 +310,33 @@ public class InstallMagisk extends ParallelTask { @Override protected void onPostExecute(Boolean result) { - FlashActivity activity = (FlashActivity) getActivity(); - if (!result) { - Shell.Async.sh("rm -rf " + install); - console.add("! Installation failed"); - activity.reboot.setVisibility(View.GONE); + if (mode == FIX_ENV_MODE) { + dialog.dismiss(); + MagiskManager.toast(result ? R.string.setup_done : R.string.setup_fail, Toast.LENGTH_LONG); + } else { + // Running in FlashActivity + FlashActivity activity = (FlashActivity) getActivity(); + if (!result) { + Shell.Async.sh("rm -rf " + install); + console.add("! Installation failed"); + activity.reboot.setVisibility(View.GONE); + } + activity.buttonPanel.setVisibility(View.VISIBLE); } - activity.buttonPanel.setVisibility(View.VISIBLE); + } + + private static class NOPList extends AbstractList { + @Override + public E get(int index) { + return null; + } + + @Override + public int size() { + return 0; + } + + @Override + public void add(int index, E element) {} } } diff --git a/src/main/java/com/topjohnwu/magisk/utils/Const.java b/src/main/java/com/topjohnwu/magisk/utils/Const.java index 5393c96e1..72a82f1b3 100644 --- a/src/main/java/com/topjohnwu/magisk/utils/Const.java +++ b/src/main/java/com/topjohnwu/magisk/utils/Const.java @@ -80,6 +80,7 @@ public class Const { public static final int HIDDEN_PATH = 1460; public static final int REMOVE_LEGACY_LINK = 1630; public static final int SEPOL_REFACTOR = 1640; + public static final int FIX_ENV = 1650; } public static class ID { diff --git a/src/main/java/com/topjohnwu/magisk/utils/ShowUI.java b/src/main/java/com/topjohnwu/magisk/utils/ShowUI.java index 460314e0e..f3a53cb19 100644 --- a/src/main/java/com/topjohnwu/magisk/utils/ShowUI.java +++ b/src/main/java/com/topjohnwu/magisk/utils/ShowUI.java @@ -17,6 +17,7 @@ import com.topjohnwu.magisk.FlashActivity; import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.SplashActivity; +import com.topjohnwu.magisk.asyncs.InstallMagisk; import com.topjohnwu.magisk.asyncs.RestoreImages; import com.topjohnwu.magisk.components.AlertDialogBuilder; import com.topjohnwu.magisk.receivers.DownloadReceiver; @@ -100,6 +101,26 @@ public class ShowUI { notificationManager.notify(Const.ID.DTBO_NOTIFICATION_ID, builder.build()); } + public static void envFixDialog(Activity activity) { + MagiskManager mm = Utils.getMagiskManager(activity); + String filename = Utils.fmt("Magisk-v%s(%d).zip", + mm.remoteMagiskVersionString, mm.remoteMagiskVersionCode); + new AlertDialogBuilder(activity) + .setTitle(R.string.env_fix_title) + .setMessage(R.string.env_fix_msg) + .setCancelable(true) + .setPositiveButton(R.string.yes, (d, i) -> { + Utils.dlAndReceive(activity, new DownloadReceiver() { + @Override + public void onDownloadDone(Uri uri) { + new InstallMagisk(activity, uri).exec(); + } + }, mm.magiskLink, filename); + }) + .setNegativeButton(R.string.no_thanks, null) + .show(); + } + public static void magiskInstallDialog(Activity activity) { MagiskManager mm = Utils.getMagiskManager(activity); String filename = Utils.fmt("Magisk-v%s(%d).zip", diff --git a/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 50b77b462..9b479cc63 100644 --- a/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -51,6 +51,10 @@ public class Utils { return ShellUtils.fastCmd(Shell.getShell(), cmd); } + public static boolean cmdResult(String cmd) { + return ShellUtils.fastCmdResult(Shell.getShell(), cmd); + } + public static void uninstallPkg(String pkg) { Shell.Sync.su("db_clean " + Const.USER_ID, "pm uninstall " + pkg); } diff --git a/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java b/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java index 3baf94363..c7f945d77 100644 --- a/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java +++ b/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java @@ -1,6 +1,8 @@ package com.topjohnwu.magisk.utils; import com.topjohnwu.superuser.ShellUtils; +import com.topjohnwu.superuser.io.SuFile; +import com.topjohnwu.superuser.io.SuFileOutputStream; import com.topjohnwu.utils.JarMap; import com.topjohnwu.utils.SignAPK; @@ -9,6 +11,7 @@ import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.ZipEntry; @@ -16,13 +19,13 @@ import java.util.zip.ZipInputStream; public class ZipUtils { - public static void unzip(File zip, File folder, String path, boolean junkPath) throws Exception { + public static void unzip(File zip, File folder, String path, boolean junkPath) throws IOException { InputStream in = new BufferedInputStream(new FileInputStream(zip)); unzip(in, folder, path, junkPath); in.close(); } - public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception { + public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws IOException { try { ZipInputStream zipfile = new ZipInputStream(zip); ZipEntry entry; @@ -37,13 +40,14 @@ public class ZipUtils { } else { name = entry.getName(); } - File dest = new File(folder, name); + SuFile dest = new SuFile(folder, name); dest.getParentFile().mkdirs(); - try (FileOutputStream out = new FileOutputStream(dest)) { + try (OutputStream out = new SuFileOutputStream(dest)) { ShellUtils.pump(zipfile, out); } } - } catch(Exception e) { + } + catch(IOException e) { e.printStackTrace(); throw e; } diff --git a/src/main/res/raw/magiskdb.sh b/src/main/res/raw/utils.sh similarity index 84% rename from src/main/res/raw/magiskdb.sh rename to src/main/res/raw/utils.sh index 61b579a3b..9209274a4 100644 --- a/src/main/res/raw/magiskdb.sh +++ b/src/main/res/raw/utils.sh @@ -36,3 +36,10 @@ db_setup() { chown $USER.$USER $DIR chmod 666 $DIR/* } + +env_check() { + for file in busybox magisk magiskboot magiskinit util_functions.sh boot_patch.sh; do + [ -e /data/adb/magisk/$file ] || return 1 + done + return 0 +} diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 7b007793d..ca3138cc9 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -125,6 +125,10 @@ SU database is corrupted, will recreate new db Cannot check SafetyNet Due to some changes in Google Play Services, it is not possible to check SafetyNet on repackaged Magisk Manager + Setup done + Setup failed + Require Additional Setup + Your device need additional setup for Magisk to work properly. It will download the Magisk setup zip, do you want to proceed now? General