Some refinements
This commit is contained in:
parent
3b20747192
commit
4daea7d7e6
@ -22,14 +22,13 @@ import android.widget.TextView;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.module.Repo;
|
||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||
import com.topjohnwu.magisk.receivers.RepoDlReceiver;
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.Utils.ByteArrayInOutStream;
|
||||
import com.topjohnwu.magisk.utils.WebWindow;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
@ -57,7 +56,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
|
||||
|
||||
String theme = PreferenceManager.getDefaultSharedPreferences(context).getString("theme", "");
|
||||
if (theme.equals("Dark")) {
|
||||
builder = new AlertDialog.Builder(context,R.style.AlertDialog_dh);
|
||||
builder = new AlertDialog.Builder(context, R.style.AlertDialog_dh);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(context);
|
||||
}
|
||||
@ -102,43 +101,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.download_install, (dialogInterface, i) -> Utils.dlAndReceive(
|
||||
context,
|
||||
new DownloadReceiver() {
|
||||
@Override
|
||||
public void task(Uri uri) {
|
||||
// Flash the zip
|
||||
new Async.FlashZIP(mContext, uri, mFilename){
|
||||
@Override
|
||||
protected void preProcessing() throws Throwable {
|
||||
// Process and sign the zip
|
||||
publishProgress(mContext.getString(R.string.zip_install_process_zip_msg));
|
||||
try {
|
||||
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream inBuffer;
|
||||
|
||||
// First remove top folder (the folder with the repo name) in Github source zip
|
||||
ZipUtils.removeTopFolder(mContext.getContentResolver().openInputStream(mUri), outBuffer);
|
||||
inBuffer = new ByteArrayInputStream(outBuffer.toByteArray());
|
||||
outBuffer.reset();
|
||||
|
||||
// Then sign the zip for the first time
|
||||
ZipUtils.signZip(mContext, inBuffer, outBuffer, false);
|
||||
|
||||
// Call zipadjust through JNI
|
||||
inBuffer = new ByteArrayInputStream(ZipUtils.zipAdjust(outBuffer.toByteArray(), outBuffer.size()));
|
||||
outBuffer.reset();
|
||||
|
||||
// Finally, sign the whole zip file again
|
||||
ZipUtils.signZip(mContext, inBuffer, outBuffer, true);
|
||||
|
||||
// Write it back to the downloaded zip
|
||||
OutputStream out = mContext.getContentResolver().openOutputStream(mUri);
|
||||
outBuffer.writeTo(out);
|
||||
out.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}.exec();
|
||||
}
|
||||
},
|
||||
new RepoDlReceiver(),
|
||||
repo.getZipUrl(),
|
||||
Utils.getLegalFilename(filename)))
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
|
@ -52,5 +52,5 @@ public abstract class DownloadReceiver extends BroadcastReceiver {
|
||||
mFilename = filename;
|
||||
}
|
||||
|
||||
public void task(Uri uri) {}
|
||||
public abstract void task(Uri uri);
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.topjohnwu.magisk.receivers;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.utils.Utils.ByteArrayInOutStream;
|
||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class RepoDlReceiver extends DownloadReceiver {
|
||||
@Override
|
||||
public void task(Uri uri) {
|
||||
// Flash the zip
|
||||
new Async.FlashZIP(mContext, uri, mFilename){
|
||||
@Override
|
||||
protected void preProcessing() throws Throwable {
|
||||
// Process and sign the zip
|
||||
publishProgress(mContext.getString(R.string.zip_install_process_zip_msg));
|
||||
ByteArrayInOutStream buffer = new ByteArrayInOutStream();
|
||||
|
||||
// First remove top folder (the folder with the repo name) in Github source zip
|
||||
ZipUtils.removeTopFolder(mContext.getContentResolver().openInputStream(mUri), buffer);
|
||||
|
||||
// Then sign the zip for the first time
|
||||
ZipUtils.signZip(mContext, buffer.getInputStream(), buffer, false);
|
||||
|
||||
// Adjust the zip to prevent unzip issues
|
||||
ZipUtils.adjustZip(buffer);
|
||||
|
||||
// Finally, sign the whole zip file again
|
||||
ZipUtils.signZip(mContext, buffer.getInputStream(), buffer, true);
|
||||
|
||||
// Write it back to the downloaded zip
|
||||
OutputStream out = mContext.getContentResolver().openOutputStream(mUri);
|
||||
buffer.writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
}.exec();
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
@ -21,7 +20,6 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -179,13 +177,13 @@ public class Async {
|
||||
mContext = context;
|
||||
mUri = uri;
|
||||
mFilename = filename;
|
||||
progress = new ProgressDialog(mContext);
|
||||
}
|
||||
|
||||
public FlashZIP(Context context, Uri uri) {
|
||||
mContext = context;
|
||||
mUri = uri;
|
||||
progress = new ProgressDialog(mContext);
|
||||
|
||||
// Try to get the filename ourselves
|
||||
Cursor c = mContext.getContentResolver().query(uri, null, null, null, null);
|
||||
if (c != null) {
|
||||
int nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||
@ -201,32 +199,23 @@ public class Async {
|
||||
}
|
||||
}
|
||||
|
||||
private void createFileFromInputStream(InputStream inputStream, File file) throws IOException {
|
||||
if (file.exists() && !file.delete()) {
|
||||
throw new IOException();
|
||||
}
|
||||
file.setWritable(true, false);
|
||||
OutputStream outputStream = new FileOutputStream(file);
|
||||
byte buffer[] = new byte[1024];
|
||||
int length;
|
||||
|
||||
while ((length = inputStream.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
outputStream.close();
|
||||
Logger.dev("FlashZip: File created successfully - " + file.getPath());
|
||||
}
|
||||
|
||||
protected void preProcessing() throws Throwable {}
|
||||
|
||||
protected void copyToCache() throws Throwable {
|
||||
try {
|
||||
InputStream in = mContext.getContentResolver().openInputStream(mUri);
|
||||
mCachedFile = new File(mContext.getCacheDir().getAbsolutePath() + "/install.zip");
|
||||
mCachedFile.delete();
|
||||
Utils.removeItem(mCachedFile.getPath());
|
||||
createFileFromInputStream(in, mCachedFile);
|
||||
if (mCachedFile.exists() && !mCachedFile.delete()) {
|
||||
throw new IOException();
|
||||
}
|
||||
OutputStream outputStream = new FileOutputStream(mCachedFile);
|
||||
byte buffer[] = new byte[1024];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, length);
|
||||
}
|
||||
outputStream.close();
|
||||
Logger.dev("FlashZip: File created successfully - " + mCachedFile.getPath());
|
||||
in.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(Logger.LOG_TAG, "FlashZip: Invalid Uri");
|
||||
@ -239,6 +228,7 @@ public class Async {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
progress = new ProgressDialog(mContext);
|
||||
progress.setTitle(R.string.zip_install_progress_title);
|
||||
progress.show();
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ import android.widget.Toast;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
@ -136,4 +138,17 @@ public class Utils {
|
||||
.replace("#", "").replace("@", "").replace("*", "");
|
||||
}
|
||||
|
||||
public static class ByteArrayInOutStream extends ByteArrayOutputStream {
|
||||
public ByteArrayInputStream getInputStream() {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(buf, 0, count);
|
||||
count = 0;
|
||||
buf = new byte[32];
|
||||
return in;
|
||||
}
|
||||
public void setBuffer(byte[] buffer) {
|
||||
buf = buffer;
|
||||
count = buffer.length;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,8 @@ package com.topjohnwu.magisk.utils;
|
||||
import android.content.Context;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Utils.ByteArrayInOutStream;
|
||||
|
||||
import org.spongycastle.asn1.ASN1InputStream;
|
||||
import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.spongycastle.asn1.DEROutputStream;
|
||||
@ -81,6 +83,11 @@ public class ZipUtils {
|
||||
|
||||
public native static byte[] zipAdjust(byte[] bytes, int size);
|
||||
|
||||
// Wrapper function for the JNI function
|
||||
public static void adjustZip(ByteArrayInOutStream buffer) {
|
||||
buffer.setBuffer(zipAdjust(buffer.toByteArray(), buffer.size()));
|
||||
}
|
||||
|
||||
public static void removeTopFolder(InputStream in, OutputStream out) {
|
||||
try {
|
||||
JarInputStream source = new JarInputStream(in);
|
||||
@ -482,7 +489,7 @@ public class ZipUtils {
|
||||
private static void copyFiles(Manifest manifest,
|
||||
JarMap in, JarOutputStream out, long timestamp) throws IOException {
|
||||
Map<String, Attributes> entries = manifest.getEntries();
|
||||
ArrayList<String> names = new ArrayList<String>(entries.keySet());
|
||||
ArrayList<String> names = new ArrayList<>(entries.keySet());
|
||||
Collections.sort(names);
|
||||
for (String name : names) {
|
||||
JarEntry inEntry = in.getJarEntry(name);
|
||||
@ -588,10 +595,7 @@ public class ZipUtils {
|
||||
copyFiles(manifest, inputJar, outputJar, timestamp);
|
||||
// Don't add Otacert, it's not an OTA
|
||||
// addOtacert(outputJar, publicKeyFile, timestamp, manifest, hash);
|
||||
signFile(manifest, inputJar,
|
||||
publicKey,
|
||||
privateKey,
|
||||
outputJar);
|
||||
signFile(manifest, inputJar, publicKey, privateKey, outputJar);
|
||||
signer.notifyClosing();
|
||||
outputJar.close();
|
||||
signer.finish();
|
||||
|
Loading…
Reference in New Issue
Block a user