diff --git a/app/src/main/java/com/topjohnwu/magisk/FlashActivity.java b/app/src/main/java/com/topjohnwu/magisk/FlashActivity.java index db45b1237..f06b5f6c3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/FlashActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/FlashActivity.java @@ -14,7 +14,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.topjohnwu.magisk.asyncs.FlashZip; -import com.topjohnwu.magisk.asyncs.PatchBootImage; +import com.topjohnwu.magisk.asyncs.InstallMagisk; import com.topjohnwu.magisk.components.Activity; import com.topjohnwu.magisk.utils.AdaptiveList; import com.topjohnwu.magisk.utils.Shell; @@ -28,9 +28,13 @@ import butterknife.OnClick; public class FlashActivity extends Activity { public static final String SET_ACTION = "action"; - public static final String SET_BOOT_URI = "boot_uri"; + public static final String SET_BOOT = "boot"; + public static final String SET_ENC = "enc"; + public static final String SET_VERITY = "verity"; + public static final String FLASH_ZIP = "flash"; public static final String PATCH_BOOT = "patch"; + public static final String FLASH_MAGISK = "magisk"; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.flash_logs) RecyclerView flashLogs; @@ -68,6 +72,9 @@ public class FlashActivity extends Activity { Intent intent = getIntent(); Uri uri = intent.getData(); + boolean keepEnc = intent.getBooleanExtra(SET_ENC, false); + boolean keepVerity = intent.getBooleanExtra(SET_VERITY, false); + switch (getIntent().getStringExtra(SET_ACTION)) { case FLASH_ZIP: new FlashZip(this, uri, rootShellOutput) @@ -75,9 +82,29 @@ public class FlashActivity extends Activity { .exec(); break; case PATCH_BOOT: - new PatchBootImage(this, uri, intent.getParcelableExtra(SET_BOOT_URI), rootShellOutput) + new InstallMagisk(this, rootShellOutput, uri, keepEnc, keepVerity, (Uri) intent.getParcelableExtra(SET_BOOT)) .setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE)) .exec(); + break; + case FLASH_MAGISK: + String boot = intent.getStringExtra(SET_BOOT); + if (getApplicationContext().remoteMagiskVersionCode < 1370) { + // Use legacy installation method + getShell().su_raw( + "echo \"BOOTIMAGE=" + boot + "\" > /dev/.magisk", + "echo \"KEEPFORCEENCRYPT=" + keepEnc + "\" >> /dev/.magisk", + "echo \"KEEPVERITY=" + keepVerity + "\" >> /dev/.magisk" + ); + new FlashZip(this, uri, rootShellOutput) + .setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE)) + .exec(); + } else { + // Use new installation method + new InstallMagisk(this, rootShellOutput, uri, keepEnc, keepVerity, boot) + .setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE)) + .exec(); + } + break; } } diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java index 6aa0af7a2..72cd754e1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java @@ -24,6 +24,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.Spinner; import android.widget.TextView; +import android.widget.Toast; import com.topjohnwu.magisk.asyncs.CheckUpdates; import com.topjohnwu.magisk.components.AlertDialogBuilder; @@ -150,6 +151,10 @@ public class MagiskFragment extends Fragment DownloadReceiver receiver = null; switch (idx) { case 1: + if (magiskManager.remoteMagiskVersionCode < 1370) { + magiskManager.toast(R.string.no_boot_file_patch_support, Toast.LENGTH_LONG); + return; + } Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); startActivityForResult(intent, SELECT_BOOT_IMG); @@ -166,13 +171,12 @@ public class MagiskFragment extends Fragment receiver = new DownloadReceiver() { @Override public void onDownloadDone(Uri uri) { - getShell().su_raw( - "echo \"BOOTIMAGE=" + boot + "\" > /dev/.magisk", - "echo \"KEEPFORCEENCRYPT=" + keepEncChkbox.isChecked() + "\" >> /dev/.magisk", - "echo \"KEEPVERITY=" + keepVerityChkbox.isChecked() + "\" >> /dev/.magisk" - ); Intent intent = new Intent(getActivity(), FlashActivity.class); - intent.setData(uri).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP); + intent.setData(uri) + .putExtra(FlashActivity.SET_BOOT, boot) + .putExtra(FlashActivity.SET_ENC, keepEncChkbox.isChecked()) + .putExtra(FlashActivity.SET_VERITY, keepVerityChkbox.isChecked()) + .putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_MAGISK); startActivity(intent); } }; @@ -304,10 +308,11 @@ public class MagiskFragment extends Fragment new DownloadReceiver() { @Override public void onDownloadDone(Uri uri) { - // Get the URI of the selected file Intent intent = new Intent(getActivity(), FlashActivity.class); intent.setData(uri) - .putExtra(FlashActivity.SET_BOOT_URI, data.getData()) + .putExtra(FlashActivity.SET_BOOT, data.getData()) + .putExtra(FlashActivity.SET_ENC, keepEncChkbox.isChecked()) + .putExtra(FlashActivity.SET_VERITY, keepVerityChkbox.isChecked()) .putExtra(FlashActivity.SET_ACTION, FlashActivity.PATCH_BOOT); startActivity(intent); } @@ -350,11 +355,11 @@ public class MagiskFragment extends Fragment int status = 0; status |= Shell.rootAccess() ? ROOT : 0; status |= Utils.checkNetworkStatus(magiskManager) ? NETWORK : 0; - status |= magiskManager.magiskVersionCode >= 130 ? UPTODATE : 0; + status |= magiskManager.magiskVersionCode >= 1300 ? UPTODATE : 0; magiskUpdateCard.setVisibility(Utils.checkBits(status, NETWORK) ? View.VISIBLE : View.GONE); safetyNetCard.setVisibility(Utils.checkBits(status, NETWORK) ? View.VISIBLE : View.GONE); bootImageCard.setVisibility(Utils.checkBits(status, NETWORK, ROOT) ? View.VISIBLE : View.GONE); - installOptionCard.setVisibility(Utils.checkBits(status, NETWORK, ROOT) ? View.VISIBLE : View.GONE); + installOptionCard.setVisibility(Utils.checkBits(status, NETWORK) ? View.VISIBLE : View.GONE); installButton.setVisibility(Utils.checkBits(status, NETWORK) ? View.VISIBLE : View.GONE); uninstallButton.setVisibility(Utils.checkBits(status, UPTODATE, ROOT) ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/PatchBootImage.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java similarity index 50% rename from app/src/main/java/com/topjohnwu/magisk/asyncs/PatchBootImage.java rename to app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java index ad6cfb75e..d61e45ba0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/PatchBootImage.java +++ b/app/src/main/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java @@ -20,18 +20,35 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.List; -public class PatchBootImage extends ParallelTask { +public class InstallMagisk extends ParallelTask { + + private static final int PATCH_MODE = 0; + private static final int DIRECT_MODE = 1; private Uri mBootImg, mZip; private AdaptiveList mList; - private File dest; + private String mBootLocation; + private boolean mKeepEnc, mKeepVerity; + private int mode; - public PatchBootImage(Activity context, Uri zip, Uri boot, AdaptiveList list) { + private InstallMagisk(Activity context, AdaptiveList list, Uri zip, boolean enc, boolean verity) { super(context); - mBootImg = boot; mList = list; mZip = zip; - dest = new File(Environment.getExternalStorageDirectory() + "/MagiskManager/" + "patched_boot.img"); + mKeepEnc = enc; + mKeepVerity = verity; + } + + public InstallMagisk(Activity context, AdaptiveList list, Uri zip, boolean enc, boolean verity, Uri boot) { + this(context, list, zip, enc, verity); + mBootImg = boot; + mode = PATCH_MODE; + } + + public InstallMagisk(Activity context, AdaptiveList list, Uri zip, boolean enc, boolean verity, String boot) { + this(context, list, zip, enc, verity); + mBootLocation = boot; + mode = DIRECT_MODE; } @Override @@ -83,42 +100,69 @@ public class PatchBootImage extends ParallelTask { throw e; } - // Copy boot image - File boot = new File(install, "boot.img"); - try ( - InputStream in = magiskManager.getContentResolver().openInputStream(mBootImg); - OutputStream out = new FileOutputStream(boot); - ) { - if (in == null) throw new FileNotFoundException(); - byte buffer[] = new byte[1024]; - int length; - while ((length = in.read(buffer)) > 0) - out.write(buffer, 0, length); - } catch (FileNotFoundException e) { - mList.add("! Invalid Uri"); - throw e; - } catch (IOException e) { - mList.add("! Copy failed"); - throw e; + File boot; + switch (mode) { + case PATCH_MODE: + boot = new File(install, "boot.img"); + // Copy boot image to local + try ( + InputStream in = magiskManager.getContentResolver().openInputStream(mBootImg); + OutputStream out = new FileOutputStream(boot); + ) { + if (in == null) throw new FileNotFoundException(); + byte buffer[] = new byte[1024]; + int length; + while ((length = in.read(buffer)) > 0) + out.write(buffer, 0, length); + } catch (FileNotFoundException e) { + mList.add("! Invalid Uri"); + throw e; + } catch (IOException e) { + mList.add("! Copy failed"); + throw e; + } + break; + case DIRECT_MODE: + boot = new File(mBootLocation); + break; + default: + return false; } mList.add("- Use boot image: " + boot); // Patch boot image getShell().sh(mList, - "chmod -R 755 " + install, "cd " + install, - "sh update-binary indep boot_patch.sh " + boot + + "KEEPFORCEENCRYPT=" + mKeepEnc + " KEEPVERITY=" + mKeepVerity + " sh " + + "update-binary indep boot_patch.sh " + boot + " 2>&1" + " && echo 'Success!' || echo 'Failed!'" ); if (!TextUtils.equals(mList.get(mList.size() - 1), "Success!")) return false; - // Move boot image - File source = new File(install, "new-boot.img"); - dest.getParentFile().mkdirs(); - getShell().sh_raw("mv " + source + " " + dest); + File patched_boot = new File(install, "new-boot.img"); + mList.add(""); + switch (mode) { + case PATCH_MODE: + // Move boot image + File dest = new File(Environment.getExternalStorageDirectory() + "/MagiskManager/" + "patched_boot.img"); + dest.getParentFile().mkdirs(); + getShell().sh_raw("cp " + patched_boot + " " + dest); + mList.add("*********************************"); + mList.add(" Patched Boot Image is placed in "); + mList.add(" " + dest + " "); + mList.add("*********************************"); + break; + case DIRECT_MODE: + // Direct flash boot image + getShell().su_raw("cat " + patched_boot + " /dev/zero | dd of=" + mBootLocation + " bs=4096"); + mList.add("Flashing patched boot to " + mBootLocation); + break; + default: + return false; + } // Finals getShell().sh_raw( @@ -133,13 +177,6 @@ public class PatchBootImage extends ParallelTask { @Override protected void onPostExecute(Boolean result) { - if (result) { - mList.add(""); - mList.add("*********************************"); - mList.add(" Patched Boot Image is placed in "); - mList.add(" " + dest + " "); - mList.add("*********************************"); - } super.onPostExecute(result); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java b/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java index a65a5b190..b9e2b3ea7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java @@ -157,7 +157,7 @@ public class ZipUtils { } public static void unzip(File zip, File folder, String path, boolean junkPath) throws Exception { - JarInputStream in = new JarInputStream(new FileInputStream(zip)); + InputStream in = new FileInputStream(zip); unzip(in, folder, path, junkPath); in.close(); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ee567dc70..6f6c79f47 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -142,6 +142,7 @@ Patch Boot Image File Direct Install (Recommend) Select Method + Target Magisk version doesn\'t support boot image file patching General