mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-29 01:00:41 +00:00
Bug 771980: provider must be re-usable, r=jaws
--HG-- extra : transplant_source : s%94%84%C2%7C%27%A3%B0%DB%5B%7F%40%96%A4S%21%FFcSA
This commit is contained in:
parent
2c31655232
commit
ed5fdc5f5a
@ -3621,3 +3621,5 @@ pref("memory.low_memory_notification_interval_ms", 10000);
|
||||
// likely leak)? This should be longer than it usually takes for an eligible
|
||||
// window to be collected via the GC/CC.
|
||||
pref("memory.ghost_window_timeout_seconds", 60);
|
||||
|
||||
pref("social.enabled", false);
|
||||
|
@ -18,8 +18,9 @@ const EXPORTED_SYMBOLS = ["SocialProvider"];
|
||||
*
|
||||
* @constructor
|
||||
* @param {jsobj} object representing the manifest file describing this provider
|
||||
* @param {bool} whether the provider should be initially enabled (defaults to true)
|
||||
*/
|
||||
function SocialProvider(input) {
|
||||
function SocialProvider(input, enabled) {
|
||||
if (!input.name)
|
||||
throw new Error("SocialProvider must be passed a name");
|
||||
if (!input.origin)
|
||||
@ -29,16 +30,53 @@ function SocialProvider(input) {
|
||||
this.workerURL = input.workerURL;
|
||||
this.origin = input.origin;
|
||||
|
||||
let workerAPIPort = this.getWorkerPort();
|
||||
if (workerAPIPort)
|
||||
this.workerAPI = new WorkerAPI(workerAPIPort);
|
||||
// If enabled is |undefined|, default to true.
|
||||
this._enabled = !(enabled == false);
|
||||
if (this._enabled)
|
||||
this._activate();
|
||||
}
|
||||
|
||||
SocialProvider.prototype = {
|
||||
/**
|
||||
* Terminates the provider's FrameWorker, if it has one.
|
||||
*/
|
||||
terminate: function terminate() {
|
||||
// Provider enabled/disabled state. Disabled providers do not have active
|
||||
// connections to their FrameWorkers.
|
||||
_enabled: true,
|
||||
get enabled() {
|
||||
return this._enabled;
|
||||
},
|
||||
set enabled(val) {
|
||||
let enable = !!val;
|
||||
if (enable == this._enabled)
|
||||
return;
|
||||
|
||||
this._enabled = enable;
|
||||
|
||||
if (enable) {
|
||||
this._activate();
|
||||
} else {
|
||||
this._terminate();
|
||||
}
|
||||
},
|
||||
|
||||
// Active port to the provider's FrameWorker. Null if the provider has no
|
||||
// FrameWorker, or is disabled.
|
||||
port: null,
|
||||
|
||||
// Reference to a workerAPI object for this provider. Null if the provider has
|
||||
// no FrameWorker, or is disabled.
|
||||
workerAPI: null,
|
||||
|
||||
// Internal helper methods
|
||||
_activate: function _activate() {
|
||||
// Initialize the workerAPI and its port first, so that its initialization
|
||||
// occurs before any other messages are processed by other ports.
|
||||
let workerAPIPort = this._getWorkerPort();
|
||||
if (workerAPIPort)
|
||||
this.workerAPI = new WorkerAPI(workerAPIPort);
|
||||
|
||||
this.port = this._getWorkerPort();
|
||||
},
|
||||
|
||||
_terminate: function _terminate() {
|
||||
if (this.workerURL) {
|
||||
try {
|
||||
getFrameWorkerHandle(this.workerURL, null).terminate();
|
||||
@ -46,18 +84,20 @@ SocialProvider.prototype = {
|
||||
Cu.reportError("SocialProvider FrameWorker termination failed: " + e);
|
||||
}
|
||||
}
|
||||
this.port = null;
|
||||
this.workerAPI = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Instantiates a FrameWorker for the provider if one doesn't exist, and
|
||||
* returns a reference to a port to that FrameWorker.
|
||||
* returns a reference to a new port to that FrameWorker.
|
||||
*
|
||||
* Returns null if this provider has no workerURL.
|
||||
* Returns null if this provider has no workerURL, or is disabled.
|
||||
*
|
||||
* @param {DOMWindow} window (optional)
|
||||
*/
|
||||
getWorkerPort: function getWorkerPort(window) {
|
||||
if (!this.workerURL)
|
||||
_getWorkerPort: function _getWorkerPort(window) {
|
||||
if (!this.workerURL || !this.enabled)
|
||||
return null;
|
||||
try {
|
||||
return getFrameWorkerHandle(this.workerURL, window).port;
|
||||
|
@ -10,30 +10,68 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/SocialProvider.jsm");
|
||||
|
||||
const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
|
||||
|
||||
let SocialServiceInternal = {};
|
||||
// Internal helper methods and state
|
||||
let SocialServiceInternal = {
|
||||
enabled: Services.prefs.getBoolPref("social.enabled"),
|
||||
get providerArray() {
|
||||
return [p for ([, p] of Iterator(this.providers))];
|
||||
}
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(SocialServiceInternal, "providers", function () {
|
||||
// Initialize the service (add a pref observer)
|
||||
function prefObserver(subject, topic, data) {
|
||||
SocialService._setEnabled(Services.prefs.getBoolPref(data));
|
||||
}
|
||||
Services.prefs.addObserver("social.enabled", prefObserver, false);
|
||||
Services.obs.addObserver(function xpcomShutdown() {
|
||||
Services.obs.removeObserver(xpcomShutdown, "xpcom-shutdown");
|
||||
Services.prefs.removeObserver("social.enabled", prefObserver);
|
||||
}, "xpcom-shutdown", false);
|
||||
|
||||
// Now retrieve the providers
|
||||
let providers = {};
|
||||
let MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
|
||||
let prefs = MANIFEST_PREFS.getChildList("", {});
|
||||
prefs.forEach(function (pref) {
|
||||
try {
|
||||
var manifest = JSON.parse(MANIFEST_PREFS.getCharPref(pref));
|
||||
if (manifest && typeof(manifest) == "object") {
|
||||
let provider = new SocialProvider(manifest);
|
||||
let provider = new SocialProvider(manifest, SocialServiceInternal.enabled);
|
||||
providers[provider.origin] = provider;
|
||||
}
|
||||
} catch (err) {
|
||||
Cu.reportError("SocialService: failed to load provider: " + pref +
|
||||
", exception: " + err);
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
|
||||
return providers;
|
||||
});
|
||||
|
||||
function schedule(callback) {
|
||||
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
// Public API
|
||||
const SocialService = {
|
||||
get enabled() {
|
||||
return SocialServiceInternal.enabled;
|
||||
},
|
||||
set enabled(val) {
|
||||
let enable = !!val;
|
||||
if (enable == SocialServiceInternal.enabled)
|
||||
return;
|
||||
|
||||
Services.prefs.setBoolPref("social.enabled", enable);
|
||||
this._setEnabled(enable);
|
||||
},
|
||||
_setEnabled: function _setEnabled(enable) {
|
||||
SocialServiceInternal.providerArray.forEach(function (p) p.enabled = enable);
|
||||
SocialServiceInternal.enabled = enable;
|
||||
},
|
||||
|
||||
// Returns a single provider object with the specified origin.
|
||||
getProvider: function getProvider(origin, onDone) {
|
||||
schedule((function () {
|
||||
onDone(SocialServiceInternal.providers[origin] || null);
|
||||
@ -42,13 +80,8 @@ const SocialService = {
|
||||
|
||||
// Returns an array of installed provider origins.
|
||||
getProviderList: function getProviderList(onDone) {
|
||||
let providers = [p for each (p in SocialServiceInternal.providers)];
|
||||
schedule((function () {
|
||||
onDone(providers);
|
||||
}).bind(this));
|
||||
schedule(function () {
|
||||
onDone(SocialServiceInternal.providerArray);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function schedule(callback) {
|
||||
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
relative_import.js \
|
||||
browser_workerAPI.js \
|
||||
worker_social.js \
|
||||
browser_SocialProvider.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -0,0 +1,35 @@
|
||||
/* 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/. */
|
||||
|
||||
let SocialProvider = Components.utils.import("resource://gre/modules/SocialProvider.jsm", {}).SocialProvider;
|
||||
|
||||
function test() {
|
||||
// This test creates a SocialProvider object directly - it would be nicer to
|
||||
// go through the SocialService, but adding a test provider before the service
|
||||
// has been initialized can be tricky.
|
||||
let provider = new SocialProvider({
|
||||
origin: 'http://example.com',
|
||||
name: "Example Provider",
|
||||
workerURL: "http://example.com/browser/toolkit/components/social/test/browser/worker_social.js"
|
||||
});
|
||||
|
||||
ok(provider.enabled, "provider is initially enabled");
|
||||
ok(provider.port, "should be able to get a port from enabled provider");
|
||||
ok(provider.workerAPI, "should be able to get a workerAPI from enabled provider");
|
||||
|
||||
provider.enabled = false;
|
||||
|
||||
ok(!provider.enabled, "provider is now disabled");
|
||||
ok(!provider.port, "shouldn't be able to get a port from disabled provider");
|
||||
ok(!provider.workerAPI, "shouldn't be able to get a workerAPI from disabled provider");
|
||||
|
||||
provider.enabled = true;
|
||||
|
||||
ok(provider.enabled, "provider is re-enabled");
|
||||
ok(provider.port, "should be able to get a port from re-enabled provider");
|
||||
ok(provider.workerAPI, "should be able to get a workerAPI from re-enabled provider");
|
||||
|
||||
// Terminate the provider
|
||||
provider.enabled = false;
|
||||
}
|
@ -19,14 +19,15 @@ function test() {
|
||||
ok(provider.workerAPI, "provider has a workerAPI");
|
||||
is(provider.workerAPI.initialized, false, "workerAPI is not yet initialized");
|
||||
|
||||
let port = provider.getWorkerPort();
|
||||
let port = provider.port;
|
||||
ok(port, "should be able to get a port from the provider");
|
||||
|
||||
port.onmessage = function onMessage(event) {
|
||||
let {topic, data} = event.data;
|
||||
if (topic == "test-initialization-complete") {
|
||||
is(provider.workerAPI.initialized, true, "workerAPI is now initialized");
|
||||
provider.terminate();
|
||||
// Terminate the provider
|
||||
provider.enabled = false;
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function run_test() {
|
||||
let manifests = [
|
||||
{ // normal provider
|
||||
@ -18,14 +20,16 @@ function run_test() {
|
||||
manifests.forEach(function (manifest) {
|
||||
MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
|
||||
});
|
||||
do_register_cleanup(function () MANIFEST_PREFS.deleteBranch(""));
|
||||
|
||||
// Enable the service for this test
|
||||
Services.prefs.setBoolPref("social.enabled", true);
|
||||
Cu.import("resource://gre/modules/SocialService.jsm");
|
||||
|
||||
let runner = new AsyncRunner();
|
||||
let next = runner.next.bind(runner);
|
||||
runner.appendIterator(testGetProvider(manifests, next));
|
||||
runner.appendIterator(testGetProviderList(manifests, next));
|
||||
runner.appendIterator(testEnabled(manifests, next));
|
||||
runner.next();
|
||||
}
|
||||
|
||||
@ -48,7 +52,31 @@ function testGetProviderList(manifests, next) {
|
||||
let providerIdx = providers.map(function (p) p.origin).indexOf(manifests[i].origin);
|
||||
let provider = providers[providerIdx];
|
||||
do_check_true(!!provider);
|
||||
do_check_true(provider.enabled);
|
||||
do_check_eq(provider.workerURL, manifests[i].workerURL);
|
||||
do_check_eq(provider.name, manifests[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
function testEnabled(manifests, next) {
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
do_check_true(providers.length >= manifests.length);
|
||||
do_check_true(SocialService.enabled);
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(provider.enabled);
|
||||
});
|
||||
|
||||
SocialService.enabled = false;
|
||||
do_check_true(!Services.prefs.getBoolPref("social.enabled"));
|
||||
do_check_true(!SocialService.enabled);
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(!provider.enabled);
|
||||
});
|
||||
|
||||
// Check that setting the pref directly updates things accordingly
|
||||
Services.prefs.setBoolPref("social.enabled", true);
|
||||
do_check_true(SocialService.enabled);
|
||||
providers.forEach(function (provider) {
|
||||
do_check_true(provider.enabled);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user