mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-29 07:42:16 +00:00
113 lines
4.2 KiB
Java
113 lines
4.2 KiB
Java
package com.topjohnwu.magisk.utils;
|
|
|
|
import android.os.AsyncTask;
|
|
|
|
import com.topjohnwu.core.App;
|
|
import com.topjohnwu.core.Data;
|
|
import com.topjohnwu.core.utils.RootUtils;
|
|
import com.topjohnwu.core.utils.Utils;
|
|
import com.topjohnwu.magisk.BuildConfig;
|
|
import com.topjohnwu.magisk.R;
|
|
import com.topjohnwu.magisk.components.ProgressNotification;
|
|
import com.topjohnwu.net.Networking;
|
|
import com.topjohnwu.net.ResponseListener;
|
|
import com.topjohnwu.superuser.ShellUtils;
|
|
import com.topjohnwu.utils.JarMap;
|
|
import com.topjohnwu.utils.SignAPK;
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
|
|
import dalvik.system.DexClassLoader;
|
|
|
|
public class DownloadApp {
|
|
|
|
public static void upgrade(String name) {
|
|
dlInstall(name, new PatchPackageName());
|
|
}
|
|
|
|
public static void restore() {
|
|
String name = Utils.fmt("MagiskManager v%s(%d)",
|
|
Data.remoteManagerVersionString, Data.remoteManagerVersionCode);
|
|
dlInstall(name, new RestoreManager());
|
|
}
|
|
|
|
private static void dlInstall(String name, ManagerDownloadListener listener) {
|
|
File apk = new File(App.self.getCacheDir(), "manager.apk");
|
|
ProgressNotification progress = new ProgressNotification(name);
|
|
listener.setProgressNotification(progress);
|
|
Networking.get(Data.managerLink)
|
|
.setExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
|
|
.setDownloadProgressListener(progress)
|
|
.setErrorHandler((conn, e) -> progress.dlFail())
|
|
.getAsFile(listener, apk);
|
|
}
|
|
|
|
abstract static class ManagerDownloadListener implements ResponseListener<File> {
|
|
|
|
private ProgressNotification progress;
|
|
|
|
private void setProgressNotification(ProgressNotification progress) {
|
|
this.progress = progress;
|
|
}
|
|
|
|
public abstract void onDownloadComplete(File apk, ProgressNotification progress);
|
|
|
|
@Override
|
|
public void onResponse(File apk) {
|
|
onDownloadComplete(apk, progress);
|
|
}
|
|
}
|
|
|
|
static class PatchPackageName extends ManagerDownloadListener {
|
|
|
|
@Override
|
|
public void onDownloadComplete(File apk, ProgressNotification progress) {
|
|
File patched = apk;
|
|
App app = App.self;
|
|
if (!App.self.getPackageName().equals(BuildConfig.APPLICATION_ID)) {
|
|
progress.getNotificationBuilder()
|
|
.setProgress(0, 0, true)
|
|
.setContentTitle(app.getString(R.string.hide_manager_title))
|
|
.setContentText("");
|
|
progress.update();
|
|
patched = new File(apk.getParent(), "patched.apk");
|
|
try {
|
|
// Try using the new APK to patch itself
|
|
ClassLoader loader = new DexClassLoader(apk.getPath(),
|
|
apk.getParent(), null, ClassLoader.getSystemClassLoader());
|
|
loader.loadClass("a.a")
|
|
.getMethod("patchAPK", String.class, String.class, String.class)
|
|
.invoke(null, apk.getPath(), patched.getPath(), app.getPackageName());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
// Fallback to use the current implementation
|
|
PatchAPK.patch(apk.getPath(), patched.getPath(), app.getPackageName());
|
|
}
|
|
}
|
|
APKInstall.install(app, patched);
|
|
progress.dismiss();
|
|
}
|
|
}
|
|
|
|
static class RestoreManager extends ManagerDownloadListener {
|
|
|
|
@Override
|
|
public void onDownloadComplete(File apk, ProgressNotification progress) {
|
|
App app = App.self;
|
|
progress.getNotificationBuilder()
|
|
.setProgress(0, 0, true)
|
|
.setContentTitle(app.getString(R.string.restore_img_msg))
|
|
.setContentText("");
|
|
progress.update();
|
|
Data.exportPrefs();
|
|
// Make it world readable
|
|
apk.setReadable(true, false);
|
|
if (ShellUtils.fastCmdResult("pm install " + apk))
|
|
RootUtils.rmAndLaunch(app.getPackageName(), BuildConfig.APPLICATION_ID);
|
|
progress.dismiss();
|
|
}
|
|
}
|
|
}
|