From 13a14463f5e60683d878421be4a923c7cee29437 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Thu, 30 Oct 2025 07:00:53 +0100 Subject: [PATCH] expose gecko fetch api --- .../api/GeckoBrowserApiImpl.kt | 2 + .../api/GeckoFetchApiImpl.kt | 92 ++++ .../pigeons/Gecko.g.kt | 447 ++++++++++++---- .../lib/flutter_mozilla_components.dart | 2 + .../domain/services/gecko_fetch_service.dart | 43 ++ .../lib/src/pigeons/gecko.g.dart | 479 ++++++++++++++---- .../pigeons/gecko.dart | 65 +++ 7 files changed, 947 insertions(+), 183 deletions(-) create mode 100644 packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoFetchApiImpl.kt create mode 100644 packages/flutter_mozilla_components/lib/src/domain/services/gecko_fetch_service.dart diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoBrowserApiImpl.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoBrowserApiImpl.kt index 860c7acc..53e2a3d4 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoBrowserApiImpl.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoBrowserApiImpl.kt @@ -27,6 +27,7 @@ import eu.weblibre.flutter_mozilla_components.pigeons.GeckoCookieApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoDeleteBrowsingDataController import eu.weblibre.flutter_mozilla_components.pigeons.GeckoDownloadsApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoEngineSettingsApi +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFindApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHistoryApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoIconsApi @@ -231,6 +232,7 @@ class GeckoBrowserApiImpl : GeckoBrowserApi { GeckoDownloadsApi.setUp(_flutterPluginBinding.binaryMessenger, GeckoDownloadsApiImpl()) GeckoBrowserExtensionApi.setUp(_flutterPluginBinding.binaryMessenger, GeckoBrowserExtensionApiImpl()) GeckoHistoryApi.setUp(_flutterPluginBinding.binaryMessenger, GeckoHistoryApiImpl()) + GeckoFetchApi.setUp(_flutterPluginBinding.binaryMessenger, GeckoFetchApiImpl()) ReaderViewEvents.setUp( _flutterPluginBinding.binaryMessenger, diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoFetchApiImpl.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoFetchApiImpl.kt new file mode 100644 index 00000000..e8829148 --- /dev/null +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/api/GeckoFetchApiImpl.kt @@ -0,0 +1,92 @@ +package eu.weblibre.flutter_mozilla_components.api + +import android.os.Build +import androidx.annotation.RequiresApi +import eu.weblibre.flutter_mozilla_components.GlobalComponents +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchApi +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchCookiePolicy +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchMethod +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchRedircet +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchRequest +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoFetchResponse +import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHeader +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import mozilla.components.concept.fetch.MutableHeaders +import mozilla.components.concept.fetch.Request +import java.util.concurrent.TimeUnit + +class GeckoFetchApiImpl : GeckoFetchApi { + private val components by lazy { + requireNotNull(GlobalComponents.components) { "Components not initialized" } + } + + companion object { + private val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) + } + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + override fun fetch( + request: GeckoFetchRequest, + callback: (Result) -> Unit + ) { + val headers = MutableHeaders() + for (header in request.headers) { + headers.append(header.key, header.value) + } + + val request = Request( + url = request.url, + method = when (request.method) { + GeckoFetchMethod.GET -> Request.Method.GET + GeckoFetchMethod.HEAD -> Request.Method.HEAD + GeckoFetchMethod.POST -> Request.Method.POST + GeckoFetchMethod.PUT -> Request.Method.PUT + GeckoFetchMethod.DELETE -> Request.Method.DELETE + GeckoFetchMethod.CONNECT -> Request.Method.CONNECT + GeckoFetchMethod.OPTIONS -> Request.Method.OPTIONS + GeckoFetchMethod.TRACE -> Request.Method.TRACE + }, + headers = headers, + connectTimeout = if (request.connectTimeoutMillis != null) Pair( + request.connectTimeoutMillis, + TimeUnit.MILLISECONDS + ) else null, + readTimeout = if (request.readTimeoutMillis != null) Pair( + request.readTimeoutMillis, + TimeUnit.MILLISECONDS + ) else null, + body = if (request.body != null) Request.Body.fromString(request.body) else null, + redirect = when (request.redirect) { + GeckoFetchRedircet.FOLLOW -> Request.Redirect.FOLLOW + GeckoFetchRedircet.MANUAL -> Request.Redirect.MANUAL + }, + cookiePolicy = when (request.cookiePolicy) { + GeckoFetchCookiePolicy.INCLUDE -> Request.CookiePolicy.INCLUDE + GeckoFetchCookiePolicy.OMIT -> Request.CookiePolicy.OMIT + }, + useCaches = request.useCaches, + private = request.private, + useOhttp = request.useOhttp, + referrerUrl = request.referrerUrl, + conservative = request.conservative + ) + + coroutineScope.launch { + withContext(Dispatchers.Main) { + val response = components.core.client.fetch(request) + callback( + Result.success( + GeckoFetchResponse( + url = response.url, + status = response.status.toLong(), + body = response.body.useStream { stream -> stream.readAllBytes() }, + headers = response.headers.map { it -> GeckoHeader(it.name, it.value) } + ))) + } + } + } +} \ No newline at end of file diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pigeons/Gecko.g.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pigeons/Gecko.g.kt index aedce966..d02af0eb 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pigeons/Gecko.g.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pigeons/Gecko.g.kt @@ -385,6 +385,45 @@ enum class LogLevel(val raw: Int) { } } +enum class GeckoFetchMethod(val raw: Int) { + GET(0), + HEAD(1), + POST(2), + PUT(3), + DELETE(4), + CONNECT(5), + OPTIONS(6), + TRACE(7); + + companion object { + fun ofRaw(raw: Int): GeckoFetchMethod? { + return values().firstOrNull { it.raw == raw } + } + } +} + +enum class GeckoFetchRedircet(val raw: Int) { + FOLLOW(0), + MANUAL(1); + + companion object { + fun ofRaw(raw: Int): GeckoFetchRedircet? { + return values().firstOrNull { it.raw == raw } + } + } +} + +enum class GeckoFetchCookiePolicy(val raw: Int) { + INCLUDE(0), + OMIT(1); + + companion object { + fun ofRaw(raw: Int): GeckoFetchCookiePolicy? { + return values().firstOrNull { it.raw == raw } + } + } +} + /** * Translation options that map to the Gecko Translations Options. * @@ -2237,6 +2276,138 @@ data class GeckoPref ( override fun hashCode(): Int = toList().hashCode() } + +/** Generated class from Pigeon that represents data sent in messages. */ +data class GeckoHeader ( + val key: String, + val value: String +) + { + companion object { + fun fromList(pigeonVar_list: List): GeckoHeader { + val key = pigeonVar_list[0] as String + val value = pigeonVar_list[1] as String + return GeckoHeader(key, value) + } + } + fun toList(): List { + return listOf( + key, + value, + ) + } + override fun equals(other: Any?): Boolean { + if (other !is GeckoHeader) { + return false + } + if (this === other) { + return true + } + return GeckoPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class GeckoFetchRequest ( + val url: String, + val method: GeckoFetchMethod, + val headers: List, + val connectTimeoutMillis: Long? = null, + val readTimeoutMillis: Long? = null, + val body: String? = null, + val redirect: GeckoFetchRedircet, + val cookiePolicy: GeckoFetchCookiePolicy, + val useCaches: Boolean, + val private: Boolean, + val useOhttp: Boolean, + val referrerUrl: String? = null, + val conservative: Boolean +) + { + companion object { + fun fromList(pigeonVar_list: List): GeckoFetchRequest { + val url = pigeonVar_list[0] as String + val method = pigeonVar_list[1] as GeckoFetchMethod + val headers = pigeonVar_list[2] as List + val connectTimeoutMillis = pigeonVar_list[3] as Long? + val readTimeoutMillis = pigeonVar_list[4] as Long? + val body = pigeonVar_list[5] as String? + val redirect = pigeonVar_list[6] as GeckoFetchRedircet + val cookiePolicy = pigeonVar_list[7] as GeckoFetchCookiePolicy + val useCaches = pigeonVar_list[8] as Boolean + val private = pigeonVar_list[9] as Boolean + val useOhttp = pigeonVar_list[10] as Boolean + val referrerUrl = pigeonVar_list[11] as String? + val conservative = pigeonVar_list[12] as Boolean + return GeckoFetchRequest(url, method, headers, connectTimeoutMillis, readTimeoutMillis, body, redirect, cookiePolicy, useCaches, private, useOhttp, referrerUrl, conservative) + } + } + fun toList(): List { + return listOf( + url, + method, + headers, + connectTimeoutMillis, + readTimeoutMillis, + body, + redirect, + cookiePolicy, + useCaches, + private, + useOhttp, + referrerUrl, + conservative, + ) + } + override fun equals(other: Any?): Boolean { + if (other !is GeckoFetchRequest) { + return false + } + if (this === other) { + return true + } + return GeckoPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class GeckoFetchResponse ( + val url: String, + val status: Long, + val headers: List, + val body: ByteArray +) + { + companion object { + fun fromList(pigeonVar_list: List): GeckoFetchResponse { + val url = pigeonVar_list[0] as String + val status = pigeonVar_list[1] as Long + val headers = pigeonVar_list[2] as List + val body = pigeonVar_list[3] as ByteArray + return GeckoFetchResponse(url, status, headers, body) + } + } + fun toList(): List { + return listOf( + url, + status, + headers, + body, + ) + } + override fun equals(other: Any?): Boolean { + if (other !is GeckoFetchResponse) { + return false + } + if (this === other) { + return true + } + return GeckoPigeonUtils.deepEquals(toList(), other.toList()) } + + override fun hashCode(): Int = toList().hashCode() +} private open class GeckoPigeonCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { @@ -2336,225 +2507,255 @@ private open class GeckoPigeonCodec : StandardMessageCodec() { } } 148.toByte() -> { - return (readValue(buffer) as? List)?.let { - TranslationOptions.fromList(it) + return (readValue(buffer) as Long?)?.let { + GeckoFetchMethod.ofRaw(it.toInt()) } } 149.toByte() -> { - return (readValue(buffer) as? List)?.let { - ReaderState.fromList(it) + return (readValue(buffer) as Long?)?.let { + GeckoFetchRedircet.ofRaw(it.toInt()) } } 150.toByte() -> { - return (readValue(buffer) as? List)?.let { - LastMediaAccessState.fromList(it) + return (readValue(buffer) as Long?)?.let { + GeckoFetchCookiePolicy.ofRaw(it.toInt()) } } 151.toByte() -> { return (readValue(buffer) as? List)?.let { - HistoryMetadataKey.fromList(it) + TranslationOptions.fromList(it) } } 152.toByte() -> { return (readValue(buffer) as? List)?.let { - PackageCategoryValue.fromList(it) + ReaderState.fromList(it) } } 153.toByte() -> { return (readValue(buffer) as? List)?.let { - ExternalPackage.fromList(it) + LastMediaAccessState.fromList(it) } } 154.toByte() -> { return (readValue(buffer) as? List)?.let { - LoadUrlFlagsValue.fromList(it) + HistoryMetadataKey.fromList(it) } } 155.toByte() -> { return (readValue(buffer) as? List)?.let { - SourceValue.fromList(it) + PackageCategoryValue.fromList(it) } } 156.toByte() -> { return (readValue(buffer) as? List)?.let { - TabState.fromList(it) + ExternalPackage.fromList(it) } } 157.toByte() -> { return (readValue(buffer) as? List)?.let { - RecoverableTab.fromList(it) + LoadUrlFlagsValue.fromList(it) } } 158.toByte() -> { return (readValue(buffer) as? List)?.let { - RecoverableBrowserState.fromList(it) + SourceValue.fromList(it) } } 159.toByte() -> { return (readValue(buffer) as? List)?.let { - IconRequest.fromList(it) + TabState.fromList(it) } } 160.toByte() -> { return (readValue(buffer) as? List)?.let { - ResourceSize.fromList(it) + RecoverableTab.fromList(it) } } 161.toByte() -> { return (readValue(buffer) as? List)?.let { - Resource.fromList(it) + RecoverableBrowserState.fromList(it) } } 162.toByte() -> { return (readValue(buffer) as? List)?.let { - IconResult.fromList(it) + IconRequest.fromList(it) } } 163.toByte() -> { return (readValue(buffer) as? List)?.let { - CookiePartitionKey.fromList(it) + ResourceSize.fromList(it) } } 164.toByte() -> { return (readValue(buffer) as? List)?.let { - Cookie.fromList(it) + Resource.fromList(it) } } 165.toByte() -> { return (readValue(buffer) as? List)?.let { - VisitInfo.fromList(it) + IconResult.fromList(it) } } 166.toByte() -> { return (readValue(buffer) as? List)?.let { - HistoryItem.fromList(it) + CookiePartitionKey.fromList(it) } } 167.toByte() -> { return (readValue(buffer) as? List)?.let { - HistoryState.fromList(it) + Cookie.fromList(it) } } 168.toByte() -> { return (readValue(buffer) as? List)?.let { - ReaderableState.fromList(it) + VisitInfo.fromList(it) } } 169.toByte() -> { return (readValue(buffer) as? List)?.let { - SecurityInfoState.fromList(it) + HistoryItem.fromList(it) } } 170.toByte() -> { return (readValue(buffer) as? List)?.let { - TabContentState.fromList(it) + HistoryState.fromList(it) } } 171.toByte() -> { return (readValue(buffer) as? List)?.let { - FindResultState.fromList(it) + ReaderableState.fromList(it) } } 172.toByte() -> { return (readValue(buffer) as? List)?.let { - CustomSelectionAction.fromList(it) + SecurityInfoState.fromList(it) } } 173.toByte() -> { return (readValue(buffer) as? List)?.let { - WebExtensionData.fromList(it) + TabContentState.fromList(it) } } 174.toByte() -> { return (readValue(buffer) as? List)?.let { - GeckoSuggestion.fromList(it) + FindResultState.fromList(it) } } 175.toByte() -> { return (readValue(buffer) as? List)?.let { - TabContent.fromList(it) + CustomSelectionAction.fromList(it) } } 176.toByte() -> { return (readValue(buffer) as? List)?.let { - ContentBlocking.fromList(it) + WebExtensionData.fromList(it) } } 177.toByte() -> { return (readValue(buffer) as? List)?.let { - DohSettings.fromList(it) + GeckoSuggestion.fromList(it) } } 178.toByte() -> { return (readValue(buffer) as? List)?.let { - GeckoEngineSettings.fromList(it) + TabContent.fromList(it) } } 179.toByte() -> { return (readValue(buffer) as? List)?.let { - AutocompleteResult.fromList(it) + ContentBlocking.fromList(it) } } 180.toByte() -> { return (readValue(buffer) as? List)?.let { - UnknownHitResult.fromList(it) + DohSettings.fromList(it) } } 181.toByte() -> { return (readValue(buffer) as? List)?.let { - ImageHitResult.fromList(it) + GeckoEngineSettings.fromList(it) } } 182.toByte() -> { return (readValue(buffer) as? List)?.let { - VideoHitResult.fromList(it) + AutocompleteResult.fromList(it) } } 183.toByte() -> { return (readValue(buffer) as? List)?.let { - AudioHitResult.fromList(it) + UnknownHitResult.fromList(it) } } 184.toByte() -> { return (readValue(buffer) as? List)?.let { - ImageSrcHitResult.fromList(it) + ImageHitResult.fromList(it) } } 185.toByte() -> { return (readValue(buffer) as? List)?.let { - PhoneHitResult.fromList(it) + VideoHitResult.fromList(it) } } 186.toByte() -> { return (readValue(buffer) as? List)?.let { - EmailHitResult.fromList(it) + AudioHitResult.fromList(it) } } 187.toByte() -> { return (readValue(buffer) as? List)?.let { - GeoHitResult.fromList(it) + ImageSrcHitResult.fromList(it) } } 188.toByte() -> { return (readValue(buffer) as? List)?.let { - DownloadState.fromList(it) + PhoneHitResult.fromList(it) } } 189.toByte() -> { return (readValue(buffer) as? List)?.let { - ShareInternetResourceState.fromList(it) + EmailHitResult.fromList(it) } } 190.toByte() -> { return (readValue(buffer) as? List)?.let { - AddonCollection.fromList(it) + GeoHitResult.fromList(it) } } 191.toByte() -> { + return (readValue(buffer) as? List)?.let { + DownloadState.fromList(it) + } + } + 192.toByte() -> { + return (readValue(buffer) as? List)?.let { + ShareInternetResourceState.fromList(it) + } + } + 193.toByte() -> { + return (readValue(buffer) as? List)?.let { + AddonCollection.fromList(it) + } + } + 194.toByte() -> { return (readValue(buffer) as? List)?.let { GeckoPref.fromList(it) } } + 195.toByte() -> { + return (readValue(buffer) as? List)?.let { + GeckoHeader.fromList(it) + } + } + 196.toByte() -> { + return (readValue(buffer) as? List)?.let { + GeckoFetchRequest.fromList(it) + } + } + 197.toByte() -> { + return (readValue(buffer) as? List)?.let { + GeckoFetchResponse.fromList(it) + } + } else -> super.readValueOfType(type, buffer) } } @@ -2636,182 +2837,206 @@ private open class GeckoPigeonCodec : StandardMessageCodec() { stream.write(147) writeValue(stream, value.raw) } - is TranslationOptions -> { + is GeckoFetchMethod -> { stream.write(148) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is ReaderState -> { + is GeckoFetchRedircet -> { stream.write(149) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is LastMediaAccessState -> { + is GeckoFetchCookiePolicy -> { stream.write(150) - writeValue(stream, value.toList()) + writeValue(stream, value.raw) } - is HistoryMetadataKey -> { + is TranslationOptions -> { stream.write(151) writeValue(stream, value.toList()) } - is PackageCategoryValue -> { + is ReaderState -> { stream.write(152) writeValue(stream, value.toList()) } - is ExternalPackage -> { + is LastMediaAccessState -> { stream.write(153) writeValue(stream, value.toList()) } - is LoadUrlFlagsValue -> { + is HistoryMetadataKey -> { stream.write(154) writeValue(stream, value.toList()) } - is SourceValue -> { + is PackageCategoryValue -> { stream.write(155) writeValue(stream, value.toList()) } - is TabState -> { + is ExternalPackage -> { stream.write(156) writeValue(stream, value.toList()) } - is RecoverableTab -> { + is LoadUrlFlagsValue -> { stream.write(157) writeValue(stream, value.toList()) } - is RecoverableBrowserState -> { + is SourceValue -> { stream.write(158) writeValue(stream, value.toList()) } - is IconRequest -> { + is TabState -> { stream.write(159) writeValue(stream, value.toList()) } - is ResourceSize -> { + is RecoverableTab -> { stream.write(160) writeValue(stream, value.toList()) } - is Resource -> { + is RecoverableBrowserState -> { stream.write(161) writeValue(stream, value.toList()) } - is IconResult -> { + is IconRequest -> { stream.write(162) writeValue(stream, value.toList()) } - is CookiePartitionKey -> { + is ResourceSize -> { stream.write(163) writeValue(stream, value.toList()) } - is Cookie -> { + is Resource -> { stream.write(164) writeValue(stream, value.toList()) } - is VisitInfo -> { + is IconResult -> { stream.write(165) writeValue(stream, value.toList()) } - is HistoryItem -> { + is CookiePartitionKey -> { stream.write(166) writeValue(stream, value.toList()) } - is HistoryState -> { + is Cookie -> { stream.write(167) writeValue(stream, value.toList()) } - is ReaderableState -> { + is VisitInfo -> { stream.write(168) writeValue(stream, value.toList()) } - is SecurityInfoState -> { + is HistoryItem -> { stream.write(169) writeValue(stream, value.toList()) } - is TabContentState -> { + is HistoryState -> { stream.write(170) writeValue(stream, value.toList()) } - is FindResultState -> { + is ReaderableState -> { stream.write(171) writeValue(stream, value.toList()) } - is CustomSelectionAction -> { + is SecurityInfoState -> { stream.write(172) writeValue(stream, value.toList()) } - is WebExtensionData -> { + is TabContentState -> { stream.write(173) writeValue(stream, value.toList()) } - is GeckoSuggestion -> { + is FindResultState -> { stream.write(174) writeValue(stream, value.toList()) } - is TabContent -> { + is CustomSelectionAction -> { stream.write(175) writeValue(stream, value.toList()) } - is ContentBlocking -> { + is WebExtensionData -> { stream.write(176) writeValue(stream, value.toList()) } - is DohSettings -> { + is GeckoSuggestion -> { stream.write(177) writeValue(stream, value.toList()) } - is GeckoEngineSettings -> { + is TabContent -> { stream.write(178) writeValue(stream, value.toList()) } - is AutocompleteResult -> { + is ContentBlocking -> { stream.write(179) writeValue(stream, value.toList()) } - is UnknownHitResult -> { + is DohSettings -> { stream.write(180) writeValue(stream, value.toList()) } - is ImageHitResult -> { + is GeckoEngineSettings -> { stream.write(181) writeValue(stream, value.toList()) } - is VideoHitResult -> { + is AutocompleteResult -> { stream.write(182) writeValue(stream, value.toList()) } - is AudioHitResult -> { + is UnknownHitResult -> { stream.write(183) writeValue(stream, value.toList()) } - is ImageSrcHitResult -> { + is ImageHitResult -> { stream.write(184) writeValue(stream, value.toList()) } - is PhoneHitResult -> { + is VideoHitResult -> { stream.write(185) writeValue(stream, value.toList()) } - is EmailHitResult -> { + is AudioHitResult -> { stream.write(186) writeValue(stream, value.toList()) } - is GeoHitResult -> { + is ImageSrcHitResult -> { stream.write(187) writeValue(stream, value.toList()) } - is DownloadState -> { + is PhoneHitResult -> { stream.write(188) writeValue(stream, value.toList()) } - is ShareInternetResourceState -> { + is EmailHitResult -> { stream.write(189) writeValue(stream, value.toList()) } - is AddonCollection -> { + is GeoHitResult -> { stream.write(190) writeValue(stream, value.toList()) } - is GeckoPref -> { + is DownloadState -> { stream.write(191) writeValue(stream, value.toList()) } + is ShareInternetResourceState -> { + stream.write(192) + writeValue(stream, value.toList()) + } + is AddonCollection -> { + stream.write(193) + writeValue(stream, value.toList()) + } + is GeckoPref -> { + stream.write(194) + writeValue(stream, value.toList()) + } + is GeckoHeader -> { + stream.write(195) + writeValue(stream, value.toList()) + } + is GeckoFetchRequest -> { + stream.write(196) + writeValue(stream, value.toList()) + } + is GeckoFetchResponse -> { + stream.write(197) + writeValue(stream, value.toList()) + } else -> super.writeValue(stream, value) } } @@ -5247,3 +5472,39 @@ class BrowserExtensionEvents(private val binaryMessenger: BinaryMessenger, priva } } } +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface GeckoFetchApi { + fun fetch(request: GeckoFetchRequest, callback: (Result) -> Unit) + + companion object { + /** The codec used by GeckoFetchApi. */ + val codec: MessageCodec by lazy { + GeckoPigeonCodec() + } + /** Sets up an instance of `GeckoFetchApi` to handle messages through the `binaryMessenger`. */ + @JvmOverloads + fun setUp(binaryMessenger: BinaryMessenger, api: GeckoFetchApi?, messageChannelSuffix: String = "") { + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoFetchApi.fetch$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val requestArg = args[0] as GeckoFetchRequest + api.fetch(requestArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(GeckoPigeonUtils.wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(GeckoPigeonUtils.wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/packages/flutter_mozilla_components/lib/flutter_mozilla_components.dart b/packages/flutter_mozilla_components/lib/flutter_mozilla_components.dart index 29e231ba..3e357761 100644 --- a/packages/flutter_mozilla_components/lib/flutter_mozilla_components.dart +++ b/packages/flutter_mozilla_components/lib/flutter_mozilla_components.dart @@ -16,6 +16,7 @@ export 'src/domain/services/gecko_delete_browser_data.dart'; export 'src/domain/services/gecko_downloads.dart'; export 'src/domain/services/gecko_engine_settings.dart'; export 'src/domain/services/gecko_event.dart'; +export 'src/domain/services/gecko_fetch_service.dart'; export 'src/domain/services/gecko_find_in_page.dart'; export 'src/domain/services/gecko_history.dart'; export 'src/domain/services/gecko_icon.dart'; @@ -42,6 +43,7 @@ export 'src/pigeons/gecko.g.dart' DohSettingsMode, EmailHitResult, GeckoEngineSettings, + GeckoFetchResponse, GeckoPref, GeckoSuggestion, GeckoSuggestionType, diff --git a/packages/flutter_mozilla_components/lib/src/domain/services/gecko_fetch_service.dart b/packages/flutter_mozilla_components/lib/src/domain/services/gecko_fetch_service.dart new file mode 100644 index 00000000..6f0fb2f3 --- /dev/null +++ b/packages/flutter_mozilla_components/lib/src/domain/services/gecko_fetch_service.dart @@ -0,0 +1,43 @@ +import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart'; + +final _apiInstance = GeckoFetchApi(); + +class GeckoFetchService { + final GeckoFetchApi _api; + + GeckoFetchService({GeckoFetchApi? api}) : _api = api ?? _apiInstance; + + Future fetch({ + required Uri url, + GeckoFetchMethod method = GeckoFetchMethod.get, + List headers = const [], + Duration? connectTimeout, + Duration? readTimeout, + String? body, + GeckoFetchRedircet redirect = GeckoFetchRedircet.follow, + GeckoFetchCookiePolicy cookiePolicy = GeckoFetchCookiePolicy.include, + bool useCaches = true, + bool private = false, + bool useOhttp = false, + String? referrerUrl, + bool conservative = false, + }) { + return _api.fetch( + GeckoFetchRequest( + url: url.toString(), + method: method, + headers: headers, + connectTimeoutMillis: connectTimeout?.inMilliseconds, + readTimeoutMillis: readTimeout?.inMilliseconds, + body: body, + redirect: redirect, + cookiePolicy: cookiePolicy, + useCaches: useCaches, + private: private, + useOhttp: useOhttp, + referrerUrl: referrerUrl, + conservative: conservative, + ), + ); + } +} diff --git a/packages/flutter_mozilla_components/lib/src/pigeons/gecko.g.dart b/packages/flutter_mozilla_components/lib/src/pigeons/gecko.g.dart index 3a99ee69..9a649027 100644 --- a/packages/flutter_mozilla_components/lib/src/pigeons/gecko.g.dart +++ b/packages/flutter_mozilla_components/lib/src/pigeons/gecko.g.dart @@ -217,6 +217,27 @@ enum LogLevel { error, } +enum GeckoFetchMethod { + get, + head, + post, + put, + delete, + connect, + options, + trace, +} + +enum GeckoFetchRedircet { + follow, + manual, +} + +enum GeckoFetchCookiePolicy { + include, + omit, +} + /// Translation options that map to the Gecko Translations Options. /// /// @property downloadModel If the necessary models should be downloaded on request. If false, then @@ -2854,6 +2875,209 @@ class GeckoPref { ; } +class GeckoHeader { + GeckoHeader({ + required this.key, + required this.value, + }); + + String key; + + String value; + + List _toList() { + return [ + key, + value, + ]; + } + + Object encode() { + return _toList(); } + + static GeckoHeader decode(Object result) { + result as List; + return GeckoHeader( + key: result[0]! as String, + value: result[1]! as String, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! GeckoHeader || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; +} + +class GeckoFetchRequest { + GeckoFetchRequest({ + required this.url, + required this.method, + required this.headers, + this.connectTimeoutMillis, + this.readTimeoutMillis, + this.body, + required this.redirect, + required this.cookiePolicy, + required this.useCaches, + required this.private, + required this.useOhttp, + this.referrerUrl, + required this.conservative, + }); + + String url; + + GeckoFetchMethod method; + + List headers; + + int? connectTimeoutMillis; + + int? readTimeoutMillis; + + String? body; + + GeckoFetchRedircet redirect; + + GeckoFetchCookiePolicy cookiePolicy; + + bool useCaches; + + bool private; + + bool useOhttp; + + String? referrerUrl; + + bool conservative; + + List _toList() { + return [ + url, + method, + headers, + connectTimeoutMillis, + readTimeoutMillis, + body, + redirect, + cookiePolicy, + useCaches, + private, + useOhttp, + referrerUrl, + conservative, + ]; + } + + Object encode() { + return _toList(); } + + static GeckoFetchRequest decode(Object result) { + result as List; + return GeckoFetchRequest( + url: result[0]! as String, + method: result[1]! as GeckoFetchMethod, + headers: (result[2] as List?)!.cast(), + connectTimeoutMillis: result[3] as int?, + readTimeoutMillis: result[4] as int?, + body: result[5] as String?, + redirect: result[6]! as GeckoFetchRedircet, + cookiePolicy: result[7]! as GeckoFetchCookiePolicy, + useCaches: result[8]! as bool, + private: result[9]! as bool, + useOhttp: result[10]! as bool, + referrerUrl: result[11] as String?, + conservative: result[12]! as bool, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! GeckoFetchRequest || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; +} + +class GeckoFetchResponse { + GeckoFetchResponse({ + required this.url, + required this.status, + required this.headers, + required this.body, + }); + + String url; + + int status; + + List headers; + + Uint8List body; + + List _toList() { + return [ + url, + status, + headers, + body, + ]; + } + + Object encode() { + return _toList(); } + + static GeckoFetchResponse decode(Object result) { + result as List; + return GeckoFetchResponse( + url: result[0]! as String, + status: result[1]! as int, + headers: (result[2] as List?)!.cast(), + body: result[3]! as Uint8List, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! GeckoFetchResponse || other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()) +; +} + class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @@ -2919,138 +3143,156 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is LogLevel) { buffer.putUint8(147); writeValue(buffer, value.index); - } else if (value is TranslationOptions) { + } else if (value is GeckoFetchMethod) { buffer.putUint8(148); - writeValue(buffer, value.encode()); - } else if (value is ReaderState) { + writeValue(buffer, value.index); + } else if (value is GeckoFetchRedircet) { buffer.putUint8(149); - writeValue(buffer, value.encode()); - } else if (value is LastMediaAccessState) { + writeValue(buffer, value.index); + } else if (value is GeckoFetchCookiePolicy) { buffer.putUint8(150); - writeValue(buffer, value.encode()); - } else if (value is HistoryMetadataKey) { + writeValue(buffer, value.index); + } else if (value is TranslationOptions) { buffer.putUint8(151); writeValue(buffer, value.encode()); - } else if (value is PackageCategoryValue) { + } else if (value is ReaderState) { buffer.putUint8(152); writeValue(buffer, value.encode()); - } else if (value is ExternalPackage) { + } else if (value is LastMediaAccessState) { buffer.putUint8(153); writeValue(buffer, value.encode()); - } else if (value is LoadUrlFlagsValue) { + } else if (value is HistoryMetadataKey) { buffer.putUint8(154); writeValue(buffer, value.encode()); - } else if (value is SourceValue) { + } else if (value is PackageCategoryValue) { buffer.putUint8(155); writeValue(buffer, value.encode()); - } else if (value is TabState) { + } else if (value is ExternalPackage) { buffer.putUint8(156); writeValue(buffer, value.encode()); - } else if (value is RecoverableTab) { + } else if (value is LoadUrlFlagsValue) { buffer.putUint8(157); writeValue(buffer, value.encode()); - } else if (value is RecoverableBrowserState) { + } else if (value is SourceValue) { buffer.putUint8(158); writeValue(buffer, value.encode()); - } else if (value is IconRequest) { + } else if (value is TabState) { buffer.putUint8(159); writeValue(buffer, value.encode()); - } else if (value is ResourceSize) { + } else if (value is RecoverableTab) { buffer.putUint8(160); writeValue(buffer, value.encode()); - } else if (value is Resource) { + } else if (value is RecoverableBrowserState) { buffer.putUint8(161); writeValue(buffer, value.encode()); - } else if (value is IconResult) { + } else if (value is IconRequest) { buffer.putUint8(162); writeValue(buffer, value.encode()); - } else if (value is CookiePartitionKey) { + } else if (value is ResourceSize) { buffer.putUint8(163); writeValue(buffer, value.encode()); - } else if (value is Cookie) { + } else if (value is Resource) { buffer.putUint8(164); writeValue(buffer, value.encode()); - } else if (value is VisitInfo) { + } else if (value is IconResult) { buffer.putUint8(165); writeValue(buffer, value.encode()); - } else if (value is HistoryItem) { + } else if (value is CookiePartitionKey) { buffer.putUint8(166); writeValue(buffer, value.encode()); - } else if (value is HistoryState) { + } else if (value is Cookie) { buffer.putUint8(167); writeValue(buffer, value.encode()); - } else if (value is ReaderableState) { + } else if (value is VisitInfo) { buffer.putUint8(168); writeValue(buffer, value.encode()); - } else if (value is SecurityInfoState) { + } else if (value is HistoryItem) { buffer.putUint8(169); writeValue(buffer, value.encode()); - } else if (value is TabContentState) { + } else if (value is HistoryState) { buffer.putUint8(170); writeValue(buffer, value.encode()); - } else if (value is FindResultState) { + } else if (value is ReaderableState) { buffer.putUint8(171); writeValue(buffer, value.encode()); - } else if (value is CustomSelectionAction) { + } else if (value is SecurityInfoState) { buffer.putUint8(172); writeValue(buffer, value.encode()); - } else if (value is WebExtensionData) { + } else if (value is TabContentState) { buffer.putUint8(173); writeValue(buffer, value.encode()); - } else if (value is GeckoSuggestion) { + } else if (value is FindResultState) { buffer.putUint8(174); writeValue(buffer, value.encode()); - } else if (value is TabContent) { + } else if (value is CustomSelectionAction) { buffer.putUint8(175); writeValue(buffer, value.encode()); - } else if (value is ContentBlocking) { + } else if (value is WebExtensionData) { buffer.putUint8(176); writeValue(buffer, value.encode()); - } else if (value is DohSettings) { + } else if (value is GeckoSuggestion) { buffer.putUint8(177); writeValue(buffer, value.encode()); - } else if (value is GeckoEngineSettings) { + } else if (value is TabContent) { buffer.putUint8(178); writeValue(buffer, value.encode()); - } else if (value is AutocompleteResult) { + } else if (value is ContentBlocking) { buffer.putUint8(179); writeValue(buffer, value.encode()); - } else if (value is UnknownHitResult) { + } else if (value is DohSettings) { buffer.putUint8(180); writeValue(buffer, value.encode()); - } else if (value is ImageHitResult) { + } else if (value is GeckoEngineSettings) { buffer.putUint8(181); writeValue(buffer, value.encode()); - } else if (value is VideoHitResult) { + } else if (value is AutocompleteResult) { buffer.putUint8(182); writeValue(buffer, value.encode()); - } else if (value is AudioHitResult) { + } else if (value is UnknownHitResult) { buffer.putUint8(183); writeValue(buffer, value.encode()); - } else if (value is ImageSrcHitResult) { + } else if (value is ImageHitResult) { buffer.putUint8(184); writeValue(buffer, value.encode()); - } else if (value is PhoneHitResult) { + } else if (value is VideoHitResult) { buffer.putUint8(185); writeValue(buffer, value.encode()); - } else if (value is EmailHitResult) { + } else if (value is AudioHitResult) { buffer.putUint8(186); writeValue(buffer, value.encode()); - } else if (value is GeoHitResult) { + } else if (value is ImageSrcHitResult) { buffer.putUint8(187); writeValue(buffer, value.encode()); - } else if (value is DownloadState) { + } else if (value is PhoneHitResult) { buffer.putUint8(188); writeValue(buffer, value.encode()); - } else if (value is ShareInternetResourceState) { + } else if (value is EmailHitResult) { buffer.putUint8(189); writeValue(buffer, value.encode()); - } else if (value is AddonCollection) { + } else if (value is GeoHitResult) { buffer.putUint8(190); writeValue(buffer, value.encode()); - } else if (value is GeckoPref) { + } else if (value is DownloadState) { buffer.putUint8(191); writeValue(buffer, value.encode()); + } else if (value is ShareInternetResourceState) { + buffer.putUint8(192); + writeValue(buffer, value.encode()); + } else if (value is AddonCollection) { + buffer.putUint8(193); + writeValue(buffer, value.encode()); + } else if (value is GeckoPref) { + buffer.putUint8(194); + writeValue(buffer, value.encode()); + } else if (value is GeckoHeader) { + buffer.putUint8(195); + writeValue(buffer, value.encode()); + } else if (value is GeckoFetchRequest) { + buffer.putUint8(196); + writeValue(buffer, value.encode()); + } else if (value is GeckoFetchResponse) { + buffer.putUint8(197); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -3117,93 +3359,108 @@ class _PigeonCodec extends StandardMessageCodec { final int? value = readValue(buffer) as int?; return value == null ? null : LogLevel.values[value]; case 148: - return TranslationOptions.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : GeckoFetchMethod.values[value]; case 149: - return ReaderState.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : GeckoFetchRedircet.values[value]; case 150: - return LastMediaAccessState.decode(readValue(buffer)!); + final int? value = readValue(buffer) as int?; + return value == null ? null : GeckoFetchCookiePolicy.values[value]; case 151: - return HistoryMetadataKey.decode(readValue(buffer)!); + return TranslationOptions.decode(readValue(buffer)!); case 152: - return PackageCategoryValue.decode(readValue(buffer)!); + return ReaderState.decode(readValue(buffer)!); case 153: - return ExternalPackage.decode(readValue(buffer)!); + return LastMediaAccessState.decode(readValue(buffer)!); case 154: - return LoadUrlFlagsValue.decode(readValue(buffer)!); + return HistoryMetadataKey.decode(readValue(buffer)!); case 155: - return SourceValue.decode(readValue(buffer)!); + return PackageCategoryValue.decode(readValue(buffer)!); case 156: - return TabState.decode(readValue(buffer)!); + return ExternalPackage.decode(readValue(buffer)!); case 157: - return RecoverableTab.decode(readValue(buffer)!); + return LoadUrlFlagsValue.decode(readValue(buffer)!); case 158: - return RecoverableBrowserState.decode(readValue(buffer)!); + return SourceValue.decode(readValue(buffer)!); case 159: - return IconRequest.decode(readValue(buffer)!); + return TabState.decode(readValue(buffer)!); case 160: - return ResourceSize.decode(readValue(buffer)!); + return RecoverableTab.decode(readValue(buffer)!); case 161: - return Resource.decode(readValue(buffer)!); + return RecoverableBrowserState.decode(readValue(buffer)!); case 162: - return IconResult.decode(readValue(buffer)!); + return IconRequest.decode(readValue(buffer)!); case 163: - return CookiePartitionKey.decode(readValue(buffer)!); + return ResourceSize.decode(readValue(buffer)!); case 164: - return Cookie.decode(readValue(buffer)!); + return Resource.decode(readValue(buffer)!); case 165: - return VisitInfo.decode(readValue(buffer)!); + return IconResult.decode(readValue(buffer)!); case 166: - return HistoryItem.decode(readValue(buffer)!); + return CookiePartitionKey.decode(readValue(buffer)!); case 167: - return HistoryState.decode(readValue(buffer)!); + return Cookie.decode(readValue(buffer)!); case 168: - return ReaderableState.decode(readValue(buffer)!); + return VisitInfo.decode(readValue(buffer)!); case 169: - return SecurityInfoState.decode(readValue(buffer)!); + return HistoryItem.decode(readValue(buffer)!); case 170: - return TabContentState.decode(readValue(buffer)!); + return HistoryState.decode(readValue(buffer)!); case 171: - return FindResultState.decode(readValue(buffer)!); + return ReaderableState.decode(readValue(buffer)!); case 172: - return CustomSelectionAction.decode(readValue(buffer)!); + return SecurityInfoState.decode(readValue(buffer)!); case 173: - return WebExtensionData.decode(readValue(buffer)!); + return TabContentState.decode(readValue(buffer)!); case 174: - return GeckoSuggestion.decode(readValue(buffer)!); + return FindResultState.decode(readValue(buffer)!); case 175: - return TabContent.decode(readValue(buffer)!); + return CustomSelectionAction.decode(readValue(buffer)!); case 176: - return ContentBlocking.decode(readValue(buffer)!); + return WebExtensionData.decode(readValue(buffer)!); case 177: - return DohSettings.decode(readValue(buffer)!); + return GeckoSuggestion.decode(readValue(buffer)!); case 178: - return GeckoEngineSettings.decode(readValue(buffer)!); + return TabContent.decode(readValue(buffer)!); case 179: - return AutocompleteResult.decode(readValue(buffer)!); + return ContentBlocking.decode(readValue(buffer)!); case 180: - return UnknownHitResult.decode(readValue(buffer)!); + return DohSettings.decode(readValue(buffer)!); case 181: - return ImageHitResult.decode(readValue(buffer)!); + return GeckoEngineSettings.decode(readValue(buffer)!); case 182: - return VideoHitResult.decode(readValue(buffer)!); + return AutocompleteResult.decode(readValue(buffer)!); case 183: - return AudioHitResult.decode(readValue(buffer)!); + return UnknownHitResult.decode(readValue(buffer)!); case 184: - return ImageSrcHitResult.decode(readValue(buffer)!); + return ImageHitResult.decode(readValue(buffer)!); case 185: - return PhoneHitResult.decode(readValue(buffer)!); + return VideoHitResult.decode(readValue(buffer)!); case 186: - return EmailHitResult.decode(readValue(buffer)!); + return AudioHitResult.decode(readValue(buffer)!); case 187: - return GeoHitResult.decode(readValue(buffer)!); + return ImageSrcHitResult.decode(readValue(buffer)!); case 188: - return DownloadState.decode(readValue(buffer)!); + return PhoneHitResult.decode(readValue(buffer)!); case 189: - return ShareInternetResourceState.decode(readValue(buffer)!); + return EmailHitResult.decode(readValue(buffer)!); case 190: - return AddonCollection.decode(readValue(buffer)!); + return GeoHitResult.decode(readValue(buffer)!); case 191: + return DownloadState.decode(readValue(buffer)!); + case 192: + return ShareInternetResourceState.decode(readValue(buffer)!); + case 193: + return AddonCollection.decode(readValue(buffer)!); + case 194: return GeckoPref.decode(readValue(buffer)!); + case 195: + return GeckoHeader.decode(readValue(buffer)!); + case 196: + return GeckoFetchRequest.decode(readValue(buffer)!); + case 197: + return GeckoFetchResponse.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -6316,3 +6573,45 @@ abstract class BrowserExtensionEvents { } } } + +class GeckoFetchApi { + /// Constructor for [GeckoFetchApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + GeckoFetchApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future fetch(GeckoFetchRequest request) async { + final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoFetchApi.fetch$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([request]); + final List? pigeonVar_replyList = + await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else if (pigeonVar_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (pigeonVar_replyList[0] as GeckoFetchResponse?)!; + } + } +} diff --git a/packages/flutter_mozilla_components/pigeons/gecko.dart b/packages/flutter_mozilla_components/pigeons/gecko.dart index 816f4d3c..28d817d8 100644 --- a/packages/flutter_mozilla_components/pigeons/gecko.dart +++ b/packages/flutter_mozilla_components/pigeons/gecko.dart @@ -1338,3 +1338,68 @@ abstract class GeckoDownloadsApi { abstract class BrowserExtensionEvents { void onFeedRequested(int timestamp, String url); } + +class GeckoHeader { + final String key; + final String value; + + GeckoHeader({required this.key, required this.value}); +} + +enum GeckoFetchMethod { get, head, post, put, delete, connect, options, trace } + +enum GeckoFetchRedircet { follow, manual } + +enum GeckoFetchCookiePolicy { include, omit } + +class GeckoFetchRequest { + final String url; + final GeckoFetchMethod method; + final List headers; + final int? connectTimeoutMillis; + final int? readTimeoutMillis; + final String? body; + final GeckoFetchRedircet redirect; + final GeckoFetchCookiePolicy cookiePolicy; + final bool useCaches; + final bool private; + final bool useOhttp; + final String? referrerUrl; + final bool conservative; + + GeckoFetchRequest({ + required this.url, + required this.method, + required this.headers, + required this.connectTimeoutMillis, + required this.readTimeoutMillis, + required this.body, + required this.redirect, + required this.cookiePolicy, + required this.useCaches, + required this.private, + required this.useOhttp, + required this.referrerUrl, + required this.conservative, + }); +} + +class GeckoFetchResponse { + final String url; + final int status; + final List headers; + final Uint8List body; + + GeckoFetchResponse({ + required this.url, + required this.status, + required this.headers, + required this.body, + }); +} + +@HostApi() +abstract class GeckoFetchApi { + @async + GeckoFetchResponse fetch(GeckoFetchRequest request); +}