deprecate and strip pref manager extension; rebuild pigeons;

This commit is contained in:
Fabian Freund
2026-04-16 08:08:26 +02:00
parent b3576d4b49
commit 560a0b51be
21 changed files with 3497 additions and 3367 deletions
@@ -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("");
}
}
}
};
}
};
@@ -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))
}
});
@@ -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>"
]
}
@@ -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"
}
}
}
]
}
]
@@ -7,7 +7,6 @@ package eu.weblibre.flutter_mozilla_components
import android.content.Context
import eu.weblibre.flutter_mozilla_components.feature.ContainerProxyFeature
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.MLEngineFeature
import eu.weblibre.flutter_mozilla_components.pigeons.BounceTrackingProtectionMode
@@ -122,7 +121,6 @@ object EngineProvider {
return GeckoEngine(context, defaultSettings, runtime).also {
WebCompatFeature.install(it)
//CookieManagerFeature.install(it)
PrefManagerFeature.install(it)
ContainerProxyFeature.install(it, stateEvents)
BrowserExtensionFeature.install(it, extensionEvents)
MLEngineFeature.install(it)
@@ -8,61 +8,18 @@ package eu.weblibre.flutter_mozilla_components.api
import eu.weblibre.flutter_mozilla_components.GlobalComponents
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.GeckoPrefApi
import mozilla.components.ExperimentalAndroidComponentsApi
import mozilla.components.concept.engine.preferences.Branch
import mozilla.components.concept.engine.preferences.BrowserPrefObserverDelegate
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 {
private val components by lazy {
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)
override fun getPrefs(
preferenceFilter: List<String>,
@@ -212,4 +169,4 @@ class GeckoPrefApiImpl : GeckoPrefApi, BrowserPrefObserverDelegate {
)
) { _ -> }
}
}
}
@@ -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)
},
)
}
}
@@ -9,14 +9,6 @@ import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
final _apiInstance = GeckoPrefApi();
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) {
return _apiInstance.getPrefs(prefs);
}
File diff suppressed because it is too large Load Diff
@@ -1504,8 +1504,6 @@ class GeckoPref {
@HostApi()
abstract class GeckoPrefApi {
@async
List<String> getPrefList();
@async
Map<String, GeckoPref> getPrefs(List<String> preferenceFilter);
@async