Inject default web-based protocol handlers into mimeTypes.rdf (bug 392978), r=myk, sr=biesi, a=mconnor

This commit is contained in:
dmose@mozilla.org 2007-09-06 15:20:52 -07:00
parent 4f3ef06d64
commit 2ddf3e3249
3 changed files with 147 additions and 3 deletions

View File

@ -496,6 +496,20 @@ pref("browser.contentHandlers.types.5.type", "application/vnd.mozilla.maybe.feed
pref("browser.feeds.handler", "ask"); pref("browser.feeds.handler", "ask");
// For now, this is living in content rather than in locales, as per Pike.
// Eventually it will get merged into region.properties; see bug 395277.
//
// At startup, if the handler service notices that the version number here
// is newer than the version number in the handler service datastore, it will
// add any handlers it finds in the prefs (as seeded by this file) to its
// datastore.
pref("gecko.handlerService.defaultHandlersVersion", "0");
//
// The default set of web-based protocol handlers shown in the application
// selection dialog
pref("gecko.handlerService.schemes.webcal.0.name", "WebCal Test Handler");
pref("gecko.handlerService.schemes.webcal.0.uriTemplate", "http://handler-test.mozilla.org/webcal?url=%s");
#ifdef MOZ_SAFE_BROWSING #ifdef MOZ_SAFE_BROWSING
// Safe browsing does nothing unless both these prefs are set. // Safe browsing does nothing unless both these prefs are set.
pref("browser.safebrowsing.enabled", true); pref("browser.safebrowsing.enabled", true);

View File

@ -19,6 +19,7 @@
* *
* Contributor(s): * Contributor(s):
* Myk Melez <myk@mozilla.org> * Myk Melez <myk@mozilla.org>
* Dan Mosedale <dmose@mozilla.org>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -47,6 +48,9 @@ const CLASS_PROTOCOLINFO = "scheme";
// namespace prefix // namespace prefix
const NC_NS = "http://home.netscape.com/NC-rdf#"; const NC_NS = "http://home.netscape.com/NC-rdf#";
// the most recent default handlers that have been injected
const NC_DEFAULT_HANDLERS_VERSION = NC_NS + "defaultHandlersVersion";
// type list properties // type list properties
const NC_MIME_TYPES = NC_NS + "MIME-types"; const NC_MIME_TYPES = NC_NS + "MIME-types";
@ -118,11 +122,33 @@ HandlerService.prototype = {
// Observe xpcom-shutdown so we can remove these observers // Observe xpcom-shutdown so we can remove these observers
// when the application shuts down. // when the application shuts down.
this._observerSvc.addObserver(this, "xpcom-shutdown", false); this._observerSvc.addObserver(this, "xpcom-shutdown", false);
// Observe profile-do-change so that non-default profiles get upgraded too
this._observerSvc.addObserver(this, "profile-do-change", false);
// do any necessary updating of the datastore
this._updateDB();
},
_updateDB: function HS__updateDB() {
// if the default prefs have changed, inject any new default handers
// into the datastore
try {
if (this._datastoreDefaultHandlersVersion <
this._prefsDefaultHandlersVersion) {
this._injectNewDefaults();
this._datastoreDefaultHandlersVersion =
this._prefsDefaultHandlersVersion;
}
} catch (ex) {
// if injecting the defaults failed, life goes on...
}
}, },
_destroy: function HS__destroy() { _destroy: function HS__destroy() {
this._observerSvc.removeObserver(this, "profile-before-change"); this._observerSvc.removeObserver(this, "profile-before-change");
this._observerSvc.removeObserver(this, "xpcom-shutdown"); this._observerSvc.removeObserver(this, "xpcom-shutdown");
this._observerSvc.removeObserver(this, "profile-do-change");
// XXX Should we also null references to all the services that get stored // XXX Should we also null references to all the services that get stored
// by our memoizing getters in the Convenience Getters section? // by our memoizing getters in the Convenience Getters section?
@ -134,6 +160,95 @@ HandlerService.prototype = {
this.__ds = null; this.__ds = null;
}, },
_isInHandlerArray: function HS__isInHandlerArray(aArray, aHandler) {
var enumerator = aArray.enumerate();
while (enumerator.hasMoreElements()) {
let handler = enumerator.getNext();
handler.QueryInterface(Ci.nsIHandlerApp);
if (handler.equals(aHandler))
return true;
}
return false;
},
get _datastoreDefaultHandlersVersion() {
var version = this._getValue("urn:root", NC_DEFAULT_HANDLERS_VERSION);
version = version ? version : -1;
return version;
},
set _datastoreDefaultHandlersVersion(aNewVersion) {
return this._setLiteral("urn:root", NC_DEFAULT_HANDLERS_VERSION,
aNewVersion);
},
get _prefsDefaultHandlersVersion() {
// get handler service pref branch
var prefSvc = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
var handlerSvcBranch = prefSvc.getBranch("gecko.handlerService.");
// get the version of the preferences for this locale
var version = handlerSvcBranch.getComplexValue("defaultHandlersVersion",
Ci.nsISupportsString).data;
return version;
},
_injectNewDefaults: function HS__injectNewDefaults() {
// get handler service pref branch
var prefSvc = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
let schemesPrefBranch = prefSvc.getBranch("gecko.handlerService.schemes.");
let schemePrefList = schemesPrefBranch.getChildList("", {});
let protoSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
var schemes = {};
// read all the scheme prefs into a hash
for each (var schemePrefName in schemePrefList) {
let [scheme, handlerNumber, attribute] = schemePrefName.split(".");
if (!(scheme in schemes))
schemes[scheme] = {};
if (!(handlerNumber in schemes[scheme]))
schemes[scheme][handlerNumber] = {};
schemes[scheme][handlerNumber][attribute] =
schemesPrefBranch.getComplexValue(schemePrefName,
Ci.nsISupportsString).data;
}
for (var scheme in schemes) {
// get a protocol info object for that scheme and cache the possible
// handlers to avoid extra xpconnect traversals
let protoInfo = protoSvc.getProtocolHandlerInfo(scheme);
let possibleHandlers = protoInfo.possibleApplicationHandlers;
for each (var handlerPrefs in schemes[scheme]) {
let handlerApp = Cc["@mozilla.org/uriloader/web-handler-app;1"].
createInstance(Ci.nsIWebHandlerApp);
handlerApp.uriTemplate = handlerPrefs.uriTemplate;
handlerApp.name = handlerPrefs.name;
if (!this._isInHandlerArray(possibleHandlers, handlerApp)) {
possibleHandlers.appendElement(handlerApp, false);
}
}
this.store(protoInfo);
}
},
//**************************************************************************// //**************************************************************************//
// nsIObserver // nsIObserver
@ -146,6 +261,9 @@ HandlerService.prototype = {
case "xpcom-shutdown": case "xpcom-shutdown":
this._destroy(); this._destroy();
break; break;
case "profile-do-change":
this._updateDB();
break;
} }
}, },

View File

@ -19,6 +19,7 @@
* *
* Contributor(s): * Contributor(s):
* Myk Melez <myk@mozilla.org> * Myk Melez <myk@mozilla.org>
* Dan Mosedale <dmose@mozilla.org>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -44,6 +45,10 @@ function run_test() {
const mimeSvc = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]. const mimeSvc = Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
getService(Ci.nsIMIMEService); getService(Ci.nsIMIMEService);
const prefSvc = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
const rootPrefBranch = prefSvc.getBranch("");
//**************************************************************************// //**************************************************************************//
// Sample Data // Sample Data
@ -141,11 +146,18 @@ function run_test() {
do_check_false(handlerInfo.alwaysAskBeforeHandling); do_check_false(handlerInfo.alwaysAskBeforeHandling);
// Make sure the handler service's enumerate method lists all known handlers. // Make sure the handler service's enumerate method lists all known handlers.
// FIXME: store and test enumeration of a protocol handler once bug 391150
// gets fixed and we can actually retrieve a protocol handler.
var handlerInfo2 = mimeSvc.getFromTypeAndExtension("nonexistent/type2", null); var handlerInfo2 = mimeSvc.getFromTypeAndExtension("nonexistent/type2", null);
handlerSvc.store(handlerInfo2); handlerSvc.store(handlerInfo2);
var handlerTypes = ["nonexistent/type", "nonexistent/type2"]; var handlerTypes = ["nonexistent/type", "nonexistent/type2"];
try {
// If we have a defaultHandlersVersion pref, then assume that we're in the
// firefox tree and that we'll also have an added webcal handler.
// Bug 395131 has been filed to make this test work more generically
// by providing our own prefs for this test rather than this icky
// special casing.
rootPrefBranch.getCharPref("gecko.handlerService.defaultHandlersVersion");
handlerTypes.push("webcal");
} catch (ex) {}
var handlers = handlerSvc.enumerate(); var handlers = handlerSvc.enumerate();
while (handlers.hasMoreElements()) { while (handlers.hasMoreElements()) {
var handler = handlers.getNext().QueryInterface(Ci.nsIHandlerInfo); var handler = handlers.getNext().QueryInterface(Ci.nsIHandlerInfo);