mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-05-02 23:04: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.AppDatabase.Companion.generateUid
|
||||||
import app.revanced.manager.data.room.apps.downloaded.DownloadedApp
|
import app.revanced.manager.data.room.apps.downloaded.DownloadedApp
|
||||||
import app.revanced.manager.network.downloader.LoadedDownloaderPlugin
|
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 app.revanced.manager.util.PM
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.channelFlow
|
import kotlinx.coroutines.flow.channelFlow
|
||||||
@ -52,7 +52,7 @@ class DownloadedAppRepository(
|
|||||||
val downloadedBytes = AtomicLong(0)
|
val downloadedBytes = AtomicLong(0)
|
||||||
|
|
||||||
channelFlow {
|
channelFlow {
|
||||||
val scope = object : DownloadScope {
|
val scope = object : OutputDownloadScope {
|
||||||
override val pluginPackageName = plugin.packageName
|
override val pluginPackageName = plugin.packageName
|
||||||
override val hostPackageName = app.packageName
|
override val hostPackageName = app.packageName
|
||||||
override suspend fun reportSize(size: Long) {
|
override suspend fun reportSize(size: Long) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package app.revanced.manager.network.downloader
|
package app.revanced.manager.network.downloader
|
||||||
|
|
||||||
import android.os.Parcelable
|
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 app.revanced.manager.plugin.downloader.GetScope
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
@ -10,6 +10,6 @@ class LoadedDownloaderPlugin(
|
|||||||
val name: String,
|
val name: String,
|
||||||
val version: String,
|
val version: String,
|
||||||
val get: suspend GetScope.(packageName: String, version: String?) -> Pair<Parcelable, 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
|
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 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 {
|
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 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 abstract interface class app/revanced/manager/plugin/downloader/webview/IWebView : android/os/IInterface {
|
||||||
public static final field DESCRIPTOR Ljava/lang/String;
|
public static final field DESCRIPTOR Ljava/lang/String;
|
||||||
public abstract fun finish ()V
|
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 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 KEY Ljava/lang/String;
|
||||||
public static final field TITLE_KEY Ljava/lang/String;
|
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun onOptionsItemSelected (Landroid/view/MenuItem;)Z
|
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 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 finish (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public abstract fun load (Ljava/lang/String;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 class app/revanced/manager/plugin/downloader/webview/WebViewScope : app/revanced/manager/plugin/downloader/Scope {
|
||||||
public final fun download (Lkotlin/jvm/functions/Function5;)V
|
public final fun download (Lkotlin/jvm/functions/Function5;)V
|
||||||
public fun getHostPackageName ()Ljava/lang/String;
|
public fun getHostPackageName ()Ljava/lang/String;
|
||||||
|
public final fun getJsEnabled ()Z
|
||||||
public fun getPluginPackageName ()Ljava/lang/String;
|
public fun getPluginPackageName ()Ljava/lang/String;
|
||||||
public final fun pageLoad (Lkotlin/jvm/functions/Function3;)V
|
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
|
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"
|
const val PLUGIN_HOST_PERMISSION = "app.revanced.manager.permission.PLUGIN_HOST"
|
@ -40,7 +40,7 @@ interface Scope {
|
|||||||
*/
|
*/
|
||||||
interface GetScope : 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].
|
* 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.
|
* @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 {}
|
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) {
|
fun download(block: suspend InputDownloadScope.(data: T) -> DownloadResult) {
|
||||||
download = { app, outputStream ->
|
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>?) {
|
fun get(block: suspend GetScope.(packageName: String, version: String?) -> GetResult<T>?) {
|
||||||
get = block
|
get = block
|
||||||
@ -139,14 +140,25 @@ class Downloader<T : Parcelable> internal constructor(
|
|||||||
@property:PluginHostApi val download: suspend OutputDownloadScope.(data: T, outputStream: OutputStream) -> Unit
|
@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)
|
fun <T : Parcelable> Downloader(block: DownloaderScope<T>.() -> Unit) = DownloaderBuilder(block)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see GetScope.requestStartActivity
|
||||||
|
*/
|
||||||
sealed class UserInteractionException(message: String) : Exception(message) {
|
sealed class UserInteractionException(message: String) : Exception(message) {
|
||||||
class RequestDenied @PluginHostApi constructor() :
|
class RequestDenied @PluginHostApi constructor() :
|
||||||
UserInteractionException("Request was denied")
|
UserInteractionException("Request denied by user")
|
||||||
|
|
||||||
sealed class Activity(message: String) : UserInteractionException(message) {
|
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?) :
|
class NotCompleted @PluginHostApi constructor(val resultCode: Int, val intent: Intent?) :
|
||||||
Activity("Unexpected activity result code: $resultCode")
|
Activity("Unexpected activity result code: $resultCode")
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import android.os.Parcelable
|
|||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scope of [DownloaderScope.download].
|
* The scope of the [OutputStream] version of [DownloaderScope.download].
|
||||||
*/
|
*/
|
||||||
interface OutputDownloadScope : BaseDownloadScope {
|
interface OutputDownloadScope : BaseDownloadScope {
|
||||||
suspend fun reportSize(size: Long)
|
suspend fun reportSize(size: Long)
|
||||||
@ -16,6 +16,7 @@ interface OutputDownloadScope : BaseDownloadScope {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A replacement for [DownloaderScope.download] that uses [OutputStream].
|
* 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) {
|
fun <T : Parcelable> DownloaderScope<T>.download(block: suspend OutputDownloadScope.(T, OutputStream) -> Unit) {
|
||||||
download = block
|
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.content.Intent
|
||||||
import android.os.Bundle
|
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.DownloaderScope
|
||||||
import app.revanced.manager.plugin.downloader.GetScope
|
import app.revanced.manager.plugin.downloader.GetScope
|
||||||
import app.revanced.manager.plugin.downloader.Scope
|
import app.revanced.manager.plugin.downloader.Scope
|
||||||
@ -14,35 +14,12 @@ import kotlinx.coroutines.cancelChildren
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.supervisorScope
|
import kotlinx.coroutines.supervisorScope
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.net.URI
|
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
typealias InitialUrl = String
|
typealias InitialUrl = String
|
||||||
typealias PageLoadCallback<T> = suspend WebViewCallbackScope<T>.(url: String) -> Unit
|
typealias PageLoadCallback<T> = suspend WebViewCallbackScope<T>.(url: String) -> Unit
|
||||||
typealias DownloadCallback<T> = suspend WebViewCallbackScope<T>.(url: String, mimeType: String, userAgent: 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 {
|
interface WebViewCallbackScope<T> : Scope {
|
||||||
/**
|
/**
|
||||||
* Finishes the activity and returns the [result].
|
* Finishes the activity and returns the [result].
|
||||||
@ -68,6 +45,12 @@ class WebViewScope<T> internal constructor(
|
|||||||
private lateinit var webView: IWebView
|
private lateinit var webView: IWebView
|
||||||
internal lateinit var initialUrl: String
|
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() {
|
internal val binder = object : IWebViewEvents.Stub() {
|
||||||
override fun ready(iface: IWebView?) {
|
override fun ready(iface: IWebView?) {
|
||||||
coroutineScope.launch(dispatcher) {
|
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>) {
|
fun download(block: DownloadCallback<T>) {
|
||||||
onDownloadCallback = block
|
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.
|
* 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 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 title The string displayed in the action bar.
|
||||||
* @param block Defines event handlers and returns an initial URL
|
* @param block The control block.
|
||||||
*/
|
*/
|
||||||
suspend fun <T> GetScope.runWebView(
|
suspend fun <T> GetScope.runWebView(
|
||||||
title: String,
|
title: String,
|
||||||
@ -140,12 +124,12 @@ suspend fun <T> GetScope.runWebView(
|
|||||||
val scope = WebViewScope<T>(this@supervisorScope, this@runWebView) { result = Container(it) }
|
val scope = WebViewScope<T>(this@supervisorScope, this@runWebView) { result = Container(it) }
|
||||||
scope.initialUrl = scope.block()
|
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 {
|
requestStartActivity(Intent().apply {
|
||||||
putExtras(Bundle().apply {
|
putExtra(
|
||||||
putBinder(WebViewActivity.BINDER_KEY, scope.binder)
|
WebViewActivity.KEY,
|
||||||
putString(WebViewActivity.TITLE_KEY, title)
|
WebViewActivity.Parameters(title, scope.jsEnabled, scope.binder)
|
||||||
})
|
)
|
||||||
setClassName(
|
setClassName(
|
||||||
hostPackageName,
|
hostPackageName,
|
||||||
WebViewActivity::class.qualifiedName!!
|
WebViewActivity::class.qualifiedName!!
|
||||||
@ -174,7 +158,14 @@ fun WebViewDownloader(block: suspend WebViewScope<DownloadUrl>.(packageName: Str
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
runWebView(label) {
|
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()
|
block(this@runWebView, packageName, version) ?: throw ReturnNull()
|
||||||
} to version
|
} to version
|
||||||
@ -184,6 +175,6 @@ fun WebViewDownloader(block: suspend WebViewScope<DownloadUrl>.(packageName: Str
|
|||||||
}
|
}
|
||||||
|
|
||||||
download {
|
download {
|
||||||
it.toResult()
|
it.toDownloadResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,8 @@ package app.revanced.manager.plugin.downloader.webview
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.os.Parcelable
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.webkit.CookieManager
|
import android.webkit.CookieManager
|
||||||
import android.webkit.WebSettings
|
import android.webkit.WebSettings
|
||||||
@ -21,6 +23,7 @@ import app.revanced.manager.plugin.downloader.R
|
|||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
class WebViewActivity : ComponentActivity() {
|
class WebViewActivity : ComponentActivity() {
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
@ -36,22 +39,23 @@ class WebViewActivity : ComponentActivity() {
|
|||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
val params = intent.getParcelableExtra<Parameters>(KEY)!!
|
||||||
actionBar?.apply {
|
actionBar?.apply {
|
||||||
title = intent.getStringExtra(TITLE_KEY)
|
title = intent.getStringExtra(params.title)
|
||||||
setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel)
|
setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel)
|
||||||
setDisplayHomeAsUpEnabled(true)
|
setDisplayHomeAsUpEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val events = IWebViewEvents.Stub.asInterface(intent.extras!!.getBinder(BINDER_KEY))!!
|
val events = IWebViewEvents.Stub.asInterface(params.events)!!
|
||||||
vm.setup(events)
|
vm.setup(events)
|
||||||
|
|
||||||
val webView = findViewById<WebView>(R.id.content).apply {
|
val webView = findViewById<WebView>(R.id.content).apply {
|
||||||
settings.apply {
|
settings.apply {
|
||||||
cacheMode = WebSettings.LOAD_NO_CACHE
|
cacheMode = WebSettings.LOAD_NO_CACHE
|
||||||
databaseEnabled = false
|
databaseEnabled = false
|
||||||
allowContentAccess = true
|
allowContentAccess = false
|
||||||
domStorageEnabled = false
|
domStorageEnabled = false
|
||||||
javaScriptEnabled = true
|
javaScriptEnabled = params.jsEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
webViewClient = vm.webViewClient
|
webViewClient = vm.webViewClient
|
||||||
@ -82,9 +86,13 @@ class WebViewActivity : ComponentActivity() {
|
|||||||
true
|
true
|
||||||
} else super.onOptionsItemSelected(item)
|
} else super.onOptionsItemSelected(item)
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
internal class Parameters(
|
||||||
|
val title: String, val jsEnabled: Boolean, val events: IBinder
|
||||||
|
) : Parcelable
|
||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
const val BINDER_KEY = "EVENTS"
|
const val KEY = "params"
|
||||||
const val TITLE_KEY = "TITLE"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user