diff --git a/app/src/main/java/com/topjohnwu/magisk/adapters/ReposAdapter.java b/app/src/main/java/com/topjohnwu/magisk/adapters/ReposAdapter.java index 3c61bf65b..a9b92b6e1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/adapters/ReposAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/adapters/ReposAdapter.java @@ -3,7 +3,6 @@ package com.topjohnwu.magisk.adapters; import android.app.Activity; import android.content.Context; import android.database.Cursor; -import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.Pair; @@ -21,7 +20,6 @@ import com.topjohnwu.magisk.components.AlertDialogBuilder; import com.topjohnwu.magisk.database.RepoDatabaseHelper; import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Repo; -import com.topjohnwu.magisk.receivers.DownloadReceiver; import com.topjohnwu.magisk.utils.Utils; import java.util.ArrayList; @@ -106,26 +104,13 @@ public class ReposAdapter extends SectionedAdapter Utils.dlAndReceive( - context, - new DownloadReceiver() { - @Override - public void onDownloadDone(Uri uri) { - new ProcessRepoZip((Activity) context, uri, true).exec(); - } - }, - repo.getZipUrl(), - Utils.getLegalFilename(filename))) - .setNeutralButton(R.string.download, (d, i) -> Utils.dlAndReceive( - context, - new DownloadReceiver() { - @Override - public void onDownloadDone(Uri uri) { - new ProcessRepoZip((Activity) context, uri, false).exec(); - } - }, - repo.getZipUrl(), - Utils.getLegalFilename(filename))) + .setPositiveButton(R.string.install, (d, i) -> + new ProcessRepoZip((Activity) context, repo.getZipUrl(), + Utils.getLegalFilename(filename), true).exec() + ) + .setNeutralButton(R.string.download, (d, i) -> + new ProcessRepoZip((Activity) context, repo.getZipUrl(), + Utils.getLegalFilename(filename), false).exec()) .setNegativeButton(R.string.no_thanks, null) .show(); }); diff --git a/app/src/main/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java b/app/src/main/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java index dc7c8ca93..2e86a8831 100644 --- a/app/src/main/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java +++ b/app/src/main/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java @@ -1,9 +1,11 @@ package com.topjohnwu.magisk.asyncs; +import android.Manifest; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; +import android.os.Environment; import android.widget.Toast; import com.topjohnwu.magisk.FlashActivity; @@ -11,32 +13,42 @@ import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Utils; +import com.topjohnwu.magisk.utils.WebService; import com.topjohnwu.magisk.utils.ZipUtils; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStream; import java.io.OutputStream; public class ProcessRepoZip extends ParallelTask { - private Uri mUri; private ProgressDialog progressDialog; private boolean mInstall; + private String mLink, mFile; - public ProcessRepoZip(Activity context, Uri uri, boolean install) { + public ProcessRepoZip(Activity context, String link, String filename, boolean install) { super(context); - mUri = uri; + mLink = link; + mFile = Environment.getExternalStorageDirectory() + "/MagiskManager/" + filename; mInstall = install; } @Override protected void onPreExecute() { Activity activity = getActivity(); - if (activity == null) return; progressDialog = ProgressDialog.show(activity, - activity.getString(R.string.zip_process_title), - activity.getString(R.string.zip_process_msg)); + activity.getString(R.string.zip_download_title), + activity.getString(R.string.zip_download_msg)); + } + + @Override + protected void onProgressUpdate(Void... values) { + progressDialog.setTitle(R.string.zip_process_title); + progressDialog.setMessage(getActivity().getString(R.string.zip_process_msg)); } @Override @@ -45,15 +57,20 @@ public class ProcessRepoZip extends ParallelTask { if (activity == null) return null; try { - // Create temp file - File temp1 = new File(activity.getCacheDir(), "1.zip"); - File temp2 = new File(activity.getCacheDir(), "2.zip"); - activity.getCacheDir().mkdirs(); - temp1.createNewFile(); - temp2.createNewFile(); + // Request zip from Internet + InputStream in = WebService.request(WebService.GET, mLink, null); + if (in == null) return false; + in = new BufferedInputStream(in); - // First remove top folder in Github source zip, Uri -> temp1 - ZipUtils.removeTopFolder(activity.getContentResolver().openInputStream(mUri), temp1); + // Temp files + File temp1 = new File(activity.getCacheDir(), "1.zip"); + File temp2 = new File(temp1.getParentFile(), "2.zip"); + temp1.getParentFile().mkdir(); + + // First remove top folder in Github source zip, Web -> temp1 + ZipUtils.removeTopFolder(in, temp1); + + publishProgress(); // Then sign the zip for the first time, temp1 -> temp2 ZipUtils.signZip(activity, temp1, temp2, false); @@ -64,18 +81,17 @@ public class ProcessRepoZip extends ParallelTask { // Finally, sign the whole zip file again, temp1 -> temp2 ZipUtils.signZip(activity, temp1, temp2, true); - // Write it back to the downloaded zip, temp2 -> Uri - try (OutputStream out = activity.getContentResolver().openOutputStream(mUri); - FileInputStream in = new FileInputStream(temp2) + // Write it to the target zip, temp2 -> file + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(mFile)); + InputStream source = new BufferedInputStream(new FileInputStream(temp2)) ) { byte[] buffer = new byte[4096]; int length; - if (out == null) throw new FileNotFoundException(); - while ((length = in.read(buffer)) > 0) + while ((length = source.read(buffer)) > 0) out.write(buffer, 0, length); } - // Delete the temp file + // Delete temp files temp1.delete(); temp2.delete(); @@ -92,17 +108,24 @@ public class ProcessRepoZip extends ParallelTask { Activity activity = getActivity(); if (activity == null) return; progressDialog.dismiss(); + Uri uri = Uri.fromFile(new File(mFile)); if (result) { if (Shell.rootAccess() && mInstall) { Intent intent = new Intent(getActivity(), FlashActivity.class); - intent.setData(mUri).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP); + intent.setData(uri).putExtra(FlashActivity.SET_ACTION, FlashActivity.FLASH_ZIP); activity.startActivity(intent); } else { - Utils.showUriSnack(activity, mUri); + Utils.showUriSnack(activity, uri); } } else { Utils.getMagiskManager(activity).toast(R.string.process_error, Toast.LENGTH_LONG); } super.onPostExecute(result); } + + @Override + public ParallelTask exec(Void... voids) { + Utils.runWithPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> super.exec(voids)); + return this; + } } 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 8a3380904..ee8b9d9f9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.java @@ -22,6 +22,8 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.util.encoders.Base64; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -126,7 +128,7 @@ public class ZipUtils { public static void removeTopFolder(InputStream in, File output) throws IOException { try { JarInputStream source = new JarInputStream(in); - JarOutputStream dest = new JarOutputStream(new FileOutputStream(output)); + JarOutputStream dest = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output))); JarEntry entry; String path; int size; @@ -157,7 +159,7 @@ public class ZipUtils { } public static void unzip(File zip, File folder, String path, boolean junkPath) throws Exception { - InputStream in = new FileInputStream(zip); + InputStream in = new BufferedInputStream(new FileInputStream(zip)); unzip(in, folder, path, junkPath); in.close(); } @@ -198,7 +200,7 @@ public class ZipUtils { public static void signZip(Context context, File input, File output, boolean minSign) { int alignment = 4; JarFile inputJar = null; - FileOutputStream outputFile = null; + BufferedOutputStream outputFile = null; int hashes = 0; try { X509Certificate publicKey = readPublicKey(context.getAssets().open(PUBLIC_KEY_NAME)); @@ -210,7 +212,7 @@ public class ZipUtils { long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000; PrivateKey privateKey = readPrivateKey(context.getAssets().open(PRIVATE_KEY_NAME)); - outputFile = new FileOutputStream(output); + outputFile = new BufferedOutputStream(new FileOutputStream(output)); if (minSign) { ZipUtils.signWholeFile(input, publicKey, privateKey, outputFile); } else { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fbb7a02a7..0675140e4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -114,7 +114,6 @@ Copying zip to temp directory Installing Unzipping zip file … - Processing zip file … Installing %1$s … Magisk Is Not Installed! Do you want to download and install Magisk? @@ -130,7 +129,10 @@ I understand Process error The zip is stored in:\n[Internal Storage]%1$s + Downloading + Downloading zip file … Processing + Processing zip file … Please manually select a boot image! New Magisk Manager Update Available! Press to download and install