intermediate prefs

This commit is contained in:
Fabian Freund
2025-01-30 10:46:38 +01:00
parent 78c17a70c5
commit 36acd46318
51 changed files with 3744 additions and 1719 deletions
@@ -0,0 +1,119 @@
"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 resetPrefs(prefNames) {
if (prefNames && prefNames.length > 0) {
for (const prefName of prefNames) {
Services.prefs.clearUserPref(prefName);
}
} else {
Services.prefs.resetPrefs();
}
},
async getPrefs(prefNames) {
const prefs = (prefNames && prefNames.length > 0)
? prefNames
: Services.prefs.getChildList("");
const result = {};
for (const prefName of prefs) {
try {
switch (Services.prefs.getPrefType(prefName)) {
case Services.prefs.PREF_BOOL:
result[prefName] = Services.prefs.getBoolPref(prefName);
break;
case Services.prefs.PREF_INT:
result[prefName] = Services.prefs.getIntPref(prefName);
break;
case Services.prefs.PREF_STRING:
result[prefName] = Services.prefs.getCharPref(prefName);
break;
default:
// Skip complex values or invalid preferences
continue;
}
} catch (e) {
lazy.log.error(`Error reading preference ${prefName}: ${e}`);
continue;
}
}
lazy.log.debug(`getAll: retrieved ${Object.keys(result).length} preferences`);
return result;
},
async parsePrefsAndApply(prefsFileContent, predicate = null) {
let prefs = {};
let addPref = (kind, name, value) => {
if (predicate && !predicate(name)) {
return;
}
prefs[name] = value;
};
Services.prefs.parsePrefsFromBuffer(
prefsFileContent,
{
onStringPref: addPref,
onIntPref: addPref,
onBoolPref: addPref,
onError(message) {
throw new Error(
`Error parsing preferences "${message}"`
);
},
},
);
await BackgroundTasksUtils.withProfileLock(profileLock => {
for (let [name, value] of Object.entries(prefs)) {
switch (typeof value) {
case "boolean":
Services.prefs.setBoolPref(name, value);
break;
case "number":
Services.prefs.setIntPref(name, value);
break;
case "string":
Services.prefs.setCharPref(name, value);
break;
default:
throw new Error(
`Pref from default profile with name "${name}" has unrecognized type`
);
}
}
});
lazy.log.debug(`applyPreferences: parsed prefs from buffer`, prefs);
return prefs;
}
}
}
};
}
};
@@ -0,0 +1,47 @@
'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 "parsePrefsAndApply":
browser.experiments.prefmanager.parsePrefsAndApply(encoder.encode(message["args"]), null)
.then(sendJsonResultForRequest(requestId))
.catch(sendErrorForRequest(requestId))
break
case "getPrefs":
browser.experiments.prefmanager.getPrefs(message["args"])
.then(sendJsonResultForRequest(requestId))
.catch(sendErrorForRequest(requestId))
break
case "resetPrefs":
browser.experiments.prefmanager.resetPrefs(message["args"])
.then(sendJsonResultForRequest(requestId))
.catch(sendErrorForRequest(requestId))
break
}
});
@@ -0,0 +1,39 @@
{
"manifest_version": 2,
"name": "Pref Manager",
"version": "1.0",
"description": "Manipulate GeckoView preferences",
"browser_specific_settings": {
"gecko": {
"id": "pref-manager@movenext.me"
}
},
"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>"
]
}
@@ -0,0 +1,78 @@
[
{
"namespace": "experiments.prefmanager",
"description": "Experimental API for updating Geckoview preferences",
"functions": [
{
"name": "getPrefs",
"type": "function",
"description": "Retrieves preferences and their values",
"async": true,
"parameters": [
{
"name": "prefNames",
"type": "array",
"optional": true,
"description": "Array of preference names to retrieve. If empty or null, retrieves all preferences",
"items": {
"type": "string"
}
}
],
"returns": {
"type": "object",
"description": "Object containing the preferences as key-value pairs",
"additionalProperties": {
"type": "any",
"description": "Preference values can be boolean, number, or string"
}
}
},
{
"name": "parsePrefsAndApply",
"type": "function",
"description": "Reads and sets preferences from an encoded preferences file content",
"async": true,
"parameters": [
{
"name": "prefsFileContent",
"type": "object",
"isInstanceOf": "Uint8Array",
"description": "Encoded content of the preferences file to parse (Uint8Array)"
},
{
"name": "predicate",
"type": "function",
"optional": true,
"description": "Optional filter function to determine which preferences to include"
}
],
"returns": {
"type": "object",
"description": "Object containing the parsed preferences as key-value pairs",
"additionalProperties": {
"type": "any",
"description": "Preference values can be boolean, number, or string"
}
}
},
{
"name": "resetPrefs",
"type": "function",
"description": "Resets multiple or all preferences to their default values",
"async": true,
"parameters": [
{
"name": "prefNames",
"type": "array",
"optional": true,
"description": "Array of preference names to reset. If empty or null, resets all preferences",
"items": {
"type": "string"
}
}
]
}
]
}
]