use of com.topjohnwu.magisk.container.TarEntry in project MagiskManager by topjohnwu.
the class InstallMagisk method doInBackground.
@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);
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
String arch;
if (abis.contains("x86_64"))
arch = "x64";
else if (abis.contains("arm64-v8a"))
arch = "arm64";
else if (abis.contains("x86"))
arch = "x86";
else
arch = "arm";
console.add("- Device platform: " + arch);
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 + "/*");
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:
return false;
}
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 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;
}
return true;
}
Aggregations