mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-06 07:17:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
249
dom/settings/SettingsDB.jsm
Normal file
249
dom/settings/SettingsDB.jsm
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.importGlobalProperties(['Blob', 'File']);
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
|
||||
|
||||
var DEBUG = false;
|
||||
var VERBOSE = false;
|
||||
|
||||
try {
|
||||
DEBUG =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsDB.debug.enabled");
|
||||
VERBOSE =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsDB.verbose.enabled");
|
||||
} catch (ex) { }
|
||||
|
||||
function debug(s) {
|
||||
dump("-*- SettingsDB: " + s + "\n");
|
||||
}
|
||||
|
||||
const TYPED_ARRAY_THINGS = new Set([
|
||||
"Int8Array",
|
||||
"Uint8Array",
|
||||
"Uint8ClampedArray",
|
||||
"Int16Array",
|
||||
"Uint16Array",
|
||||
"Int32Array",
|
||||
"Uint32Array",
|
||||
"Float32Array",
|
||||
"Float64Array",
|
||||
]);
|
||||
|
||||
this.SETTINGSDB_NAME = "settings";
|
||||
this.SETTINGSDB_VERSION = 8;
|
||||
this.SETTINGSSTORE_NAME = "settings";
|
||||
|
||||
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
this.SettingsDB = function SettingsDB() {}
|
||||
|
||||
SettingsDB.prototype = {
|
||||
|
||||
__proto__: IndexedDBHelper.prototype,
|
||||
|
||||
upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
|
||||
let objectStore;
|
||||
if (aOldVersion == 0) {
|
||||
objectStore = aDb.createObjectStore(SETTINGSSTORE_NAME, { keyPath: "settingName" });
|
||||
if (VERBOSE) debug("Created object stores");
|
||||
} else if (aOldVersion == 1) {
|
||||
if (VERBOSE) debug("Get object store for upgrade and remove old index");
|
||||
objectStore = aTransaction.objectStore(SETTINGSSTORE_NAME);
|
||||
objectStore.deleteIndex("settingValue");
|
||||
} else {
|
||||
if (VERBOSE) debug("Get object store for upgrade");
|
||||
objectStore = aTransaction.objectStore(SETTINGSSTORE_NAME);
|
||||
}
|
||||
|
||||
// Loading resource://app/defaults/settings.json doesn't work because
|
||||
// settings.json is not in the omnijar.
|
||||
// So we look for the app dir instead and go from here...
|
||||
let settingsFile = FileUtils.getFile("DefRt", ["settings.json"], false);
|
||||
if (!settingsFile || (settingsFile && !settingsFile.exists())) {
|
||||
// On b2g desktop builds the settings.json file is moved in the
|
||||
// profile directory by the build system.
|
||||
settingsFile = FileUtils.getFile("ProfD", ["settings.json"], false);
|
||||
if (!settingsFile || (settingsFile && !settingsFile.exists())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(settingsFile),
|
||||
loadUsingSystemPrincipal: true});
|
||||
let stream = chan.open2();
|
||||
// Obtain a converter to read from a UTF-8 encoded input stream.
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let rawstr = converter.ConvertToUnicode(NetUtil.readInputStreamToString(
|
||||
stream,
|
||||
stream.available()) || "");
|
||||
let settings;
|
||||
try {
|
||||
settings = JSON.parse(rawstr);
|
||||
} catch(e) {
|
||||
if (DEBUG) debug("Error parsing " + settingsFile.path + " : " + e);
|
||||
return;
|
||||
}
|
||||
stream.close();
|
||||
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
let value = cursor.value;
|
||||
if (value.settingName in settings) {
|
||||
if (VERBOSE) debug("Upgrade " +settings[value.settingName]);
|
||||
value.defaultValue = this.prepareValue(settings[value.settingName]);
|
||||
delete settings[value.settingName];
|
||||
if ("settingValue" in value) {
|
||||
value.userValue = this.prepareValue(value.settingValue);
|
||||
delete value.settingValue;
|
||||
}
|
||||
cursor.update(value);
|
||||
} else if ("userValue" in value || "settingValue" in value) {
|
||||
value.defaultValue = undefined;
|
||||
if (aOldVersion == 1 && value.settingValue) {
|
||||
value.userValue = this.prepareValue(value.settingValue);
|
||||
delete value.settingValue;
|
||||
}
|
||||
cursor.update(value);
|
||||
} else {
|
||||
cursor.delete();
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
for (let name in settings) {
|
||||
let value = this.prepareValue(settings[name]);
|
||||
if (VERBOSE) debug("Set new:" + name +", " + value);
|
||||
objectStore.add({ settingName: name, defaultValue: value, userValue: undefined });
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
// If the value is a data: uri, convert it to a Blob.
|
||||
convertDataURIToBlob: function(aValue) {
|
||||
/* base64 to ArrayBuffer decoding, from
|
||||
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
|
||||
*/
|
||||
function b64ToUint6 (nChr) {
|
||||
return nChr > 64 && nChr < 91 ?
|
||||
nChr - 65
|
||||
: nChr > 96 && nChr < 123 ?
|
||||
nChr - 71
|
||||
: nChr > 47 && nChr < 58 ?
|
||||
nChr + 4
|
||||
: nChr === 43 ?
|
||||
62
|
||||
: nChr === 47 ?
|
||||
63
|
||||
:
|
||||
0;
|
||||
}
|
||||
|
||||
function base64DecToArr(sBase64, nBlocksSize) {
|
||||
let sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""),
|
||||
nInLen = sB64Enc.length,
|
||||
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize
|
||||
: nInLen * 3 + 1 >> 2,
|
||||
taBytes = new Uint8Array(nOutLen);
|
||||
|
||||
for (let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
|
||||
nMod4 = nInIdx & 3;
|
||||
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
|
||||
if (nMod4 === 3 || nInLen - nInIdx === 1) {
|
||||
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
|
||||
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
|
||||
}
|
||||
nUint24 = 0;
|
||||
}
|
||||
}
|
||||
return taBytes;
|
||||
}
|
||||
|
||||
// Check if we have a data: uri, and if it's base64 encoded.
|
||||
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEA...
|
||||
if (typeof aValue == "string" && aValue.startsWith("data:")) {
|
||||
try {
|
||||
let uri = Services.io.newURI(aValue, null, null);
|
||||
// XXX: that would be nice to reuse the c++ bits of the data:
|
||||
// protocol handler instead.
|
||||
let mimeType = "application/octet-stream";
|
||||
let mimeDelim = aValue.indexOf(";");
|
||||
if (mimeDelim !== -1) {
|
||||
mimeType = aValue.substring(5, mimeDelim);
|
||||
}
|
||||
let start = aValue.indexOf(",") + 1;
|
||||
let isBase64 = ((aValue.indexOf("base64") + 7) == start);
|
||||
let payload = aValue.substring(start);
|
||||
|
||||
return new Blob([isBase64 ? base64DecToArr(payload) : payload],
|
||||
{ type: mimeType });
|
||||
} catch(e) {
|
||||
dump(e);
|
||||
}
|
||||
}
|
||||
return aValue
|
||||
},
|
||||
|
||||
getObjectKind: function(aObject) {
|
||||
if (aObject === null || aObject === undefined) {
|
||||
return "primitive";
|
||||
} else if (Array.isArray(aObject)) {
|
||||
return "array";
|
||||
} else if (aObject instanceof File) {
|
||||
return "file";
|
||||
} else if (aObject instanceof Ci.nsIDOMBlob) {
|
||||
return "blob";
|
||||
} else if (aObject.constructor.name == "Date") {
|
||||
return "date";
|
||||
} else if (TYPED_ARRAY_THINGS.has(aObject.constructor.name)) {
|
||||
return aObject.constructor.name;
|
||||
} else if (typeof aObject == "object") {
|
||||
return "object";
|
||||
} else {
|
||||
return "primitive";
|
||||
}
|
||||
},
|
||||
|
||||
// Makes sure any property that is a data: uri gets converted to a Blob.
|
||||
prepareValue: function(aObject) {
|
||||
let kind = this.getObjectKind(aObject);
|
||||
if (kind == "array") {
|
||||
let res = [];
|
||||
aObject.forEach(function(aObj) {
|
||||
res.push(this.prepareValue(aObj));
|
||||
}, this);
|
||||
return res;
|
||||
} else if (kind == "file" || kind == "blob" || kind == "date") {
|
||||
return aObject;
|
||||
} else if (kind == "primitive") {
|
||||
return this.convertDataURIToBlob(aObject);
|
||||
}
|
||||
|
||||
// Fall-through, we now have a dictionary object.
|
||||
let res = {};
|
||||
for (let prop in aObject) {
|
||||
res[prop] = this.prepareValue(aObject[prop]);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
init: function init() {
|
||||
this.initDBHelper(SETTINGSDB_NAME, SETTINGSDB_VERSION,
|
||||
[SETTINGSSTORE_NAME]);
|
||||
}
|
||||
}
|
||||
506
dom/settings/SettingsManager.js
Normal file
506
dom/settings/SettingsManager.js
Normal file
|
|
@ -0,0 +1,506 @@
|
|||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
var DEBUG = false;
|
||||
var VERBOSE = false;
|
||||
|
||||
try {
|
||||
DEBUG =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsManager.debug.enabled");
|
||||
VERBOSE =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsManager.verbose.enabled");
|
||||
} catch (ex) { }
|
||||
|
||||
function debug(s) {
|
||||
dump("-*- SettingsManager: " + s + "\n");
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "DOMRequest",
|
||||
"@mozilla.org/dom/dom-request-service;1",
|
||||
"nsIDOMRequestService");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "mrm",
|
||||
"@mozilla.org/memory-reporter-manager;1",
|
||||
"nsIMemoryReporterManager");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
"nsIUUIDGenerator");
|
||||
|
||||
const kObserverSoftLimit = 10;
|
||||
|
||||
/**
|
||||
* In order to make SettingsManager work with Privileged Apps, we need the lock
|
||||
* to be OOP. However, the lock state needs to be managed on the child process,
|
||||
* while the IDB functions now happen on the parent process so we don't have to
|
||||
* expose IDB permissions at the child process level. We use the
|
||||
* DOMRequestHelper mechanism to deal with DOMRequests/promises across the
|
||||
* processes.
|
||||
*
|
||||
* However, due to the nature of the IDBTransaction lifetime, we need to relay
|
||||
* to the parent when to finalize the transaction once the child is done with the
|
||||
* lock. We keep a list of all open requests for a lock, and once the lock
|
||||
* reaches the end of its receiveMessage function with no more queued requests,
|
||||
* we consider it dead. At that point, we send a message to the parent to notify
|
||||
* it to finalize the transaction.
|
||||
*/
|
||||
|
||||
function SettingsLock(aSettingsManager) {
|
||||
if (VERBOSE) debug("settings lock init");
|
||||
this._open = true;
|
||||
this._settingsManager = aSettingsManager;
|
||||
this._id = uuidgen.generateUUID().toString();
|
||||
|
||||
// DOMRequestIpcHelper.initHelper sets this._window
|
||||
this.initDOMRequestHelper(this._settingsManager._window, ["Settings:Get:OK", "Settings:Get:KO",
|
||||
"Settings:Clear:OK", "Settings:Clear:KO",
|
||||
"Settings:Set:OK", "Settings:Set:KO",
|
||||
"Settings:Finalize:OK", "Settings:Finalize:KO"]);
|
||||
let createLockPayload = {
|
||||
lockID: this._id,
|
||||
isServiceLock: false,
|
||||
windowID: this._settingsManager.innerWindowID,
|
||||
lockStack: (new Error).stack
|
||||
};
|
||||
this.sendMessage("Settings:CreateLock", createLockPayload);
|
||||
Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
||||
// We only want to file closeHelper once per set of receiveMessage calls.
|
||||
this._closeCalled = true;
|
||||
}
|
||||
|
||||
SettingsLock.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
set onsettingstransactionsuccess(aHandler) {
|
||||
this.__DOM_IMPL__.setEventHandler("onsettingstransactionsuccess", aHandler);
|
||||
},
|
||||
|
||||
get onsettingstransactionsuccess() {
|
||||
return this.__DOM_IMPL__.getEventHandler("onsettingstransactionsuccess");
|
||||
},
|
||||
|
||||
set onsettingstransactionfailure(aHandler) {
|
||||
this.__DOM_IMPL__.setEventHandler("onsettingstransactionfailure", aHandler);
|
||||
},
|
||||
|
||||
get onsettingstransactionfailure() {
|
||||
return this.__DOM_IMPL__.getEventHandler("onsettingstransactionfailure");
|
||||
},
|
||||
|
||||
get closed() {
|
||||
return !this._open;
|
||||
},
|
||||
|
||||
_closeHelper: function() {
|
||||
if (VERBOSE) debug("closing lock " + this._id);
|
||||
this._open = false;
|
||||
this._closeCalled = false;
|
||||
if (!this._requests || Object.keys(this._requests).length == 0) {
|
||||
if (VERBOSE) debug("Requests exhausted, finalizing " + this._id);
|
||||
this._settingsManager.unregisterLock(this._id);
|
||||
this.sendMessage("Settings:Finalize", {lockID: this._id});
|
||||
} else {
|
||||
if (VERBOSE) debug("Requests left: " + Object.keys(this._requests).length);
|
||||
this.sendMessage("Settings:Run", {lockID: this._id});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_wrap: function _wrap(obj) {
|
||||
return Cu.cloneInto(obj, this._settingsManager._window);
|
||||
},
|
||||
|
||||
sendMessage: function(aMessageName, aData) {
|
||||
// sendMessage can be called after our window has died, or get
|
||||
// queued to run later in a thread via _closeHelper, but the
|
||||
// SettingsManager may have died in between the time it was
|
||||
// scheduled and the time it runs. Make sure our window is valid
|
||||
// before sending, otherwise just ignore.
|
||||
if (!this._settingsManager._window) {
|
||||
Cu.reportError(
|
||||
"SettingsManager window died, cannot run settings transaction." +
|
||||
" SettingsMessage: " + aMessageName +
|
||||
" SettingsData: " + JSON.stringify(aData));
|
||||
return;
|
||||
}
|
||||
cpmm.sendAsyncMessage(aMessageName,
|
||||
aData,
|
||||
undefined,
|
||||
this._settingsManager._window.document.nodePrincipal);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let msg = aMessage.data;
|
||||
|
||||
// SettingsRequestManager broadcasts changes to all locks in the child. If
|
||||
// our lock isn't being addressed, just return.
|
||||
if (msg.lockID != this._id) {
|
||||
return;
|
||||
}
|
||||
if (VERBOSE) debug("receiveMessage (" + this._id + "): " + aMessage.name);
|
||||
|
||||
// Finalizing a transaction does not return a request ID since we are
|
||||
// supposed to fire callbacks.
|
||||
//
|
||||
// We also destroy the DOMRequestHelper after we've received the
|
||||
// finalize message. At this point, we will be guarenteed no more
|
||||
// request returns are coming from the SettingsRequestManager.
|
||||
|
||||
if (!msg.requestID) {
|
||||
let event;
|
||||
switch (aMessage.name) {
|
||||
case "Settings:Finalize:OK":
|
||||
if (VERBOSE) debug("Lock finalize ok: " + this._id);
|
||||
event = new this._window.MozSettingsTransactionEvent("settingstransactionsuccess", {});
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
this.destroyDOMRequestHelper();
|
||||
break;
|
||||
case "Settings:Finalize:KO":
|
||||
if (DEBUG) debug("Lock finalize failed: " + this._id);
|
||||
event = new this._window.MozSettingsTransactionEvent("settingstransactionfailure", {
|
||||
error: msg.errorMsg
|
||||
});
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
this.destroyDOMRequestHelper();
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Message type " + aMessage.name + " is missing a requestID");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (!req) {
|
||||
if (DEBUG) debug("Matching request not found.");
|
||||
return;
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
// DOMRequest callbacks called from here can die due to having
|
||||
// things like marionetteScriptFinished in them. Make sure we file
|
||||
// our call to run/finalize BEFORE opening the lock and fulfilling
|
||||
// DOMRequests.
|
||||
if (!this._closeCalled) {
|
||||
// We only want to file closeHelper once per set of receiveMessage calls.
|
||||
Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
|
||||
this._closeCalled = true;
|
||||
}
|
||||
if (VERBOSE) debug("receiveMessage: " + aMessage.name);
|
||||
switch (aMessage.name) {
|
||||
case "Settings:Get:OK":
|
||||
for (let i in msg.settings) {
|
||||
msg.settings[i] = this._wrap(msg.settings[i]);
|
||||
}
|
||||
this._open = true;
|
||||
Services.DOMRequest.fireSuccess(req.request, this._wrap(msg.settings));
|
||||
this._open = false;
|
||||
break;
|
||||
case "Settings:Set:OK":
|
||||
case "Settings:Clear:OK":
|
||||
this._open = true;
|
||||
Services.DOMRequest.fireSuccess(req.request, 0);
|
||||
this._open = false;
|
||||
break;
|
||||
case "Settings:Get:KO":
|
||||
case "Settings:Set:KO":
|
||||
case "Settings:Clear:KO":
|
||||
if (DEBUG) debug("error:" + msg.errorMsg);
|
||||
Services.DOMRequest.fireError(req.request, msg.errorMsg);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Wrong message: " + aMessage.name);
|
||||
}
|
||||
},
|
||||
|
||||
get: function get(aName) {
|
||||
if (VERBOSE) debug("get (" + this._id + "): " + aName);
|
||||
if (!this._open) {
|
||||
dump("Settings lock not open!\n");
|
||||
throw Components.results.NS_ERROR_ABORT;
|
||||
}
|
||||
let req = this.createRequest();
|
||||
let reqID = this.getRequestId({request: req});
|
||||
this.sendMessage("Settings:Get", {requestID: reqID,
|
||||
lockID: this._id,
|
||||
name: aName});
|
||||
return req;
|
||||
},
|
||||
|
||||
set: function set(aSettings) {
|
||||
if (VERBOSE) debug("send: " + JSON.stringify(aSettings));
|
||||
if (!this._open) {
|
||||
throw "Settings lock not open";
|
||||
}
|
||||
let req = this.createRequest();
|
||||
let reqID = this.getRequestId({request: req});
|
||||
this.sendMessage("Settings:Set", {requestID: reqID,
|
||||
lockID: this._id,
|
||||
settings: aSettings});
|
||||
return req;
|
||||
},
|
||||
|
||||
clear: function clear() {
|
||||
if (VERBOSE) debug("clear");
|
||||
if (!this._open) {
|
||||
throw "Settings lock not open";
|
||||
}
|
||||
let req = this.createRequest();
|
||||
let reqID = this.getRequestId({request: req});
|
||||
this.sendMessage("Settings:Clear", {requestID: reqID,
|
||||
lockID: this._id});
|
||||
return req;
|
||||
},
|
||||
|
||||
classID: Components.ID("{60c9357c-3ae0-4222-8f55-da01428470d5}"),
|
||||
contractID: "@mozilla.org/settingsLock;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
function SettingsManager() {
|
||||
this._callbacks = null;
|
||||
this._isRegistered = false;
|
||||
this._locks = [];
|
||||
this._createdLocks = 0;
|
||||
this._unregisteredLocks = 0;
|
||||
}
|
||||
|
||||
SettingsManager.prototype = {
|
||||
_wrap: function _wrap(obj) {
|
||||
return Cu.cloneInto(obj, this._window);
|
||||
},
|
||||
|
||||
set onsettingchange(aHandler) {
|
||||
this.__DOM_IMPL__.setEventHandler("onsettingchange", aHandler);
|
||||
this.checkMessageRegistration();
|
||||
},
|
||||
|
||||
get onsettingchange() {
|
||||
return this.__DOM_IMPL__.getEventHandler("onsettingchange");
|
||||
},
|
||||
|
||||
createLock: function() {
|
||||
let lock = new SettingsLock(this);
|
||||
if (VERBOSE) debug("creating lock " + lock._id);
|
||||
this._locks.push(lock._id);
|
||||
this._createdLocks++;
|
||||
return lock;
|
||||
},
|
||||
|
||||
unregisterLock: function(aLockID) {
|
||||
let lock_index = this._locks.indexOf(aLockID);
|
||||
if (lock_index != -1) {
|
||||
if (VERBOSE) debug("Unregistering lock " + aLockID);
|
||||
this._locks.splice(lock_index, 1);
|
||||
this._unregisteredLocks++;
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (VERBOSE) debug("Settings::receiveMessage: " + aMessage.name);
|
||||
let msg = aMessage.json;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Settings:Change:Return:OK":
|
||||
if (VERBOSE) debug('data:' + msg.key + ':' + msg.value + '\n');
|
||||
|
||||
let event = new this._window.MozSettingsEvent("settingchange", this._wrap({
|
||||
settingName: msg.key,
|
||||
settingValue: msg.value
|
||||
}));
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
|
||||
if (this._callbacks && this._callbacks[msg.key]) {
|
||||
if (VERBOSE) debug("observe callback called! " + msg.key + " " + this._callbacks[msg.key].length);
|
||||
this._callbacks[msg.key].forEach(function(cb) {
|
||||
cb(this._wrap({settingName: msg.key, settingValue: msg.value}));
|
||||
}.bind(this));
|
||||
} else {
|
||||
if (VERBOSE) debug("no observers stored!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Wrong message: " + aMessage.name);
|
||||
}
|
||||
},
|
||||
|
||||
// If we have either observer callbacks or an event handler,
|
||||
// register for messages from the main thread. Otherwise, if no one
|
||||
// is listening, unregister to reduce parent load.
|
||||
checkMessageRegistration: function checkRegistration() {
|
||||
let handler = this.__DOM_IMPL__.getEventHandler("onsettingchange");
|
||||
if (!this._isRegistered) {
|
||||
if (VERBOSE) debug("Registering for messages");
|
||||
cpmm.sendAsyncMessage("Settings:RegisterForMessages",
|
||||
undefined,
|
||||
undefined,
|
||||
this._window.document.nodePrincipal);
|
||||
this._isRegistered = true;
|
||||
} else {
|
||||
if ((!this._callbacks || Object.keys(this._callbacks).length == 0) &&
|
||||
!handler) {
|
||||
if (VERBOSE) debug("Unregistering for messages");
|
||||
cpmm.sendAsyncMessage("Settings:UnregisterForMessages",
|
||||
undefined,
|
||||
undefined,
|
||||
this._window.document.nodePrincipal);
|
||||
this._isRegistered = false;
|
||||
this._callbacks = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addObserver: function addObserver(aName, aCallback) {
|
||||
if (VERBOSE) debug("addObserver " + aName);
|
||||
|
||||
if (!this._callbacks) {
|
||||
this._callbacks = {};
|
||||
}
|
||||
|
||||
if (!this._callbacks[aName]) {
|
||||
this._callbacks[aName] = [aCallback];
|
||||
} else {
|
||||
this._callbacks[aName].push(aCallback);
|
||||
}
|
||||
|
||||
let length = this._callbacks[aName].length;
|
||||
if (length >= kObserverSoftLimit) {
|
||||
debug("WARNING: MORE THAN " + kObserverSoftLimit + " OBSERVERS FOR " +
|
||||
aName + ": " + length + " FROM" + (new Error).stack);
|
||||
#ifdef DEBUG
|
||||
debug("JS STOPS EXECUTING AT THIS POINT IN DEBUG BUILDS!");
|
||||
throw Components.results.NS_ERROR_ABORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
this.checkMessageRegistration();
|
||||
},
|
||||
|
||||
removeObserver: function removeObserver(aName, aCallback) {
|
||||
if (VERBOSE) debug("deleteObserver " + aName);
|
||||
if (this._callbacks && this._callbacks[aName]) {
|
||||
let index = this._callbacks[aName].indexOf(aCallback);
|
||||
if (index != -1) {
|
||||
this._callbacks[aName].splice(index, 1);
|
||||
if (this._callbacks[aName].length == 0) {
|
||||
delete this._callbacks[aName];
|
||||
}
|
||||
} else {
|
||||
if (VERBOSE) debug("Callback not found for: " + aName);
|
||||
}
|
||||
} else {
|
||||
if (VERBOSE) debug("No observers stored for " + aName);
|
||||
}
|
||||
this.checkMessageRegistration();
|
||||
},
|
||||
|
||||
init: function(aWindow) {
|
||||
if (VERBOSE) debug("SettingsManager init");
|
||||
mrm.registerStrongReporter(this);
|
||||
cpmm.addMessageListener("Settings:Change:Return:OK", this);
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
this._window = aWindow;
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (VERBOSE) debug("Topic: " + aTopic);
|
||||
if (aTopic === "inner-window-destroyed") {
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId === this.innerWindowID) {
|
||||
if (DEBUG) debug("Received: inner-window-destroyed for valid innerWindowID=" + wId + ", cleanup.");
|
||||
this.cleanup();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
collectReports: function(aCallback, aData, aAnonymize) {
|
||||
for (let topic in this._callbacks) {
|
||||
let length = this._callbacks[topic].length;
|
||||
if (length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let path;
|
||||
if (length < kObserverSoftLimit) {
|
||||
path = "settings-observers";
|
||||
} else {
|
||||
path = "settings-observers-suspect/referent(topic=" +
|
||||
(aAnonymize ? "<anonymized>" : topic) + ")";
|
||||
}
|
||||
|
||||
aCallback.callback("", path,
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
length,
|
||||
"The number of settings observers for this topic.",
|
||||
aData);
|
||||
}
|
||||
|
||||
aCallback.callback("",
|
||||
"settings-locks/alive",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._locks.length,
|
||||
"The number of locks that are currently alives.",
|
||||
aData);
|
||||
|
||||
aCallback.callback("",
|
||||
"settings-locks/created",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._createdLocks,
|
||||
"The number of locks that were created.",
|
||||
aData);
|
||||
|
||||
aCallback.callback("",
|
||||
"settings-locks/deleted",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._unregisteredLocks,
|
||||
"The number of locks that were deleted.",
|
||||
aData);
|
||||
},
|
||||
|
||||
cleanup: function() {
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
// At this point, the window is dying, so there's nothing left
|
||||
// that we could do with our lock. Go ahead and run finalize on
|
||||
// it to make sure changes are commited.
|
||||
for (let i = 0; i < this._locks.length; ++i) {
|
||||
if (DEBUG) debug("Lock alive at destroy, finalizing: " + this._locks[i]);
|
||||
// Due to bug 1105511 we should be able to send this without
|
||||
// cached principals. However, this is scary because any iframe
|
||||
// in the process could run this?
|
||||
cpmm.sendAsyncMessage("Settings:Finalize",
|
||||
{lockID: this._locks[i]});
|
||||
}
|
||||
cpmm.removeMessageListener("Settings:Change:Return:OK", this);
|
||||
mrm.unregisterStrongReporter(this);
|
||||
this.innerWindowID = null;
|
||||
this._window = null;
|
||||
},
|
||||
|
||||
classID: Components.ID("{c40b1c70-00fb-11e2-a21f-0800200c9a66}"),
|
||||
contractID: "@mozilla.org/settingsManager;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsIMemoryReporter]),
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SettingsManager, SettingsLock]);
|
||||
5
dom/settings/SettingsManager.manifest
Normal file
5
dom/settings/SettingsManager.manifest
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
component {c40b1c70-00fb-11e2-a21f-0800200c9a66} SettingsManager.js
|
||||
contract @mozilla.org/settingsManager;1 {c40b1c70-00fb-11e2-a21f-0800200c9a66}
|
||||
|
||||
component {60c9357c-3ae0-4222-8f55-da01428470d5} SettingsManager.js
|
||||
contract @mozilla.org/settingsLock;1 {60c9357c-3ae0-4222-8f55-da01428470d5}
|
||||
1224
dom/settings/SettingsRequestManager.jsm
Normal file
1224
dom/settings/SettingsRequestManager.jsm
Normal file
File diff suppressed because it is too large
Load diff
358
dom/settings/SettingsService.js
Normal file
358
dom/settings/SettingsService.js
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
/* 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 http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import('resource://gre/modules/SettingsRequestManager.jsm');
|
||||
|
||||
/* static functions */
|
||||
var DEBUG = false;
|
||||
var VERBOSE = false;
|
||||
|
||||
try {
|
||||
DEBUG =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsService.debug.enabled");
|
||||
VERBOSE =
|
||||
Services.prefs.getBoolPref("dom.mozSettings.SettingsService.verbose.enabled");
|
||||
} catch (ex) { }
|
||||
|
||||
function debug(s) {
|
||||
dump("-*- SettingsService: " + s + "\n");
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
"nsIUUIDGenerator");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "mrm",
|
||||
"@mozilla.org/memory-reporter-manager;1",
|
||||
"nsIMemoryReporterManager");
|
||||
|
||||
const nsIClassInfo = Ci.nsIClassInfo;
|
||||
const kXpcomShutdownObserverTopic = "xpcom-shutdown";
|
||||
|
||||
const SETTINGSSERVICELOCK_CONTRACTID = "@mozilla.org/settingsServiceLock;1";
|
||||
const SETTINGSSERVICELOCK_CID = Components.ID("{d7a395a0-e292-11e1-834e-1761d57f5f99}");
|
||||
const nsISettingsServiceLock = Ci.nsISettingsServiceLock;
|
||||
|
||||
function makeSettingsServiceRequest(aCallback, aName, aValue) {
|
||||
return {
|
||||
callback: aCallback,
|
||||
name: aName,
|
||||
value: aValue
|
||||
};
|
||||
};
|
||||
|
||||
const kLockListeners = ["Settings:Get:OK", "Settings:Get:KO",
|
||||
"Settings:Clear:OK", "Settings:Clear:KO",
|
||||
"Settings:Set:OK", "Settings:Set:KO",
|
||||
"Settings:Finalize:OK", "Settings:Finalize:KO"];
|
||||
|
||||
function SettingsServiceLock(aSettingsService, aTransactionCallback) {
|
||||
if (VERBOSE) debug("settingsServiceLock constr!");
|
||||
this._open = true;
|
||||
this._settingsService = aSettingsService;
|
||||
this._id = uuidgen.generateUUID().toString();
|
||||
this._transactionCallback = aTransactionCallback;
|
||||
this._requests = {};
|
||||
let closeHelper = function() {
|
||||
if (VERBOSE) debug("closing lock " + this._id);
|
||||
this._open = false;
|
||||
this.runOrFinalizeQueries();
|
||||
}.bind(this);
|
||||
|
||||
this.addListeners();
|
||||
|
||||
let createLockPayload = {
|
||||
lockID: this._id,
|
||||
isServiceLock: true,
|
||||
windowID: undefined,
|
||||
lockStack: (new Error).stack
|
||||
};
|
||||
|
||||
this.returnMessage("Settings:CreateLock", createLockPayload);
|
||||
Services.tm.currentThread.dispatch(closeHelper, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
SettingsServiceLock.prototype = {
|
||||
get closed() {
|
||||
return !this._open;
|
||||
},
|
||||
|
||||
addListeners: function() {
|
||||
for (let msg of kLockListeners) {
|
||||
cpmm.addMessageListener(msg, this);
|
||||
}
|
||||
},
|
||||
|
||||
removeListeners: function() {
|
||||
for (let msg of kLockListeners) {
|
||||
cpmm.removeMessageListener(msg, this);
|
||||
}
|
||||
},
|
||||
|
||||
returnMessage: function(aMessage, aData) {
|
||||
SettingsRequestManager.receiveMessage({
|
||||
name: aMessage,
|
||||
data: aData,
|
||||
target: undefined,
|
||||
principal: Services.scriptSecurityManager.getSystemPrincipal()
|
||||
});
|
||||
},
|
||||
|
||||
runOrFinalizeQueries: function() {
|
||||
if (!this._requests || Object.keys(this._requests).length == 0) {
|
||||
this.returnMessage("Settings:Finalize", {lockID: this._id});
|
||||
} else {
|
||||
this.returnMessage("Settings:Run", {lockID: this._id});
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
|
||||
let msg = aMessage.data;
|
||||
// SettingsRequestManager broadcasts changes to all locks in the child. If
|
||||
// our lock isn't being addressed, just return.
|
||||
if(msg.lockID != this._id) {
|
||||
return;
|
||||
}
|
||||
if (VERBOSE) debug("receiveMessage (" + this._id + "): " + aMessage.name);
|
||||
// Finalizing a transaction does not return a request ID since we are
|
||||
// supposed to fire callbacks.
|
||||
if (!msg.requestID) {
|
||||
switch (aMessage.name) {
|
||||
case "Settings:Finalize:OK":
|
||||
if (VERBOSE) debug("Lock finalize ok!");
|
||||
this.callTransactionHandle();
|
||||
break;
|
||||
case "Settings:Finalize:KO":
|
||||
if (DEBUG) debug("Lock finalize failed!");
|
||||
this.callAbort();
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Message type " + aMessage.name + " is missing a requestID");
|
||||
}
|
||||
|
||||
this._settingsService.unregisterLock(this._id);
|
||||
return;
|
||||
}
|
||||
|
||||
let req = this._requests[msg.requestID];
|
||||
if (!req) {
|
||||
if (DEBUG) debug("Matching request not found.");
|
||||
return;
|
||||
}
|
||||
delete this._requests[msg.requestID];
|
||||
switch (aMessage.name) {
|
||||
case "Settings:Get:OK":
|
||||
this._open = true;
|
||||
let settings_names = Object.keys(msg.settings);
|
||||
if (settings_names.length > 0) {
|
||||
let name = settings_names[0];
|
||||
if (DEBUG && settings_names.length > 1) {
|
||||
debug("Warning: overloaded setting:" + name);
|
||||
}
|
||||
let result = msg.settings[name];
|
||||
this.callHandle(req.callback, name, result);
|
||||
} else {
|
||||
this.callHandle(req.callback, req.name, null);
|
||||
}
|
||||
this._open = false;
|
||||
break;
|
||||
case "Settings:Set:OK":
|
||||
this._open = true;
|
||||
// We don't pass values back from sets in SettingsManager...
|
||||
this.callHandle(req.callback, req.name, req.value);
|
||||
this._open = false;
|
||||
break;
|
||||
case "Settings:Get:KO":
|
||||
case "Settings:Set:KO":
|
||||
if (DEBUG) debug("error:" + msg.errorMsg);
|
||||
this.callError(req.callback, msg.error);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) debug("Wrong message: " + aMessage.name);
|
||||
}
|
||||
this.runOrFinalizeQueries();
|
||||
},
|
||||
|
||||
get: function get(aName, aCallback) {
|
||||
if (VERBOSE) debug("get (" + this._id + "): " + aName);
|
||||
if (!this._open) {
|
||||
if (DEBUG) debug("Settings lock not open!\n");
|
||||
throw Components.results.NS_ERROR_ABORT;
|
||||
}
|
||||
let reqID = uuidgen.generateUUID().toString();
|
||||
this._requests[reqID] = makeSettingsServiceRequest(aCallback, aName);
|
||||
this.returnMessage("Settings:Get", {requestID: reqID,
|
||||
lockID: this._id,
|
||||
name: aName});
|
||||
},
|
||||
|
||||
set: function set(aName, aValue, aCallback) {
|
||||
if (VERBOSE) debug("set: " + aName + " " + aValue);
|
||||
if (!this._open) {
|
||||
throw "Settings lock not open";
|
||||
}
|
||||
let reqID = uuidgen.generateUUID().toString();
|
||||
this._requests[reqID] = makeSettingsServiceRequest(aCallback, aName, aValue);
|
||||
let settings = {};
|
||||
settings[aName] = aValue;
|
||||
this.returnMessage("Settings:Set", {requestID: reqID,
|
||||
lockID: this._id,
|
||||
settings: settings});
|
||||
},
|
||||
|
||||
callHandle: function callHandle(aCallback, aName, aValue) {
|
||||
try {
|
||||
aCallback && aCallback.handle ? aCallback.handle(aName, aValue) : null;
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("settings 'handle' for " + aName + " callback threw an exception, dropping: " + e + "\n");
|
||||
}
|
||||
},
|
||||
|
||||
callAbort: function callAbort(aCallback, aMessage) {
|
||||
try {
|
||||
aCallback && aCallback.handleAbort ? aCallback.handleAbort(aMessage) : null;
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("settings 'abort' callback threw an exception, dropping: " + e + "\n");
|
||||
}
|
||||
},
|
||||
|
||||
callError: function callError(aCallback, aMessage) {
|
||||
try {
|
||||
aCallback && aCallback.handleError ? aCallback.handleError(aMessage) : null;
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("settings 'error' callback threw an exception, dropping: " + e + "\n");
|
||||
}
|
||||
},
|
||||
|
||||
callTransactionHandle: function callTransactionHandle() {
|
||||
try {
|
||||
this._transactionCallback && this._transactionCallback.handle ? this._transactionCallback.handle() : null;
|
||||
} catch (e) {
|
||||
if (DEBUG) debug("settings 'Transaction handle' callback threw an exception, dropping: " + e + "\n");
|
||||
}
|
||||
},
|
||||
|
||||
classID : SETTINGSSERVICELOCK_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([nsISettingsServiceLock])
|
||||
};
|
||||
|
||||
const SETTINGSSERVICE_CID = Components.ID("{f656f0c0-f776-11e1-a21f-0800200c9a66}");
|
||||
|
||||
function SettingsService()
|
||||
{
|
||||
if (VERBOSE) debug("settingsService Constructor");
|
||||
this._locks = [];
|
||||
this._serviceLocks = {};
|
||||
this._createdLocks = 0;
|
||||
this._unregisteredLocks = 0;
|
||||
this.init();
|
||||
}
|
||||
|
||||
SettingsService.prototype = {
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false);
|
||||
mrm.registerStrongReporter(this);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
Services.obs.removeObserver(this, kXpcomShutdownObserverTopic);
|
||||
mrm.unregisterStrongReporter(this);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (VERBOSE) debug("observe: " + aTopic);
|
||||
if (aTopic === kXpcomShutdownObserverTopic) {
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (VERBOSE) debug("Entering receiveMessage");
|
||||
|
||||
let lockID = aMessage.data.lockID;
|
||||
if (!lockID) {
|
||||
if (DEBUG) debug("No lock ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(lockID in this._serviceLocks)) {
|
||||
if (DEBUG) debug("Received message for lock " + lockID + " but no lock");
|
||||
return;
|
||||
}
|
||||
|
||||
if (VERBOSE) debug("Delivering message");
|
||||
this._serviceLocks[lockID].receiveMessage(aMessage);
|
||||
},
|
||||
|
||||
createLock: function createLock(aCallback) {
|
||||
if (VERBOSE) debug("Calling createLock");
|
||||
var lock = new SettingsServiceLock(this, aCallback);
|
||||
if (VERBOSE) debug("Created lock " + lock._id);
|
||||
this.registerLock(lock);
|
||||
return lock;
|
||||
},
|
||||
|
||||
registerLock: function(aLock) {
|
||||
if (VERBOSE) debug("Registering lock " + aLock._id);
|
||||
this._locks.push(aLock._id);
|
||||
this._serviceLocks[aLock._id] = aLock;
|
||||
this._createdLocks++;
|
||||
},
|
||||
|
||||
unregisterLock: function(aLockID) {
|
||||
let lock_index = this._locks.indexOf(aLockID);
|
||||
if (lock_index != -1) {
|
||||
if (VERBOSE) debug("Unregistering lock " + aLockID);
|
||||
this._locks.splice(lock_index, 1);
|
||||
this._serviceLocks[aLockID].removeListeners();
|
||||
this._serviceLocks[aLockID] = null;
|
||||
delete this._serviceLocks[aLockID];
|
||||
this._unregisteredLocks++;
|
||||
}
|
||||
},
|
||||
|
||||
collectReports: function(aCallback, aData, aAnonymize) {
|
||||
aCallback.callback("",
|
||||
"settings-service-locks/alive",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._locks.length,
|
||||
"The number of service locks that are currently alives.",
|
||||
aData);
|
||||
|
||||
aCallback.callback("",
|
||||
"settings-service-locks/created",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._createdLocks,
|
||||
"The number of service locks that were created.",
|
||||
aData);
|
||||
|
||||
aCallback.callback("",
|
||||
"settings-service-locks/deleted",
|
||||
Ci.nsIMemoryReporter.KIND_OTHER,
|
||||
Ci.nsIMemoryReporter.UNITS_COUNT,
|
||||
this._unregisteredLocks,
|
||||
"The number of service locks that were deleted.",
|
||||
aData);
|
||||
},
|
||||
|
||||
classID : SETTINGSSERVICE_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsISettingsService,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsIMemoryReporter])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SettingsService, SettingsServiceLock]);
|
||||
5
dom/settings/SettingsService.manifest
Normal file
5
dom/settings/SettingsService.manifest
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
component {d7a395a0-e292-11e1-834e-1761d57f5f99} SettingsService.js
|
||||
contract @mozilla.org/settingsServiceLock;1 {d7a395a0-e292-11e1-834e-1761d57f5f99}
|
||||
|
||||
component {f656f0c0-f776-11e1-a21f-0800200c9a66} SettingsService.js
|
||||
contract @mozilla.org/settingsService;1 {f656f0c0-f776-11e1-a21f-0800200c9a66}
|
||||
28
dom/settings/moz.build
Normal file
28
dom/settings/moz.build
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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 http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'SettingsManager.manifest'
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'SettingsManager.js'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'SettingsService.js',
|
||||
'SettingsService.manifest',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'SettingsDB.jsm',
|
||||
'SettingsRequestManager.jsm'
|
||||
]
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
24
dom/settings/tests/chrome.ini
Normal file
24
dom/settings/tests/chrome.ini
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
[DEFAULT]
|
||||
skip-if = toolkit == 'android' # Bug 1287455: takes too long to complete on Android
|
||||
support-files =
|
||||
file_loadserver.js
|
||||
file_bug1110872.js
|
||||
file_bug1110872.html
|
||||
test_settings_service.js
|
||||
test_settings_service_callback.js
|
||||
|
||||
[test_settings_service.xul]
|
||||
run-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
[test_settings_service_callback.xul]
|
||||
run-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
[test_settings_basics.html]
|
||||
[test_settings_permissions.html]
|
||||
[test_settings_blobs.html]
|
||||
[test_settings_data_uris.html]
|
||||
[test_settings_events.html]
|
||||
[test_settings_navigator_object.html]
|
||||
[test_settings_onsettingchange.html]
|
||||
[test_settings_bug1110872.html]
|
||||
skip-if = !e10s
|
||||
[test_settings_observer_killer.html]
|
||||
skip-if = !debug
|
||||
47
dom/settings/tests/file_bug1110872.html
Normal file
47
dom/settings/tests/file_bug1110872.html
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug {1110872} Settings API Reloads</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var createLock = function (msg) {
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
var req = lock.get("wallpaper.image");
|
||||
// We don't actually care about success or failure here, we just
|
||||
// want to know the queue gets processed at all.
|
||||
req.onsuccess = function () {
|
||||
parent.postMessage({name:"done" + msg.data.step}, "*");
|
||||
}
|
||||
req.onerror = function () {
|
||||
parent.postMessage({name:"done" + msg.data.step}, "*");
|
||||
};
|
||||
return req;
|
||||
}
|
||||
window.onload = function() {
|
||||
window.addEventListener("message", function (msg) {
|
||||
var i;
|
||||
var reqs = [];
|
||||
if (msg.data.step == 1) {
|
||||
for (i = 0; i < 100; ++i) {
|
||||
reqs.push(createLock(msg));
|
||||
}
|
||||
} else {
|
||||
reqs.push(createLock(msg));
|
||||
}
|
||||
// If this is our first time through, reload
|
||||
// before the SettingsManager has a chance to get a response
|
||||
// to our query.
|
||||
if (msg.data.step == 1) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1110872}">Mozilla Bug {1110872} Inner Window for Reload Test</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
47
dom/settings/tests/file_bug1110872.js
Normal file
47
dom/settings/tests/file_bug1110872.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe;
|
||||
var loadedEvents = 0;
|
||||
|
||||
function loadServer() {
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.addEventListener('load', mozbrowserLoaded);
|
||||
iframe.src = 'file_bug1110872.html';
|
||||
}
|
||||
|
||||
function iframeBodyRecv(msg) {
|
||||
switch (loadedEvents) {
|
||||
case 1:
|
||||
// If we get a message back before we've seen 2 loads, that means
|
||||
// something went wrong with the test. Fail immediately.
|
||||
ok(true, 'got response from first test!');
|
||||
break;
|
||||
case 2:
|
||||
// If we get a message back after 2 loads (initial load, reload),
|
||||
// it means the callback for the last lock fired, which means the
|
||||
// SettingsRequestManager queue has to have been cleared
|
||||
// correctly.
|
||||
ok(true, 'further queries returned ok after SettingsManager death');
|
||||
SimpleTest.finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function mozbrowserLoaded() {
|
||||
loadedEvents++;
|
||||
iframe.contentWindow.postMessage({name: "start", step: loadedEvents}, '*');
|
||||
window.addEventListener('message', iframeBodyRecv);
|
||||
}
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
loadServer();
|
||||
runTest();
|
||||
});
|
||||
17
dom/settings/tests/file_loadserver.js
Normal file
17
dom/settings/tests/file_loadserver.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
var Cu = Components.utils;
|
||||
|
||||
// Stolen from SpecialPowers, since at this point we don't know we're in a test.
|
||||
var isMainProcess = function() {
|
||||
try {
|
||||
return Cc["@mozilla.org/xre/app-info;1"].
|
||||
getService(Ci.nsIXULRuntime).
|
||||
processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
} catch (e) { }
|
||||
return true;
|
||||
};
|
||||
|
||||
if (isMainProcess()) {
|
||||
Components.utils.import("resource://gre/modules/SettingsRequestManager.jsm");
|
||||
}
|
||||
816
dom/settings/tests/test_settings_basics.html
Normal file
816
dom/settings/tests/test_settings_basics.html
Normal file
|
|
@ -0,0 +1,816 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug {678695} Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={678695}">Mozilla Bug {678695}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
function onUnwantedSuccess() {
|
||||
ok(false, "onUnwantedSuccess: shouldn't get here");
|
||||
}
|
||||
|
||||
function onFailure() {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
|
||||
const wifi = {"net3g.apn": "internet.mnc012.mcc345.gprs"};
|
||||
const wifi2 = {"net3g.apn": "internet.mnc012.mcc345.test"};
|
||||
var wifi3 = {"net3g.apn2": "internet.mnc012.mcc345.test3"};
|
||||
var wifiEnabled = {"wifi.enabled": true};
|
||||
var wifiDisabled = {"wifi.enabled": false};
|
||||
var screenBright = {"screen.brightness": 0.7};
|
||||
var screenBright2 = {"screen.brightness": 0.1};
|
||||
var wifiNetworks0 = { "wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret"}};
|
||||
var wifiNetworks1 = { "wifi.networks[1]": { ssid: "myfreenetwork2", mac: "01:23:45:67:89:ab", passwd: "secret2"}};
|
||||
|
||||
var combination = {
|
||||
"wifi.enabled": false,
|
||||
"screen.brightness": 0.7,
|
||||
"wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret" },
|
||||
"test.test": true,
|
||||
"net3g.apn2": "internet.mnc012.mcc345.gprs"
|
||||
}
|
||||
|
||||
function equals(o1, o2) {
|
||||
var k1 = Object.keys(o1).sort();
|
||||
var k2 = Object.keys(o2).sort();
|
||||
if (k1.length != k2.length) return false;
|
||||
return k1.zip(k2, function(keyPair) {
|
||||
if(typeof o1[keyPair[0]] == typeof o2[keyPair[1]] == "object"){
|
||||
return equals(o1[keyPair[0]], o2[keyPair[1]])
|
||||
} else {
|
||||
return o1[keyPair[0]] == o2[keyPair[1]];
|
||||
}
|
||||
}).all();
|
||||
};
|
||||
|
||||
function observer1(setting) {
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
};
|
||||
|
||||
function observer2(setting) {
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
};
|
||||
|
||||
function observerWithNext(setting) {
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
next();
|
||||
};
|
||||
|
||||
function onsettingschangeWithNext(event) {
|
||||
is(event.settingName, "screen.brightness", "Same settingName");
|
||||
is(event.settingValue, 0.7, "Same settingvalue");
|
||||
next();
|
||||
};
|
||||
|
||||
function check(o1, o2) {
|
||||
is(JSON.stringify(o1), JSON.stringify(o2), "same");
|
||||
}
|
||||
|
||||
var req, req2, req3, req4, req5, req6;
|
||||
var index = 0;
|
||||
|
||||
var steps = [
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
},
|
||||
function () {
|
||||
ok(true, "Setting wifi");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifi);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req2 = lock2.get("net3g.apn");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wifi, req2.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi1");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
ok(true, "Get changed net3g.apn");
|
||||
req2 = lock.get("net3g.apn");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wifi2, req2.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Set Combination");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req3 = lock.set(combination);
|
||||
req3.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
req4 = lock.get("net3g.apn2");
|
||||
req4.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
|
||||
next();
|
||||
}
|
||||
}
|
||||
req3.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req4 = lock.get("net3g.apn2");
|
||||
req4.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
|
||||
next();
|
||||
}
|
||||
req4.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Get unknown key");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("abc.def");
|
||||
req.onsuccess = function() {
|
||||
is(req.result["abc.def"], undefined, "no result");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "adding onsettingchange");
|
||||
navigator.mozSettings.onsettingchange = onsettingschangeWithNext;
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.get("screen.brightness");
|
||||
req2.onsuccess = function() {
|
||||
ok(true, "end adding onsettingchange");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Test onsettingchange");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done, observer has to call next");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "delete onsettingschange");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
navigator.mozSettings.onsettingchange = null;
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Waiting for all set callbacks");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "adding Observers 1");
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observerWithNext);
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.get("screen.brightness");
|
||||
req2.onsuccess = function() {
|
||||
ok(true, "set observeSetting done!");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test observers");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observerWithNext);
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
ok(true, "get done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Nested test");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
req3 = lock.set({"screen.brightness": req.result["screen.brightness"] + 1})
|
||||
req3.onsuccess = function () {
|
||||
req4 = lock.get("screen.brightness");
|
||||
req4.onsuccess = function() {
|
||||
is(req4.result["screen.brightness"], 1.7, "same Value");
|
||||
}
|
||||
req4.onerror = onFailure;
|
||||
}
|
||||
req3.onerror = onFailure;
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
|
||||
req2 = lock.get("screen.brightness");
|
||||
req2.onsuccess = function () {
|
||||
is(req2.result["screen.brightness"], 0.7, "same Value");
|
||||
}
|
||||
req2.onerror = onFailure;
|
||||
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req5 = lock2.get("screen.brightness");
|
||||
req5.onsuccess = function () {
|
||||
is(req5.result["screen.brightness"], 1.7, "same Value");
|
||||
next();
|
||||
}
|
||||
req5.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
},
|
||||
function () {
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.set(wifi);
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req2.onerror = onFailure;
|
||||
|
||||
ok(true, "Get all settings");
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req3 = lock2.get("*");
|
||||
req3.onsuccess = function () {
|
||||
is(Object.keys(req3.result).length, 1, "length 1");
|
||||
check(req3.result, wifi);
|
||||
ok(true, JSON.stringify(req3.result));
|
||||
ok(true, "Get all settings Done");
|
||||
};
|
||||
req3.onerror = onFailure;
|
||||
|
||||
req4 = lock2.get("net3g.apn");
|
||||
req4.onsuccess = function () {
|
||||
is(Object.keys(req4.result).length, 1, "length 1");
|
||||
check(wifi, req4.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req4.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi1");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
|
||||
ok(true, "Get changed net3g.apn");
|
||||
req2 = lock.get("net3g.apn");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wifi2, req2.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test locking");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifiEnabled);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Test Locking Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
|
||||
req2 = lock2.set(wifiDisabled);
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test locking result");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("wifi.enabled");
|
||||
req.onsuccess = function() {
|
||||
check(req.result, wifiDisabled);
|
||||
ok(true, "Test1 locking result done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test locking heavy");
|
||||
for (var i=0; i<30; i++) {
|
||||
// only new locks!
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
var obj = {};
|
||||
obj["wifi.enabled" + i] = true;
|
||||
req = lock.set( obj );
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set1 Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
};
|
||||
{
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req2 = lock2.get("*");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 32, "length 12");
|
||||
ok(true, JSON.stringify(req2.result));
|
||||
ok(true, "Get all settings Done");
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
}
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
var obj = {};
|
||||
obj["wifi.enabled" + 30] = true;
|
||||
req3 = lock2.set( obj );
|
||||
req3.onsuccess = function () {
|
||||
ok(true, "Set12 Done");
|
||||
};
|
||||
req3.onerror = onFailure;
|
||||
|
||||
var lock3 = navigator.mozSettings.createLock();
|
||||
// with one lock
|
||||
for (var i = 0; i < 30; i++) {
|
||||
req4 = lock3.get("wifi.enabled" + i);
|
||||
var testObj = {};
|
||||
testObj["wifi.enabled" + i] = true;
|
||||
req4.onsuccess = function () {
|
||||
check(this.request.result, this.testObj);
|
||||
ok(true, "Get1 Done");
|
||||
}.bind({testObj: testObj, request: req4});
|
||||
req4.onerror = onFailure;
|
||||
}
|
||||
|
||||
ok(true, "start next2!");
|
||||
var lock4 = navigator.mozSettings.createLock();
|
||||
for (var i=0; i<30; i++) {
|
||||
var obj = {};
|
||||
obj["wifi.enabled" + i] = false;
|
||||
req4 = lock4.set( obj );
|
||||
req4.onsuccess = function () {
|
||||
ok(true, "Set2 Done");
|
||||
};
|
||||
req4.onerror = onFailure;
|
||||
}
|
||||
var lock5 = navigator.mozSettings.createLock();
|
||||
for (var i=0; i<30; i++) {
|
||||
req5 = lock5.get("wifi.enabled" + i);
|
||||
var testObj = {};
|
||||
testObj["wifi.enabled" + i] = false;
|
||||
req5.onsuccess = function () {
|
||||
check(this.request.result, this.testObj);
|
||||
ok(true, "Get2 Done");
|
||||
}.bind({testObj: testObj, request: req5});
|
||||
req5.onerror = onFailure;
|
||||
}
|
||||
|
||||
var lock6 = navigator.mozSettings.createLock();
|
||||
req6 = lock6.clear();
|
||||
req6.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req6.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "reverse Test locking");
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
|
||||
req = lock.set(wifiEnabled);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Test Locking Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
|
||||
req2 = lock2.set(wifiDisabled);
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test locking result");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
|
||||
req = lock.get("wifi.enabled");
|
||||
req.onsuccess = function() {
|
||||
check(req.result, wifiEnabled);
|
||||
ok(true, "Test2 locking result done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req2 = lock2.clear();
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
|
||||
var lock3 = navigator.mozSettings.createLock();
|
||||
req3 = lock3.set(wifi);
|
||||
req3.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
next();
|
||||
}
|
||||
req3.onerror = onFailure;
|
||||
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get all settings");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("*");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 1, "length 1");
|
||||
check(wifi, req.result);
|
||||
ok(true, "Get all settings Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get net3g.apn");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("net3g.apn");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 1, "length 1");
|
||||
check(wifi, req.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi2");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get net3g.apn");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("net3g.apn");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 1, "length 1");
|
||||
check(wifi2, req.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Add wifi.enabled");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifiEnabled);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get Wifi Enabled");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("wifi.enabled");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 1, "length 1");
|
||||
check(wifiEnabled, req.result);
|
||||
ok(true, "Get wifi.enabledDone");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get all");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("*");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 2, "length 2");
|
||||
check(wifiEnabled["wifi.enabled"], req.result["wifi.enabled"]);
|
||||
check(wifi2["net3g.apn"], req.result["net3g.apn"]);
|
||||
ok(true, "Get all Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Add wifiNetworks");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifiNetworks0);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
|
||||
req2 = lock.set(wifiNetworks1);
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get Wifi Networks");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("wifi.networks[0]");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 1, "length 1");
|
||||
check(wifiNetworks0, req.result);
|
||||
ok(true, "Get wifi.networks[0]");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB, multiple locks");
|
||||
var lock4 = navigator.mozSettings.createLock();
|
||||
var lock3 = navigator.mozSettings.createLock();
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
var lock6 = navigator.mozSettings.createLock();
|
||||
var lock7 = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Add wifiNetworks");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifiNetworks0);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test set after lock closed");
|
||||
var lockx = navigator.mozSettings.createLock();
|
||||
var cb = function() {
|
||||
var reqx = null;
|
||||
try {
|
||||
reqx = lockx.set(wifiNetworks0);
|
||||
ok(false, "should have thrown");
|
||||
} catch (ex) {
|
||||
ok(reqx == null, "request is still null");
|
||||
ok(true, "Caught Exception");
|
||||
next();
|
||||
}
|
||||
}
|
||||
SimpleTest.executeSoon(cb);
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Set with multiple arguments");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(combination);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "request argument from multiple set");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
check(req.result["screen.brightness"], 0.7, "get done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Test closed attribute on a valid lock");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
is(lock.closed, false, "closed attribute is false on creation");
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
is(lock.closed, false, "closed attribute is false on success callback");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test closed attribute on invalid lock");
|
||||
var lockx = navigator.mozSettings.createLock();
|
||||
var cb = function() {
|
||||
var reqx = null;
|
||||
try {
|
||||
reqx = lockx.set(wifiNetworks0);
|
||||
ok(false, "should have thrown");
|
||||
} catch (ex) {
|
||||
is(lockx.closed, true, "closed attribute is true");
|
||||
ok(true, "Caught Exception");
|
||||
next();
|
||||
}
|
||||
}
|
||||
SimpleTest.executeSoon(cb);
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Set object value");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set({"setting-obj": {foo: {bar: 23}}});
|
||||
req.onsuccess = function() {
|
||||
req2 = lock.get("setting-obj");
|
||||
req2.onsuccess = function(event) {
|
||||
var result = event.target.result["setting-obj"];
|
||||
ok(result, "Got valid result");
|
||||
ok(typeof result == "object", "Result is object");
|
||||
ok("foo" in result && "bar" in result.foo, "Result has properties");
|
||||
ok(result.foo.bar == 23, "Result properties are set");
|
||||
next();
|
||||
};
|
||||
};
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Call success callback when transaction commits");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
lock.onsettingstransactionsuccess = function () {
|
||||
next();
|
||||
};
|
||||
req = lock.set({"setting-obj": {foo: {bar: 23}}});
|
||||
req.onsuccess = function() {
|
||||
req2 = lock.get("setting-obj");
|
||||
req2.onsuccess = function(event) {
|
||||
var result = event.target.result["setting-obj"];
|
||||
ok(result, "Got valid result");
|
||||
ok(typeof result == "object", "Result is object");
|
||||
ok("foo" in result && "bar" in result.foo, "Result has properties");
|
||||
ok(result.foo.bar == 23, "Result properties are set");
|
||||
};
|
||||
};
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
ok(true, "Begin!");
|
||||
if (index >= steps.length) {
|
||||
ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
steps[index]();
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
148
dom/settings/tests/test_settings_blobs.html
Normal file
148
dom/settings/tests/test_settings_blobs.html
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=821630
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 821630 Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821630">Mozilla Bug 821630</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
function onUnwantedSuccess() {
|
||||
ok(false, "onUnwantedSuccess: shouldn't get here");
|
||||
}
|
||||
|
||||
function onFailure() {
|
||||
return function(s) {
|
||||
if (s) {
|
||||
ok(false, "in on Failure! - " + s);
|
||||
} else {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let req;
|
||||
|
||||
let storedBlob = new Blob(['12345'], {"type": "text/plain"});
|
||||
|
||||
function checkBlob(blob) {
|
||||
try {
|
||||
let url = URL.createObjectURL(blob);
|
||||
ok(true, "Valid blob");
|
||||
} catch (e) {
|
||||
ok(false, "Valid blob");
|
||||
}
|
||||
}
|
||||
|
||||
let steps = [
|
||||
function() {
|
||||
let lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = next;
|
||||
req.onerror = onFailure("Deleting database");
|
||||
},
|
||||
function() {
|
||||
function obs(e) {
|
||||
checkBlob(e.settingValue);
|
||||
navigator.mozSettings.removeObserver("test1", obs);
|
||||
next();
|
||||
}
|
||||
navigator.mozSettings.addObserver("test1", obs);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
// next is called by the observer above
|
||||
let req = navigator.mozSettings.createLock().set({"test1": storedBlob});
|
||||
req.onerror = onFailure("Saving blob");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test1");
|
||||
req.onsuccess = function(event) {
|
||||
checkBlob(event.target.result["test1"]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting blob");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().set({"test2": [1, 2, storedBlob, 4]});
|
||||
req.onsuccess = next;
|
||||
req.onerror = onFailure("Saving array");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test2");
|
||||
req.onsuccess = function(event) {
|
||||
let val = event.target.result["test2"];
|
||||
ok(Array.isArray(val), "Result is an array");
|
||||
ok(val[0] == 1 && val[1] == 2 && val[3] == 4, "Primitives are preserved");
|
||||
checkBlob(val[2]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting array");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().set({"test3": {foo: "bar", baz: {number: 1, arr: [storedBlob]}}});
|
||||
req.onsuccess = next();
|
||||
req.onerror = onFailure("Saving object");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test3");
|
||||
req.onsuccess = function(event) {
|
||||
let val = event.target.result["test3"];
|
||||
ok(typeof(val) == "object", "Result is an object");
|
||||
ok("foo" in val && typeof(val.foo) == "string", "String property preserved");
|
||||
ok("baz" in val && typeof(val.baz) == "object", "Object property preserved");
|
||||
let baz = val.baz;
|
||||
ok("number" in baz && baz.number == 1, "Primite inside object preserved");
|
||||
ok("arr" in baz && Array.isArray(baz.arr), "Array inside object is preserved");
|
||||
checkBlob(baz.arr[0]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting object");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().clear();
|
||||
req.onsuccess = function() {
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Deleting database");
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
try {
|
||||
let step = steps.shift();
|
||||
if (step) {
|
||||
step();
|
||||
}
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
17
dom/settings/tests/test_settings_bug1110872.html
Normal file
17
dom/settings/tests/test_settings_bug1110872.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug {1110872} Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="file_bug1110872.js">
|
||||
</script>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1110872}">Mozilla Bug {1110872}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
149
dom/settings/tests/test_settings_data_uris.html
Normal file
149
dom/settings/tests/test_settings_data_uris.html
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=806374
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 806374 Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821630">Mozilla Bug 821630</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
function onUnwantedSuccess() {
|
||||
ok(false, "onUnwantedSuccess: shouldn't get here");
|
||||
}
|
||||
|
||||
function onFailure() {
|
||||
return function(s) {
|
||||
if (s) {
|
||||
ok(false, "in on Failure! - " + s);
|
||||
} else {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let req;
|
||||
|
||||
// A simple data URI that will be converted to a blob.
|
||||
let dataURI = "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;";
|
||||
|
||||
function checkBlob(blob) {
|
||||
try {
|
||||
let url = URL.createObjectURL(blob);
|
||||
ok(true, "Valid blob");
|
||||
} catch (e) {
|
||||
ok(false, "Valid blob");
|
||||
}
|
||||
}
|
||||
|
||||
let steps = [
|
||||
function() {
|
||||
let lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = next;
|
||||
req.onerror = onFailure("Deleting database");
|
||||
},
|
||||
function() {
|
||||
function obs(e) {
|
||||
checkBlob(e.settingValue);
|
||||
navigator.mozSettings.removeObserver("test1", obs);
|
||||
next();
|
||||
}
|
||||
navigator.mozSettings.addObserver("test1", obs);
|
||||
next();
|
||||
},
|
||||
function() {
|
||||
// next is called by the observer above
|
||||
let req = navigator.mozSettings.createLock().set({"test1": dataURI});
|
||||
req.onerror = onFailure("Saving blob");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test1");
|
||||
req.onsuccess = function(event) {
|
||||
checkBlob(event.target.result["test1"]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting blob");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().set({"test2": [1, 2, dataURI, 4]});
|
||||
req.onsuccess = next;
|
||||
req.onerror = onFailure("Saving array");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test2");
|
||||
req.onsuccess = function(event) {
|
||||
let val = event.target.result["test2"];
|
||||
ok(Array.isArray(val), "Result is an array");
|
||||
ok(val[0] == 1 && val[1] == 2 && val[3] == 4, "Primitives are preserved");
|
||||
checkBlob(val[2]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting array");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().set({"test3": {foo: "bar", baz: {number: 1, arr: [dataURI]}}});
|
||||
req.onsuccess = next();
|
||||
req.onerror = onFailure("Saving object");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().get("test3");
|
||||
req.onsuccess = function(event) {
|
||||
let val = event.target.result["test3"];
|
||||
ok(typeof(val) == "object", "Result is an object");
|
||||
ok("foo" in val && typeof(val.foo) == "string", "String property preserved");
|
||||
ok("baz" in val && typeof(val.baz) == "object", "Object property preserved");
|
||||
let baz = val.baz;
|
||||
ok("number" in baz && baz.number == 1, "Primite inside object preserved");
|
||||
ok("arr" in baz && Array.isArray(baz.arr), "Array inside object is preserved");
|
||||
checkBlob(baz.arr[0]);
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Getting object");
|
||||
},
|
||||
function() {
|
||||
let req = navigator.mozSettings.createLock().clear();
|
||||
req.onsuccess = function() {
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure("Deleting database");
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
try {
|
||||
let step = steps.shift();
|
||||
if (step) {
|
||||
step();
|
||||
}
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
47
dom/settings/tests/test_settings_events.html
Normal file
47
dom/settings/tests/test_settings_events.html
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=678695
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 678695</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 678695 **/
|
||||
|
||||
var e = new MozSettingsEvent("settingchanged", {settingName: "a", settingValue: 1});
|
||||
ok(e, "Should have settings event!");
|
||||
is(e.settingName, "a", "Name should be a.");
|
||||
is(e.settingValue, 1, "Value should be 1.");
|
||||
|
||||
e = new MozSettingsEvent("settingchanged", {settingName: "test", settingValue: {test: "test"}});
|
||||
is(e.settingName, "test", "Name should be 'test'.");
|
||||
is(e.settingValue.test, "test", "Name should be 'test'.");
|
||||
|
||||
e = new MozSettingsEvent("settingchanged", {settingName: "a", settingValue: true});
|
||||
is(e.settingName, "a", "Name should be a.");
|
||||
is(e.settingValue, true, "Value should be true.");
|
||||
|
||||
var e = new MozSettingsTransactionEvent("settingtransactionsuccess", {});
|
||||
ok(e, "Should have settings event!");
|
||||
is(e.error, "", "error should be null");
|
||||
|
||||
var e = new MozSettingsTransactionEvent("settingtransactionfailure", {error: "Test error."});
|
||||
ok(e, "Should have settings event!");
|
||||
is(e.error, "Test error.", "error should be 'Test error.'");
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
37
dom/settings/tests/test_settings_navigator_object.html
Normal file
37
dom/settings/tests/test_settings_navigator_object.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=898512
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 898512 Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=898512">Mozilla Bug 898512</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testPref() {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.mozSettings.enabled", false]]
|
||||
}, function() {
|
||||
is(navigator.mozSettings, undefined, "navigator.mozSettings is undefined");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
testPref();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
60
dom/settings/tests/test_settings_observer_killer.html
Normal file
60
dom/settings/tests/test_settings_observer_killer.html
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1193469
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1193469 Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1193469">Mozilla Bug 1193469</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.mozSettings.enabled", true]]
|
||||
},
|
||||
function () {
|
||||
ok(true, "abusing observers");
|
||||
|
||||
var obs;
|
||||
for (obs = 0; obs < 9; obs++) {
|
||||
navigator.mozSettings.addObserver("fake.setting.key", function(v) {
|
||||
// nothing to do for real ...
|
||||
ok(false, "should not be called");
|
||||
});
|
||||
ok(true, "first: added observer #" + obs);
|
||||
}
|
||||
ok(true, "adding first observers, should not have thrown");
|
||||
|
||||
try {
|
||||
ok(true, "second: adding new observer");
|
||||
navigator.mozSettings.addObserver("fake.setting.key", function(v) {
|
||||
// nothing to do for real ...
|
||||
ok(false, "should not be called");
|
||||
});
|
||||
ok(false, "adding too many observers should have thrown");
|
||||
} catch (ex) {
|
||||
ok(true, "got exception when trying to add too many observers");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
306
dom/settings/tests/test_settings_onsettingchange.html
Normal file
306
dom/settings/tests/test_settings_onsettingchange.html
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=678695
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 678695 Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
var screenBright = {"screen.brightness": 0.7};
|
||||
|
||||
function onFailure() {
|
||||
ok(false, "in on Failure!");
|
||||
}
|
||||
|
||||
function observer1(setting) {
|
||||
dump("observer 1 called!\n");
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
};
|
||||
|
||||
function observer2(setting) {
|
||||
dump("observer 2 called!\n");
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
};
|
||||
|
||||
var calls = 0;
|
||||
function observerOnlyCalledOnce(setting) {
|
||||
is(++calls, 1, "Observer only called once!");
|
||||
};
|
||||
|
||||
|
||||
function observerWithNext(setting) {
|
||||
dump("observer with next called!\n");
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, 0.7, "Same settingvalue");
|
||||
next();
|
||||
};
|
||||
|
||||
function onsettingschangeWithNext(event) {
|
||||
dump("onsettingschangewithnext called!\n");
|
||||
is(event.settingName, "screen.brightness", "Same settingName");
|
||||
is(event.settingValue, 0.7, "Same settingvalue");
|
||||
next();
|
||||
};
|
||||
|
||||
var cset = {'a':'b','c':[{'d':'e'}]};
|
||||
|
||||
function onComplexSettingschangeWithNext(event) {
|
||||
is(event.settingName, "test.key", "Same settingName");
|
||||
is(event.settingValue['a'], "b", "Same settingvalue");
|
||||
var c = event.settingValue['c'];
|
||||
ok(Array.isArray(c), "c is array!");
|
||||
is(c[0]['d'], 'e', "Right settingValue!");
|
||||
next();
|
||||
};
|
||||
|
||||
var req, req2;
|
||||
var index = 0;
|
||||
|
||||
var steps = [
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.set(screenBright);
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
navigator.mozSettings.onsettingchange = onsettingschangeWithNext;
|
||||
next();
|
||||
}
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "testing");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.set(screenBright);
|
||||
req2.onsuccess = function() {
|
||||
ok(true, "end adding onsettingchange");
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test observers");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
ok(true, "get done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "adding Observers 1");
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observerOnlyCalledOnce);
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.get("screen.brightness");
|
||||
req2.onsuccess = function() {
|
||||
ok(true, "set observeSetting done!");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test observers");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set1 done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test observers");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observerOnlyCalledOnce);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set1 done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set2 done");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
|
||||
function() {
|
||||
ok(true, "delete onsettingschange");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
navigator.mozSettings.onsettingchange = null;
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set0 done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Waiting for all set callbacks");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "adding Observers 1");
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer1);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.addObserver("screen.brightness", observerWithNext);
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req2 = lock.get("screen.brightness");
|
||||
req2.onsuccess = function() {
|
||||
ok(true, "set observeSetting done!");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test observers");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set1 done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set2 done");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "test Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set3 done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observerWithNext);
|
||||
req = lock.set(screenBright);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set4 done");
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer2);
|
||||
navigator.mozSettings.removeObserver("screen.brightness", observer1);
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "removing Event Listener");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("screen.brightness");
|
||||
req.onsuccess = function () {
|
||||
ok(true, "get5 done");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Clear DB");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
navigator.mozSettings.onsettingchange = onComplexSettingschangeWithNext;
|
||||
req2 = navigator.mozSettings.createLock().set({'test.key': cset});
|
||||
req2.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
ok(true, "Begin!");
|
||||
if (index >= steps.length) {
|
||||
ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
steps[index]();
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
184
dom/settings/tests/test_settings_permissions.html
Normal file
184
dom/settings/tests/test_settings_permissions.html
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug {678695} Settings API</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={900551}">Mozilla Bug {900551}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
"use strict";
|
||||
|
||||
var url = SimpleTest.getTestFileURL("file_loadserver.js");
|
||||
var script = SpecialPowers.loadChromeScript(url);
|
||||
|
||||
function onUnwantedSuccess() {
|
||||
ok(false, "onUnwantedSuccess: shouldn't get here");
|
||||
}
|
||||
|
||||
// No more permissions, so failure cannot happen
|
||||
function onFailure() {
|
||||
ok(true, "in on Failure!");
|
||||
next();
|
||||
}
|
||||
|
||||
const wifi = {"wifi.enabled": false}
|
||||
const wallpaper = {"wallpaper.image": "test-image"};
|
||||
|
||||
var combination = {
|
||||
"wifi.enabled": false,
|
||||
"wallpaper.image": "test-image"
|
||||
}
|
||||
|
||||
function equals(o1, o2) {
|
||||
var k1 = Object.keys(o1).sort();
|
||||
var k2 = Object.keys(o2).sort();
|
||||
if (k1.length != k2.length) return false;
|
||||
return k1.zip(k2, function(keyPair) {
|
||||
if(typeof o1[keyPair[0]] == typeof o2[keyPair[1]] == "object"){
|
||||
return equals(o1[keyPair[0]], o2[keyPair[1]])
|
||||
} else {
|
||||
return o1[keyPair[0]] == o2[keyPair[1]];
|
||||
}
|
||||
}).all();
|
||||
};
|
||||
|
||||
function observer1(setting) {
|
||||
is(setting.settingName, "screen.brightness", "Same settingName");
|
||||
is(setting.settingValue, "0.7", "Same settingvalue");
|
||||
};
|
||||
|
||||
function onsettingschangeWithNext(event) {
|
||||
is(event.settingName, "screen.brightness", "Same settingName");
|
||||
is(event.settingValue, "0.7", "Same settingvalue");
|
||||
next();
|
||||
};
|
||||
|
||||
function check(o1, o2) {
|
||||
is(JSON.stringify(o1), JSON.stringify(o2), "same");
|
||||
}
|
||||
|
||||
var req, req2, req3, req4, req5, req6;
|
||||
var index = 0;
|
||||
|
||||
var steps = [
|
||||
// Can't delete database here since that requires permissions we don't want
|
||||
// to give the page.
|
||||
function () {
|
||||
ok(true, "Setting wallpaper");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wallpaper);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
|
||||
var lock2 = navigator.mozSettings.createLock();
|
||||
req2 = lock2.get("wallpaper.image");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wallpaper, req2.result);
|
||||
ok(true, "Get wallpaper Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Get Wifi");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.get("wifi.enabled");
|
||||
req.onerror = function () {
|
||||
ok(true, "get failed (expected)");
|
||||
next();
|
||||
}
|
||||
req.onsuccess = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Set Wifi");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(wifi);
|
||||
req.onerror = function () {
|
||||
ok(true, "set failed (expected)");
|
||||
next();
|
||||
}
|
||||
req.onsuccess = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Set combination (1 valid 1 not valid)");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(combination);
|
||||
req.onerror = function () {
|
||||
ok(true, "set failed (expected)");
|
||||
next();
|
||||
}
|
||||
req.onsuccess = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "All requests on a failed lock should fail");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
lock.onsettingstransactionfailure = function (evt) {
|
||||
ok(evt.error == "Lock failed a permissions check, all requests now failing.", "transaction failure on permissions error message correct.");
|
||||
ok(true, "transaction failed (expected) ");
|
||||
next();
|
||||
};
|
||||
lock.onsettingstransactionsuccess = onFailure;
|
||||
|
||||
req = lock.set(wifi);
|
||||
req.onerror = function () {
|
||||
ok(true, "set failed (expected)");
|
||||
}
|
||||
req.onsuccess = onFailure;
|
||||
req2 = lock.get("wallpaper.image");
|
||||
req2.onerror = function () {
|
||||
ok(true, "get failed (expected)");
|
||||
}
|
||||
req2.onsuccess = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Set combination (1 valid 1 not valid)");
|
||||
var lock = navigator.mozSettings.createLock();
|
||||
req = lock.set(combination);
|
||||
req.onerror = function () {
|
||||
ok(true, "set failed (expected)");
|
||||
next();
|
||||
}
|
||||
req.onsuccess = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "all done!\n");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
ok(true, "Begin!");
|
||||
if (index >= steps.length) {
|
||||
ok(false, "Shouldn't get here!");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
steps[index]();
|
||||
} catch(ex) {
|
||||
ok(false, "Caught exception", ex);
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
138
dom/settings/tests/test_settings_service.js
Normal file
138
dom/settings/tests/test_settings_service.js
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/SettingsRequestManager.jsm");
|
||||
}
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "SettingsService",
|
||||
"@mozilla.org/settingsService;1",
|
||||
"nsISettingsService");
|
||||
|
||||
var tests = [
|
||||
/* Callback tests */
|
||||
function() {
|
||||
let callbackCount = 10;
|
||||
|
||||
let callback = {
|
||||
handle: function(name, result) {
|
||||
switch (callbackCount) {
|
||||
case 10:
|
||||
case 9:
|
||||
is(result, true, "result is true");
|
||||
break;
|
||||
case 8:
|
||||
case 7:
|
||||
is(result, false, "result is false");
|
||||
break;
|
||||
case 6:
|
||||
case 5:
|
||||
is(result, 9, "result is 9");
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
is(result, 9.4, "result is 9.4");
|
||||
break;
|
||||
case 2:
|
||||
is(result, false, "result is false");
|
||||
break;
|
||||
case 1:
|
||||
is(result, null, "result is null");
|
||||
break;
|
||||
default:
|
||||
ok(false, "Unexpected call: " + callbackCount);
|
||||
}
|
||||
|
||||
--callbackCount;
|
||||
if (callbackCount === 0) {
|
||||
next();
|
||||
}
|
||||
},
|
||||
|
||||
handleError: function(name) {
|
||||
ok(false, "error: " + name);
|
||||
}
|
||||
};
|
||||
|
||||
let lock = SettingsService.createLock();
|
||||
let lock1 = SettingsService.createLock();
|
||||
|
||||
lock.set("asdf", true, callback, null);
|
||||
lock1.get("asdf", callback);
|
||||
lock.get("asdf", callback);
|
||||
lock.set("asdf", false, callback, null);
|
||||
lock.get("asdf", callback);
|
||||
lock.set("int", 9, callback, null);
|
||||
lock.get("int", callback);
|
||||
lock.set("doub", 9.4, callback, null);
|
||||
lock.get("doub", callback);
|
||||
lock1.get("asdfxxx", callback);
|
||||
},
|
||||
|
||||
/* Observer tests */
|
||||
function() {
|
||||
const MOZSETTINGS_CHANGED = "mozsettings-changed";
|
||||
const TEST_OBSERVER_KEY = "test.observer.key";
|
||||
const TEST_OBSERVER_VALUE = true;
|
||||
const TEST_OBSERVER_MESSAGE = "test.observer.message";
|
||||
|
||||
var obs = {
|
||||
observe: function (subject, topic, data) {
|
||||
|
||||
if (topic !== MOZSETTINGS_CHANGED) {
|
||||
ok(false, "Event is not mozsettings-changed.");
|
||||
return;
|
||||
}
|
||||
// Data is now stored in subject
|
||||
if ("wrappedJSObject" in subject) {
|
||||
ok(true, "JS object wrapped into subject");
|
||||
subject = subject.wrappedJSObject;
|
||||
}
|
||||
if (subject["key"] != TEST_OBSERVER_KEY) {
|
||||
return;
|
||||
}
|
||||
|
||||
function checkProp(name, type, value) {
|
||||
ok(name in subject, "subject." + name + " is present");
|
||||
is(typeof subject[name], type, "subject." + name + " is " + type);
|
||||
is(subject[name], value, "subject." + name + " is " + value);
|
||||
}
|
||||
|
||||
checkProp("key", "string", TEST_OBSERVER_KEY);
|
||||
checkProp("value", "boolean", TEST_OBSERVER_VALUE);
|
||||
checkProp("isInternalChange", "boolean", true);
|
||||
|
||||
Services.obs.removeObserver(this, MOZSETTINGS_CHANGED);
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(obs, MOZSETTINGS_CHANGED, false);
|
||||
|
||||
let lock = SettingsService.createLock();
|
||||
lock.set(TEST_OBSERVER_KEY, TEST_OBSERVER_VALUE, null);
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
let step = tests.shift();
|
||||
if (step) {
|
||||
try {
|
||||
step();
|
||||
} catch(e) {
|
||||
ok(false, "Test threw: " + e);
|
||||
}
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
19
dom/settings/tests/test_settings_service.xul
Normal file
19
dom/settings/tests/test_settings_service.xul
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=678695
|
||||
-->
|
||||
<window title="Mozilla Bug 678695"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695"
|
||||
target="_blank">Mozilla Bug 678695</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="test_settings_service.js" />
|
||||
</window>
|
||||
47
dom/settings/tests/test_settings_service_callback.js
Normal file
47
dom/settings/tests/test_settings_service_callback.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "SettingsService",
|
||||
"@mozilla.org/settingsService;1",
|
||||
"nsISettingsService");
|
||||
|
||||
var tests = [
|
||||
function () {
|
||||
let callback = {
|
||||
handle: function() {
|
||||
ok(true, "handle called!");
|
||||
next();
|
||||
},
|
||||
|
||||
handleAbort: function(name) {
|
||||
ok(false, "error: " + name);
|
||||
next();
|
||||
}
|
||||
}
|
||||
let lock = SettingsService.createLock(callback);
|
||||
lock.set("xasdf", true, null, null);
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
let step = tests.shift();
|
||||
if (step) {
|
||||
try {
|
||||
step();
|
||||
} catch(e) {
|
||||
ok(false, "Test threw: " + e);
|
||||
}
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
19
dom/settings/tests/test_settings_service_callback.xul
Normal file
19
dom/settings/tests/test_settings_service_callback.xul
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1012214
|
||||
-->
|
||||
<window title="Mozilla Bug 1012214"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1012214"
|
||||
target="_blank">Mozilla Bug 1012214</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="test_settings_service_callback.js" />
|
||||
</window>
|
||||
174
dom/settings/tests/unit/test_settingsrequestmanager_messages.js
Normal file
174
dom/settings/tests/unit/test_settingsrequestmanager_messages.js
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
var principal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
var lockID = "{435d2192-4f21-48d4-90b7-285f147a56be}";
|
||||
|
||||
// Helper to start the Settings Request Manager
|
||||
function startSettingsRequestManager() {
|
||||
Cu.import("resource://gre/modules/SettingsRequestManager.jsm");
|
||||
}
|
||||
|
||||
function handlerHelper(reply, callback, runNext = true) {
|
||||
let handler = {
|
||||
receiveMessage: function(message) {
|
||||
if (message.name === reply) {
|
||||
cpmm.removeMessageListener(reply, handler);
|
||||
callback(message);
|
||||
if (runNext) {
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
cpmm.addMessageListener(reply, handler);
|
||||
}
|
||||
|
||||
// Helper function to add a listener, send message and treat the reply
|
||||
function addAndSend(msg, reply, callback, payload, runNext = true) {
|
||||
handlerHelper(reply, callback, runNext);
|
||||
cpmm.sendAsyncMessage(msg, payload, undefined, principal);
|
||||
}
|
||||
|
||||
function errorHandler(reply, str) {
|
||||
let errHandler = function(message) {
|
||||
ok(true, str);
|
||||
};
|
||||
|
||||
handlerHelper(reply, errHandler);
|
||||
}
|
||||
|
||||
// We need to trigger a Settings:Run message to make the queue progress
|
||||
function send_settingsRun() {
|
||||
let msg = {lockID: lockID, isServiceLock: true};
|
||||
cpmm.sendAsyncMessage("Settings:Run", msg, undefined, principal);
|
||||
}
|
||||
|
||||
function kill_child() {
|
||||
let msg = {lockID: lockID, isServiceLock: true};
|
||||
cpmm.sendAsyncMessage("child-process-shutdown", msg, undefined, principal);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
startSettingsRequestManager();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_createLock() {
|
||||
let msg = {lockID: lockID, isServiceLock: true};
|
||||
cpmm.sendAsyncMessage("Settings:CreateLock", msg, undefined, principal);
|
||||
cpmm.sendAsyncMessage(
|
||||
"Settings:RegisterForMessages", undefined, undefined, principal);
|
||||
ok(true);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_get_empty() {
|
||||
let requestID = 10;
|
||||
let msgReply = "Settings:Get:OK";
|
||||
let msgHandler = function(message) {
|
||||
equal(requestID, message.data.requestID);
|
||||
equal(lockID, message.data.lockID);
|
||||
ok(Object.keys(message.data.settings).length >= 0);
|
||||
};
|
||||
|
||||
errorHandler("Settings:Get:KO", "Settings GET failed");
|
||||
|
||||
addAndSend("Settings:Get", msgReply, msgHandler, {
|
||||
requestID: requestID,
|
||||
lockID: lockID,
|
||||
name: "language.current"
|
||||
});
|
||||
|
||||
send_settingsRun();
|
||||
});
|
||||
|
||||
add_test(function test_set_get_nonempty() {
|
||||
let settings = { "language.current": "fr-FR:XPC" };
|
||||
let requestIDSet = 20;
|
||||
let msgReplySet = "Settings:Set:OK";
|
||||
let msgHandlerSet = function(message) {
|
||||
equal(requestIDSet, message.data.requestID);
|
||||
equal(lockID, message.data.lockID);
|
||||
};
|
||||
|
||||
errorHandler("Settings:Set:KO", "Settings SET failed");
|
||||
|
||||
addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
|
||||
requestID: requestIDSet,
|
||||
lockID: lockID,
|
||||
settings: settings
|
||||
}, false);
|
||||
|
||||
let requestIDGet = 25;
|
||||
let msgReplyGet = "Settings:Get:OK";
|
||||
let msgHandlerGet = function(message) {
|
||||
equal(requestIDGet, message.data.requestID);
|
||||
equal(lockID, message.data.lockID);
|
||||
for(let p in settings) {
|
||||
equal(settings[p], message.data.settings[p]);
|
||||
}
|
||||
};
|
||||
|
||||
addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
|
||||
requestID: requestIDGet,
|
||||
lockID: lockID,
|
||||
name: Object.keys(settings)[0]
|
||||
});
|
||||
|
||||
// Set and Get have been push into the queue, let's run
|
||||
send_settingsRun();
|
||||
});
|
||||
|
||||
// This test exposes bug 1076597 behavior
|
||||
add_test(function test_wait_for_finalize() {
|
||||
let settings = { "language.current": "en-US:XPC" };
|
||||
let requestIDSet = 30;
|
||||
let msgReplySet = "Settings:Set:OK";
|
||||
let msgHandlerSet = function(message) {
|
||||
equal(requestIDSet, message.data.requestID);
|
||||
equal(lockID, message.data.lockID);
|
||||
};
|
||||
|
||||
errorHandler("Settings:Set:KO", "Settings SET failed");
|
||||
|
||||
addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
|
||||
requestID: requestIDSet,
|
||||
lockID: lockID,
|
||||
settings: settings
|
||||
}, false);
|
||||
|
||||
let requestIDGet = 35;
|
||||
let msgReplyGet = "Settings:Get:OK";
|
||||
let msgHandlerGet = function(message) {
|
||||
equal(requestIDGet, message.data.requestID);
|
||||
equal(lockID, message.data.lockID);
|
||||
for(let p in settings) {
|
||||
equal(settings[p], message.data.settings[p]);
|
||||
}
|
||||
};
|
||||
|
||||
errorHandler("Settings:Get:KO", "Settings GET failed");
|
||||
|
||||
addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
|
||||
requestID: requestIDGet,
|
||||
lockID: lockID,
|
||||
name: Object.keys(settings)[0]
|
||||
});
|
||||
|
||||
// We simulate a child death, which will force previous requests to be set
|
||||
// into finalize state
|
||||
kill_child();
|
||||
|
||||
// Then when we issue Settings:Run, those finalized should be triggered
|
||||
send_settingsRun();
|
||||
});
|
||||
6
dom/settings/tests/unit/xpcshell.ini
Normal file
6
dom/settings/tests/unit/xpcshell.ini
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
|
||||
[test_settingsrequestmanager_messages.js]
|
||||
skip-if = (buildapp != 'b2g')
|
||||
Loading…
Add table
Add a link
Reference in a new issue