Magisk/app/src/full/java/com/topjohnwu/magisk/asyncs/ProcessRepoZip.java

197 lines
6.5 KiB
Java
Raw Normal View History

2017-02-15 05:24:02 +08:00
package com.topjohnwu.magisk.asyncs;
import android.Manifest;
2017-02-15 05:24:02 +08:00
import android.app.ProgressDialog;
2017-07-18 00:59:22 +08:00
import android.content.Intent;
2017-02-15 05:24:02 +08:00
import android.net.Uri;
import android.support.annotation.NonNull;
2017-02-15 05:24:02 +08:00
import android.widget.Toast;
2018-07-31 17:42:35 +08:00
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
2017-07-18 00:59:22 +08:00
import com.topjohnwu.magisk.FlashActivity;
2017-02-15 05:24:02 +08:00
import com.topjohnwu.magisk.R;
2018-08-01 17:57:11 +08:00
import com.topjohnwu.magisk.components.BaseActivity;
2018-06-02 22:00:52 +08:00
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Repo;
2018-07-30 20:37:00 +08:00
import com.topjohnwu.magisk.utils.Download;
2018-07-31 17:41:54 +08:00
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebService;
2017-02-15 05:24:02 +08:00
import com.topjohnwu.magisk.utils.ZipUtils;
2018-01-21 06:07:24 +08:00
import com.topjohnwu.superuser.Shell;
2018-02-12 23:07:35 +08:00
import com.topjohnwu.superuser.ShellUtils;
2017-02-15 05:24:02 +08:00
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
2017-12-01 11:42:05 +08:00
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
2017-02-15 05:24:02 +08:00
import java.io.OutputStream;
2017-10-01 01:12:45 +08:00
import java.net.HttpURLConnection;
2017-10-04 22:27:14 +08:00
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
2017-02-15 05:24:02 +08:00
public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
2017-02-15 05:24:02 +08:00
private ProgressDialog progressDialog;
2017-02-16 17:50:36 +08:00
private boolean mInstall;
private File mFile;
private Repo mRepo;
2017-10-13 03:25:56 +08:00
private int progress = 0, total = -1;
2017-02-15 05:24:02 +08:00
public ProcessRepoZip(BaseActivity context, Repo repo, boolean install) {
2017-02-15 05:24:02 +08:00
super(context);
mRepo = repo;
mInstall = install && Shell.rootAccess();
mFile = new File(Download.EXTERNAL_PATH, repo.getDownloadFilename());
2017-02-15 05:24:02 +08:00
}
private void removeTopFolder(File input, File output) throws IOException {
2017-10-04 22:27:14 +08:00
JarEntry entry;
try (
JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(input)));
JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output)))
) {
String path;
while ((entry = in.getNextJarEntry()) != null) {
// Remove the top directory from the path
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
// If it's the top folder, ignore it
if (path.isEmpty()) {
continue;
}
// Don't include placeholder
if (path.equals("system/placeholder")) {
continue;
}
out.putNextEntry(new JarEntry(path));
2018-02-12 23:07:35 +08:00
ShellUtils.pump(in, out);
2017-10-04 22:27:14 +08:00
}
}
}
2018-07-30 20:37:00 +08:00
@Override
2018-08-01 17:57:11 +08:00
protected BaseActivity getActivity() {
return (BaseActivity) super.getActivity();
2018-07-30 20:37:00 +08:00
}
2017-02-15 05:24:02 +08:00
@Override
protected void onPreExecute() {
2018-08-01 17:57:11 +08:00
BaseActivity activity = getActivity();
mFile.getParentFile().mkdirs();
progressDialog = ProgressDialog.show(activity, activity.getString(R.string.zip_download_title), activity.getString(R.string.zip_download_msg, 0));
}
2017-02-15 05:24:02 +08:00
@Override
protected Boolean doInBackground(Void... params) {
2018-08-01 17:57:11 +08:00
BaseActivity activity = getActivity();
if (activity == null) return null;
2017-02-15 05:24:02 +08:00
try {
// Request zip from Internet
HttpURLConnection conn = WebService.mustRequest(mRepo.getZipUrl(), null);
2018-07-29 22:58:22 +08:00
total = conn.getContentLength();
2017-10-13 03:25:56 +08:00
// Temp files
2017-07-19 16:10:17 +08:00
File temp1 = new File(activity.getCacheDir(), "1.zip");
File temp2 = new File(temp1.getParentFile(), "2.zip");
temp1.getParentFile().mkdir();
// First download the zip, Web -> temp1
try (
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
) {
2018-02-12 23:07:35 +08:00
ShellUtils.pump(in, out);
in.close();
}
2017-10-01 01:12:45 +08:00
conn.disconnect();
Data.mainHandler.post(() -> {
2017-11-09 02:12:55 +08:00
progressDialog.setTitle(R.string.zip_process_title);
progressDialog.setMessage(getActivity().getString(R.string.zip_process_msg));
});
2017-02-15 05:24:02 +08:00
// First remove top folder in Github source zip, temp1 -> temp2
removeTopFolder(temp1, temp2);
2018-01-27 08:23:02 +08:00
// Then sign the zip
ZipUtils.signZip(temp2, mFile);
// Delete temp files
temp1.delete();
temp2.delete();
2017-02-15 05:24:02 +08:00
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
2018-08-01 17:57:11 +08:00
BaseActivity activity = getActivity();
if (activity == null) return;
2017-02-15 05:24:02 +08:00
progressDialog.dismiss();
if (result) {
Uri uri = Uri.fromFile(mFile);
if (mInstall) {
2017-11-06 04:41:23 +08:00
Intent intent = new Intent(activity, FlashActivity.class);
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
2017-08-31 03:07:33 +08:00
activity.startActivity(intent);
} else {
2018-06-02 22:00:52 +08:00
SnackbarMaker.showUri(activity, uri);
}
2017-02-15 05:24:02 +08:00
} else {
2018-07-31 17:41:54 +08:00
Utils.toast(R.string.process_error, Toast.LENGTH_LONG);
2017-02-15 05:24:02 +08:00
}
2017-08-31 03:07:33 +08:00
super.onPostExecute(result);
2017-02-15 05:24:02 +08:00
}
@Override
public void exec(Void... voids) {
2018-07-30 20:37:00 +08:00
getActivity().runWithPermission(
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, super::exec);
}
2017-12-01 11:42:05 +08:00
private class ProgressInputStream extends FilterInputStream {
2017-10-13 20:47:14 +08:00
ProgressInputStream(InputStream in) {
super(in);
}
2017-11-09 02:12:55 +08:00
private void updateDlProgress(int step) {
progress += step;
2018-07-29 22:58:22 +08:00
progressDialog.setMessage(getActivity().getString(R.string.zip_download_msg,
(int) (100 * (double) progress / total + 0.5)));
2017-11-09 02:12:55 +08:00
}
@Override
public synchronized int read() throws IOException {
2017-11-09 02:12:55 +08:00
int b = super.read();
if (b > 0) {
Data.mainHandler.post(() -> updateDlProgress(1));
2017-11-09 02:12:55 +08:00
}
return b;
}
@Override
public int read(@NonNull byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public synchronized int read(@NonNull byte[] b, int off, int len) throws IOException {
int read = super.read(b, off, len);
2017-11-09 02:12:55 +08:00
if (read > 0) {
Data.mainHandler.post(() -> updateDlProgress(read));
2017-11-09 02:12:55 +08:00
}
return read;
}
}
2017-02-15 05:24:02 +08:00
}