From a0cfce7cbc641a6a9d2f65e72993bea3418b9373 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 3 May 2019 04:42:57 -0400 Subject: [PATCH] Rewrite FlashZip in Kotlin --- .../com/topjohnwu/magisk/tasks/FlashZip.java | 85 ------------------- .../com/topjohnwu/magisk/tasks/FlashZip.kt | 73 ++++++++++++++++ .../com/topjohnwu/magisk/utils/Utils.java | 18 ---- .../com/topjohnwu/magisk/utils/XAndroid.kt | 23 +++++ .../com/topjohnwu/magisk/utils/ZipUtils.kt | 1 - .../topjohnwu/magisk/view/SnackbarMaker.java | 8 +- 6 files changed, 100 insertions(+), 108 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.kt diff --git a/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.java b/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.java deleted file mode 100644 index c7ffc74a9..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.topjohnwu.magisk.tasks; - -import android.net.Uri; - -import com.topjohnwu.magisk.App; -import com.topjohnwu.magisk.Const; -import com.topjohnwu.magisk.utils.Utils; -import com.topjohnwu.magisk.utils.ZipUtilsKt; -import com.topjohnwu.superuser.Shell; -import com.topjohnwu.superuser.ShellUtils; -import com.topjohnwu.superuser.internal.UiThreadHandler; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.List; - -public abstract class FlashZip { - - private Uri mUri; - private File tmpFile; - private List console, logs; - - public FlashZip(Uri uri, List out, List err) { - mUri = uri; - console = out; - logs = err; - tmpFile = new File(App.self.getCacheDir(), "install.zip"); - } - - private boolean unzipAndCheck() throws IOException { - ZipUtilsKt.unzip(tmpFile, tmpFile.getParentFile(), "META-INF/com/google/android", true); - return Shell.su("grep -q '#MAGISK' " + new File(tmpFile.getParentFile(), "updater-script")) - .exec().isSuccess(); - } - - private boolean flash() throws IOException { - console.add("- Copying zip to temp directory"); - try (InputStream in = App.self.getContentResolver().openInputStream(mUri); - OutputStream out = new BufferedOutputStream(new FileOutputStream(tmpFile))) { - if (in == null) throw new FileNotFoundException(); - InputStream buf= new BufferedInputStream(in); - ShellUtils.pump(buf, out); - } catch (FileNotFoundException e) { - console.add("! Invalid Uri"); - throw e; - } catch (IOException e) { - console.add("! Cannot copy to cache"); - throw e; - } - try { - if (!unzipAndCheck()) { - console.add("! This zip is not a Magisk Module!"); - return false; - } - } catch (IOException e) { - console.add("! Unzip error"); - throw e; - } - console.add("- Installing " + Utils.getNameFromUri(App.self, mUri)); - return Shell.su("cd " + tmpFile.getParent(), - "BOOTMODE=true sh update-binary dummy 1 " + tmpFile) - .to(console, logs) - .exec().isSuccess(); - } - - public void exec() { - App.THREAD_POOL.execute(() -> { - boolean success = false; - try { - success = flash(); - } catch (IOException ignored) {} - Shell.su("cd /", "rm -rf " + tmpFile.getParent() + " " + Const.TMP_FOLDER_PATH).submit(); - boolean finalSuccess = success; - UiThreadHandler.run(() -> onResult(finalSuccess)); - }); - } - - protected abstract void onResult(boolean success); -} diff --git a/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.kt b/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.kt new file mode 100644 index 000000000..0594dc2bb --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/tasks/FlashZip.kt @@ -0,0 +1,73 @@ +package com.topjohnwu.magisk.tasks + +import android.net.Uri + +import com.topjohnwu.magisk.App +import com.topjohnwu.magisk.Const +import com.topjohnwu.magisk.utils.* +import com.topjohnwu.superuser.Shell +import com.topjohnwu.superuser.internal.UiThreadHandler + +import java.io.File +import java.io.FileNotFoundException +import java.io.IOException + +abstract class FlashZip(private val mUri: Uri, + private val console: MutableList, + private val logs: MutableList) { + + private val tmpFile: File = File(App.self.cacheDir, "install.zip") + + @Throws(IOException::class) + private fun unzipAndCheck(): Boolean { + unzip(tmpFile, tmpFile.parentFile!!, "META-INF/com/google/android", true) + return Shell.su("grep -q '#MAGISK' ${File(tmpFile.parentFile, "updater-script")}") + .exec().isSuccess + } + + @Throws(IOException::class) + private fun flash(): Boolean { + console.add("- Copying zip to temp directory") + try { + App.self.readUri(mUri).use { input -> + tmpFile.outputStream().use { out -> input.copyTo(out) } + } + } catch (e: FileNotFoundException) { + console.add("! Invalid Uri") + throw e + } catch (e: IOException) { + console.add("! Cannot copy to cache") + throw e + } + + try { + if (!unzipAndCheck()) { + console.add("! This zip is not a Magisk Module!") + return false + } + } catch (e: IOException) { + console.add("! Unzip error") + throw e + } + + console.add("- Installing ${mUri.fileName}") + return Shell.su("cd " + tmpFile.parent!!, + "BOOTMODE=true sh update-binary dummy 1 $tmpFile") + .to(console, logs) + .exec().isSuccess + } + + fun exec() { + App.THREAD_POOL.execute { + val success = try { + flash() + } catch (e: IOException) { + false + } + Shell.su("cd /", "rm -rf ${tmpFile.parent} ${Const.TMP_FOLDER_PATH}").submit() + UiThreadHandler.run { onResult(success) } + } + } + + protected abstract fun onResult(success: Boolean) +} diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index 562fcadf0..83c686696 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -58,24 +58,6 @@ public class Utils { return getPrefsInt(prefs, key, 0); } - public static String getNameFromUri(Context context, Uri uri) { - String name = null; - try (Cursor c = context.getContentResolver().query(uri, null, null, null, null)) { - if (c != null) { - int nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME); - if (nameIndex != -1) { - c.moveToFirst(); - name = c.getString(nameIndex); - } - } - } - if (name == null) { - int idx = uri.getPath().lastIndexOf('/'); - name = uri.getPath().substring(idx + 1); - } - return name; - } - public static int dpInPx(int dp) { float scale = App.self.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5); diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/XAndroid.kt b/app/src/main/java/com/topjohnwu/magisk/utils/XAndroid.kt index e722bd134..0db67d30b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/XAndroid.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/XAndroid.kt @@ -6,6 +6,10 @@ import android.content.pm.ComponentInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.content.pm.PackageManager.* +import android.net.Uri +import android.provider.OpenableColumns +import com.topjohnwu.magisk.App +import java.io.FileNotFoundException val PackageInfo.processes get() = activities?.processNames.orEmpty() + @@ -38,6 +42,22 @@ val ApplicationInfo.packageInfo: PackageInfo? } } +val Uri.fileName: String get() { + var name: String? = null + App.self.contentResolver.query(this, null, null, null, null)?.use { c -> + val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME) + if (nameIndex != -1) { + c.moveToFirst() + name = c.getString(nameIndex) + } + } + if (name == null && path != null) { + val idx = path!!.lastIndexOf('/') + name = path!!.substring(idx + 1) + } + return name.orEmpty() +} + fun PackageManager.activities(packageName: String) = getPackageInfo(packageName, GET_ACTIVITIES) @@ -51,3 +71,6 @@ fun PackageManager.providers(packageName: String) = getPackageInfo(packageName, GET_PROVIDERS).providers fun Context.rawResource(id: Int) = resources.openRawResource(id) + +fun Context.readUri(uri: Uri) = contentResolver.openInputStream(uri) ?: throw FileNotFoundException() + diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.kt b/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.kt index 956bf2184..80a90a13a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/ZipUtils.kt @@ -9,7 +9,6 @@ import java.util.zip.ZipEntry import java.util.zip.ZipInputStream @Throws(IOException::class) -@JvmOverloads fun unzip(zip: File, folder: File, path: String = "", junkPath: Boolean = false) { zip.inputStream().buffered().use { unzip(it, folder, path, junkPath) diff --git a/app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java b/app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java index dc0f1ca61..5884824e1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java +++ b/app/src/main/java/com/topjohnwu/magisk/view/SnackbarMaker.java @@ -5,11 +5,11 @@ import android.net.Uri; import android.view.View; import android.widget.TextView; +import androidx.annotation.StringRes; + import com.google.android.material.snackbar.Snackbar; import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.utils.Utils; - -import androidx.annotation.StringRes; +import com.topjohnwu.magisk.utils.XAndroidKt; public class SnackbarMaker { @@ -41,7 +41,7 @@ public class SnackbarMaker { public static void showUri(Activity activity, Uri uri) { make(activity, activity.getString(R.string.internal_storage, - "/Download/" + Utils.getNameFromUri(activity, uri)), + "/Download/" + XAndroidKt.getFileName(uri)), Snackbar.LENGTH_LONG) .setAction(R.string.ok, (v)->{}).show(); }