one step closer

This commit is contained in:
Fabian Freund
2024-10-22 07:27:37 +02:00
parent c4d93e8fe7
commit 8d351e55c0
92 changed files with 3829 additions and 2694 deletions
@@ -3,6 +3,8 @@ version = "1.0-SNAPSHOT"
buildscript {
ext.kotlin_version = "1.9.22"
ext.mozillaComponentsVersion = '131.0.3'
repositories {
google()
mavenCentral()
@@ -56,37 +58,36 @@ android {
}
dependencies {
implementation 'org.mozilla.components:support-utils:131.0b1'
implementation 'org.mozilla.components:support-ktx:131.0b1'
implementation 'org.mozilla.components:support-webextensions:131.0b1'
implementation 'org.mozilla.components:support-locale:131.0b1'
implementation 'org.mozilla.components:lib-fetch-httpurlconnection:131.0b1'
implementation 'org.mozilla.components:lib-crash:131.0b1'
implementation 'org.mozilla.components:lib-publicsuffixlist:131.0b1'
implementation 'org.mozilla.components:lib-dataprotect:131.0b1'
implementation 'org.mozilla.components:concept-engine:131.0b1'
implementation 'org.mozilla.components:concept-fetch:131.0b1'
implementation 'org.mozilla.components:browser-engine-gecko:131.0b1'
implementation 'org.mozilla.components:browser-state:131.0b1'
implementation 'org.mozilla.components:browser-session-storage:131.0b1'
implementation 'org.mozilla.components:browser-icons:131.0b1'
//implementation 'org.mozilla.components:browser-storage-sync:131.0b1'
implementation 'org.mozilla.components:browser-thumbnails:131.0b1'
implementation 'org.mozilla.components:feature-addons:131.0b1'
implementation 'org.mozilla.components:feature-app-links:131.0b1'
implementation 'org.mozilla.components:feature-autofill:131.0b1'
implementation 'org.mozilla.components:feature-downloads:131.0b1'
implementation 'org.mozilla.components:feature-media:131.0b1'
implementation 'org.mozilla.components:feature-tabs:131.0b1'
implementation 'org.mozilla.components:feature-prompts:131.0b1'
implementation 'org.mozilla.components:feature-session:131.0b1'
implementation 'org.mozilla.components:feature-readerview:131.0b1'
implementation 'org.mozilla.components:feature-privatemode:131.0b1'
implementation 'org.mozilla.components:feature-sitepermissions:131.0b1'
implementation 'org.mozilla.components:feature-webcompat:131.0b1'
implementation 'org.mozilla.components:feature-webnotifications:131.0b1'
implementation 'org.mozilla.components:service-digitalassetlinks:131.0b1'
implementation 'org.mozilla.components:ui-widgets:131.0b1'
implementation "org.mozilla.components:support-utils:$mozillaComponentsVersion"
implementation "org.mozilla.components:support-ktx:$mozillaComponentsVersion"
implementation "org.mozilla.components:support-webextensions:$mozillaComponentsVersion"
implementation "org.mozilla.components:support-locale:$mozillaComponentsVersion"
implementation "org.mozilla.components:lib-fetch-httpurlconnection:$mozillaComponentsVersion"
implementation "org.mozilla.components:lib-crash:$mozillaComponentsVersion"
implementation "org.mozilla.components:lib-publicsuffixlist:$mozillaComponentsVersion"
implementation "org.mozilla.components:lib-dataprotect:$mozillaComponentsVersion"
implementation "org.mozilla.components:concept-engine:$mozillaComponentsVersion"
implementation "org.mozilla.components:concept-fetch:$mozillaComponentsVersion"
implementation "org.mozilla.components:browser-engine-gecko:$mozillaComponentsVersion"
implementation "org.mozilla.components:browser-state:$mozillaComponentsVersion"
implementation "org.mozilla.components:browser-session-storage:$mozillaComponentsVersion"
implementation "org.mozilla.components:browser-icons:$mozillaComponentsVersion"
implementation "org.mozilla.components:browser-thumbnails:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-addons:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-app-links:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-autofill:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-downloads:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-media:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-tabs:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-prompts:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-session:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-readerview:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-privatemode:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-sitepermissions:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-webcompat:$mozillaComponentsVersion"
implementation "org.mozilla.components:feature-webnotifications:$mozillaComponentsVersion"
implementation "org.mozilla.components:service-digitalassetlinks:$mozillaComponentsVersion"
implementation "org.mozilla.components:ui-widgets:$mozillaComponentsVersion"
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
@@ -229,22 +229,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// consumeFlow(components.store) { flow ->
// flow.mapNotNull { state -> state.findCustomTabOrSelectedTab(sessionId) }
// .ifAnyChanged { tab ->
// arrayOf(
// tab.content.loading,
// tab.content.canGoBack,
// tab.content.canGoForward,
// )
// }
// .collect {
// binding.toolbar.invalidateActions()
// }
// }
}
@CallSuper
override fun onBackPressed(): Boolean =
listOf(sessionFeature).any { it.onBackPressed() }
@@ -31,9 +31,9 @@ class BrowserFragment(private val context: Context) : BaseBrowserFragment(), Use
override fun createEngine(components: Components): EngineView {
return components.engine.createView(context).apply {
selectionActionDelegate = DefaultSelectionActionDelegate(
components.selectionAction
)
// selectionActionDelegate = DefaultSelectionActionDelegate(
// components.selectionAction
// )
}
}
@@ -88,6 +88,7 @@ open class DefaultComponents(
}
var engineView: EngineView? = null
var engineReportedInitialized = false
val preferences: SharedPreferences =
applicationContext.getSharedPreferences(SAMPLE_BROWSER_PREFERENCES, Context.MODE_PRIVATE)
@@ -166,6 +167,7 @@ open class DefaultComponents(
.distinctUntilChanged()
.collect { tabId ->
flutterEvents.onSelectedTabChange(
System.currentTimeMillis(),
tabId
) { _ -> }
}
@@ -181,6 +183,7 @@ open class DefaultComponents(
.collect { tab ->
val iconBytes = tab.content.icon?.toWebPBytes()
flutterEvents.onIconChange(
System.currentTimeMillis(),
tab.id,
iconBytes
) { _ -> }
@@ -195,6 +198,7 @@ open class DefaultComponents(
.debounce { 50 }
.collect { tab ->
flutterEvents.onSecurityInfoStateChange(
System.currentTimeMillis(),
tab.id,
SecurityInfoState(
tab.content.securityInfo.secure,
@@ -218,6 +222,7 @@ open class DefaultComponents(
.debounce { 50 }
.collect { tab ->
flutterEvents.onReaderableStateChange(
System.currentTimeMillis(),
tab.id,
ReaderableState(
tab.readerState.readerable,
@@ -241,6 +246,7 @@ open class DefaultComponents(
.debounce { 50 }
.collect { tab ->
flutterEvents.onHistoryStateChange(
System.currentTimeMillis(),
tab.id,
HistoryState(
items = tab.content.history.items.map { item -> HistoryItem(
@@ -259,7 +265,7 @@ open class DefaultComponents(
flow.mapNotNull { state -> state.tabs.map {tab -> tab.id} }
.distinctUntilChanged()
.collect { tabs ->
flutterEvents.onTabListChange(tabs) { _ -> }
flutterEvents.onTabListChange(System.currentTimeMillis(), tabs) { _ -> }
}
}
@@ -280,6 +286,7 @@ open class DefaultComponents(
.collect { tab ->
logger.info("title: ${tab.content.title} ${tab.content.url}")
flutterEvents.onTabContentStateChange(
System.currentTimeMillis(),
TabContentState(
id = tab.id,
contextId = tab.contextId,
@@ -303,6 +310,7 @@ open class DefaultComponents(
.collect { tab ->
tab.content.findResults
flutterEvents.onFindResults(
System.currentTimeMillis(),
tab.id,
tab.content.findResults.map { result -> FindResultState(
activeMatchOrdinal = result.activeMatchOrdinal.toLong(),
@@ -40,7 +40,9 @@ private class NativeFragmentView(
override fun onFlutterViewAttached(flutterView: View) {
super.onFlutterViewAttached(flutterView)
flutterEvents.onFragmentReadyStateChange(true) { _ -> }
GlobalComponents.components!!.engineReportedInitialized = false;
flutterEvents.onViewReadyStateChange(System.currentTimeMillis(),true) { _ -> }
}
override fun getView(): View {
@@ -84,8 +84,6 @@ object GlobalComponents {
Logger.error("Failed to initialize web extension support", e)
}
newComponents.tabsUseCases.addTab.invoke("https://google.com", selectTab = true)
_components = newComponents
}
}
@@ -1,9 +1,21 @@
package eu.lensai.flutter_mozilla_components.api
import eu.lensai.flutter_mozilla_components.GlobalComponents
import eu.lensai.flutter_mozilla_components.pigeons.GeckoBrowserApi
import mozilla.components.browser.state.action.SystemAction
import mozilla.components.feature.addons.logger
class GeckoBrowserApiImpl(private val showFragmentCallback: () -> Unit) : GeckoBrowserApi {
override fun showNativeFragment() {
showFragmentCallback.invoke();
}
override fun onTrimMemory(level: Long) {
logger.debug("onTrimMemory: $level")
val components = GlobalComponents.components!!
components.store.dispatch(SystemAction.LowMemoryAction(level.toInt()))
components.icons.onTrimMemory(level.toInt())
}
}
@@ -19,7 +19,13 @@ import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import mozilla.components.browser.icons.BrowserIcons
import mozilla.components.browser.icons.IconRequest
import mozilla.components.browser.session.storage.RecoverableBrowserState
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.selector.findTab
@@ -43,6 +49,7 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
private val engine: Engine by lazy { GlobalComponents.components!!.engine }
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
private val thumbnailStorage: ThumbnailStorage by lazy { GlobalComponents.components!!.thumbnailStorage }
private val icons: BrowserIcons by lazy { GlobalComponents.components!!.icons }
private val events: GeckoStateEvents by lazy { GlobalComponents.components!!.flutterEvents }
private fun restoreSource(source: SourceValue ) : SessionState.Source {
@@ -115,19 +122,27 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
onFindResults: Boolean,
onThumbnailChange: Boolean,
) {
val tabs = state.tabs.map { x -> x.copy() }.toList()
val selectedTab = state.selectedTabId
if(onSelectedTabChange) {
events.onSelectedTabChange(
state.selectedTabId
System.currentTimeMillis(),
selectedTab
) { _ -> }
}
if(onTabListChange) {
events.onTabListChange(state.tabs.map {tab -> tab.id}) { _ -> }
events.onTabListChange(
System.currentTimeMillis(),
tabs.map {tab -> tab.id}
) { _ -> }
}
if(onTabContentStateChange) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
events.onTabContentStateChange(
System.currentTimeMillis(),
TabContentState(
id = tab.id,
contextId = tab.contextId,
@@ -143,21 +158,35 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
}
if(onIconChange) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
if(tab.content.icon != null) {
val iconBytes = tab.content.icon?.toWebPBytes()
events.onIconChange(
System.currentTimeMillis(),
tab.id,
iconBytes
) { _ -> }
} else {
CoroutineScope(Dispatchers.Default).launch {
val result = icons.loadIcon(IconRequest(url = tab.content.url)).await()
val iconBytes = result.bitmap.toWebPBytes()
runOnUiThread {
events.onIconChange(
System.currentTimeMillis(),
tab.id,
iconBytes
) { _ -> }
}
}
}
}
}
if(onSecurityInfoStateChange) {
state.tabs.forEach { tab ->
val iconBytes = tab.content.icon?.toWebPBytes()
tabs.forEach { tab ->
events.onSecurityInfoStateChange(
System.currentTimeMillis(),
tab.id,
SecurityInfoState(
tab.content.securityInfo.secure,
@@ -169,8 +198,9 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
}
if(onReaderableStateChange) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
events.onReaderableStateChange(
System.currentTimeMillis(),
tab.id,
ReaderableState(
tab.readerState.readerable,
@@ -181,8 +211,9 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
}
if(onHistoryStateChange) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
events.onHistoryStateChange(
System.currentTimeMillis(),
tab.id,
HistoryState(
items = tab.content.history.items.map { item -> HistoryItem(
@@ -198,8 +229,9 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
}
if(onFindResults) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
events.onFindResults(
System.currentTimeMillis(),
tab.id,
tab.content.findResults.map { result -> FindResultState(
activeMatchOrdinal = result.activeMatchOrdinal.toLong(),
@@ -211,13 +243,13 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
}
if(onThumbnailChange) {
state.tabs.forEach { tab ->
tabs.forEach { tab ->
CoroutineScope(Dispatchers.Default).launch {
val bitmap = thumbnailStorage.loadThumbnail(
ImageLoadRequest(
id = tab.id,
//TODO: make this configurable
size = 600,
size = 1024,
isPrivate = tab.content.private
)
).await()
@@ -225,7 +257,7 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
if(bitmap != null) {
val bytes = bitmap.toWebPBytes()
runOnUiThread {
events.onThumbnailChange(tab.id, bytes) { _ -> }
events.onThumbnailChange(System.currentTimeMillis(), tab.id, bytes) { _ -> }
}
}
}
@@ -4,6 +4,23 @@ import android.graphics.Bitmap
import android.os.Build
import java.io.ByteArrayOutputStream
fun Bitmap.resize(maxWidth: Int, maxHeight: Int): Bitmap {
var width = this.width
var height = this.height
val aspectRatio: Float = width.toFloat() / height.toFloat()
if (width > height) {
width = maxWidth
height = (width / aspectRatio).toInt()
} else {
height = maxHeight
width = (height * aspectRatio).toInt()
}
return Bitmap.createScaledBitmap(this, width, height, true)
}
fun Bitmap.toWebPBytes(): ByteArray {
val stream = ByteArrayOutputStream()
val compressFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -5,16 +5,22 @@ package eu.lensai.flutter_mozilla_components.middleware
import android.graphics.Bitmap
import android.util.Log
import eu.lensai.flutter_mozilla_components.GlobalComponents
import eu.lensai.flutter_mozilla_components.ext.resize
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
import mozilla.components.browser.state.action.BrowserAction
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.LastAccessAction
import mozilla.components.browser.state.action.ReaderAction
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.feature.addons.logger
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
import java.io.ByteArrayOutputStream
import kotlin.reflect.typeOf
/**
@@ -30,13 +36,37 @@ class FlutterEventMiddleware(private val flutterEvents: GeckoStateEvents) : Midd
) {
when (action) {
is ContentAction.UpdateThumbnailAction -> {
val bytes = action.thumbnail.toWebPBytes()
val resized = action.thumbnail.resize(maxWidth = 640, maxHeight = 480);
val bytes = resized.toWebPBytes()
runOnUiThread {
flutterEvents.onThumbnailChange(action.sessionId, bytes) { _ -> }
flutterEvents.onThumbnailChange(System.currentTimeMillis(), action.sessionId, bytes) { _ -> }
}
}
//UpdateReaderConnectRequiredAction seems to be the only event that is called predictable
//after a hot reload
is ReaderAction.UpdateReaderConnectRequiredAction -> {
if(!GlobalComponents.components!!.engineReportedInitialized) {
runOnUiThread {
flutterEvents.onEngineReadyStateChange(
System.currentTimeMillis(),
true
) { _ -> }
}
GlobalComponents.components!!.engineReportedInitialized = true
}
}
is TabListAction.AddTabAction -> {
runOnUiThread {
flutterEvents.onTabAdded(
System.currentTimeMillis(),
action.tab.id
) { _ -> }
}
}
else -> {
// no-op
//logger.debug("Event fired: " + action.javaClass.name)
}
}
next(action)
@@ -1158,6 +1158,7 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface GeckoBrowserApi {
fun showNativeFragment()
fun onTrimMemory(level: Long)
companion object {
/** The codec used by GeckoBrowserApi. */
@@ -1184,6 +1185,24 @@ interface GeckoBrowserApi {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoBrowserApi.onTrimMemory$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val levelArg = args[0] as Long
val wrapped: List<Any?> = try {
api.onTrimMemory(levelArg)
listOf(null)
} catch (exception: Throwable) {
wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
@@ -2153,12 +2172,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
GeckoPigeonCodec()
}
}
fun onFragmentReadyStateChange(stateArg: Boolean, callback: (Result<Unit>) -> Unit)
fun onViewReadyStateChange(timestampArg: Long, stateArg: Boolean, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange$separatedMessageChannelSuffix"
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onViewReadyStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(stateArg)) {
channel.send(listOf(timestampArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2170,12 +2189,46 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onTabListChange(tabIdsArg: List<String>, callback: (Result<Unit>) -> Unit)
fun onEngineReadyStateChange(timestampArg: Long, stateArg: Boolean, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onEngineReadyStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(timestampArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
} else {
callback(Result.success(Unit))
}
} else {
callback(Result.failure(createConnectionError(channelName)))
}
}
}
fun onTabAdded(timestampArg: Long, tabIdArg: String, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabAdded$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(timestampArg, tabIdArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
} else {
callback(Result.success(Unit))
}
} else {
callback(Result.failure(createConnectionError(channelName)))
}
}
}
fun onTabListChange(timestampArg: Long, tabIdsArg: List<String>, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabListChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(tabIdsArg)) {
channel.send(listOf(timestampArg, tabIdsArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2187,12 +2240,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onSelectedTabChange(idArg: String?, callback: (Result<Unit>) -> Unit)
fun onSelectedTabChange(timestampArg: Long, idArg: String?, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onSelectedTabChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg)) {
channel.send(listOf(timestampArg, idArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2204,12 +2257,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onTabContentStateChange(stateArg: TabContentState, callback: (Result<Unit>) -> Unit)
fun onTabContentStateChange(timestampArg: Long, stateArg: TabContentState, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabContentStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(stateArg)) {
channel.send(listOf(timestampArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2221,12 +2274,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onHistoryStateChange(idArg: String, stateArg: HistoryState, callback: (Result<Unit>) -> Unit)
fun onHistoryStateChange(timestampArg: Long, idArg: String, stateArg: HistoryState, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onHistoryStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, stateArg)) {
channel.send(listOf(timestampArg, idArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2238,12 +2291,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onReaderableStateChange(idArg: String, stateArg: ReaderableState, callback: (Result<Unit>) -> Unit)
fun onReaderableStateChange(timestampArg: Long, idArg: String, stateArg: ReaderableState, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onReaderableStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, stateArg)) {
channel.send(listOf(timestampArg, idArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2255,12 +2308,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onSecurityInfoStateChange(idArg: String, stateArg: SecurityInfoState, callback: (Result<Unit>) -> Unit)
fun onSecurityInfoStateChange(timestampArg: Long, idArg: String, stateArg: SecurityInfoState, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onSecurityInfoStateChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, stateArg)) {
channel.send(listOf(timestampArg, idArg, stateArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2272,12 +2325,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onIconChange(idArg: String, bytesArg: ByteArray?, callback: (Result<Unit>) -> Unit)
fun onIconChange(timestampArg: Long, idArg: String, bytesArg: ByteArray?, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onIconChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, bytesArg)) {
channel.send(listOf(timestampArg, idArg, bytesArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2289,12 +2342,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onThumbnailChange(idArg: String, bytesArg: ByteArray?, callback: (Result<Unit>) -> Unit)
fun onThumbnailChange(timestampArg: Long, idArg: String, bytesArg: ByteArray?, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onThumbnailChange$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, bytesArg)) {
channel.send(listOf(timestampArg, idArg, bytesArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
@@ -2306,12 +2359,12 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
}
}
}
fun onFindResults(idArg: String, resultsArg: List<FindResultState>, callback: (Result<Unit>) -> Unit)
fun onFindResults(timestampArg: Long, idArg: String, resultsArg: List<FindResultState>, callback: (Result<Unit>) -> Unit)
{
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFindResults$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(idArg, resultsArg)) {
channel.send(listOf(timestampArg, idArg, resultsArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))