switch to new gecko pref api
This commit is contained in:
+2
-86
@@ -25,92 +25,8 @@ var prefmanager = class extends ExtensionAPI {
|
||||
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;
|
||||
async getPrefList() {
|
||||
return Services.prefs.getChildList("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-13
@@ -28,20 +28,9 @@ function sendErrorForRequest(id) {
|
||||
port.onMessage.addListener(message => {
|
||||
let requestId = message["id"]
|
||||
switch (message["action"]) {
|
||||
case "parsePrefsAndApply":
|
||||
browser.experiments.prefmanager.parsePrefsAndApply(encoder.encode(message["args"]), null)
|
||||
case "getPrefList":
|
||||
browser.experiments.prefmanager.getPrefList()
|
||||
.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
|
||||
}
|
||||
});
|
||||
|
||||
+6
-62
@@ -4,74 +4,18 @@
|
||||
"description": "Experimental API for updating Geckoview preferences",
|
||||
"functions": [
|
||||
{
|
||||
"name": "getPrefs",
|
||||
"name": "getPrefList",
|
||||
"type": "function",
|
||||
"description": "Retrieves preferences and their values",
|
||||
"description": "Retrieves list of all preferences",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": [],
|
||||
"returns": {
|
||||
"type": "object",
|
||||
"array": "object",
|
||||
"description": "Object containing the preferences as key-value pairs",
|
||||
"additionalProperties": {
|
||||
"type": "any",
|
||||
"description": "Preference values can be boolean, number, or string"
|
||||
"items": {
|
||||
"type": "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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+111
-27
@@ -6,13 +6,22 @@
|
||||
|
||||
package eu.weblibre.flutter_mozilla_components.api
|
||||
|
||||
import eu.weblibre.flutter_mozilla_components.GlobalComponents
|
||||
import eu.weblibre.flutter_mozilla_components.feature.PrefManagerFeature
|
||||
import eu.weblibre.flutter_mozilla_components.feature.ResultConsumer
|
||||
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPrefApi
|
||||
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoPrefValue
|
||||
import mozilla.components.ExperimentalAndroidComponentsApi
|
||||
import mozilla.components.concept.engine.preferences.Branch
|
||||
import mozilla.components.support.ktx.android.org.json.toList
|
||||
import org.json.JSONObject
|
||||
import org.json.JSONArray
|
||||
|
||||
class GeckoPrefApiImpl : GeckoPrefApi {
|
||||
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) }
|
||||
@@ -36,44 +45,119 @@ class GeckoPrefApiImpl : GeckoPrefApi {
|
||||
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>?,
|
||||
callback: (Result<Map<String, Any>>) -> Unit
|
||||
preferenceFilter: List<String>,
|
||||
callback: (Result<Map<String, GeckoPrefValue>>) -> Unit
|
||||
) {
|
||||
PrefManagerFeature.scheduleRequest("getPrefs", preferenceFilter.toJson(), object : ResultConsumer<JSONObject> {
|
||||
override fun success(result: JSONObject) {
|
||||
callback(Result.success(result.getJSONObject("result").toMap()))
|
||||
components.core.engine.getBrowserPrefs(
|
||||
preferenceFilter, onSuccess = {
|
||||
callback(
|
||||
Result.success(
|
||||
it.associate {
|
||||
it.pref to GeckoPrefValue(
|
||||
value = it.value,
|
||||
defaultValue = it.defaultValue,
|
||||
userValue = it.userValue,
|
||||
hasUserChangedValue = it.hasUserChangedValue,
|
||||
)
|
||||
})
|
||||
)
|
||||
},
|
||||
onError = {
|
||||
callback(Result.failure(Exception("${it.message} ${it.cause}")))
|
||||
}
|
||||
|
||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
||||
callback(Result.failure(Exception("$errorCode $errorMessage $errorDetails")))
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
override fun applyPrefs(prefBuffer: String, callback: (Result<Map<String, Any>>) -> Unit) {
|
||||
PrefManagerFeature.scheduleRequest("parsePrefsAndApply", prefBuffer, object : ResultConsumer<JSONObject> {
|
||||
override fun success(result: JSONObject) {
|
||||
callback(Result.success(result.getJSONObject("result").toMap()))
|
||||
@OptIn(ExperimentalAndroidComponentsApi::class)
|
||||
override fun applyPrefs(
|
||||
prefs: Map<String, Any>,
|
||||
callback: (Result<Map<String, GeckoPrefValue>>) -> Unit
|
||||
) {
|
||||
var fault: Boolean = false;
|
||||
|
||||
for (pref in prefs) {
|
||||
when (pref.value) {
|
||||
is String -> components.core.engine.setBrowserPref(
|
||||
pref.key,
|
||||
pref.value as String,
|
||||
Branch.USER,
|
||||
onSuccess = {},
|
||||
onError = {
|
||||
callback(Result.failure(Exception("${it.message} ${it.cause}")))
|
||||
fault = true
|
||||
}
|
||||
)
|
||||
|
||||
is Boolean -> components.core.engine.setBrowserPref(
|
||||
pref.key,
|
||||
pref.value as Boolean,
|
||||
Branch.USER,
|
||||
onSuccess = {},
|
||||
onError = {
|
||||
callback(Result.failure(Exception("${it.message} ${it.cause}")))
|
||||
fault = true
|
||||
}
|
||||
)
|
||||
|
||||
is Long -> components.core.engine.setBrowserPref(
|
||||
pref.key,
|
||||
(pref.value as Long).toInt(),
|
||||
Branch.USER,
|
||||
onSuccess = {},
|
||||
onError = {
|
||||
callback(Result.failure(Exception("${it.message} ${it.cause}")))
|
||||
fault = true
|
||||
}
|
||||
)
|
||||
|
||||
else -> {
|
||||
callback(Result.failure(Exception("Unsupported value type: ${pref.value::class.simpleName}")))
|
||||
fault = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
||||
callback(Result.failure(Exception("$errorCode $errorMessage $errorDetails")))
|
||||
if (fault) {
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getPrefs(
|
||||
prefs.keys.toList(),
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
|
||||
override fun resetPrefs(preferenceNames: List<String>?, callback: (Result<Unit>) -> Unit) {
|
||||
PrefManagerFeature.scheduleRequest("resetPrefs", preferenceNames.toJson(), object : ResultConsumer<JSONObject> {
|
||||
override fun success(result: JSONObject) {
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
@OptIn(ExperimentalAndroidComponentsApi::class)
|
||||
override fun resetPrefs(preferenceNames: List<String>, callback: (Result<Unit>) -> Unit) {
|
||||
var fault: Boolean = false;
|
||||
|
||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
||||
callback(Result.failure(Exception("$errorCode $errorMessage $errorDetails")))
|
||||
for (pref in preferenceNames) {
|
||||
components.core.engine.clearBrowserUserPref(
|
||||
pref = pref,
|
||||
onSuccess = {},
|
||||
onError = {
|
||||
callback(Result.failure(Exception("${it.message} ${it.cause}")))
|
||||
fault = true
|
||||
}
|
||||
)
|
||||
|
||||
if (fault) {
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+73
-8
@@ -2194,6 +2194,43 @@ data class AddonCollection (
|
||||
|
||||
override fun hashCode(): Int = toList().hashCode()
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
data class GeckoPrefValue (
|
||||
val value: Any? = null,
|
||||
val defaultValue: Any? = null,
|
||||
val userValue: Any? = null,
|
||||
val hasUserChangedValue: Boolean
|
||||
)
|
||||
{
|
||||
companion object {
|
||||
fun fromList(pigeonVar_list: List<Any?>): GeckoPrefValue {
|
||||
val value = pigeonVar_list[0]
|
||||
val defaultValue = pigeonVar_list[1]
|
||||
val userValue = pigeonVar_list[2]
|
||||
val hasUserChangedValue = pigeonVar_list[3] as Boolean
|
||||
return GeckoPrefValue(value, defaultValue, userValue, hasUserChangedValue)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf(
|
||||
value,
|
||||
defaultValue,
|
||||
userValue,
|
||||
hasUserChangedValue,
|
||||
)
|
||||
}
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is GeckoPrefValue) {
|
||||
return false
|
||||
}
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
return GeckoPigeonUtils.deepEquals(toList(), other.toList()) }
|
||||
|
||||
override fun hashCode(): Int = toList().hashCode()
|
||||
}
|
||||
private open class GeckoPigeonCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
return when (type) {
|
||||
@@ -2507,6 +2544,11 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
|
||||
AddonCollection.fromList(it)
|
||||
}
|
||||
}
|
||||
191.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
GeckoPrefValue.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
@@ -2760,6 +2802,10 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
|
||||
stream.write(190)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
is GeckoPrefValue -> {
|
||||
stream.write(191)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
@@ -3714,9 +3760,10 @@ interface GeckoIconsApi {
|
||||
}
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface GeckoPrefApi {
|
||||
fun getPrefs(preferenceFilter: List<String>?, callback: (Result<Map<String, Any>>) -> Unit)
|
||||
fun applyPrefs(prefBuffer: String, callback: (Result<Map<String, Any>>) -> Unit)
|
||||
fun resetPrefs(preferenceNames: List<String>?, callback: (Result<Unit>) -> Unit)
|
||||
fun getPrefList(callback: (Result<List<String>>) -> Unit)
|
||||
fun getPrefs(preferenceFilter: List<String>, callback: (Result<Map<String, GeckoPrefValue>>) -> Unit)
|
||||
fun applyPrefs(prefs: Map<String, Any>, callback: (Result<Map<String, GeckoPrefValue>>) -> Unit)
|
||||
fun resetPrefs(preferenceNames: List<String>, callback: (Result<Unit>) -> Unit)
|
||||
|
||||
companion object {
|
||||
/** The codec used by GeckoPrefApi. */
|
||||
@@ -3727,13 +3774,31 @@ interface GeckoPrefApi {
|
||||
@JvmOverloads
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: GeckoPrefApi?, messageChannelSuffix: String = "") {
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoPrefApi.getPrefList$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { _, reply ->
|
||||
api.getPrefList{ result: Result<List<String>> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(GeckoPigeonUtils.wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(GeckoPigeonUtils.wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoPrefApi.getPrefs$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val preferenceFilterArg = args[0] as List<String>?
|
||||
api.getPrefs(preferenceFilterArg) { result: Result<Map<String, Any>> ->
|
||||
val preferenceFilterArg = args[0] as List<String>
|
||||
api.getPrefs(preferenceFilterArg) { result: Result<Map<String, GeckoPrefValue>> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(GeckoPigeonUtils.wrapError(error))
|
||||
@@ -3752,8 +3817,8 @@ interface GeckoPrefApi {
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val prefBufferArg = args[0] as String
|
||||
api.applyPrefs(prefBufferArg) { result: Result<Map<String, Any>> ->
|
||||
val prefsArg = args[0] as Map<String, Any>
|
||||
api.applyPrefs(prefsArg) { result: Result<Map<String, GeckoPrefValue>> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(GeckoPigeonUtils.wrapError(error))
|
||||
@@ -3772,7 +3837,7 @@ interface GeckoPrefApi {
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val preferenceNamesArg = args[0] as List<String>?
|
||||
val preferenceNamesArg = args[0] as List<String>
|
||||
api.resetPrefs(preferenceNamesArg) { result: Result<Unit> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
|
||||
Reference in New Issue
Block a user