mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-05-02 14:54:25 +02:00
update docs and stuff
This commit is contained in:
parent
33fe3248f4
commit
56ff299fa0
@ -7,7 +7,7 @@ import app.revanced.manager.data.room.AppDatabase
|
||||
import app.revanced.manager.data.room.AppDatabase.Companion.generateUid
|
||||
import app.revanced.manager.data.room.apps.downloaded.DownloadedApp
|
||||
import app.revanced.manager.network.downloader.LoadedDownloaderPlugin
|
||||
import app.revanced.manager.plugin.downloader.DownloadScope
|
||||
import app.revanced.manager.plugin.downloader.OutputDownloadScope
|
||||
import app.revanced.manager.util.PM
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
@ -52,7 +52,7 @@ class DownloadedAppRepository(
|
||||
val downloadedBytes = AtomicLong(0)
|
||||
|
||||
channelFlow {
|
||||
val scope = object : DownloadScope {
|
||||
val scope = object : OutputDownloadScope {
|
||||
override val pluginPackageName = plugin.packageName
|
||||
override val hostPackageName = app.packageName
|
||||
override suspend fun reportSize(size: Long) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package app.revanced.manager.network.downloader
|
||||
|
||||
import android.os.Parcelable
|
||||
import app.revanced.manager.plugin.downloader.DownloadScope
|
||||
import app.revanced.manager.plugin.downloader.OutputDownloadScope
|
||||
import app.revanced.manager.plugin.downloader.GetScope
|
||||
import java.io.OutputStream
|
||||
|
||||
@ -10,6 +10,6 @@ class LoadedDownloaderPlugin(
|
||||
val name: String,
|
||||
val version: String,
|
||||
val get: suspend GetScope.(packageName: String, version: String?) -> Pair<Parcelable, String?>?,
|
||||
val download: suspend DownloadScope.(data: Parcelable, outputStream: OutputStream) -> Unit,
|
||||
val download: suspend OutputDownloadScope.(data: Parcelable, outputStream: OutputStream) -> Unit,
|
||||
val classLoader: ClassLoader
|
||||
)
|
@ -5,6 +5,32 @@ public final class app/revanced/manager/plugin/downloader/ConstantsKt {
|
||||
public static final field PLUGIN_HOST_PERMISSION Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/DownloadUrl : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/util/Map;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/util/Map;
|
||||
public final fun copy (Ljava/lang/String;Ljava/util/Map;)Lapp/revanced/manager/plugin/downloader/DownloadUrl;
|
||||
public static synthetic fun copy$default (Lapp/revanced/manager/plugin/downloader/DownloadUrl;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/revanced/manager/plugin/downloader/DownloadUrl;
|
||||
public final fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getHeaders ()Ljava/util/Map;
|
||||
public final fun getUrl ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public final fun toDownloadResult ()Lkotlin/Pair;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public final fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/DownloadUrl$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lapp/revanced/manager/plugin/downloader/DownloadUrl;
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lapp/revanced/manager/plugin/downloader/DownloadUrl;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/Downloader {
|
||||
}
|
||||
|
||||
@ -94,31 +120,6 @@ public final class app/revanced/manager/plugin/downloader/webview/APIKt {
|
||||
public static final fun runWebView (Lapp/revanced/manager/plugin/downloader/GetScope;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/webview/DownloadUrl : android/os/Parcelable {
|
||||
public static final field CREATOR Landroid/os/Parcelable$Creator;
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lapp/revanced/manager/plugin/downloader/webview/DownloadUrl;
|
||||
public static synthetic fun copy$default (Lapp/revanced/manager/plugin/downloader/webview/DownloadUrl;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/revanced/manager/plugin/downloader/webview/DownloadUrl;
|
||||
public final fun describeContents ()I
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getUrl ()Ljava/lang/String;
|
||||
public final fun getUserAgent ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public final fun toResult ()Lkotlin/Pair;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public final fun writeToParcel (Landroid/os/Parcel;I)V
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/webview/DownloadUrl$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lapp/revanced/manager/plugin/downloader/webview/DownloadUrl;
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lapp/revanced/manager/plugin/downloader/webview/DownloadUrl;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public abstract interface class app/revanced/manager/plugin/downloader/webview/IWebView : android/os/IInterface {
|
||||
public static final field DESCRIPTOR Ljava/lang/String;
|
||||
public abstract fun finish ()V
|
||||
@ -162,12 +163,19 @@ public abstract class app/revanced/manager/plugin/downloader/webview/IWebViewEve
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/webview/WebViewActivity : androidx/activity/ComponentActivity {
|
||||
public static final field BINDER_KEY Ljava/lang/String;
|
||||
public static final field TITLE_KEY Ljava/lang/String;
|
||||
public static final field KEY Ljava/lang/String;
|
||||
public fun <init> ()V
|
||||
public fun onOptionsItemSelected (Landroid/view/MenuItem;)Z
|
||||
}
|
||||
|
||||
public final class app/revanced/manager/plugin/downloader/webview/WebViewActivity$Parameters$Creator : android/os/Parcelable$Creator {
|
||||
public fun <init> ()V
|
||||
public final fun createFromParcel (Landroid/os/Parcel;)Lapp/revanced/manager/plugin/downloader/webview/WebViewActivity$Parameters;
|
||||
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
|
||||
public final fun newArray (I)[Lapp/revanced/manager/plugin/downloader/webview/WebViewActivity$Parameters;
|
||||
public synthetic fun newArray (I)[Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public abstract interface class app/revanced/manager/plugin/downloader/webview/WebViewCallbackScope : app/revanced/manager/plugin/downloader/Scope {
|
||||
public abstract fun finish (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun load (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@ -176,7 +184,9 @@ public abstract interface class app/revanced/manager/plugin/downloader/webview/W
|
||||
public final class app/revanced/manager/plugin/downloader/webview/WebViewScope : app/revanced/manager/plugin/downloader/Scope {
|
||||
public final fun download (Lkotlin/jvm/functions/Function5;)V
|
||||
public fun getHostPackageName ()Ljava/lang/String;
|
||||
public final fun getJsEnabled ()Z
|
||||
public fun getPluginPackageName ()Ljava/lang/String;
|
||||
public final fun pageLoad (Lkotlin/jvm/functions/Function3;)V
|
||||
public final fun setJsEnabled (Z)V
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
package app.revanced.manager.plugin.downloader
|
||||
|
||||
/**
|
||||
* The permission ID of the special plugin host permission. Only ReVanced Manager will have this permission.
|
||||
* Plugin UI activities and internal services can be protected using this permission.
|
||||
*/
|
||||
const val PLUGIN_HOST_PERMISSION = "app.revanced.manager.permission.PLUGIN_HOST"
|
@ -40,7 +40,7 @@ interface Scope {
|
||||
*/
|
||||
interface GetScope : Scope {
|
||||
/**
|
||||
* Ask the user to perform some required interaction contained in the activity specified by the provided [Intent].
|
||||
* Ask the user to perform some required interaction in the activity specified by the provided [Intent].
|
||||
* This function returns normally with the resulting [Intent] when the activity finishes with code [Activity.RESULT_OK].
|
||||
*
|
||||
* @throws UserInteractionException.RequestDenied User decided to skip this plugin.
|
||||
@ -74,7 +74,7 @@ class DownloaderScope<T : Parcelable> internal constructor(
|
||||
private val inputDownloadScopeImpl = object : InputDownloadScope, Scope by scopeImpl {}
|
||||
|
||||
/**
|
||||
* Define the download function for this plugin.
|
||||
* Define the download block of the plugin.
|
||||
*/
|
||||
fun download(block: suspend InputDownloadScope.(data: T) -> DownloadResult) {
|
||||
download = { app, outputStream ->
|
||||
@ -88,7 +88,8 @@ class DownloaderScope<T : Parcelable> internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the get function for this plugin.
|
||||
* Define the get block of the plugin.
|
||||
* The block should return null if the app cannot be found. The version in the result must match the version argument unless it is null.
|
||||
*/
|
||||
fun get(block: suspend GetScope.(packageName: String, version: String?) -> GetResult<T>?) {
|
||||
get = block
|
||||
@ -139,14 +140,25 @@ class Downloader<T : Parcelable> internal constructor(
|
||||
@property:PluginHostApi val download: suspend OutputDownloadScope.(data: T, outputStream: OutputStream) -> Unit
|
||||
)
|
||||
|
||||
/**
|
||||
* Define a downloader plugin.
|
||||
*/
|
||||
fun <T : Parcelable> Downloader(block: DownloaderScope<T>.() -> Unit) = DownloaderBuilder(block)
|
||||
|
||||
/**
|
||||
* @see GetScope.requestStartActivity
|
||||
*/
|
||||
sealed class UserInteractionException(message: String) : Exception(message) {
|
||||
class RequestDenied @PluginHostApi constructor() :
|
||||
UserInteractionException("Request was denied")
|
||||
UserInteractionException("Request denied by user")
|
||||
|
||||
sealed class Activity(message: String) : UserInteractionException(message) {
|
||||
class Cancelled @PluginHostApi constructor() : Activity("Interaction was cancelled")
|
||||
class Cancelled @PluginHostApi constructor() : Activity("Interaction cancelled")
|
||||
|
||||
/**
|
||||
* @param resultCode The result code of the activity.
|
||||
* @param intent The [Intent] of the activity.
|
||||
*/
|
||||
class NotCompleted @PluginHostApi constructor(val resultCode: Int, val intent: Intent?) :
|
||||
Activity("Unexpected activity result code: $resultCode")
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import android.os.Parcelable
|
||||
import java.io.OutputStream
|
||||
|
||||
/**
|
||||
* The scope of [DownloaderScope.download].
|
||||
* The scope of the [OutputStream] version of [DownloaderScope.download].
|
||||
*/
|
||||
interface OutputDownloadScope : BaseDownloadScope {
|
||||
suspend fun reportSize(size: Long)
|
||||
@ -16,6 +16,7 @@ interface OutputDownloadScope : BaseDownloadScope {
|
||||
|
||||
/**
|
||||
* A replacement for [DownloaderScope.download] that uses [OutputStream].
|
||||
* The provided [OutputStream] does not need to be closed manually.
|
||||
*/
|
||||
fun <T : Parcelable> DownloaderScope<T>.download(block: suspend OutputDownloadScope.(T, OutputStream) -> Unit) {
|
||||
download = block
|
||||
|
@ -1,7 +0,0 @@
|
||||
package app.revanced.manager.plugin.downloader
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class Package(val name: String, val version: String) : Parcelable
|
@ -0,0 +1,39 @@
|
||||
package app.revanced.manager.plugin.downloader
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URI
|
||||
|
||||
/**
|
||||
* A simple parcelable data class for storing a package name and version.
|
||||
* This can be used as the data type for plugins that only need a name and version to implement their [DownloaderScope.download] function.
|
||||
*
|
||||
* @param name The package name.
|
||||
* @param version The version.
|
||||
*/
|
||||
@Parcelize
|
||||
data class Package(val name: String, val version: String) : Parcelable
|
||||
|
||||
/**
|
||||
* A data class for storing a download URL.
|
||||
*
|
||||
* @param url The download URL.
|
||||
* @param headers The headers to use for the request.
|
||||
*/
|
||||
@Parcelize
|
||||
data class DownloadUrl(val url: String, val headers: Map<String, String> = emptyMap()) : Parcelable {
|
||||
/**
|
||||
* Converts this into a [DownloadResult].
|
||||
*/
|
||||
fun toDownloadResult(): DownloadResult = with(URI.create(url).toURL().openConnection() as HttpURLConnection) {
|
||||
useCaches = false
|
||||
allowUserInteraction = false
|
||||
headers.forEach(::setRequestProperty)
|
||||
|
||||
connectTimeout = 10_000
|
||||
connect()
|
||||
|
||||
inputStream to getHeaderField("Content-Length").toLong()
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package app.revanced.manager.plugin.downloader.webview
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import app.revanced.manager.plugin.downloader.DownloadUrl
|
||||
import app.revanced.manager.plugin.downloader.DownloaderScope
|
||||
import app.revanced.manager.plugin.downloader.GetScope
|
||||
import app.revanced.manager.plugin.downloader.Scope
|
||||
@ -14,35 +14,12 @@ import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URI
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
typealias InitialUrl = String
|
||||
typealias PageLoadCallback<T> = suspend WebViewCallbackScope<T>.(url: String) -> Unit
|
||||
typealias DownloadCallback<T> = suspend WebViewCallbackScope<T>.(url: String, mimeType: String, userAgent: String) -> Unit
|
||||
|
||||
@Parcelize
|
||||
/**
|
||||
* A data class for storing a download
|
||||
*/
|
||||
data class DownloadUrl(val url: String, val userAgent: String?) : Parcelable {
|
||||
/**
|
||||
* Converts this into a [app.revanced.manager.plugin.downloader.DownloadResult].
|
||||
*/
|
||||
fun toResult() = with(URI.create(url).toURL().openConnection() as HttpURLConnection) {
|
||||
useCaches = false
|
||||
allowUserInteraction = false
|
||||
userAgent?.let { setRequestProperty("User-Agent", it) }
|
||||
|
||||
connectTimeout = 10_000
|
||||
connect()
|
||||
|
||||
inputStream to getHeaderField("Content-Length").toLong()
|
||||
}
|
||||
}
|
||||
|
||||
interface WebViewCallbackScope<T> : Scope {
|
||||
/**
|
||||
* Finishes the activity and returns the [result].
|
||||
@ -68,6 +45,12 @@ class WebViewScope<T> internal constructor(
|
||||
private lateinit var webView: IWebView
|
||||
internal lateinit var initialUrl: String
|
||||
|
||||
/**
|
||||
* Controls whether JavaScript is enabled in the WebView. The default value is false.
|
||||
* Changing this after the WebView has been launched has no effect.
|
||||
*/
|
||||
var jsEnabled = false
|
||||
|
||||
internal val binder = object : IWebViewEvents.Stub() {
|
||||
override fun ready(iface: IWebView?) {
|
||||
coroutineScope.launch(dispatcher) {
|
||||
@ -107,7 +90,7 @@ class WebViewScope<T> internal constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the WebView attempts to navigate to a downloadable file.
|
||||
* Called when the WebView attempts to download a file to disk.
|
||||
*/
|
||||
fun download(block: DownloadCallback<T>) {
|
||||
onDownloadCallback = block
|
||||
@ -127,9 +110,10 @@ private value class Container<U>(val value: U)
|
||||
/**
|
||||
* Run a [android.webkit.WebView] Activity controlled by the provided code block.
|
||||
* The activity will keep running until it is cancelled or an event handler calls [WebViewCallbackScope.finish].
|
||||
* The [block] defines the event handlers and returns the initial URL.
|
||||
*
|
||||
* @param title The string displayed in the action bar
|
||||
* @param block Defines event handlers and returns an initial URL
|
||||
* @param title The string displayed in the action bar.
|
||||
* @param block The control block.
|
||||
*/
|
||||
suspend fun <T> GetScope.runWebView(
|
||||
title: String,
|
||||
@ -140,12 +124,12 @@ suspend fun <T> GetScope.runWebView(
|
||||
val scope = WebViewScope<T>(this@supervisorScope, this@runWebView) { result = Container(it) }
|
||||
scope.initialUrl = scope.block()
|
||||
|
||||
// Start the webview activity and wait until it finishes
|
||||
// Start the webview activity and wait until it finishes.
|
||||
requestStartActivity(Intent().apply {
|
||||
putExtras(Bundle().apply {
|
||||
putBinder(WebViewActivity.BINDER_KEY, scope.binder)
|
||||
putString(WebViewActivity.TITLE_KEY, title)
|
||||
})
|
||||
putExtra(
|
||||
WebViewActivity.KEY,
|
||||
WebViewActivity.Parameters(title, scope.jsEnabled, scope.binder)
|
||||
)
|
||||
setClassName(
|
||||
hostPackageName,
|
||||
WebViewActivity::class.qualifiedName!!
|
||||
@ -174,7 +158,14 @@ fun WebViewDownloader(block: suspend WebViewScope<DownloadUrl>.(packageName: Str
|
||||
|
||||
try {
|
||||
runWebView(label) {
|
||||
download { url, _, userAgent -> finish(DownloadUrl(url, userAgent)) }
|
||||
download { url, _, userAgent ->
|
||||
finish(
|
||||
DownloadUrl(
|
||||
url,
|
||||
mapOf("User-Agent" to userAgent)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
block(this@runWebView, packageName, version) ?: throw ReturnNull()
|
||||
} to version
|
||||
@ -184,6 +175,6 @@ fun WebViewDownloader(block: suspend WebViewScope<DownloadUrl>.(packageName: Str
|
||||
}
|
||||
|
||||
download {
|
||||
it.toResult()
|
||||
it.toDownloadResult()
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package app.revanced.manager.plugin.downloader.webview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.os.Parcelable
|
||||
import android.view.MenuItem
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebSettings
|
||||
@ -21,6 +23,7 @@ import app.revanced.manager.plugin.downloader.R
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
class WebViewActivity : ComponentActivity() {
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@ -36,22 +39,23 @@ class WebViewActivity : ComponentActivity() {
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
val params = intent.getParcelableExtra<Parameters>(KEY)!!
|
||||
actionBar?.apply {
|
||||
title = intent.getStringExtra(TITLE_KEY)
|
||||
title = intent.getStringExtra(params.title)
|
||||
setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel)
|
||||
setDisplayHomeAsUpEnabled(true)
|
||||
}
|
||||
|
||||
val events = IWebViewEvents.Stub.asInterface(intent.extras!!.getBinder(BINDER_KEY))!!
|
||||
val events = IWebViewEvents.Stub.asInterface(params.events)!!
|
||||
vm.setup(events)
|
||||
|
||||
val webView = findViewById<WebView>(R.id.content).apply {
|
||||
settings.apply {
|
||||
cacheMode = WebSettings.LOAD_NO_CACHE
|
||||
databaseEnabled = false
|
||||
allowContentAccess = true
|
||||
allowContentAccess = false
|
||||
domStorageEnabled = false
|
||||
javaScriptEnabled = true
|
||||
javaScriptEnabled = params.jsEnabled
|
||||
}
|
||||
|
||||
webViewClient = vm.webViewClient
|
||||
@ -82,9 +86,13 @@ class WebViewActivity : ComponentActivity() {
|
||||
true
|
||||
} else super.onOptionsItemSelected(item)
|
||||
|
||||
@Parcelize
|
||||
internal class Parameters(
|
||||
val title: String, val jsEnabled: Boolean, val events: IBinder
|
||||
) : Parcelable
|
||||
|
||||
internal companion object {
|
||||
const val BINDER_KEY = "EVENTS"
|
||||
const val TITLE_KEY = "TITLE"
|
||||
const val KEY = "params"
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user