Bug 1344519 - Add web extension events for containers onUpdated, onCreated and onRemoved r=aswan,baku

MozReview-Commit-ID: 9Zxjc1J2CAt

--HG--
extra : rebase_source : b4369d2657f428d61b1359875c32d0d6fb4dd3f3
This commit is contained in:
Jonathan Kingston 2017-05-14 00:39:32 +01:00
Родитель 9f5c1f2e4b
Коммит 5a77d88f1b
6 изменённых файлов: 178 добавлений и 3 удалений

Просмотреть файл

@ -216,6 +216,8 @@ _ContextualIdentityService.prototype = {
this._identities.push(identity);
this.saveSoon();
Services.obs.notifyObservers(this.getIdentityObserverOutput(identity),
"contextual-identity-created");
return Cu.cloneInto(identity, {});
},
@ -232,8 +234,9 @@ _ContextualIdentityService.prototype = {
delete identity.l10nID;
delete identity.accessKey;
Services.obs.notifyObservers(null, "contextual-identity-updated", userContextId);
this.saveSoon();
Services.obs.notifyObservers(this.getIdentityObserverOutput(identity),
"contextual-identity-updated");
}
return !!identity;
@ -250,13 +253,26 @@ _ContextualIdentityService.prototype = {
Services.obs.notifyObservers(null, "clear-origin-attributes-data",
JSON.stringify({ userContextId }));
let deletedOutput = this.getIdentityObserverOutput(this.getPublicIdentityFromId(userContextId));
this._identities.splice(index, 1);
this._openedIdentities.delete(userContextId);
this.saveSoon();
Services.obs.notifyObservers(deletedOutput, "contextual-identity-deleted");
return true;
},
getIdentityObserverOutput(identity) {
let wrappedJSObject = {
name: this.getUserContextLabel(identity.userContextId),
icon: identity.icon,
color: identity.color,
userContextId: identity.userContextId,
};
return {wrappedJSObject};
},
ensureDataReady() {
if (this._dataReady) {
return;

Просмотреть файл

@ -5,8 +5,9 @@ do_get_profile();
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
const TEST_STORE_FILE_NAME = "test-containers.json";
const TEST_STORE_FILE_PATH = OS.Path.join(OS.Constants.Path.profileDir, "test-containers.json");
let cis;
@ -14,7 +15,7 @@ let cis;
add_task(function() {
ok(!!ContextualIdentityService, "ContextualIdentityService exists");
cis = ContextualIdentityService.createNewInstanceForTesting(TEST_STORE_FILE_NAME);
cis = ContextualIdentityService.createNewInstanceForTesting(TEST_STORE_FILE_PATH);
ok(!!cis, "We have our instance of ContextualIdentityService");
equal(cis.getPublicIdentities().length, 4, "By default, 4 containers.");

Просмотреть файл

@ -1,3 +1,4 @@
[DEFAULT]
firefox-appdir = browser
[test_basic.js]

Просмотреть файл

@ -19,6 +19,18 @@ const convertIdentity = identity => {
return result;
};
const convertIdentityFromObserver = wrappedIdentity => {
let identity = wrappedIdentity.wrappedJSObject;
let result = {
name: identity.name,
icon: identity.icon,
color: identity.color,
cookieStoreId: getCookieStoreIdForContainer(identity.userContextId),
};
return result;
};
this.contextualIdentities = class extends ExtensionAPI {
getAPI(context) {
let self = {
@ -126,6 +138,40 @@ this.contextualIdentities = class extends ExtensionAPI {
return Promise.resolve(convertedIdentity);
},
onCreated: new EventManager(context, "contextualIdentities.onCreated", fire => {
let observer = (subject, topic) => {
fire.async({contextualIdentity: convertIdentityFromObserver(subject)});
};
Services.obs.addObserver(observer, "contextual-identity-created");
return () => {
Services.obs.removeObserver(observer, "contextual-identity-created");
};
}).api(),
onUpdated: new EventManager(context, "contextualIdentities.onUpdated", fire => {
let observer = (subject, topic) => {
fire.async({contextualIdentity: convertIdentityFromObserver(subject)});
};
Services.obs.addObserver(observer, "contextual-identity-updated");
return () => {
Services.obs.removeObserver(observer, "contextual-identity-updated");
};
}).api(),
onRemoved: new EventManager(context, "contextualIdentities.onRemoved", fire => {
let observer = (subject, topic) => {
fire.async({contextualIdentity: convertIdentityFromObserver(subject)});
};
Services.obs.addObserver(observer, "contextual-identity-deleted");
return () => {
Services.obs.removeObserver(observer, "contextual-identity-deleted");
};
}).api(),
},
};

Просмотреть файл

@ -118,6 +118,50 @@
}
]
}
],
"events": [
{
"name": "onUpdated",
"type": "function",
"description": "Fired when a container is updated.",
"parameters": [
{
"type": "object",
"name": "changeInfo",
"properties": {
"contextualIdentity": {"$ref": "ContextualIdentity", "description": "Contextual identity that has been updated"}
}
}
]
},
{
"name": "onCreated",
"type": "function",
"description": "Fired when a new container is created.",
"parameters": [
{
"type": "object",
"name": "changeInfo",
"properties": {
"contextualIdentity": {"$ref": "ContextualIdentity", "description": "Contextual identity that has been created"}
}
}
]
},
{
"name": "onRemoved",
"type": "function",
"description": "Fired when a container is removed.",
"parameters": [
{
"type": "object",
"name": "changeInfo",
"properties": {
"contextualIdentity": {"$ref": "ContextualIdentity", "description": "Contextual identity that has been removed"}
}
}
]
}
]
}
]

Просмотреть файл

@ -61,6 +61,73 @@ add_task(async function test_contextualIdentity_no_containers() {
Services.prefs.clearUserPref("privacy.userContext.enabled");
});
add_task(async function test_contextualIdentity_events() {
async function backgroundScript() {
function createOneTimeListener(type) {
return new Promise((resolve, reject) => {
try {
browser.test.assertTrue(type in browser.contextualIdentities, `Found API object browser.contextualIdentities.${type}`);
const listener = (change) => {
browser.test.assertTrue("contextualIdentity" in change, `Found identity in change`);
browser.contextualIdentities[type].removeListener(listener);
resolve(change);
};
browser.contextualIdentities[type].addListener(listener);
} catch (e) {
reject(e);
}
});
}
function assertExpected(expected, container) {
for (let key of Object.keys(container)) {
browser.test.assertTrue(key in expected, `found property ${key}`);
browser.test.assertEq(expected[key], container[key], `property value for ${key} is correct`);
}
browser.test.assertEq(Object.keys(expected).length, Object.keys(container).length, "all expected properties found");
}
let onCreatePromise = createOneTimeListener("onCreated");
let containerObj = {name: "foobar", color: "red", icon: "icon"};
let ci = await browser.contextualIdentities.create(containerObj);
browser.test.assertTrue(!!ci, "We have an identity");
const onCreateListenerResponse = await onCreatePromise;
const cookieStoreId = ci.cookieStoreId;
assertExpected(onCreateListenerResponse.contextualIdentity, Object.assign(containerObj, {cookieStoreId}));
let onUpdatedPromise = createOneTimeListener("onUpdated");
let updateContainerObj = {name: "testing", color: "blue", icon: "thing"};
ci = await browser.contextualIdentities.update(cookieStoreId, updateContainerObj);
browser.test.assertTrue(!!ci, "We have an update identity");
const onUpdatedListenerResponse = await onUpdatedPromise;
assertExpected(onUpdatedListenerResponse.contextualIdentity, Object.assign(updateContainerObj, {cookieStoreId}));
let onRemovePromise = createOneTimeListener("onRemoved");
ci = await browser.contextualIdentities.remove(updateContainerObj.cookieStoreId);
browser.test.assertTrue(!!ci, "We have an remove identity");
const onRemoveListenerResponse = await onRemovePromise;
assertExpected(onRemoveListenerResponse.contextualIdentity, Object.assign(updateContainerObj, {cookieStoreId}));
browser.test.notifyPass("contextualIdentities_events");
}
let extension = ExtensionTestUtils.loadExtension({
background: `(${backgroundScript})()`,
manifest: {
permissions: ["contextualIdentities"],
},
});
Services.prefs.setBoolPref("privacy.userContext.enabled", true);
await extension.startup();
await extension.awaitFinish("contextualIdentities_events");
await extension.unload();
Services.prefs.clearUserPref("privacy.userContext.enabled");
});
add_task(async function test_contextualIdentity_with_permissions() {
async function backgroundScript() {
let ci = await browser.contextualIdentities.get("foobar");