deprecate and strip pref manager extension; rebuild pigeons;
This commit is contained in:
+33
-12
@@ -125,11 +125,22 @@ Future<PreferenceSettingGroup> _preferenceSettingGroup(
|
|||||||
@Riverpod()
|
@Riverpod()
|
||||||
class _PreferenceRepository extends _$PreferenceRepository {
|
class _PreferenceRepository extends _$PreferenceRepository {
|
||||||
final _prefManager = GeckoPrefService();
|
final _prefManager = GeckoPrefService();
|
||||||
// Use BehaviorSubject instead of StreamController
|
|
||||||
late BehaviorSubject<Map<String, GeckoPref>> _prefSubject;
|
late BehaviorSubject<Map<String, GeckoPref>> _prefSubject;
|
||||||
|
|
||||||
Future<void> _updatePrefs() async {
|
Future<void> _updatePrefs() async {
|
||||||
final prefs = await _prefManager.getAllPrefs();
|
final groups = await ref.read(
|
||||||
|
_preferenceSettingGroupsProvider(partition).future,
|
||||||
|
);
|
||||||
|
|
||||||
|
final prefNames = groups.values
|
||||||
|
.map((group) => group.settings.keys)
|
||||||
|
.flattened
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final prefs = prefNames.isEmpty
|
||||||
|
? <String, GeckoPref>{}
|
||||||
|
: await _prefManager.getPrefs(prefNames);
|
||||||
|
|
||||||
_prefSubject.add(prefs);
|
_prefSubject.add(prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,18 +155,28 @@ class _PreferenceRepository extends _$PreferenceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Raw<Stream<Map<String, GeckoPref>>> build() {
|
Raw<Stream<Map<String, GeckoPref>>> build(
|
||||||
|
PreferencePartition partition,
|
||||||
|
) async* {
|
||||||
|
final prefCompleter = Completer();
|
||||||
|
|
||||||
_prefSubject = BehaviorSubject<Map<String, GeckoPref>>();
|
_prefSubject = BehaviorSubject<Map<String, GeckoPref>>();
|
||||||
|
|
||||||
ref.onDispose(() async {
|
ref.onDispose(() async {
|
||||||
await _prefSubject.close();
|
await _prefSubject.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
ref.onAddListener(() async {
|
ref.onAddListener(() {
|
||||||
await _updatePrefs();
|
if (prefCompleter.isCompleted) {
|
||||||
|
ref.invalidateSelf();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return _prefSubject.stream;
|
await _updatePrefs().whenComplete(() {
|
||||||
|
prefCompleter.complete();
|
||||||
|
});
|
||||||
|
|
||||||
|
yield* _prefSubject.stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +187,7 @@ class UnifiedPreferenceSettingsRepository
|
|||||||
|
|
||||||
Future<void> apply() async {
|
Future<void> apply() async {
|
||||||
final preferenceRepository = ref.read(
|
final preferenceRepository = ref.read(
|
||||||
_preferenceRepositoryProvider.notifier,
|
_preferenceRepositoryProvider(partition).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
_statelessGroups = await ref.read(
|
_statelessGroups = await ref.read(
|
||||||
@@ -187,7 +208,7 @@ class UnifiedPreferenceSettingsRepository
|
|||||||
|
|
||||||
Future<void> reset() async {
|
Future<void> reset() async {
|
||||||
final preferenceRepository = ref.read(
|
final preferenceRepository = ref.read(
|
||||||
_preferenceRepositoryProvider.notifier,
|
_preferenceRepositoryProvider(partition).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
_statelessGroups = await ref.read(
|
_statelessGroups = await ref.read(
|
||||||
@@ -210,7 +231,7 @@ class UnifiedPreferenceSettingsRepository
|
|||||||
_preferenceSettingGroupsProvider(partition).future,
|
_preferenceSettingGroupsProvider(partition).future,
|
||||||
);
|
);
|
||||||
|
|
||||||
final prefStream = ref.watch(_preferenceRepositoryProvider);
|
final prefStream = ref.watch(_preferenceRepositoryProvider(partition));
|
||||||
|
|
||||||
yield* prefStream.map(
|
yield* prefStream.map(
|
||||||
(prefs) => _statelessGroups!.map(
|
(prefs) => _statelessGroups!.map(
|
||||||
@@ -235,7 +256,7 @@ class PreferenceSettingsGroupRepository
|
|||||||
|
|
||||||
Future<void> apply({List<String>? filter}) async {
|
Future<void> apply({List<String>? filter}) async {
|
||||||
final preferenceRepository = ref.read(
|
final preferenceRepository = ref.read(
|
||||||
_preferenceRepositoryProvider.notifier,
|
_preferenceRepositoryProvider(partition).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
_statelessSettingGroup ??= await ref.read(
|
_statelessSettingGroup ??= await ref.read(
|
||||||
@@ -260,7 +281,7 @@ class PreferenceSettingsGroupRepository
|
|||||||
|
|
||||||
Future<void> reset({List<String>? filter}) async {
|
Future<void> reset({List<String>? filter}) async {
|
||||||
final preferenceRepository = ref.read(
|
final preferenceRepository = ref.read(
|
||||||
_preferenceRepositoryProvider.notifier,
|
_preferenceRepositoryProvider(partition).notifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
_statelessSettingGroup ??= await ref.read(
|
_statelessSettingGroup ??= await ref.read(
|
||||||
@@ -288,7 +309,7 @@ class PreferenceSettingsGroupRepository
|
|||||||
_preferenceSettingGroupProvider(partition, groupName).future,
|
_preferenceSettingGroupProvider(partition, groupName).future,
|
||||||
);
|
);
|
||||||
|
|
||||||
final prefStream = ref.watch(_preferenceRepositoryProvider);
|
final prefStream = ref.watch(_preferenceRepositoryProvider(partition));
|
||||||
|
|
||||||
yield* prefStream.map(
|
yield* prefStream.map(
|
||||||
(prefs) => _statelessSettingGroup!.copyWith.settings(
|
(prefs) => _statelessSettingGroup!.copyWith.settings(
|
||||||
|
|||||||
+55
-10
@@ -279,7 +279,7 @@ final class _PreferenceSettingGroupFamily extends $Family
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ProviderFor(_PreferenceRepository)
|
@ProviderFor(_PreferenceRepository)
|
||||||
final _preferenceRepositoryProvider = _PreferenceRepositoryProvider._();
|
final _preferenceRepositoryProvider = _PreferenceRepositoryFamily._();
|
||||||
|
|
||||||
final class _PreferenceRepositoryProvider
|
final class _PreferenceRepositoryProvider
|
||||||
extends
|
extends
|
||||||
@@ -287,10 +287,10 @@ final class _PreferenceRepositoryProvider
|
|||||||
_PreferenceRepository,
|
_PreferenceRepository,
|
||||||
Raw<Stream<Map<String, GeckoPref>>>
|
Raw<Stream<Map<String, GeckoPref>>>
|
||||||
> {
|
> {
|
||||||
_PreferenceRepositoryProvider._()
|
_PreferenceRepositoryProvider._({
|
||||||
: super(
|
required _PreferenceRepositoryFamily super.from,
|
||||||
from: null,
|
required PreferencePartition super.argument,
|
||||||
argument: null,
|
}) : super(
|
||||||
retry: null,
|
retry: null,
|
||||||
name: r'_preferenceRepositoryProvider',
|
name: r'_preferenceRepositoryProvider',
|
||||||
isAutoDispose: true,
|
isAutoDispose: true,
|
||||||
@@ -301,6 +301,13 @@ final class _PreferenceRepositoryProvider
|
|||||||
@override
|
@override
|
||||||
String debugGetCreateSourceHash() => _$_preferenceRepositoryHash();
|
String debugGetCreateSourceHash() => _$_preferenceRepositoryHash();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return r'_preferenceRepositoryProvider'
|
||||||
|
''
|
||||||
|
'($argument)';
|
||||||
|
}
|
||||||
|
|
||||||
@$internal
|
@$internal
|
||||||
@override
|
@override
|
||||||
_PreferenceRepository create() => _PreferenceRepository();
|
_PreferenceRepository create() => _PreferenceRepository();
|
||||||
@@ -314,14 +321,52 @@ final class _PreferenceRepositoryProvider
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is _PreferenceRepositoryProvider && other.argument == argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return argument.hashCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$_preferenceRepositoryHash() =>
|
String _$_preferenceRepositoryHash() =>
|
||||||
r'0f6812988a23407f6648e32fb1585984d2433bbc';
|
r'b7a0aab286dd1f8da758de5cf259ad0c14b733d9';
|
||||||
|
|
||||||
|
final class _PreferenceRepositoryFamily extends $Family
|
||||||
|
with
|
||||||
|
$ClassFamilyOverride<
|
||||||
|
_PreferenceRepository,
|
||||||
|
Raw<Stream<Map<String, GeckoPref>>>,
|
||||||
|
Raw<Stream<Map<String, GeckoPref>>>,
|
||||||
|
Raw<Stream<Map<String, GeckoPref>>>,
|
||||||
|
PreferencePartition
|
||||||
|
> {
|
||||||
|
_PreferenceRepositoryFamily._()
|
||||||
|
: super(
|
||||||
|
retry: null,
|
||||||
|
name: r'_preferenceRepositoryProvider',
|
||||||
|
dependencies: null,
|
||||||
|
$allTransitiveDependencies: null,
|
||||||
|
isAutoDispose: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
_PreferenceRepositoryProvider call(PreferencePartition partition) =>
|
||||||
|
_PreferenceRepositoryProvider._(argument: partition, from: this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => r'_preferenceRepositoryProvider';
|
||||||
|
}
|
||||||
|
|
||||||
abstract class _$PreferenceRepository
|
abstract class _$PreferenceRepository
|
||||||
extends $Notifier<Raw<Stream<Map<String, GeckoPref>>>> {
|
extends $Notifier<Raw<Stream<Map<String, GeckoPref>>>> {
|
||||||
Raw<Stream<Map<String, GeckoPref>>> build();
|
late final _$args = ref.$arg as PreferencePartition;
|
||||||
|
PreferencePartition get partition => _$args;
|
||||||
|
|
||||||
|
Raw<Stream<Map<String, GeckoPref>>> build(PreferencePartition partition);
|
||||||
@$mustCallSuper
|
@$mustCallSuper
|
||||||
@override
|
@override
|
||||||
void runBuild() {
|
void runBuild() {
|
||||||
@@ -342,7 +387,7 @@ abstract class _$PreferenceRepository
|
|||||||
Object?,
|
Object?,
|
||||||
Object?
|
Object?
|
||||||
>;
|
>;
|
||||||
element.handleCreate(ref, build);
|
element.handleCreate(ref, () => build(_$args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +441,7 @@ final class UnifiedPreferenceSettingsRepositoryProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$unifiedPreferenceSettingsRepositoryHash() =>
|
String _$unifiedPreferenceSettingsRepositoryHash() =>
|
||||||
r'800e74a051113b4ebc3631b6ade55d66cb7e1af1';
|
r'03c8c2f247974ff32bba14b4b34857a0f14f6f37';
|
||||||
|
|
||||||
final class UnifiedPreferenceSettingsRepositoryFamily extends $Family
|
final class UnifiedPreferenceSettingsRepositoryFamily extends $Family
|
||||||
with
|
with
|
||||||
@@ -509,7 +554,7 @@ final class PreferenceSettingsGroupRepositoryProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$preferenceSettingsGroupRepositoryHash() =>
|
String _$preferenceSettingsGroupRepositoryHash() =>
|
||||||
r'8e025cdea5cef8a6ea029db6f9ebcd86abf906d8';
|
r'b5c439643ec78094122c33983e58d0977641832a';
|
||||||
|
|
||||||
final class PreferenceSettingsGroupRepositoryFamily extends $Family
|
final class PreferenceSettingsGroupRepositoryFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { BackgroundTasksUtils } = ChromeUtils.importESModule(
|
|
||||||
"resource://gre/modules/BackgroundTasksUtils.sys.mjs"
|
|
||||||
);
|
|
||||||
|
|
||||||
const lazy = {};
|
|
||||||
|
|
||||||
ChromeUtils.defineLazyGetter(lazy, "log", () => {
|
|
||||||
let { ConsoleAPI } = ChromeUtils.importESModule(
|
|
||||||
"resource://gre/modules/Console.sys.mjs"
|
|
||||||
);
|
|
||||||
let consoleOptions = {
|
|
||||||
// tip: set maxLogLevel to "debug" and use log.debug() to create detailed
|
|
||||||
// messages during development. See LOG_LEVELS in Console.sys.mjs for details.
|
|
||||||
maxLogLevel: "error",
|
|
||||||
maxLogLevelPref: "app.update.background.loglevel",
|
|
||||||
prefix: "PrefsManager",
|
|
||||||
};
|
|
||||||
return new ConsoleAPI(consoleOptions);
|
|
||||||
});
|
|
||||||
|
|
||||||
var prefmanager = class extends ExtensionAPI {
|
|
||||||
getAPI(context) {
|
|
||||||
return {
|
|
||||||
experiments: {
|
|
||||||
prefmanager: {
|
|
||||||
async getPrefList() {
|
|
||||||
return Services.prefs.getChildList("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
|
|
||||||
const port = browser.runtime.connectNative("prefManager");
|
|
||||||
|
|
||||||
function sendJsonResultForRequest(id) {
|
|
||||||
return function (result) {
|
|
||||||
port.postMessage({
|
|
||||||
"id": id,
|
|
||||||
"status": "success",
|
|
||||||
"result": result
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendErrorForRequest(id) {
|
|
||||||
return function (error) {
|
|
||||||
console.error(error);
|
|
||||||
port.postMessage({
|
|
||||||
"id": id,
|
|
||||||
"status": "error",
|
|
||||||
"error": error
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
port.onMessage.addListener(message => {
|
|
||||||
let requestId = message["id"]
|
|
||||||
switch (message["action"]) {
|
|
||||||
case "getPrefList":
|
|
||||||
browser.experiments.prefmanager.getPrefList()
|
|
||||||
.then(sendJsonResultForRequest(requestId))
|
|
||||||
.catch(sendErrorForRequest(requestId))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"manifest_version": 2,
|
|
||||||
"name": "Pref Manager",
|
|
||||||
"version": "1.0",
|
|
||||||
"description": "Manipulate GeckoView preferences",
|
|
||||||
"browser_specific_settings": {
|
|
||||||
"gecko": {
|
|
||||||
"id": "pref-manager@weblibre.eu"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"background": {
|
|
||||||
"scripts": [
|
|
||||||
"background.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"experiment_apis": {
|
|
||||||
"prefmanager": {
|
|
||||||
"schema": "schema.json",
|
|
||||||
"parent": {
|
|
||||||
"scopes": [
|
|
||||||
"addon_parent"
|
|
||||||
],
|
|
||||||
"paths": [
|
|
||||||
[
|
|
||||||
"experiments",
|
|
||||||
"prefmanager"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"script": "api.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"permissions": [
|
|
||||||
"nativeMessaging",
|
|
||||||
"nativeMessagingFromContent",
|
|
||||||
"geckoViewAddons",
|
|
||||||
"<all_urls>"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"namespace": "experiments.prefmanager",
|
|
||||||
"description": "Experimental API for updating Geckoview preferences",
|
|
||||||
"functions": [
|
|
||||||
{
|
|
||||||
"name": "getPrefList",
|
|
||||||
"type": "function",
|
|
||||||
"description": "Retrieves list of all preferences",
|
|
||||||
"async": true,
|
|
||||||
"parameters": [],
|
|
||||||
"returns": {
|
|
||||||
"array": "object",
|
|
||||||
"description": "Object containing the preferences as key-value pairs",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
-2
@@ -7,7 +7,6 @@ package eu.weblibre.flutter_mozilla_components
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.ContainerProxyFeature
|
import eu.weblibre.flutter_mozilla_components.feature.ContainerProxyFeature
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.CookieManagerFeature
|
import eu.weblibre.flutter_mozilla_components.feature.CookieManagerFeature
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.PrefManagerFeature
|
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.BrowserExtensionFeature
|
import eu.weblibre.flutter_mozilla_components.feature.BrowserExtensionFeature
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.MLEngineFeature
|
import eu.weblibre.flutter_mozilla_components.feature.MLEngineFeature
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.BounceTrackingProtectionMode
|
import eu.weblibre.flutter_mozilla_components.pigeons.BounceTrackingProtectionMode
|
||||||
@@ -122,7 +121,6 @@ object EngineProvider {
|
|||||||
return GeckoEngine(context, defaultSettings, runtime).also {
|
return GeckoEngine(context, defaultSettings, runtime).also {
|
||||||
WebCompatFeature.install(it)
|
WebCompatFeature.install(it)
|
||||||
//CookieManagerFeature.install(it)
|
//CookieManagerFeature.install(it)
|
||||||
PrefManagerFeature.install(it)
|
|
||||||
ContainerProxyFeature.install(it, stateEvents)
|
ContainerProxyFeature.install(it, stateEvents)
|
||||||
BrowserExtensionFeature.install(it, extensionEvents)
|
BrowserExtensionFeature.install(it, extensionEvents)
|
||||||
MLEngineFeature.install(it)
|
MLEngineFeature.install(it)
|
||||||
|
|||||||
-43
@@ -8,61 +8,18 @@ package eu.weblibre.flutter_mozilla_components.api
|
|||||||
|
|
||||||
import eu.weblibre.flutter_mozilla_components.GlobalComponents
|
import eu.weblibre.flutter_mozilla_components.GlobalComponents
|
||||||
import eu.weblibre.flutter_mozilla_components.ext.EventSequence
|
import eu.weblibre.flutter_mozilla_components.ext.EventSequence
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.PrefManagerFeature
|
|
||||||
import eu.weblibre.flutter_mozilla_components.feature.ResultConsumer
|
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPref
|
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPref
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPrefApi
|
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPrefApi
|
||||||
import mozilla.components.ExperimentalAndroidComponentsApi
|
import mozilla.components.ExperimentalAndroidComponentsApi
|
||||||
import mozilla.components.concept.engine.preferences.Branch
|
import mozilla.components.concept.engine.preferences.Branch
|
||||||
import mozilla.components.concept.engine.preferences.BrowserPrefObserverDelegate
|
import mozilla.components.concept.engine.preferences.BrowserPrefObserverDelegate
|
||||||
import mozilla.components.concept.engine.preferences.BrowserPreference
|
import mozilla.components.concept.engine.preferences.BrowserPreference
|
||||||
import mozilla.components.support.ktx.android.org.json.toList
|
|
||||||
import org.json.JSONObject
|
|
||||||
import org.json.JSONArray
|
|
||||||
|
|
||||||
class GeckoPrefApiImpl : GeckoPrefApi, BrowserPrefObserverDelegate {
|
class GeckoPrefApiImpl : GeckoPrefApi, BrowserPrefObserverDelegate {
|
||||||
private val components by lazy {
|
private val components by lazy {
|
||||||
requireNotNull(GlobalComponents.components) { "Components not initialized" }
|
requireNotNull(GlobalComponents.components) { "Components not initialized" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<String>?.toJson(): JSONArray {
|
|
||||||
return JSONArray().apply {
|
|
||||||
this@toJson?.forEach { put(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun JSONObject.toMap(): Map<String, Any> {
|
|
||||||
val map = mutableMapOf<String, Any>()
|
|
||||||
val keys = this.keys()
|
|
||||||
|
|
||||||
while (keys.hasNext()) {
|
|
||||||
val key = keys.next()
|
|
||||||
when (val value = this.get(key)) {
|
|
||||||
is JSONObject -> map[key] = value.toMap()
|
|
||||||
// is JSONArray -> map[key] = value.toList()
|
|
||||||
// JSONObject.NULL -> map[key] = null
|
|
||||||
else -> map[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPrefList(callback: (Result<List<String>>) -> Unit) {
|
|
||||||
PrefManagerFeature.scheduleRequest(
|
|
||||||
"getPrefList",
|
|
||||||
Unit,
|
|
||||||
object : ResultConsumer<JSONObject> {
|
|
||||||
override fun success(result: JSONObject) {
|
|
||||||
callback(Result.success(result.getJSONArray("result").toList()))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
|
||||||
callback(Result.failure(Exception("$errorCode $errorMessage $errorDetails")))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalAndroidComponentsApi::class)
|
@OptIn(ExperimentalAndroidComponentsApi::class)
|
||||||
override fun getPrefs(
|
override fun getPrefs(
|
||||||
preferenceFilter: List<String>,
|
preferenceFilter: List<String>,
|
||||||
|
|||||||
-107
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package eu.weblibre.flutter_mozilla_components.feature
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import mozilla.components.concept.engine.webextension.MessageHandler
|
|
||||||
import mozilla.components.concept.engine.webextension.Port
|
|
||||||
import mozilla.components.concept.engine.webextension.WebExtensionRuntime
|
|
||||||
import mozilla.components.support.base.log.logger.Logger
|
|
||||||
import mozilla.components.support.webextensions.BuiltInWebExtensionController
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
object PrefManagerFeature {
|
|
||||||
private val logger = Logger("pref-manager")
|
|
||||||
|
|
||||||
private const val PREF_MANAGER_REPORTER_EXTENSION_ID = "pref-manager@weblibre.eu"
|
|
||||||
private const val PREF_MANAGER_REPORTER_EXTENSION_URL = "resource://android/assets/extensions/pref_manager/"
|
|
||||||
private const val PREF_MANAGER_REPORTER_MESSAGING_ID = "prefManager"
|
|
||||||
|
|
||||||
private var nextRequestId: Int = 0
|
|
||||||
private val requestHandlers = HashMap<Int, ResultConsumer<JSONObject>>()
|
|
||||||
private val mutex = Mutex()
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
// This is an internal var to make it mutable for unit testing purposes only
|
|
||||||
internal var extensionController = BuiltInWebExtensionController(
|
|
||||||
PREF_MANAGER_REPORTER_EXTENSION_ID,
|
|
||||||
PREF_MANAGER_REPORTER_EXTENSION_URL,
|
|
||||||
PREF_MANAGER_REPORTER_MESSAGING_ID,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun scheduleRequest(command: String, args: Any, callback: ResultConsumer<JSONObject>) {
|
|
||||||
val message = JSONObject()
|
|
||||||
message.put("action", command);
|
|
||||||
message.put("args", args)
|
|
||||||
|
|
||||||
runBlocking {
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
mutex.withLock {
|
|
||||||
message.put("id", nextRequestId)
|
|
||||||
|
|
||||||
requestHandlers[nextRequestId] = callback
|
|
||||||
|
|
||||||
nextRequestId += 1
|
|
||||||
|
|
||||||
extensionController.sendBackgroundMessage(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PrefManagerReporterBackgroundMessageHandler() : MessageHandler {
|
|
||||||
override fun onPortMessage(message: Any, port: Port) {
|
|
||||||
runBlocking {
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
mutex.withLock {
|
|
||||||
val messageJSON = message as JSONObject;
|
|
||||||
|
|
||||||
val requestId = messageJSON.getInt("id")
|
|
||||||
val status = messageJSON.getString("status")
|
|
||||||
val handler = requestHandlers.remove(requestId)
|
|
||||||
if (status == "success") {
|
|
||||||
handler?.success(message)
|
|
||||||
} else {
|
|
||||||
handler?.error(
|
|
||||||
"Pref Manager",
|
|
||||||
"Failed to perform operation",
|
|
||||||
message.getString("error")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs the web extension in the runtime through the WebExtensionRuntime install method
|
|
||||||
*
|
|
||||||
* @param runtime a WebExtensionRuntime.
|
|
||||||
* @param productName a custom product name used to automatically label reports. Defaults to
|
|
||||||
* "android-components".
|
|
||||||
*/
|
|
||||||
fun install(runtime: WebExtensionRuntime) {
|
|
||||||
extensionController.registerBackgroundMessageHandler(
|
|
||||||
PrefManagerReporterBackgroundMessageHandler(),
|
|
||||||
)
|
|
||||||
extensionController.install(
|
|
||||||
runtime,
|
|
||||||
onSuccess = {
|
|
||||||
logger.debug("Installed PrefManager webextension: ${it.id}")
|
|
||||||
},
|
|
||||||
onError = { throwable ->
|
|
||||||
logger.error("Failed to install PrefManager webextension: ", throwable)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1083
-247
File diff suppressed because it is too large
Load Diff
@@ -9,14 +9,6 @@ import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
|||||||
final _apiInstance = GeckoPrefApi();
|
final _apiInstance = GeckoPrefApi();
|
||||||
|
|
||||||
class GeckoPrefService {
|
class GeckoPrefService {
|
||||||
Future<List<String>> getPrefList() {
|
|
||||||
return _apiInstance.getPrefList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, GeckoPref>> getAllPrefs() async {
|
|
||||||
return _apiInstance.getPrefs(await getPrefList());
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, GeckoPref>> getPrefs(List<String> prefs) {
|
Future<Map<String, GeckoPref>> getPrefs(List<String> prefs) {
|
||||||
return _apiInstance.getPrefs(prefs);
|
return _apiInstance.getPrefs(prefs);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1504,8 +1504,6 @@ class GeckoPref {
|
|||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class GeckoPrefApi {
|
abstract class GeckoPrefApi {
|
||||||
@async
|
|
||||||
List<String> getPrefList();
|
|
||||||
@async
|
@async
|
||||||
Map<String, GeckoPref> getPrefs(List<String> preferenceFilter);
|
Map<String, GeckoPref> getPrefs(List<String> preferenceFilter);
|
||||||
@async
|
@async
|
||||||
|
|||||||
+160
-18
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
@@ -37,7 +37,36 @@ private object TorApiPigeonUtils {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun doubleEquals(a: Double, b: Double): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0) 0.0 else a) == (if (b == 0.0) 0.0 else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatEquals(a: Float, b: Float): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0f) 0.0f else a) == (if (b == 0.0f) 0.0f else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doubleHash(d: Double): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (d == 0.0) 0.0 else d
|
||||||
|
val bits = java.lang.Double.doubleToLongBits(normalized)
|
||||||
|
return (bits xor (bits ushr 32)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatHash(f: Float): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (f == 0.0f) 0.0f else f
|
||||||
|
return java.lang.Float.floatToIntBits(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
fun deepEquals(a: Any?, b: Any?): Boolean {
|
fun deepEquals(a: Any?, b: Any?): Boolean {
|
||||||
|
if (a === b) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (a is ByteArray && b is ByteArray) {
|
if (a is ByteArray && b is ByteArray) {
|
||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
@@ -48,25 +77,110 @@ private object TorApiPigeonUtils {
|
|||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
if (a is DoubleArray && b is DoubleArray) {
|
if (a is DoubleArray && b is DoubleArray) {
|
||||||
return a.contentEquals(b)
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!doubleEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is FloatArray && b is FloatArray) {
|
||||||
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!floatEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Array<*> && b is Array<*>) {
|
if (a is Array<*> && b is Array<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
for (i in a.indices) {
|
||||||
|
if (!deepEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is List<*> && b is List<*>) {
|
if (a is List<*> && b is List<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
val iterA = a.iterator()
|
||||||
|
val iterB = b.iterator()
|
||||||
|
while (iterA.hasNext() && iterB.hasNext()) {
|
||||||
|
if (!deepEquals(iterA.next(), iterB.next())) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Map<*, *> && b is Map<*, *>) {
|
if (a is Map<*, *> && b is Map<*, *>) {
|
||||||
return a.size == b.size && a.all {
|
if (a.size != b.size) return false
|
||||||
(b as Map<Any?, Any?>).contains(it.key) &&
|
for (entry in a) {
|
||||||
deepEquals(it.value, b[it.key])
|
val key = entry.key
|
||||||
|
var found = false
|
||||||
|
for (bEntry in b) {
|
||||||
|
if (deepEquals(key, bEntry.key)) {
|
||||||
|
if (deepEquals(entry.value, bEntry.value)) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!found) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is Double && b is Double) {
|
||||||
|
return doubleEquals(a, b)
|
||||||
|
}
|
||||||
|
if (a is Float && b is Float) {
|
||||||
|
return floatEquals(a, b)
|
||||||
|
}
|
||||||
return a == b
|
return a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deepHash(value: Any?): Int {
|
||||||
|
return when (value) {
|
||||||
|
null -> 0
|
||||||
|
is ByteArray -> value.contentHashCode()
|
||||||
|
is IntArray -> value.contentHashCode()
|
||||||
|
is LongArray -> value.contentHashCode()
|
||||||
|
is DoubleArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + doubleHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is FloatArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + floatHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Array<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is List<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Map<*, *> -> {
|
||||||
|
var result = 0
|
||||||
|
for (entry in value) {
|
||||||
|
result += ((deepHash(entry.key) * 31) xor deepHash(entry.value))
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Double -> doubleHash(value)
|
||||||
|
is Float -> floatHash(value)
|
||||||
|
else -> value.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,15 +259,25 @@ data class TorConfiguration (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is TorConfiguration) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return TorApiPigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as TorConfiguration
|
||||||
|
return TorApiPigeonUtils.deepEquals(this.transport, other.transport) && TorApiPigeonUtils.deepEquals(this.bridgeLines, other.bridgeLines) && TorApiPigeonUtils.deepEquals(this.entryNodeCountries, other.entryNodeCountries) && TorApiPigeonUtils.deepEquals(this.exitNodeCountries, other.exitNodeCountries) && TorApiPigeonUtils.deepEquals(this.strictNodes, other.strictNodes)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.transport)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.bridgeLines)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.entryNodeCountries)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.exitNodeCountries)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.strictNodes)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,15 +318,25 @@ data class TorStatus (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is TorStatus) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return TorApiPigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as TorStatus
|
||||||
|
return TorApiPigeonUtils.deepEquals(this.isRunning, other.isRunning) && TorApiPigeonUtils.deepEquals(this.socksPort, other.socksPort) && TorApiPigeonUtils.deepEquals(this.bootstrapProgress, other.bootstrapProgress) && TorApiPigeonUtils.deepEquals(this.currentCircuit, other.currentCircuit) && TorApiPigeonUtils.deepEquals(this.exitNodeCountry, other.exitNodeCountry)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.isRunning)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.socksPort)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.bootstrapProgress)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.currentCircuit)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.exitNodeCountry)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -235,15 +369,23 @@ data class TorLogMessage (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is TorLogMessage) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return TorApiPigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as TorLogMessage
|
||||||
|
return TorApiPigeonUtils.deepEquals(this.severity, other.severity) && TorApiPigeonUtils.deepEquals(this.message, other.message) && TorApiPigeonUtils.deepEquals(this.timestamp, other.timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.severity)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.message)
|
||||||
|
result = 31 * result + TorApiPigeonUtils.deepHash(this.timestamp)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private open class TorApiPigeonCodec : StandardMessageCodec() {
|
private open class TorApiPigeonCodec : StandardMessageCodec() {
|
||||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||||
|
|||||||
@@ -1,19 +1,39 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
// ignore_for_file: unused_import, unused_shown_name
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
import 'dart:typed_data' show Float64List, Int32List, Int64List;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
|
||||||
|
|
||||||
PlatformException _createConnectionError(String channelName) {
|
Object? _extractReplyValueOrThrow(
|
||||||
return PlatformException(
|
List<Object?>? replyList,
|
||||||
|
String channelName, {
|
||||||
|
required bool isNullValid,
|
||||||
|
}) {
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
code: 'channel-error',
|
code: 'channel-error',
|
||||||
message: 'Unable to establish connection on channel: "$channelName".',
|
message: 'Unable to establish connection on channel: "$channelName".',
|
||||||
);
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return replyList.firstOrNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
||||||
if (empty) {
|
if (empty) {
|
||||||
@@ -25,19 +45,67 @@ List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty
|
|||||||
return <Object?>[error.code, error.message, error.details];
|
return <Object?>[error.code, error.message, error.details];
|
||||||
}
|
}
|
||||||
bool _deepEquals(Object? a, Object? b) {
|
bool _deepEquals(Object? a, Object? b) {
|
||||||
|
if (identical(a, b)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a is double && b is double) {
|
||||||
|
if (a.isNaN && b.isNaN) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
if (a is List && b is List) {
|
if (a is List && b is List) {
|
||||||
return a.length == b.length &&
|
return a.length == b.length &&
|
||||||
a.indexed
|
a.indexed
|
||||||
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
||||||
}
|
}
|
||||||
if (a is Map && b is Map) {
|
if (a is Map && b is Map) {
|
||||||
return a.length == b.length && a.entries.every((MapEntry<Object?, Object?> entry) =>
|
if (a.length != b.length) {
|
||||||
(b as Map<Object?, Object?>).containsKey(entry.key) &&
|
return false;
|
||||||
_deepEquals(entry.value, b[entry.key]));
|
}
|
||||||
|
for (final MapEntry<Object?, Object?> entryA in a.entries) {
|
||||||
|
bool found = false;
|
||||||
|
for (final MapEntry<Object?, Object?> entryB in b.entries) {
|
||||||
|
if (_deepEquals(entryA.key, entryB.key)) {
|
||||||
|
if (_deepEquals(entryA.value, entryB.value)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _deepHash(Object? value) {
|
||||||
|
if (value is List) {
|
||||||
|
return Object.hashAll(value.map(_deepHash));
|
||||||
|
}
|
||||||
|
if (value is Map) {
|
||||||
|
int result = 0;
|
||||||
|
for (final MapEntry<Object?, Object?> entry in value.entries) {
|
||||||
|
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (value is double && value.isNaN) {
|
||||||
|
// Normalize NaN to a consistent hash.
|
||||||
|
return 0x7FF8000000000000.hashCode;
|
||||||
|
}
|
||||||
|
if (value is double && value == 0.0) {
|
||||||
|
// Normalize -0.0 to 0.0 so they have the same hash code.
|
||||||
|
return 0.0.hashCode;
|
||||||
|
}
|
||||||
|
return value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Transport types for Tor connections
|
/// Transport types for Tor connections
|
||||||
enum TransportType {
|
enum TransportType {
|
||||||
@@ -101,7 +169,7 @@ class TorConfiguration {
|
|||||||
result as List<Object?>;
|
result as List<Object?>;
|
||||||
return TorConfiguration(
|
return TorConfiguration(
|
||||||
transport: result[0]! as TransportType,
|
transport: result[0]! as TransportType,
|
||||||
bridgeLines: (result[1] as List<Object?>?)!.cast<String>(),
|
bridgeLines: (result[1]! as List<Object?>).cast<String>(),
|
||||||
entryNodeCountries: result[2] as String?,
|
entryNodeCountries: result[2] as String?,
|
||||||
exitNodeCountries: result[3] as String?,
|
exitNodeCountries: result[3] as String?,
|
||||||
strictNodes: result[4] as bool?,
|
strictNodes: result[4] as bool?,
|
||||||
@@ -117,13 +185,12 @@ class TorConfiguration {
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return _deepEquals(encode(), other.encode());
|
return _deepEquals(transport, other.transport) && _deepEquals(bridgeLines, other.bridgeLines) && _deepEquals(entryNodeCountries, other.entryNodeCountries) && _deepEquals(exitNodeCountries, other.exitNodeCountries) && _deepEquals(strictNodes, other.strictNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||||
int get hashCode => Object.hashAll(_toList())
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Current Tor status
|
/// Current Tor status
|
||||||
@@ -184,13 +251,12 @@ class TorStatus {
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return _deepEquals(encode(), other.encode());
|
return _deepEquals(isRunning, other.isRunning) && _deepEquals(socksPort, other.socksPort) && _deepEquals(bootstrapProgress, other.bootstrapProgress) && _deepEquals(currentCircuit, other.currentCircuit) && _deepEquals(exitNodeCountry, other.exitNodeCountry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||||
int get hashCode => Object.hashAll(_toList())
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Log message from Tor
|
/// Log message from Tor
|
||||||
@@ -239,13 +305,12 @@ class TorLogMessage {
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return _deepEquals(encode(), other.encode());
|
return _deepEquals(severity, other.severity) && _deepEquals(message, other.message) && _deepEquals(timestamp, other.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||||
int get hashCode => Object.hashAll(_toList())
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -316,22 +381,14 @@ class TorApi {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[config]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[config]);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: false,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
return pigeonVar_replyValue! as int;
|
||||||
} 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 int?)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop Tor
|
/// Stop Tor
|
||||||
@@ -344,17 +401,13 @@ class TorApi {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
_extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: true,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current status
|
/// Get current status
|
||||||
@@ -367,22 +420,14 @@ class TorApi {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: false,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
return pigeonVar_replyValue! as TorStatus;
|
||||||
} 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 TorStatus?)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request a new Tor identity (new circuit)
|
/// Request a new Tor identity (new circuit)
|
||||||
@@ -395,17 +440,13 @@ class TorApi {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
_extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: true,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,14 +470,10 @@ abstract class TorLogApi {
|
|||||||
pigeonVar_channel.setMessageHandler(null);
|
pigeonVar_channel.setMessageHandler(null);
|
||||||
} else {
|
} else {
|
||||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||||
assert(message != null,
|
final List<Object?> args = message! as List<Object?>;
|
||||||
'Argument for dev.flutter.pigeon.flutter_tor.TorLogApi.onLogMessage was null.');
|
final TorLogMessage arg_log = args[0]! as TorLogMessage;
|
||||||
final List<Object?> args = (message as List<Object?>?)!;
|
|
||||||
final TorLogMessage? arg_log = (args[0] as TorLogMessage?);
|
|
||||||
assert(arg_log != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_tor.TorLogApi.onLogMessage was null, expected non-null TorLogMessage.');
|
|
||||||
try {
|
try {
|
||||||
api.onLogMessage(arg_log!);
|
api.onLogMessage(arg_log);
|
||||||
return wrapResponse(empty: true);
|
return wrapResponse(empty: true);
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
return wrapResponse(error: e);
|
return wrapResponse(error: e);
|
||||||
@@ -454,14 +491,10 @@ abstract class TorLogApi {
|
|||||||
pigeonVar_channel.setMessageHandler(null);
|
pigeonVar_channel.setMessageHandler(null);
|
||||||
} else {
|
} else {
|
||||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||||
assert(message != null,
|
final List<Object?> args = message! as List<Object?>;
|
||||||
'Argument for dev.flutter.pigeon.flutter_tor.TorLogApi.onStatusChanged was null.');
|
final TorStatus arg_status = args[0]! as TorStatus;
|
||||||
final List<Object?> args = (message as List<Object?>?)!;
|
|
||||||
final TorStatus? arg_status = (args[0] as TorStatus?);
|
|
||||||
assert(arg_status != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_tor.TorLogApi.onStatusChanged was null, expected non-null TorStatus.');
|
|
||||||
try {
|
try {
|
||||||
api.onStatusChanged(arg_status!);
|
api.onStatusChanged(arg_status);
|
||||||
return wrapResponse(empty: true);
|
return wrapResponse(empty: true);
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
return wrapResponse(error: e);
|
return wrapResponse(error: e);
|
||||||
@@ -496,22 +529,14 @@ class IPtProxyController {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType, proxy]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType, proxy]);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: false,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
return pigeonVar_replyValue! as int;
|
||||||
} 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 int?)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> stop(TransportType proxyType) async {
|
Future<void> stop(TransportType proxyType) async {
|
||||||
@@ -523,16 +548,12 @@ class IPtProxyController {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[proxyType]);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
_extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: true,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+133
-12
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
@@ -34,7 +34,36 @@ private object LocalesPigeonUtils {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun doubleEquals(a: Double, b: Double): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0) 0.0 else a) == (if (b == 0.0) 0.0 else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatEquals(a: Float, b: Float): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0f) 0.0f else a) == (if (b == 0.0f) 0.0f else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doubleHash(d: Double): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (d == 0.0) 0.0 else d
|
||||||
|
val bits = java.lang.Double.doubleToLongBits(normalized)
|
||||||
|
return (bits xor (bits ushr 32)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatHash(f: Float): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (f == 0.0f) 0.0f else f
|
||||||
|
return java.lang.Float.floatToIntBits(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
fun deepEquals(a: Any?, b: Any?): Boolean {
|
fun deepEquals(a: Any?, b: Any?): Boolean {
|
||||||
|
if (a === b) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (a is ByteArray && b is ByteArray) {
|
if (a is ByteArray && b is ByteArray) {
|
||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
@@ -45,25 +74,110 @@ private object LocalesPigeonUtils {
|
|||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
if (a is DoubleArray && b is DoubleArray) {
|
if (a is DoubleArray && b is DoubleArray) {
|
||||||
return a.contentEquals(b)
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!doubleEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is FloatArray && b is FloatArray) {
|
||||||
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!floatEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Array<*> && b is Array<*>) {
|
if (a is Array<*> && b is Array<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
for (i in a.indices) {
|
||||||
|
if (!deepEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is List<*> && b is List<*>) {
|
if (a is List<*> && b is List<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
val iterA = a.iterator()
|
||||||
|
val iterB = b.iterator()
|
||||||
|
while (iterA.hasNext() && iterB.hasNext()) {
|
||||||
|
if (!deepEquals(iterA.next(), iterB.next())) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Map<*, *> && b is Map<*, *>) {
|
if (a is Map<*, *> && b is Map<*, *>) {
|
||||||
return a.size == b.size && a.all {
|
if (a.size != b.size) return false
|
||||||
(b as Map<Any?, Any?>).contains(it.key) &&
|
for (entry in a) {
|
||||||
deepEquals(it.value, b[it.key])
|
val key = entry.key
|
||||||
|
var found = false
|
||||||
|
for (bEntry in b) {
|
||||||
|
if (deepEquals(key, bEntry.key)) {
|
||||||
|
if (deepEquals(entry.value, bEntry.value)) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!found) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is Double && b is Double) {
|
||||||
|
return doubleEquals(a, b)
|
||||||
|
}
|
||||||
|
if (a is Float && b is Float) {
|
||||||
|
return floatEquals(a, b)
|
||||||
|
}
|
||||||
return a == b
|
return a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deepHash(value: Any?): Int {
|
||||||
|
return when (value) {
|
||||||
|
null -> 0
|
||||||
|
is ByteArray -> value.contentHashCode()
|
||||||
|
is IntArray -> value.contentHashCode()
|
||||||
|
is LongArray -> value.contentHashCode()
|
||||||
|
is DoubleArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + doubleHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is FloatArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + floatHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Array<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is List<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Map<*, *> -> {
|
||||||
|
var result = 0
|
||||||
|
for (entry in value) {
|
||||||
|
result += ((deepHash(entry.key) * 31) xor deepHash(entry.value))
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Double -> doubleHash(value)
|
||||||
|
is Float -> floatHash(value)
|
||||||
|
else -> value.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,15 +212,22 @@ data class LocalizedResult (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is LocalizedResult) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return LocalesPigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as LocalizedResult
|
||||||
|
return LocalesPigeonUtils.deepEquals(this.languageName, other.languageName) && LocalesPigeonUtils.deepEquals(this.countryName, other.countryName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + LocalesPigeonUtils.deepHash(this.languageName)
|
||||||
|
result = 31 * result + LocalesPigeonUtils.deepHash(this.countryName)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private open class LocalesPigeonCodec : StandardMessageCodec() {
|
private open class LocalesPigeonCodec : StandardMessageCodec() {
|
||||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||||
|
|||||||
@@ -1,33 +1,101 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
// ignore_for_file: unused_import, unused_shown_name
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
import 'dart:typed_data' show Float64List, Int32List, Int64List;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
|
||||||
|
|
||||||
PlatformException _createConnectionError(String channelName) {
|
Object? _extractReplyValueOrThrow(
|
||||||
return PlatformException(
|
List<Object?>? replyList,
|
||||||
|
String channelName, {
|
||||||
|
required bool isNullValid,
|
||||||
|
}) {
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
code: 'channel-error',
|
code: 'channel-error',
|
||||||
message: 'Unable to establish connection on channel: "$channelName".',
|
message: 'Unable to establish connection on channel: "$channelName".',
|
||||||
);
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return replyList.firstOrNull;
|
||||||
|
}
|
||||||
|
|
||||||
bool _deepEquals(Object? a, Object? b) {
|
bool _deepEquals(Object? a, Object? b) {
|
||||||
|
if (identical(a, b)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a is double && b is double) {
|
||||||
|
if (a.isNaN && b.isNaN) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
if (a is List && b is List) {
|
if (a is List && b is List) {
|
||||||
return a.length == b.length &&
|
return a.length == b.length &&
|
||||||
a.indexed
|
a.indexed
|
||||||
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
||||||
}
|
}
|
||||||
if (a is Map && b is Map) {
|
if (a is Map && b is Map) {
|
||||||
return a.length == b.length && a.entries.every((MapEntry<Object?, Object?> entry) =>
|
if (a.length != b.length) {
|
||||||
(b as Map<Object?, Object?>).containsKey(entry.key) &&
|
return false;
|
||||||
_deepEquals(entry.value, b[entry.key]));
|
}
|
||||||
|
for (final MapEntry<Object?, Object?> entryA in a.entries) {
|
||||||
|
bool found = false;
|
||||||
|
for (final MapEntry<Object?, Object?> entryB in b.entries) {
|
||||||
|
if (_deepEquals(entryA.key, entryB.key)) {
|
||||||
|
if (_deepEquals(entryA.value, entryB.value)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _deepHash(Object? value) {
|
||||||
|
if (value is List) {
|
||||||
|
return Object.hashAll(value.map(_deepHash));
|
||||||
|
}
|
||||||
|
if (value is Map) {
|
||||||
|
int result = 0;
|
||||||
|
for (final MapEntry<Object?, Object?> entry in value.entries) {
|
||||||
|
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (value is double && value.isNaN) {
|
||||||
|
// Normalize NaN to a consistent hash.
|
||||||
|
return 0x7FF8000000000000.hashCode;
|
||||||
|
}
|
||||||
|
if (value is double && value == 0.0) {
|
||||||
|
// Normalize -0.0 to 0.0 so they have the same hash code.
|
||||||
|
return 0.0.hashCode;
|
||||||
|
}
|
||||||
|
return value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class LocalizedResult {
|
class LocalizedResult {
|
||||||
LocalizedResult({
|
LocalizedResult({
|
||||||
@@ -66,13 +134,12 @@ class LocalizedResult {
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return _deepEquals(encode(), other.encode());
|
return _deepEquals(languageName, other.languageName) && _deepEquals(countryName, other.countryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||||
int get hashCode => Object.hashAll(_toList())
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -124,21 +191,13 @@ class LocaleResolver {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[languageTag, targetLangouageTag]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[languageTag, targetLangouageTag]);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: false,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
return pigeonVar_replyValue! as LocalizedResult;
|
||||||
} 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 LocalizedResult?)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+137
-12
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
@@ -17,7 +17,36 @@ private object IntentPigeonUtils {
|
|||||||
|
|
||||||
fun createConnectionError(channelName: String): FlutterError {
|
fun createConnectionError(channelName: String): FlutterError {
|
||||||
return FlutterError("channel-error", "Unable to establish connection on channel: '$channelName'.", "") }
|
return FlutterError("channel-error", "Unable to establish connection on channel: '$channelName'.", "") }
|
||||||
|
fun doubleEquals(a: Double, b: Double): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0) 0.0 else a) == (if (b == 0.0) 0.0 else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatEquals(a: Float, b: Float): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0f) 0.0f else a) == (if (b == 0.0f) 0.0f else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doubleHash(d: Double): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (d == 0.0) 0.0 else d
|
||||||
|
val bits = java.lang.Double.doubleToLongBits(normalized)
|
||||||
|
return (bits xor (bits ushr 32)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatHash(f: Float): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (f == 0.0f) 0.0f else f
|
||||||
|
return java.lang.Float.floatToIntBits(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
fun deepEquals(a: Any?, b: Any?): Boolean {
|
fun deepEquals(a: Any?, b: Any?): Boolean {
|
||||||
|
if (a === b) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (a is ByteArray && b is ByteArray) {
|
if (a is ByteArray && b is ByteArray) {
|
||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
@@ -28,25 +57,110 @@ private object IntentPigeonUtils {
|
|||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
if (a is DoubleArray && b is DoubleArray) {
|
if (a is DoubleArray && b is DoubleArray) {
|
||||||
return a.contentEquals(b)
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!doubleEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is FloatArray && b is FloatArray) {
|
||||||
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!floatEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Array<*> && b is Array<*>) {
|
if (a is Array<*> && b is Array<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
for (i in a.indices) {
|
||||||
|
if (!deepEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is List<*> && b is List<*>) {
|
if (a is List<*> && b is List<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
val iterA = a.iterator()
|
||||||
|
val iterB = b.iterator()
|
||||||
|
while (iterA.hasNext() && iterB.hasNext()) {
|
||||||
|
if (!deepEquals(iterA.next(), iterB.next())) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Map<*, *> && b is Map<*, *>) {
|
if (a is Map<*, *> && b is Map<*, *>) {
|
||||||
return a.size == b.size && a.all {
|
if (a.size != b.size) return false
|
||||||
(b as Map<Any?, Any?>).contains(it.key) &&
|
for (entry in a) {
|
||||||
deepEquals(it.value, b[it.key])
|
val key = entry.key
|
||||||
|
var found = false
|
||||||
|
for (bEntry in b) {
|
||||||
|
if (deepEquals(key, bEntry.key)) {
|
||||||
|
if (deepEquals(entry.value, bEntry.value)) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!found) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is Double && b is Double) {
|
||||||
|
return doubleEquals(a, b)
|
||||||
|
}
|
||||||
|
if (a is Float && b is Float) {
|
||||||
|
return floatEquals(a, b)
|
||||||
|
}
|
||||||
return a == b
|
return a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deepHash(value: Any?): Int {
|
||||||
|
return when (value) {
|
||||||
|
null -> 0
|
||||||
|
is ByteArray -> value.contentHashCode()
|
||||||
|
is IntArray -> value.contentHashCode()
|
||||||
|
is LongArray -> value.contentHashCode()
|
||||||
|
is DoubleArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + doubleHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is FloatArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + floatHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Array<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is List<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Map<*, *> -> {
|
||||||
|
var result = 0
|
||||||
|
for (entry in value) {
|
||||||
|
result += ((deepHash(entry.key) * 31) xor deepHash(entry.value))
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Double -> doubleHash(value)
|
||||||
|
is Float -> floatHash(value)
|
||||||
|
else -> value.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,15 +207,26 @@ data class Intent (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is Intent) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return IntentPigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as Intent
|
||||||
|
return IntentPigeonUtils.deepEquals(this.fromPackageName, other.fromPackageName) && IntentPigeonUtils.deepEquals(this.action, other.action) && IntentPigeonUtils.deepEquals(this.data, other.data) && IntentPigeonUtils.deepEquals(this.categories, other.categories) && IntentPigeonUtils.deepEquals(this.mimeType, other.mimeType) && IntentPigeonUtils.deepEquals(this.extra, other.extra)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.fromPackageName)
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.action)
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.data)
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.categories)
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.mimeType)
|
||||||
|
result = 31 * result + IntentPigeonUtils.deepHash(this.extra)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private open class IntentPigeonCodec : StandardMessageCodec() {
|
private open class IntentPigeonCodec : StandardMessageCodec() {
|
||||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
// ignore_for_file: unused_import, unused_shown_name
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
import 'dart:typed_data' show Float64List, Int32List, Int64List;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
|
||||||
|
|
||||||
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
||||||
if (empty) {
|
if (empty) {
|
||||||
@@ -18,19 +19,67 @@ List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty
|
|||||||
return <Object?>[error.code, error.message, error.details];
|
return <Object?>[error.code, error.message, error.details];
|
||||||
}
|
}
|
||||||
bool _deepEquals(Object? a, Object? b) {
|
bool _deepEquals(Object? a, Object? b) {
|
||||||
|
if (identical(a, b)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a is double && b is double) {
|
||||||
|
if (a.isNaN && b.isNaN) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
if (a is List && b is List) {
|
if (a is List && b is List) {
|
||||||
return a.length == b.length &&
|
return a.length == b.length &&
|
||||||
a.indexed
|
a.indexed
|
||||||
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
.every(((int, dynamic) item) => _deepEquals(item.$2, b[item.$1]));
|
||||||
}
|
}
|
||||||
if (a is Map && b is Map) {
|
if (a is Map && b is Map) {
|
||||||
return a.length == b.length && a.entries.every((MapEntry<Object?, Object?> entry) =>
|
if (a.length != b.length) {
|
||||||
(b as Map<Object?, Object?>).containsKey(entry.key) &&
|
return false;
|
||||||
_deepEquals(entry.value, b[entry.key]));
|
}
|
||||||
|
for (final MapEntry<Object?, Object?> entryA in a.entries) {
|
||||||
|
bool found = false;
|
||||||
|
for (final MapEntry<Object?, Object?> entryB in b.entries) {
|
||||||
|
if (_deepEquals(entryA.key, entryB.key)) {
|
||||||
|
if (_deepEquals(entryA.value, entryB.value)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _deepHash(Object? value) {
|
||||||
|
if (value is List) {
|
||||||
|
return Object.hashAll(value.map(_deepHash));
|
||||||
|
}
|
||||||
|
if (value is Map) {
|
||||||
|
int result = 0;
|
||||||
|
for (final MapEntry<Object?, Object?> entry in value.entries) {
|
||||||
|
result += (_deepHash(entry.key) * 31) ^ _deepHash(entry.value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (value is double && value.isNaN) {
|
||||||
|
// Normalize NaN to a consistent hash.
|
||||||
|
return 0x7FF8000000000000.hashCode;
|
||||||
|
}
|
||||||
|
if (value is double && value == 0.0) {
|
||||||
|
// Normalize -0.0 to 0.0 so they have the same hash code.
|
||||||
|
return 0.0.hashCode;
|
||||||
|
}
|
||||||
|
return value.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Intent {
|
class Intent {
|
||||||
Intent({
|
Intent({
|
||||||
@@ -74,9 +123,9 @@ class Intent {
|
|||||||
fromPackageName: result[0] as String?,
|
fromPackageName: result[0] as String?,
|
||||||
action: result[1] as String?,
|
action: result[1] as String?,
|
||||||
data: result[2] as String?,
|
data: result[2] as String?,
|
||||||
categories: (result[3] as List<Object?>?)!.cast<String>(),
|
categories: (result[3]! as List<Object?>).cast<String>(),
|
||||||
mimeType: result[4] as String?,
|
mimeType: result[4] as String?,
|
||||||
extra: (result[5] as Map<Object?, Object?>?)!.cast<String, Object?>(),
|
extra: (result[5]! as Map<Object?, Object?>).cast<String, Object?>(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,13 +138,12 @@ class Intent {
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return _deepEquals(encode(), other.encode());
|
return _deepEquals(fromPackageName, other.fromPackageName) && _deepEquals(action, other.action) && _deepEquals(data, other.data) && _deepEquals(categories, other.categories) && _deepEquals(mimeType, other.mimeType) && _deepEquals(extra, other.extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||||||
int get hashCode => Object.hashAll(_toList())
|
int get hashCode => _deepHash(<Object?>[runtimeType, ..._toList()]);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,17 +188,11 @@ abstract class IntentEvents {
|
|||||||
pigeonVar_channel.setMessageHandler(null);
|
pigeonVar_channel.setMessageHandler(null);
|
||||||
} else {
|
} else {
|
||||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||||
assert(message != null,
|
final List<Object?> args = message! as List<Object?>;
|
||||||
'Argument for dev.flutter.pigeon.simple_intent_receiver.IntentEvents.onIntentReceived was null.');
|
final int arg_sequence = args[0]! as int;
|
||||||
final List<Object?> args = (message as List<Object?>?)!;
|
final Intent arg_intent = args[1]! as Intent;
|
||||||
final int? arg_sequence = (args[0] as int?);
|
|
||||||
assert(arg_sequence != null,
|
|
||||||
'Argument for dev.flutter.pigeon.simple_intent_receiver.IntentEvents.onIntentReceived was null, expected non-null int.');
|
|
||||||
final Intent? arg_intent = (args[1] as Intent?);
|
|
||||||
assert(arg_intent != null,
|
|
||||||
'Argument for dev.flutter.pigeon.simple_intent_receiver.IntentEvents.onIntentReceived was null, expected non-null Intent.');
|
|
||||||
try {
|
try {
|
||||||
api.onIntentReceived(arg_sequence!, arg_intent!);
|
api.onIntentReceived(arg_sequence, arg_intent);
|
||||||
return wrapResponse(empty: true);
|
return wrapResponse(empty: true);
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
return wrapResponse(error: e);
|
return wrapResponse(error: e);
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,39 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.7), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.2), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
// ignore_for_file: unused_import, unused_shown_name
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
import 'dart:typed_data' show Float64List, Int32List, Int64List;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:meta/meta.dart' show immutable, protected, visibleForTesting;
|
||||||
|
|
||||||
PlatformException _createConnectionError(String channelName) {
|
Object? _extractReplyValueOrThrow(
|
||||||
return PlatformException(
|
List<Object?>? replyList,
|
||||||
|
String channelName, {
|
||||||
|
required bool isNullValid,
|
||||||
|
}) {
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
code: 'channel-error',
|
code: 'channel-error',
|
||||||
message: 'Unable to establish connection on channel: "$channelName".',
|
message: 'Unable to establish connection on channel: "$channelName".',
|
||||||
);
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return replyList.firstOrNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
||||||
if (empty) {
|
if (empty) {
|
||||||
@@ -77,22 +97,14 @@ class SpeechToTextApi {
|
|||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[locale]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[locale]);
|
||||||
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
} else if (pigeonVar_replyList.length > 1) {
|
pigeonVar_replyList,
|
||||||
throw PlatformException(
|
pigeonVar_channelName,
|
||||||
code: pigeonVar_replyList[0]! as String,
|
isNullValid: false,
|
||||||
message: pigeonVar_replyList[1] as String?,
|
)
|
||||||
details: pigeonVar_replyList[2],
|
;
|
||||||
);
|
return pigeonVar_replyValue! as bool;
|
||||||
} 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 bool?)!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,14 +128,10 @@ abstract class SpeechToTextEvents {
|
|||||||
pigeonVar_channel.setMessageHandler(null);
|
pigeonVar_channel.setMessageHandler(null);
|
||||||
} else {
|
} else {
|
||||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||||
assert(message != null,
|
final List<Object?> args = message! as List<Object?>;
|
||||||
'Argument for dev.flutter.pigeon.speech_to_text_dialog.SpeechToTextEvents.onTextReceived was null.');
|
final String arg_text = args[0]! as String;
|
||||||
final List<Object?> args = (message as List<Object?>?)!;
|
|
||||||
final String? arg_text = (args[0] as String?);
|
|
||||||
assert(arg_text != null,
|
|
||||||
'Argument for dev.flutter.pigeon.speech_to_text_dialog.SpeechToTextEvents.onTextReceived was null, expected non-null String.');
|
|
||||||
try {
|
try {
|
||||||
api.onTextReceived(arg_text!);
|
api.onTextReceived(arg_text);
|
||||||
return wrapResponse(empty: true);
|
return wrapResponse(empty: true);
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
return wrapResponse(error: e);
|
return wrapResponse(error: e);
|
||||||
|
|||||||
Reference in New Issue
Block a user