You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Added (ported back) features from initial design [retrofit,moshi,kotpref]
Marked most of the old classes using Networking as deprecated to clearly visualise their future removal
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.collection.ArraySet;
|
||||
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.collection.ArraySet;
|
||||
|
||||
@Deprecated
|
||||
public class Event {
|
||||
|
||||
public static final int MAGISK_HIDE_DONE = 0;
|
||||
@@ -23,8 +24,9 @@ public class Event {
|
||||
public @interface EventID {}
|
||||
|
||||
// We will not dynamically add topics, so use arrays instead of hash tables
|
||||
private static Store[] eventList = new Store[5];
|
||||
private static final Store[] eventList = new Store[5];
|
||||
|
||||
@Deprecated
|
||||
public static void register(Listener listener, @EventID int... events) {
|
||||
for (int event : events) {
|
||||
if (eventList[event] == null)
|
||||
@@ -36,10 +38,12 @@ public class Event {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void register(AutoListener listener) {
|
||||
register(listener, listener.getListeningEvents());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void unregister(Listener listener, @EventID int... events) {
|
||||
for (int event : events) {
|
||||
if (eventList[event] == null)
|
||||
@@ -48,22 +52,27 @@ public class Event {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void unregister(AutoListener listener) {
|
||||
unregister(listener, listener.getListeningEvents());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void trigger(@EventID int event) {
|
||||
trigger(true, event, null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void trigger(@EventID int event, Object result) {
|
||||
trigger(true, event, result);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void trigger(boolean perm, @EventID int event) {
|
||||
trigger(perm, event, null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void trigger(boolean perm, @EventID int event, Object result) {
|
||||
if (eventList[event] == null)
|
||||
eventList[event] = new Store();
|
||||
@@ -76,6 +85,7 @@ public class Event {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void reset(@EventID int event) {
|
||||
if (eventList[event] == null)
|
||||
return;
|
||||
@@ -83,17 +93,20 @@ public class Event {
|
||||
eventList[event].result = null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void reset(AutoListener listener) {
|
||||
for (int event : listener.getListeningEvents())
|
||||
reset(event);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isTriggered(@EventID int event) {
|
||||
if (eventList[event] == null)
|
||||
return false;
|
||||
return eventList[event].triggered;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isTriggered(AutoListener listener) {
|
||||
for (int event : listener.getListeningEvents()) {
|
||||
if (!isTriggered(event))
|
||||
@@ -102,22 +115,26 @@ public class Event {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static <T> T getResult(@EventID int event) {
|
||||
return (T) eventList[event].result;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public interface Listener {
|
||||
void onEvent(int event);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public interface AutoListener extends Listener {
|
||||
@EventID
|
||||
int[] getListeningEvents();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static class Store {
|
||||
boolean triggered = false;
|
||||
Set<Listener> listeners = new ArraySet<>();
|
||||
Object result;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onEvent(int event);
|
||||
}
|
||||
|
||||
public interface AutoListener extends Listener {
|
||||
@EventID
|
||||
int[] getListeningEvents();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.ComponentInfo
|
||||
import android.content.pm.PackageInfo
|
||||
@@ -9,6 +10,7 @@ import android.content.pm.PackageManager.*
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import com.topjohnwu.magisk.App
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
val PackageInfo.processes
|
||||
@@ -74,3 +76,22 @@ fun Context.rawResource(id: Int) = resources.openRawResource(id)
|
||||
|
||||
fun Context.readUri(uri: Uri) = contentResolver.openInputStream(uri) ?: throw FileNotFoundException()
|
||||
|
||||
fun ApplicationInfo.findAppLabel(pm: PackageManager): String {
|
||||
return pm.getApplicationLabel(this)?.toString().orEmpty()
|
||||
}
|
||||
|
||||
fun Intent.startActivity(context: Context) = context.startActivity(this)
|
||||
|
||||
fun File.provide(): Uri {
|
||||
val context: Context by inject()
|
||||
return FileProvider.getUriForFile(context, "com.topjohnwu.magisk.fileprovider", this)
|
||||
}
|
||||
|
||||
fun File.mv(destination: File) {
|
||||
inputStream().copyTo(destination)
|
||||
deleteRecursively()
|
||||
}
|
||||
|
||||
fun String.toFile() = File(this)
|
||||
|
||||
fun Intent.chooser(title: String = "Pick an app") = Intent.createChooser(this, title)
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toFile
|
||||
import org.kamranzafar.jtar.TarInputStream
|
||||
import org.kamranzafar.jtar.TarOutputStream
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
fun ZipInputStream.forEach(callback: (ZipEntry) -> Unit) {
|
||||
var entry: ZipEntry? = nextEntry
|
||||
while (entry != null) {
|
||||
callback(entry)
|
||||
entry = nextEntry
|
||||
}
|
||||
}
|
||||
|
||||
fun Uri.copyTo(file: File) = toFile().copyTo(file)
|
||||
fun InputStream.copyTo(file: File) =
|
||||
withStreams(this, file.outputStream()) { reader, writer -> reader.copyTo(writer) }
|
||||
|
||||
fun File.tarInputStream() = TarInputStream(inputStream())
|
||||
fun File.tarOutputStream() = TarOutputStream(this)
|
||||
|
||||
inline fun <In : InputStream, Out : OutputStream> withStreams(
|
||||
inStream: In,
|
||||
outStream: Out,
|
||||
withBoth: (In, Out) -> Unit
|
||||
) {
|
||||
inStream.use { reader ->
|
||||
outStream.use { writer ->
|
||||
withBoth(reader, writer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import okhttp3.ResponseBody
|
||||
import java.io.File
|
||||
|
||||
fun ResponseBody.writeToFile(context: Context, fileName: String): File {
|
||||
val file = File(context.cacheDir, fileName)
|
||||
withStreams(byteStream(), file.outputStream()) { inStream, outStream ->
|
||||
inStream.copyTo(outStream)
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
fun ResponseBody.writeToString() = string()
|
||||
|
||||
fun String.launch() = if (Config.useCustomTabs) {
|
||||
launchWithCustomTabs()
|
||||
} else {
|
||||
launchWithIntent()
|
||||
}
|
||||
|
||||
|
||||
private fun String.launchWithCustomTabs() {
|
||||
val context: Context by inject()
|
||||
val primaryColor = ContextCompat.getColor(context, R.color.colorPrimary)
|
||||
val secondaryColor = ContextCompat.getColor(context, R.color.colorSecondary)
|
||||
|
||||
CustomTabsIntent.Builder()
|
||||
.enableUrlBarHiding()
|
||||
.setShowTitle(true)
|
||||
.setToolbarColor(primaryColor)
|
||||
.setSecondaryToolbarColor(secondaryColor)
|
||||
.build()
|
||||
.apply { intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK }
|
||||
.launchUrl(context, this.toUri())
|
||||
}
|
||||
|
||||
private fun String.launchWithIntent() {
|
||||
val context: Context by inject()
|
||||
|
||||
Intent(Intent.ACTION_VIEW)
|
||||
.apply {
|
||||
data = toUri()
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
.startActivity(context)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.topjohnwu.superuser.io.SuFileInputStream
|
||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
||||
import java.io.File
|
||||
|
||||
fun reboot(recovery: Boolean = false): Shell.Result {
|
||||
val command = StringBuilder("/system/bin/reboot")
|
||||
.appendIf(recovery) {
|
||||
append(" recovery")
|
||||
}
|
||||
.toString()
|
||||
|
||||
return Shell.su(command).exec()
|
||||
}
|
||||
|
||||
fun File.suOutputStream() = SuFileOutputStream(this)
|
||||
fun File.suInputStream() = SuFileInputStream(this)
|
||||
@@ -8,4 +8,7 @@ fun String.replaceRandomWithSpecial(): String {
|
||||
random = random()
|
||||
} while (random == '.')
|
||||
return replace(random, specialChars.random())
|
||||
}
|
||||
}
|
||||
|
||||
fun StringBuilder.appendIf(condition: Boolean, builder: StringBuilder.() -> Unit) =
|
||||
if (condition) apply(builder) else this
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
|
||||
fun View.setOnViewReadyListener(callback: () -> Unit) = addOnGlobalLayoutListener(true, callback)
|
||||
|
||||
fun View.addOnGlobalLayoutListener(oneShot: Boolean = false, callback: () -> Unit) =
|
||||
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
if (oneShot) viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
callback()
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user