--- a/browser/components/feeds/WebContentConverter.js
+++ b/browser/components/feeds/WebContentConverter.js
@@ -26,16 +26,17 @@ const TYPE_ANY = "*/*";
const PREF_CONTENTHANDLERS_AUTO = "browser.contentHandlers.auto.";
const PREF_CONTENTHANDLERS_BRANCH = "browser.contentHandlers.types.";
const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const PREF_HANDLER_EXTERNAL_PREFIX = "network.protocol-handler.external";
const PREF_ALLOW_DIFFERENT_HOST = "gecko.handlerService.allowRegisterFromDifferentHost";
+const PREF_HANDLERSVC_JSON = "browser.handlerSvcJson.enabled";
const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
const NS_ERROR_MODULE_DOM = 2152923136;
const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
function WebContentConverter() {
}
@@ -321,18 +322,24 @@ WebContentConverterRegistrar.prototype =
getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
let handlers = handlerInfo.possibleApplicationHandlers;
for (let i = 0; i < handlers.length; i++) {
try { // We only want to test web handlers
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
if (handler.uriTemplate == aURITemplate) {
handlers.removeElementAt(i);
- let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
- getService(Ci.nsIHandlerService);
+ var hs;
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON)) {
+ hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ } else {
+ hs = Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService);
+ }
hs.store(handlerInfo);
return;
}
} catch (e) { /* it wasn't a web handler */ }
}
},
/**
@@ -448,18 +455,24 @@ WebContentConverterRegistrar.prototype =
handlerInfo.possibleApplicationHandlers.appendElement(handler, false);
// Since the user has agreed to add a new handler, chances are good
// that the next time they see a handler of this type, they're going
// to want to use it. Reset the handlerInfo to ask before the next
// use.
handlerInfo.alwaysAskBeforeHandling = true;
- let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
- getService(Ci.nsIHandlerService);
+ var hs;
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON)) {
+ hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ } else {
+ hs = Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService);
+ }
hs.store(handlerInfo);
}
};
let notificationBox = browser.getTabBrowser().getNotificationBox(browser);
notificationBox.appendNotification(message,
notificationValue,
notificationIcon,
notificationBox.PRIORITY_INFO_LOW,
--- a/browser/components/preferences/in-content/applications.js
+++ b/browser/components/preferences/in-content/applications.js
@@ -18,16 +18,18 @@ const TOPIC_PDFJS_HANDLER_CHANGED = "pdf
const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
// Preferences that affect which entries to show in the list.
const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
"browser.download.hide_plugins_without_extensions";
+const PREF_HANDLERSVC_JSON = "browser.handlerSvcJson.enabled";
+
/*
* Preferences where we store handling information about the feed type.
*
* browser.feeds.handler
* - "bookmarks", "reader" (clarified further using the .default preference),
* or "ask" -- indicates the default handler being used to process feeds;
* "bookmarks" is obsolete; to specify that the handler is bookmarks,
* set browser.feeds.handler.default to "bookmarks";
@@ -160,16 +162,18 @@ HandlerInfoWrapper.prototype = {
// we haven't (yet?) implemented, so we make it a public property.
wrappedHandlerInfo: null,
// Convenience Utils
_handlerSvc: Cc["@mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService),
+ _handlerSvcJson : Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService),
_prefSvc: Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch),
_categoryMgr: Cc["@mozilla.org/categorymanager;1"].
getService(Ci.nsICategoryManager),
element: function(aID) {
@@ -408,17 +412,20 @@ HandlerInfoWrapper.prototype = {
false,
true);
},
// Storage
store: function() {
- this._handlerSvc.store(this.wrappedHandlerInfo);
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON))
+ this._handlerSvc.store(this.wrappedHandlerInfo);
+ else
+ this._handlerSvcJson.store(this.wrappedHandlerInfo);
},
// Icons
get smallIcon() {
return this._getIcon(16);
},
@@ -861,16 +868,18 @@ var gApplicationsPane = {
_mimeSvc : Cc["@mozilla.org/mime;1"].
getService(Ci.nsIMIMEService),
_helperAppSvc : Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
getService(Ci.nsIExternalHelperAppService),
_handlerSvc : Cc["@mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService),
+ _handlerSvcJson : Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService),
_ioSvc : Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService),
// Initialization & Destruction
init: function() {
@@ -1086,16 +1095,20 @@ var gApplicationsPane = {
}
},
/**
* Load the set of handlers defined by the application datastore.
*/
_loadApplicationHandlers: function() {
var wrappedHandlerInfos = this._handlerSvc.enumerate();
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON))
+ wrappedHandlerInfos = this._handlerSvc.enumerate();
+ else
+ wrappedHandlerInfos = this._handlerSvcJson.enumerate();
while (wrappedHandlerInfos.hasMoreElements()) {
let wrappedHandlerInfo =
wrappedHandlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
let type = wrappedHandlerInfo.type;
let handlerInfoWrapper;
if (type in this._handledTypes)
handlerInfoWrapper = this._handledTypes[type];
--- a/browser/extensions/pdfjs/content/PdfJs.jsm
+++ b/browser/extensions/pdfjs/content/PdfJs.jsm
@@ -28,16 +28,17 @@ const Cu = Components.utils;
const PREF_PREFIX = 'pdfjs';
const PREF_DISABLED = PREF_PREFIX + '.disabled';
const PREF_MIGRATION_VERSION = PREF_PREFIX + '.migrationVersion';
const PREF_PREVIOUS_ACTION = PREF_PREFIX + '.previousHandler.preferredAction';
const PREF_PREVIOUS_ASK = PREF_PREFIX +
'.previousHandler.alwaysAskBeforeHandling';
const PREF_DISABLED_PLUGIN_TYPES = 'plugin.disable_full_page_plugin_for_types';
+const PREF_HANDLERSVC_JSON = "browser.handlerSvcJson.enabled";
const TOPIC_PDFJS_HANDLER_CHANGED = 'pdfjs:handlerChanged';
const TOPIC_PLUGINS_LIST_UPDATED = 'plugins-list-updated';
const TOPIC_PLUGIN_INFO_UPDATED = 'plugin-info-updated';
const PDF_CONTENT_TYPE = 'application/pdf';
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
@@ -232,18 +233,24 @@ var PdfJs = {
handlerInfo.preferredAction !== false) {
// Store the previous settings of preferredAction and
// alwaysAskBeforeHandling in case we need to revert them in a hotfix that
// would turn pdf.js off.
prefs.setIntPref(PREF_PREVIOUS_ACTION, handlerInfo.preferredAction);
prefs.setBoolPref(PREF_PREVIOUS_ASK, handlerInfo.alwaysAskBeforeHandling);
}
- let handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].
- getService(Ci.nsIHandlerService);
+ var handlerService;
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON)) {
+ handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].
+ getService(Ci.nsIHandlerService);
+ } else {
+ handlerService = Cc['@mozilla.org/uriloader/handler-service-json;1'].
+ getService(Ci.nsIHandlerService);
+ }
// Change and save mime handler settings.
handlerInfo.alwaysAskBeforeHandling = false;
handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
handlerService.store(handlerInfo);
// Also disable any plugins for pdfs.
var stringTypes = '';
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -446,16 +446,18 @@
@RESPATH@/components/ColorAnalyzer.js
@RESPATH@/components/PageThumbsProtocol.js
@RESPATH@/components/nsDefaultCLH.manifest
@RESPATH@/components/nsDefaultCLH.js
@RESPATH@/components/nsContentPrefService.manifest
@RESPATH@/components/nsContentPrefService.js
@RESPATH@/components/nsContentDispatchChooser.manifest
@RESPATH@/components/nsContentDispatchChooser.js
+@RESPATH@/components/nsHandlerService-json.manifest
+@RESPATH@/components/nsHandlerService-json.js
@RESPATH@/components/nsHandlerService.manifest
@RESPATH@/components/nsHandlerService.js
@RESPATH@/components/nsWebHandlerApp.manifest
@RESPATH@/components/nsWebHandlerApp.js
@RESPATH@/components/satchel.manifest
@RESPATH@/components/nsFormAutoComplete.js
@RESPATH@/components/nsFormHistory.js
@RESPATH@/components/FormHistoryStartup.js
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -187,16 +187,17 @@ const mozilla::Module::ContractIDEntry k
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
{ NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID },
{ NS_HANDLERSERVICE_CONTRACTID, &kNS_CONTENTHANDLERSERVICE_CID, mozilla::Module::CONTENT_PROCESS_ONLY },
+ { NS_HANDLERSERVICEJSON_CONTRACTID, &kNS_CONTENTHANDLERSERVICE_CID, mozilla::Module::CONTENT_PROCESS_ONLY },
{ NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
{ NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
{ NS_MIMESERVICE_CONTRACTID, &kNS_EXTERNALHELPERAPPSERVICE_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default", &kNS_EXTERNALPROTOCOLHANDLER_CID },
{ NS_PREFETCHSERVICE_CONTRACTID, &kNS_PREFETCHSERVICE_CID },
{ NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &kNS_OFFLINECACHEUPDATESERVICE_CID },
{ NS_OFFLINECACHEUPDATE_CONTRACTID, &kNS_OFFLINECACHEUPDATE_CID },
{ NS_LOCALHANDLERAPP_CONTRACTID, &kNS_LOCALHANDLERAPP_CID },
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5533,8 +5533,10 @@ pref("dom.storageManager.enabled", true)
#else
pref("dom.storageManager.enabled", false);
#endif
// Enable the Storage management in about:preferences and persistent-storage permission request
// To enable the DOM implementation, turn on "dom.storageManager.enabled"
pref("browser.storageManager.enabled", false);
+// Swich the backend of handler service (RDF/JSON)
+pref("browser.handlerSvcJson.enabled", false);
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -867,17 +867,25 @@ nsUnknownContentTypeDialog.prototype = {
return needUpdate && !discardUpdate;
},
// See if the user changed things, and if so, update the
// mimeTypes.rdf entry for this mime type.
updateHelperAppPref: function() {
var handlerInfo = this.mLauncher.MIMEInfo;
- var hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
+ var hs;
+ var jsonEnabled = Services.prefs.getBoolPref(browser.handlerSvcJson.enabled);
+ if (jsonEnabled) {
+ hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ } else {
+ hs = Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService);
+ }
hs.store(handlerInfo);
},
// onOK:
onOK: function() {
// Verify typed app path, if necessary.
if (this.useOtherHandler) {
var helperApp = this.helperAppChoice();
--- a/toolkit/mozapps/handling/content/dialog.js
+++ b/toolkit/mozapps/handling/content/dialog.js
@@ -216,18 +216,24 @@ var dialog = {
this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
this._handlerInfo.preferredApplicationHandler = this.selectedItem.obj;
}
else
this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useSystemDefault;
}
this._handlerInfo.alwaysAskBeforeHandling = !checkbox.checked;
- var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
- getService(Ci.nsIHandlerService);
+ var hs;
+ if (!Services.prefs.getBoolPref(PREF_HANDLERSVC_JSON)) {
+ hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ } else {
+ hs = Cc["@mozilla.org/uriloader/handler-service-json;1"].
+ getService(Ci.nsIHandlerService);
+ }
hs.store(this._handlerInfo);
this._handlerInfo.launchWithURI(this._URI, this._windowCtxt);
return true;
},
/**
--- a/uriloader/exthandler/moz.build
+++ b/uriloader/exthandler/moz.build
@@ -103,16 +103,18 @@ if CONFIG['MOZ_ENABLE_DBUS']:
]
if CONFIG['MOZ_ENABLE_CONTENTACTION']:
UNIFIED_SOURCES += [
'nsContentHandlerApp.cpp',
]
EXTRA_COMPONENTS += [
+ 'nsHandlerService-json.js',
+ 'nsHandlerService-json.manifest',
'nsHandlerService.js',
'nsHandlerService.manifest',
'nsWebHandlerApp.js',
'nsWebHandlerApp.manifest',
]
IPDL_SOURCES += [
'PExternalHelperApp.ipdl',
--- a/uriloader/exthandler/nsCExternalHandlerService.idl
+++ b/uriloader/exthandler/nsCExternalHandlerService.idl
@@ -19,16 +19,19 @@ nsIExternalHelperAppService
{ 0xa7f800e0, 0x4306, 0x11d4, { 0x98, 0xd0, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
#define NS_EXTERNALHELPERAPPSERVICE_CONTRACTID \
"@mozilla.org/uriloader/external-helper-app-service;1"
#define NS_HANDLERSERVICE_CONTRACTID \
"@mozilla.org/uriloader/handler-service;1"
+#define NS_HANDLERSERVICEJSON_CONTRACTID \
+"@mozilla.org/uriloader/handler-service-json;1"
+
#define NS_EXTERNALPROTOCOLSERVICE_CONTRACTID \
"@mozilla.org/uriloader/external-protocol-service;1"
#define NS_MIMESERVICE_CONTRACTID \
"@mozilla.org/mime;1"
#define NS_EXTERNALPROTOCOLHANDLER_CID \
{ 0xbd6390c8, 0xfbea, 0x11d4, {0x98, 0xf6, 0x0, 0x10, 0x83, 0x1, 0xe, 0x9b } }
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -111,16 +111,18 @@
#endif
using namespace mozilla;
using namespace mozilla::ipc;
// Download Folder location constants
#define NS_PREF_DOWNLOAD_DIR "browser.download.dir"
#define NS_PREF_DOWNLOAD_FOLDERLIST "browser.download.folderList"
+#define NS_PREF_HANDLERSVC_JSON "browser.handlerSvcJson.enabled"
+
enum {
NS_FOLDER_VALUE_DESKTOP = 0
, NS_FOLDER_VALUE_DOWNLOADS = 1
, NS_FOLDER_VALUE_CUSTOM = 2
};
LazyLogModule nsExternalHelperAppService::mLog("HelperAppService");
@@ -130,16 +132,17 @@ LazyLogModule nsExternalHelperAppService
#undef LOG
#define LOG(args) MOZ_LOG(nsExternalHelperAppService::mLog, mozilla::LogLevel::Info, args)
#define LOG_ENABLED() MOZ_LOG_TEST(nsExternalHelperAppService::mLog, mozilla::LogLevel::Info)
static const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF[] =
"browser.helperApps.neverAsk.saveToDisk";
static const char NEVER_ASK_FOR_OPEN_FILE_PREF[] =
"browser.helperApps.neverAsk.openFile";
+static bool handlerSvcWithJSON = false;
// Helper functions for Content-Disposition headers
/**
* Given a URI fragment, unescape it
* @param aFragment The string to unescape
* @param aURI The URI from which this fragment is taken. Only its character set
* will be used.
@@ -654,33 +657,51 @@ NS_IMPL_ISUPPORTS(
nsIExternalProtocolService,
nsIMIMEService,
nsIObserver,
nsISupportsWeakReference)
nsExternalHelperAppService::nsExternalHelperAppService()
{
}
+
+void
+HandlerSvcPrefChangedCallback(const char* aPrefName,
+ void* aClosure)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(!strcmp(aPrefName, NS_PREF_HANDLERSVC_JSON));
+ MOZ_ASSERT(!aClosure);
+
+ handlerSvcWithJSON = Preferences::GetBool(NS_PREF_HANDLERSVC_JSON, false);
+}
+
+
+
nsresult nsExternalHelperAppService::Init()
{
// Add an observer for profile change
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs)
return NS_ERROR_FAILURE;
nsresult rv = obs->AddObserver(this, "profile-before-change", true);
NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = Preferences::RegisterCallbackAndCall(HandlerSvcPrefChangedCallback, NS_PREF_HANDLERSVC_JSON);
+ NS_ENSURE_SUCCESS(rv, rv);
+
return obs->AddObserver(this, "last-pb-context-exited", true);
}
nsExternalHelperAppService::~nsExternalHelperAppService()
{
+ Preferences::UnregisterCallback(HandlerSvcPrefChangedCallback, NS_PREF_HANDLERSVC_JSON);
}
-
nsresult
nsExternalHelperAppService::DoContentContentProcessHelper(const nsACString& aMimeContentType,
nsIRequest *aRequest,
nsIInterfaceRequestor *aContentContext,
bool aForceSave,
nsIInterfaceRequestor *aWindowContext,
nsIStreamListener ** aStreamListener)
{
@@ -1160,17 +1181,23 @@ nsExternalHelperAppService::GetProtocolH
bool exists;
nsresult rv = GetProtocolHandlerInfoFromOS(aScheme, &exists, aHandlerInfo);
if (NS_FAILED(rv)) {
// Either it knows nothing, or we ran out of memory
return NS_ERROR_FAILURE;
}
- nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+ nsCOMPtr<nsIHandlerService> handlerSvc;
+ if (!handlerSvcWithJSON) {
+ handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+ } else {
+ handlerSvc = do_GetService(NS_HANDLERSERVICEJSON_CONTRACTID);
+ }
+
if (handlerSvc) {
bool hasHandler = false;
(void) handlerSvc->Exists(*aHandlerInfo, &hasHandler);
if (hasHandler) {
rv = handlerSvc->FillHandlerInfo(*aHandlerInfo, EmptyCString());
if (NS_SUCCEEDED(rv))
return NS_OK;
}
@@ -1730,17 +1757,24 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
if (alwaysAsk) {
// But we *don't* ask if this mimeInfo didn't come from
// our user configuration datastore and the user has said
// at some point in the distant past that they don't
// want to be asked. The latter fact would have been
// stored in pref strings back in the old days.
bool mimeTypeIsInDatastore = false;
- nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+
+ nsCOMPtr<nsIHandlerService> handlerSvc;
+ if (!handlerSvcWithJSON) {
+ handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+ } else {
+ handlerSvc = do_GetService(NS_HANDLERSERVICEJSON_CONTRACTID);
+ }
+
if (handlerSvc) {
handlerSvc->Exists(mMimeInfo, &mimeTypeIsInDatastore);
}
if (!handlerSvc || !mimeTypeIsInDatastore) {
nsAutoCString MIMEType;
mMimeInfo->GetMIMEType(MIMEType);
if (!GetNeverAskFlagFromPref(NEVER_ASK_FOR_SAVE_TO_DISK_PREF, MIMEType.get())) {
// Don't need to ask after all.
@@ -2638,17 +2672,22 @@ NS_IMETHODIMP nsExternalHelperAppService
// If we got no mimeinfo, something went wrong. Probably lack of memory.
if (!*_retval)
return NS_ERROR_OUT_OF_MEMORY;
// (2) Now, let's see if we can find something in our datastore
// This will not overwrite the OS information that interests us
// (i.e. default application, default app. description)
nsresult rv;
- nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+ nsCOMPtr<nsIHandlerService> handlerSvc;
+ if (!handlerSvcWithJSON) {
+ handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
+ } else {
+ handlerSvc = do_GetService(NS_HANDLERSERVICEJSON_CONTRACTID);
+ }
if (handlerSvc) {
bool hasHandler = false;
(void) handlerSvc->Exists(*_retval, &hasHandler);
if (hasHandler) {
rv = handlerSvc->FillHandlerInfo(*_retval, EmptyCString());
LOG(("Data source: Via type: retval 0x%08x\n", rv));
} else {
rv = NS_ERROR_NOT_AVAILABLE;
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsHandlerService-json.js
@@ -0,0 +1,553 @@
+/* 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/. */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/osfile.jsm");
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import("resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "JSONFile",
+ "resource://gre/modules/JSONFile.jsm");
+
+// Observer Service
+XPCOMUtils.defineLazyServiceGetter(this, "observerSvc",
+ "@mozilla.org/observer-service;1",
+ "nsIObserverService");
+// MIME Service
+XPCOMUtils.defineLazyServiceGetter(this, "mimeSvc",
+ "@mozilla.org/mime;1",
+ "nsIMIMEService");
+// Protocol Service
+XPCOMUtils.defineLazyServiceGetter(this, "protoSvc",
+ "@mozilla.org/uriloader/external-protocol-service;1",
+ "nsIExternalProtocolService");
+
+function HandlerService() {
+ this._init();
+}
+
+const HandlerServiceFactory = {
+ _instance: null,
+ createInstance: function (outer, iid) {
+ if (this._instance)
+ return this._instance;
+
+ let processType = Cc["@mozilla.org/xre/runtime;1"].
+ getService(Ci.nsIXULRuntime).processType;
+ if (processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT)
+ return Cr.NS_ERROR_NOT_IMPLEMENTED;
+
+ return (this._instance = new HandlerService());
+ }
+};
+
+HandlerService.prototype = {
+ //**************************************************************************//
+ // XPCOM Plumbing
+
+ classID: Components.ID("{220cc253-b60f-41f6-b9cf-fdcb325f970f}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIHandlerService]),
+ _xpcom_factory: HandlerServiceFactory,
+
+ //**************************************************************************//
+ // Initialization & Destruction
+
+ _init() {
+ // Observe profile-before-change so we can switch to the datasource
+ // in the new profile when the user changes profiles.
+ observerSvc.addObserver(this, "profile-before-change", false);
+
+ // Observe xpcom-shutdown so we can remove these observers
+ // when the application shuts down.
+ observerSvc.addObserver(this, "xpcom-shutdown", false);
+
+ // Observe profile-do-change so that non-default profiles get upgraded too
+ observerSvc.addObserver(this, "profile-do-change", false);
+
+ let jsonPath = OS.Path.join(OS.Constants.Path.profileDir,
+ "mimeTypes.json");
+
+ // LOAD DATA
+ this._store = new JSONFile({
+ path: jsonPath,
+ dataPostProcessor: this._dataPostProcessor.bind(this),
+ });
+ this._store.load();
+ this._store.saveSoon();
+
+ // Update DB
+ // do any necessary updating of the datastore
+ this._updateDB();
+ },
+
+ _dataPostProcessor(data) {
+ /* we can do import here if there is no mimeTypes.json */
+ if (!data || !data.mimetypes || !data.schemes) {
+ data = {"version":{},"mimetypes":{},"schemes":{}};
+ // TODO : Do import here
+ }
+ return data;
+ },
+
+ _updateDB() {
+ this._store.ensureDataReady();
+
+ try {
+ if (!(this._currentLocale in this._store.data.version)) {
+ this._store.data.version[this._currentLocale] = -1;
+ }
+ var defaultHandlersVersion = this._store.data.version[this._currentLocale];
+
+ if (defaultHandlersVersion < this._prefsDefaultHandlersVersion ) {
+ // set the new version first so that if we recurse we don't
+ // call _injectNewDefaults several times
+ this._store.data.version[this._currentLocale] = this._prefsDefaultHandlersVersion;
+ this._injectNewDefaults();
+ }
+ } catch (ex) {
+ // if injecting the defaults failed, set the version back to the
+ // previous value
+ this._store.data.version[this._currentLocale] = defaultHandlersVersion;
+ }
+ },
+
+ get _prefsDefaultHandlersVersion() {
+ // get handler service pref branch
+ var handlerSvcBranch = Services.prefs.getBranch("gecko.handlerService.");
+
+ // get the version of the preferences for this locale
+ return Number(handlerSvcBranch.
+ getComplexValue("defaultHandlersVersion",
+ Ci.nsIPrefLocalizedString).data);
+ },
+
+ get _currentLocale() {
+ var chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIXULChromeRegistry);
+ var currentLocale = chromeRegistry.getSelectedLocale("global");
+ return currentLocale;
+ },
+
+ _injectNewDefaults() {
+ // get handler service pref branch
+
+ let schemesPrefBranch = Services.prefs.getBranch("gecko.handlerService.schemes.");
+ let schemePrefList = schemesPrefBranch.getChildList("");
+
+ var schemes = {};
+
+ // read all the scheme prefs into a hash
+ for (var schemePrefName of schemePrefList) {
+
+ let [scheme, handlerNumber, attribute] = schemePrefName.split(".");
+
+ try {
+ var attrData =
+ schemesPrefBranch.getComplexValue(schemePrefName,
+ Ci.nsIPrefLocalizedString).data;
+ if (!(scheme in schemes))
+ schemes[scheme] = {};
+
+ if (!(handlerNumber in schemes[scheme]))
+ schemes[scheme][handlerNumber] = {};
+
+ schemes[scheme][handlerNumber][attribute] = attrData;
+ } catch (ex) {}
+ }
+
+ for (var scheme in schemes) {
+
+ // This clause is essentially a reimplementation of
+ // nsIExternalProtocolHandlerService.getProtocolHandlerInfo().
+ // Necessary because calling that from here would make XPConnect barf
+ // when getService tried to re-enter the constructor for this
+ // service.
+ let osDefaultHandlerFound = {};
+ let protoInfo = protoSvc.getProtocolHandlerInfoFromOS(scheme,
+ osDefaultHandlerFound);
+
+ if (this.exists(protoInfo))
+ this.fillHandlerInfo(protoInfo, null);
+ else
+ protoSvc.setProtocolHandlerDefaults(protoInfo,
+ osDefaultHandlerFound.value);
+
+ // cache the possible handlers to avoid extra xpconnect traversals.
+ let possibleHandlers = protoInfo.possibleApplicationHandlers;
+
+ for (let handlerNumber in schemes[scheme]) {
+ let handlerPrefs = schemes[scheme][handlerNumber];
+ 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);
+ }
+ },
+
+ _destroy() {
+ observerSvc.removeObserver(this, "profile-before-change");
+ observerSvc.removeObserver(this, "xpcom-shutdown");
+ observerSvc.removeObserver(this, "profile-do-change");
+
+ // XXX Should we also null references to all the services that get stored
+ // by our memoizing getters in the Convenience Getters section?
+ },
+
+ _onProfileChange() {
+ // Lose our reference to the datasource so we reacquire it
+ // from the new profile the next time we need it.
+ this.__ds = null;
+ },
+
+ _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;
+ },
+
+
+ //**************************************************************************//
+ // nsIObserver
+
+ observe(subject, topic, data) {
+ switch(topic) {
+ case "profile-before-change":
+ this._onProfileChange();
+ break;
+ case "xpcom-shutdown":
+ this._destroy();
+ break;
+ case "profile-do-change":
+ this._updateDB();
+ break;
+ }
+ },
+
+
+ //**************************************************************************//
+ // nsIHandlerService
+
+ enumerate() {
+ var handlers = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ this._appendHandlers(handlers, "mimetypes");
+ this._appendHandlers(handlers, "schemes");
+ return handlers.enumerate();
+ },
+
+ fillHandlerInfo(aHandlerInfo, aOverrideType) {
+ var type = aOverrideType || aHandlerInfo.type;
+
+ // Determine whether or not information about this handler is available
+ // in the datastore.
+ var overrideObj;
+ this._store.ensureDataReady();
+ if ((type in this._store.data.mimetypes)) {
+ overrideObj = this._store.data.mimetypes[type];
+ } else if ((aHandlerInfo.type in this._store.data.schemes)) {
+ overrideObj = this._store.data.schemes[type];
+ } else {
+ return Cr.NS_ERROR_NOT_AVAILABLE;
+ }
+
+ aHandlerInfo.description = overrideObj.description;
+ aHandlerInfo.preferredAction = overrideObj.action;
+
+ aHandlerInfo.preferredApplicationHandler =
+ this._retrieveHandlerApp(overrideObj.preferredHandler);
+ if (aHandlerInfo.preferredApplicationHandler != null)
+ aHandlerInfo.possibleApplicationHandlers.appendElement(aHandlerInfo.preferredApplicationHandler, false);
+
+ for (let handler of overrideObj.possibleHandlers) {
+ var possibleHandler = this._retrieveHandlerApp(handler);
+ aHandlerInfo.possibleApplicationHandlers.appendElement(possibleHandler, false);
+ }
+
+ // If we have an "always ask" flag stored in the RDF, always use its
+ // value. Otherwise, use the default value stored in the pref service.
+ var alwaysAsk;
+ if (overrideObj.askBeforeHandle != null) {
+ alwaysAsk = overrideObj.askBeforeHandle;
+ } else {
+ var prefBranch = Services.prefs.getBranch("network.protocol-handler.");
+ try {
+ alwaysAsk = prefBranch.getBoolPref("warn-external." + type);
+ } catch (e) {
+ // will throw if pref didn't exist.
+ try {
+ alwaysAsk = prefBranch.getBoolPref("warn-external-default");
+ } catch (e) {
+ // Nothing to tell us what to do, so be paranoid and prompt.
+ alwaysAsk = true;
+ }
+ }
+ }
+ aHandlerInfo.alwaysAskBeforeHandling = alwaysAsk;
+
+ // extensions
+ if(aHandlerInfo instanceof Ci.nsIMIMEInfo) {
+ for (let extension of overrideObj.fileExtensions)
+ aHandlerInfo.appendExtension(extension);
+ }
+ },
+
+ store(aHandlerInfo) {
+ var type = aHandlerInfo.type;
+ var description = aHandlerInfo.description;
+ var action = aHandlerInfo.preferredAction;
+ var askBeforeHandle = aHandlerInfo.alwaysAskBeforeHandling;
+
+ var handlerObj = {
+ "description": description,
+ "action": action,
+ "askBeforeHandle": askBeforeHandle,
+ "fileExtensions": [],
+ "preferredHandler": {},
+ "possibleHandlers": [],
+ };
+
+ var HandlerType = {
+ LocalHandlerApp: 0,
+ WebHandlerApp: 1,
+ DBusHandlerApp: 2,
+ };
+
+ var preferredHandler = aHandlerInfo.preferredApplicationHandler;
+ if (preferredHandler) {
+
+ var preferredHandlerRecord;
+ if (preferredHandler instanceof Ci.nsILocalHandlerApp) {
+ preferredHandlerRecord = {
+ "name": preferredHandler.name,
+ "description": preferredHandler.detailedDescription,
+ "type": HandlerType.LocalHandlerApp,
+ "path": preferredHandler.executable.path,
+ };
+ } else if(preferredHandler instanceof Ci.nsIWebHandlerApp) {
+ preferredHandlerRecord = {
+ "name": preferredHandler.name,
+ "description": preferredHandler.detailedDescription,
+ "type": HandlerType.WebHandlerApp,
+ "uriTemplate": preferredHandler.uriTemplate,
+ };
+ } else if(preferredHandler instanceof Ci.nsIDBusHandlerApp) {
+ preferredHandlerRecord = {
+ "name": preferredHandler.name,
+ "description": preferredHandler.detailedDescription,
+ "type": HandlerType.DBusHandlerApp,
+ "service": preferredHandler.service,
+ "method": preferredHandler.method,
+ "objectPath": preferredHandler.objectPath,
+ "dBusInterface": preferredHandler.dBusInterface,
+ };
+ }
+ handlerObj.preferredHandler = preferredHandlerRecord;
+ }
+
+ var handlers = aHandlerInfo.possibleApplicationHandlers;
+ var apps = handlers.enumerate();
+ while (apps.hasMoreElements()) {
+ var handler = apps.getNext();
+ handler.QueryInterface(Ci.nsIHandlerApp);
+
+ if (handler instanceof Ci.nsILocalHandlerApp) {
+ handlerObj.possibleHandlers.push( {
+ "name": handler.name,
+ "description": handler.detailedDescription,
+ "type": HandlerType.LocalHandlerApp,
+ "path": handler.executable.path,
+ });
+ } else if(handler instanceof Ci.nsIWebHandlerApp) {
+ handlerObj.possibleHandlers.push( {
+ "name": handler.name,
+ "description": handler.detailedDescription,
+ "type": HandlerType.WebHandlerApp,
+ "uriTemplate": handler.uriTemplate,
+ });
+ } else if(handler instanceof Ci.nsIDBusHandlerApp) {
+ handlerObj.possibleHandlers.push( {
+ "name": handler.name,
+ "description": handler.detailedDescription,
+ "type": HandlerType.DBusHandlerApp,
+ "service": handler.service,
+ "method": handler.method,
+ "objectPath": handler.objectPath,
+ "dBusInterface": handler.dBusInterface,
+ });
+ } else {
+ continue;
+ }
+ } // end_while(apps.hasMoreElements())
+
+ this._store.ensureDataReady();
+ if(aHandlerInfo instanceof Ci.nsIMIMEInfo) {
+ var extEnumerator = aHandlerInfo.getFileExtensions();
+ while (extEnumerator.hasMore()) {
+ var extension = extEnumerator.getNext();
+ if (handlerObj.fileExtensions.indexOf(extension) == -1)
+ handlerObj.fileExtensions.push(extension);
+ }
+ this._store.data.mimetypes[type] = handlerObj;
+ } else {
+ this._store.data.schemes[type] = handlerObj;
+ }
+ this._store.saveSoon();
+ },
+
+ exists(aHandlerInfo) {
+ this._store.ensureDataReady();
+ if ((aHandlerInfo.type in this._store.data.mimetypes))
+ return true;
+ if ((aHandlerInfo.type in this._store.data.schemes))
+ return true;
+ return false;
+ },
+
+ remove(aHandlerInfo) {
+ this._store.ensureDataReady();
+ if ((aHandlerInfo.type in this._store.data.mimetypes)) {
+ delete this._store.data.mimetypes[aHandlerInfo.type];
+ } else if ((aHandlerInfo.type in this._store.data.schemes)) {
+ delete this._store.data.schemes[aHandlerInfo.type];
+ }
+ this._store.saveSoon();
+ },
+
+ getTypeFromExtension(aFileExtension) {
+ var fileExtension = aFileExtension.toLowerCase();
+ this._store.ensureDataReady();
+ var mimeTypes = this._store.data.mimetypes;
+ for (var type in mimeTypes) {
+ if (mimeTypes[type].fileExtensions.includes(fileExtension))
+ return type;
+ }
+ return "";
+ },
+
+ /**
+ * Retrieve the handler app object with the given ID.
+ *
+ * @param aHandlerAppID {string} the ID of the handler app to retrieve
+ *
+ * @returns {nsIHandlerApp} the handler app, if any; otherwise null
+ */
+ _retrieveHandlerApp(aHandlerObj) {
+ if (!("type" in aHandlerObj))
+ return null;
+
+ var handlerApp;
+ var HandlerType = {
+ LocalHandlerApp: 0,
+ WebHandlerApp: 1,
+ DBusHandlerApp: 2,
+ };
+
+ if (aHandlerObj.type == HandlerType.LocalHandlerApp) {
+ if (aHandlerObj.path) {
+ let executable = this._getFileWithPath(aHandlerObj.path);
+ if (!executable)
+ return null;
+ handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Ci.nsILocalHandlerApp);
+ handlerApp.executable = executable;
+ }
+ } else if(aHandlerObj.type == HandlerType.WebHandlerApp) {
+ handlerApp = Cc["@mozilla.org/uriloader/web-handler-app;1"].
+ createInstance(Ci.nsIWebHandlerApp);
+ handlerApp.uriTemplate = aHandlerObj.uriTemplate;
+ } else if(aHandlerObj.type == HandlerType.WebHandlerApp) {
+ handlerApp = Cc["@mozilla.org/uriloader/dbus-handler-app;1"].
+ createInstance(Ci.nsIDBusHandlerApp);
+ handlerApp.service = aHandlerObj.service;
+ handlerApp.method = aHandlerObj.method;
+ handlerApp.objectPath = aHandlerObj.objpath;
+ handlerApp.dBusInterface = aHandlerObj.iface;
+ } else
+ return null;
+
+ handlerApp.name = aHandlerObj.name;
+ return handlerApp;
+ },
+
+ /**
+ * Get the file with the given path. This is not as simple as merely
+ * initializing a local file object with the path, because the path might be
+ * relative to the current process directory, in which case we have to
+ * construct a path starting from that directory.
+ *
+ * @param aPath {string} a path to a file
+ *
+ * @returns {nsILocalFile} the file, or null if the file does not exist
+ */
+ _getFileWithPath(aPath) {
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+
+ try {
+ file.initWithPath(aPath);
+
+ if (file.exists())
+ return file;
+ }
+ catch(ex) {
+ // Note: for historical reasons, we don't actually check to see
+ // if the exception is NS_ERROR_FILE_UNRECOGNIZED_PATH, which is what
+ // nsILocalFile::initWithPath throws when a path is relative.
+
+ file = Service.dirSvc.get("XCurProcD", Ci.nsIFile);
+
+ try {
+ file.append(aPath);
+ if (file.exists())
+ return file;
+ }
+ catch(ex) {}
+ }
+
+ return null;
+ },
+
+ /**
+ * Append known handlers of the given class to the given array.
+ *
+ * @param aHandlers {array} the array of handlers to append to
+ * @param aClass {string} the class for which to append handlers
+ */
+ _appendHandlers(aHandlers, aClass) {
+ this._store.ensureDataReady();
+ var typesObj = this._store.data[aClass]
+ var handler;
+ for (var type in typesObj) {
+ if (aClass.localeCompare("mimetypes") == 0) {
+ handler = mimeSvc.getFromTypeAndExtension(type, null);
+ } else if (aClass.localeCompare("schemes") == 0){
+ handler = protoSvc.getProtocolHandlerInfo(type);
+ } else {
+ continue;
+ }
+ aHandlers.appendElement(handler, false);
+ }
+ },
+};
+
+//****************************************************************************//
+// More XPCOM Plumbing
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HandlerService]);
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsHandlerService-json.manifest
@@ -0,0 +1,2 @@
+component {220cc253-b60f-41f6-b9cf-fdcb325f970f} nsHandlerService-json.js
+contract @mozilla.org/uriloader/handler-service-json;1 {220cc253-b60f-41f6-b9cf-fdcb325f970f} process=main
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/unit/mimeTypes.json
@@ -0,0 +1,1 @@
+{"version":{"en-US":4},"mimetypes":{"application/pdf":{"description":"PDF document","action":3,"askBeforeHandle":false,"fileExtensions":["pdf"],"preferredHandler":{},"possibleHandlers":[]},"application/x-php":{"description":"PHP script","action":2,"askBeforeHandle":false,"fileExtensions":[],"preferredHandler":{"name":"Firefox browser","description":"","type":0,"path":"/usr/bin/firefox"},"possibleHandlers":[{"name":"Firefox browser","description":"","type":0,"path":"/usr/bin/firefox"}]}},"schemes":{"webcal":{"description":"","action":2,"askBeforeHandle":false,"fileExtensions":[],"preferredHandler":{},"possibleHandlers":[{"name":"30 Boxes","description":null,"type":1,"uriTemplate":"http://30boxes.com/external/widget?refer=ff&url=%s"},{"name":"30 Boxes","description":null,"type":1,"uriTemplate":"https://30boxes.com/external/widget?refer=ff&url=%s"}]},"ircs":{"description":"","action":2,"askBeforeHandle":false,"fileExtensions":[],"preferredHandler":{},"possibleHandlers":[{"name":"Mibbit","description":null,"type":1,"uriTemplate":"https://www.mibbit.com/?url=%s"},{"name":"IRCCloud","description":null,"type":1,"uriTemplate":"https://www.irccloud.com/#?/irc_url=%s"},{"name":"IRCCloud","description":null,"type":1,"uriTemplate":"https://irccloud.mozilla.com/#?/irc_url=%s"}]}}}
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/unit/test_handlerService-json.js
@@ -0,0 +1,125 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests new implementation of handler service by reloading mimeType.json
+ */
+
+"use strict"
+
+Cu.import("resource://gre/modules/osfile.jsm")
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+XPCOMUtils.defineLazyServiceGetter(this, "mimeSvc",
+ "@mozilla.org/mime;1",
+ "nsIMIMEService");
+XPCOMUtils.defineLazyServiceGetter(this, "handlerJsonSvc",
+ "@mozilla.org/uriloader/handler-service-json;1",
+ "nsIHandlerService");
+
+const pdfHandlerInfo = mimeSvc.getFromTypeAndExtension("application/pdf", null);
+const gzipHandlerInfo = mimeSvc.getFromTypeAndExtension("application/x-gzip", null);
+
+function run_test() {
+ do_get_profile();
+ run_next_test();
+}
+
+function test_exists(handlerJsonSvc) {
+ // test "exists()" only
+ do_check_true(handlerJsonSvc.exists(pdfHandlerInfo));
+ do_check_false(handlerJsonSvc.exists(gzipHandlerInfo));
+}
+
+function test_getTypeFromExtension(handlerJsonSvc) {
+ // test "getTypeFromExtension()" only
+ var type = handlerJsonSvc.getTypeFromExtension("doc");
+ do_check_eq(type, "");
+ type = handlerJsonSvc.getTypeFromExtension("pdf");
+ do_check_eq(type, "application/pdf");
+}
+
+function test_remove(handlerJsonSvc) {
+ // test "remove()" combined with "exist()" and "getTypeFromExtension()"
+ handlerJsonSvc.remove(pdfHandlerInfo);
+ do_check_false(handlerJsonSvc.exists(pdfHandlerInfo));
+ var type = handlerJsonSvc.getTypeFromExtension("pdf");
+ do_check_eq(type, "");
+}
+
+function test_store(handlerJsonSvc) {
+ // test "store()" combined with "exist()" and "getTypeFromExtension()"
+ handlerJsonSvc.store(pdfHandlerInfo);
+ do_check_true(handlerJsonSvc.exists(pdfHandlerInfo));
+ var type = handlerJsonSvc.getTypeFromExtension("pdf");
+ do_check_eq(type, "application/pdf");
+}
+
+function test_enumerate(handlerJsonSvc) {
+ // test "enumerate()"
+ var handlerTypes = ["application/x-php", "application/pdf", "webcal", "ircs"];
+ var handlerInfos = handlerJsonSvc.enumerate();
+ while (handlerInfos.hasMoreElements()) {
+ var handlerInfo = handlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
+ do_check_neq(handlerTypes.indexOf(handlerInfo.type), -1);
+ }
+
+ // test "enumerate()" combined with "store()"
+ handlerJsonSvc.store(gzipHandlerInfo);
+ handlerTypes.push("application/x-gzip");
+ handlerInfos = handlerJsonSvc.enumerate();
+ while (handlerInfos.hasMoreElements()) {
+ handlerInfo = handlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
+ do_check_neq(handlerTypes.indexOf(handlerInfo.type), -1);
+ handlerTypes.splice(handlerTypes.indexOf(handlerInfo.type), 1);
+ }
+ do_check_eq(handlerTypes.length, 0);
+
+ // test "enumerate()" combined with "remove()"
+ handlerJsonSvc.remove(pdfHandlerInfo);
+ handlerTypes = ["application/x-php", "application/x-gzip", "webcal", "ircs"];
+ handlerInfos = handlerJsonSvc.enumerate();
+ while (handlerInfos.hasMoreElements()) {
+ handlerInfo = handlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
+ do_check_neq(handlerTypes.indexOf(handlerInfo.type), -1);
+ handlerTypes.splice(handlerTypes.indexOf(handlerInfo.type), 1);
+ }
+ do_check_eq(handlerTypes.length, 0);
+}
+
+// test "fillHandlerInfo()"
+function test_fillHandlerInfo(handlerJsonSvc) {
+ // Get a handler info for a MIME type that neither the application nor
+ // the OS knows about and make sure its properties are set to the proper
+ // default values.
+ var handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
+ do_check_eq(handlerInfo.description, "");
+ do_check_eq(handlerInfo.preferredAction, Ci.nsIHandlerInfo.saveToDisk);
+ do_check_eq(handlerInfo.possibleApplicationHandlers.length, 0);
+
+ handlerJsonSvc.fillHandlerInfo(handlerInfo, "application/x-php");
+ var phpHandlerInfo = mimeSvc.getFromTypeAndExtension("application/x-php", null);
+ do_check_eq(handlerInfo.description, phpHandlerInfo.description);
+ do_check_eq(handlerInfo.preferredAction, phpHandlerInfo.preferredAction);
+ do_check_eq(handlerInfo.possibleApplicationHandlers.length, phpHandlerInfo.possibleApplicationHandlers.length);
+}
+
+add_task(function* testHandlerServiceJson() {
+ let src = "mimeTypes.json";
+ let dst = OS.Path.join(OS.Constants.Path.profileDir, src);
+
+ yield OS.File.copy(src, dst);
+ Assert.ok((yield OS.File.exists(dst)), "should have a DB now");
+ Services.prefs.setBoolPref("browser.handlerSvcJson.enabled", true);
+
+ test_exists(handlerJsonSvc);
+ test_getTypeFromExtension(handlerJsonSvc);
+ test_remove(handlerJsonSvc);
+ test_store(handlerJsonSvc);
+ test_enumerate(handlerJsonSvc);
+ test_fillHandlerInfo(handlerJsonSvc);
+});
+
--- a/uriloader/exthandler/tests/unit/test_handlerService.js
+++ b/uriloader/exthandler/tests/unit/test_handlerService.js
@@ -1,104 +1,101 @@
-/* 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/. */
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests two different backend of handler service
+ */
+
+"use strict"
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+
+XPCOMUtils.defineLazyServiceGetter(this, "mimeSvc",
+ "@mozilla.org/mime;1",
+ "nsIMIMEService");
+XPCOMUtils.defineLazyServiceGetter(this, "protoSvc",
+ "@mozilla.org/uriloader/external-protocol-service;1",
+ "nsIExternalProtocolService");
+XPCOMUtils.defineLazyServiceGetter(this, "env",
+ "@mozilla.org/process/environment;1",
+ "nsIEnvironment");
+XPCOMUtils.defineLazyServiceGetter(this, "handlerSvcRdf",
+ "@mozilla.org/uriloader/handler-service;1",
+ "nsIHandlerService");
+XPCOMUtils.defineLazyServiceGetter(this, "handlerSvcJson",
+ "@mozilla.org/uriloader/handler-service-json;1",
+ "nsIHandlerService");
+
+//**************************************************************************//
+// Constants
+const rootPrefBranch = Services.prefs.getBranch("");
function run_test() {
- //**************************************************************************//
- // Constants
-
- const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].
- getService(Ci.nsIHandlerService);
-
- const mimeSvc = Cc["@mozilla.org/mime;1"].
- getService(Ci.nsIMIMEService);
+ do_get_profile();
+ run_next_test();
+}
- const protoSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Ci.nsIExternalProtocolService);
-
- const prefSvc = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService);
-
- const ioService = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
-
- const env = Cc["@mozilla.org/process/environment;1"].
- getService(Components.interfaces.nsIEnvironment);
-
- const rootPrefBranch = prefSvc.getBranch("");
-
+function checkMailto() {
let noMailto = false;
if (mozinfo.os == "win") {
// Check mailto handler from registry.
// If registry entry is nothing, no mailto handler
let regSvc = Cc["@mozilla.org/windows-registry-key;1"].
createInstance(Ci.nsIWindowsRegKey);
try {
regSvc.open(regSvc.ROOT_KEY_CLASSES_ROOT,
"mailto",
regSvc.ACCESS_READ);
noMailto = false;
} catch (ex) {
noMailto = true;
}
regSvc.close();
- }
-
- if (mozinfo.os == "linux") {
+ }else if (mozinfo.os == "linux") {
// Check mailto handler from GIO
// If there isn't one, then we have no mailto handler
let gIOSvc = Cc["@mozilla.org/gio-service;1"].
createInstance(Ci.nsIGIOService);
try {
gIOSvc.getAppForURIScheme("mailto");
noMailto = false;
} catch (ex) {
noMailto = true;
}
}
-
- //**************************************************************************//
- // Sample Data
+ return noMailto;
+}
- // It doesn't matter whether or not this nsIFile is actually executable,
- // only that it has a path and exists. Since we don't know any executable
- // that exists on all platforms (except possibly the application being
- // tested, but there doesn't seem to be a way to get a reference to that
- // from the directory service), we use the temporary directory itself.
- var executable = HandlerServiceTest._dirSvc.get("TmpD", Ci.nsIFile);
- // XXX We could, of course, create an actual executable in the directory:
- //executable.append("localhandler");
- //if (!executable.exists())
- // executable.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o755);
-
- var localHandler = {
+function configure_localHandler(executable) {
+ return {
name: "Local Handler",
executable: executable,
interfaces: [Ci.nsIHandlerApp, Ci.nsILocalHandlerApp, Ci.nsISupports],
QueryInterface: function(iid) {
if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
throw Cr.NS_ERROR_NO_INTERFACE;
return this;
}
};
-
+}
+
+function configure_webHandler() {
var webHandler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
createInstance(Ci.nsIWebHandlerApp);
webHandler.name = "Web Handler";
webHandler.uriTemplate = "http://www.example.com/?%s";
-
- // FIXME: these tests create and manipulate enough variables that it would
- // make sense to move each test into its own scope so we don't run the risk
- // of one test stomping on another's data.
+ return webHandler;
+}
-
- //**************************************************************************//
- // Test Default Properties
-
+function configureAndTest_handlerInfo() {
// Get a handler info for a MIME type that neither the application nor
// the OS knows about and make sure its properties are set to the proper
// default values.
var handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
// Make sure it's also an nsIHandlerInfo.
do_check_true(handlerInfo instanceof Ci.nsIHandlerInfo);
@@ -115,73 +112,65 @@ function run_test() {
do_check_true(handlerInfo.alwaysAskBeforeHandling);
// These properties are initialized to default values by the service,
// so we might as well make sure they're initialized to the right defaults.
do_check_eq(handlerInfo.description, "");
do_check_eq(handlerInfo.hasDefaultHandler, false);
do_check_eq(handlerInfo.defaultDescription, "");
- // test some default protocol info properties
- var haveDefaultHandlersVersion = false;
- try {
- // If we have a defaultHandlersVersion pref, then assume that we're in the
- // firefox tree and that we'll also have default handlers.
- // 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");
- haveDefaultHandlersVersion = true;
- } catch (ex) {}
+ return handlerInfo;
+}
- const kExternalWarningDefault =
- "network.protocol-handler.warn-external-default";
- prefSvc.setBoolPref(kExternalWarningDefault, true);
+function SetExternalWarningPref(type, value) {
+ const kExternalWarningPrefPrefix = "network.protocol-handler.warn-external.";
+ Services.prefs.setBoolPref(kExternalWarningPrefPrefix + type, value);
+}
- // XXX add more thorough protocol info property checking
-
+
+function configureAndTest_protoInfo(noMailto, haveDefaultHandlersVersion) {
+
// no OS default handler exists
var protoInfo = protoSvc.getProtocolHandlerInfo("x-moz-rheet");
do_check_eq(protoInfo.preferredAction, protoInfo.alwaysAsk);
do_check_true(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default does not exist,
// explicit warning pref: false
- const kExternalWarningPrefPrefix = "network.protocol-handler.warn-external.";
- prefSvc.setBoolPref(kExternalWarningPrefPrefix + "http", false);
+ SetExternalWarningPref("http", false);
protoInfo = protoSvc.getProtocolHandlerInfo("http");
do_check_eq(0, protoInfo.possibleApplicationHandlers.length);
do_check_false(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default does not exist,
// explicit warning pref: true
- prefSvc.setBoolPref(kExternalWarningPrefPrefix + "http", true);
+ SetExternalWarningPref("http", true);
protoInfo = protoSvc.getProtocolHandlerInfo("http");
// OS handler isn't included in possibleApplicationHandlers, so length is 0
// Once they become instances of nsILocalHandlerApp, this number will need
// to change.
do_check_eq(0, protoInfo.possibleApplicationHandlers.length);
do_check_true(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default exists, explicit warning pref: false
- prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", false);
+ SetExternalWarningPref("mailto", false);
protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
if (haveDefaultHandlersVersion)
do_check_eq(2, protoInfo.possibleApplicationHandlers.length);
else
do_check_eq(0, protoInfo.possibleApplicationHandlers.length);
// Win7+ or Linux's GIO might not have a default mailto: handler
if (noMailto)
do_check_true(protoInfo.alwaysAskBeforeHandling);
else
do_check_false(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default exists, explicit warning pref: true
- prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", true);
+ SetExternalWarningPref("mailto", true);
protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
if (haveDefaultHandlersVersion) {
do_check_eq(2, protoInfo.possibleApplicationHandlers.length);
// Win7+ or Linux's GIO may have no default mailto: handler. Otherwise
// alwaysAskBeforeHandling is expected to be false here, because although
// the pref is true, the value in RDF is false. The injected mailto handler
// carried over the default pref value, and so when we set the pref above
// to true it's ignored.
@@ -190,82 +179,81 @@ function run_test() {
else
do_check_false(protoInfo.alwaysAskBeforeHandling);
} else {
do_check_eq(0, protoInfo.possibleApplicationHandlers.length);
do_check_true(protoInfo.alwaysAskBeforeHandling);
}
- if (haveDefaultHandlersVersion) {
- // Now set the value stored in RDF to true, and the pref to false, to make
- // sure we still get the right value. (Basically, same thing as above but
- // with the values reversed.)
- prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", false);
- protoInfo.alwaysAskBeforeHandling = true;
- handlerSvc.store(protoInfo);
- protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
- do_check_eq(2, protoInfo.possibleApplicationHandlers.length);
- do_check_true(protoInfo.alwaysAskBeforeHandling);
- }
+ return protoInfo;
+}
+function test_storeProtoInfoBySvc(protoInfo, handlerSvc) {
- //**************************************************************************//
- // Test Round-Trip Data Integrity
-
- // Test round-trip data integrity by setting the properties of the handler
- // info object to different values, telling the handler service to store the
- // object, and then retrieving a new info object for the same type and making
- // sure its properties are identical.
+ // Now set the value stored in DB to true, and the pref to false, to make
+ // sure we still get the right value. (Basically, same thing as above but
+ // with the values reversed.)
+ SetExternalWarningPref("mailto", false);
+ protoInfo.alwaysAskBeforeHandling = true;
+ handlerSvc.store(protoInfo);
+ protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
+ do_check_eq(2, protoInfo.possibleApplicationHandlers.length);
+ do_check_true(protoInfo.alwaysAskBeforeHandling);
- handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
- handlerInfo.preferredApplicationHandler = localHandler;
- handlerInfo.alwaysAskBeforeHandling = false;
+}
- handlerSvc.store(handlerInfo);
-
- handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
+function test_chekHandlerInfoFromMimeSvc(localHandler) {
+ var handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
do_check_eq(handlerInfo.preferredAction, Ci.nsIHandlerInfo.useHelperApp);
do_check_neq(handlerInfo.preferredApplicationHandler, null);
var preferredHandler = handlerInfo.preferredApplicationHandler;
do_check_eq(typeof preferredHandler, "object");
do_check_eq(preferredHandler.name, "Local Handler");
do_check_true(preferredHandler instanceof Ci.nsILocalHandlerApp);
preferredHandler.QueryInterface(Ci.nsILocalHandlerApp);
do_check_eq(preferredHandler.executable.path, localHandler.executable.path);
do_check_false(handlerInfo.alwaysAskBeforeHandling);
+}
+function test_enumerate(handlerSvc, haveDefaultHandlersVersion) {
// Make sure the handler service's enumerate method lists all known handlers.
var handlerInfo2 = mimeSvc.getFromTypeAndExtension("nonexistent/type2", null);
handlerSvc.store(handlerInfo2);
var handlerTypes = ["nonexistent/type", "nonexistent/type2"];
if (haveDefaultHandlersVersion) {
handlerTypes.push("webcal");
handlerTypes.push("mailto");
handlerTypes.push("irc");
handlerTypes.push("ircs");
}
+
var handlers = handlerSvc.enumerate();
while (handlers.hasMoreElements()) {
var handler = handlers.getNext().QueryInterface(Ci.nsIHandlerInfo);
do_check_neq(handlerTypes.indexOf(handler.type), -1);
handlerTypes.splice(handlerTypes.indexOf(handler.type), 1);
}
do_check_eq(handlerTypes.length, 0);
+}
+function test_remove(handlerSvc) {
// Make sure the handler service's remove method removes a handler record.
+ var handlerInfo2 = mimeSvc.getFromTypeAndExtension("nonexistent/type2", null)
handlerSvc.remove(handlerInfo2);
- handlers = handlerSvc.enumerate();
+ var handlers = handlerSvc.enumerate();
while (handlers.hasMoreElements())
do_check_neq(handlers.getNext().QueryInterface(Ci.nsIHandlerInfo).type,
handlerInfo2.type);
+}
+function test_storeAndReceive(handlerSvc, localHandler, webHandler) {
// Make sure we can store and retrieve a handler info object with no preferred
// handler.
var noPreferredHandlerInfo =
mimeSvc.getFromTypeAndExtension("nonexistent/no-preferred-handler", null);
handlerSvc.store(noPreferredHandlerInfo);
noPreferredHandlerInfo =
mimeSvc.getFromTypeAndExtension("nonexistent/no-preferred-handler", null);
do_check_eq(noPreferredHandlerInfo.preferredApplicationHandler, null);
@@ -344,19 +332,20 @@ function run_test() {
do_check_eq(possibleHandlersInfo.possibleApplicationHandlers.length, 1);
// Make sure the handler is the one we didn't remove.
webPossibleHandler = possibleHandlersInfo.possibleApplicationHandlers.
queryElementAt(0, Ci.nsIWebHandlerApp);
do_check_eq(webPossibleHandler.name, webHandler.name);
do_check_true(webPossibleHandler.equals(webHandler));
- //////////////////////////////////////////////////////
- // handler info command line parameters and equality
- var localApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+}
+
+function test_LocalApp(executable) {
+ var localApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
createInstance(Ci.nsILocalHandlerApp);
var handlerApp = localApp.QueryInterface(Ci.nsIHandlerApp);
do_check_true(handlerApp.equals(localApp));
localApp.executable = executable;
do_check_eq(0, localApp.parameterCount);
@@ -407,64 +396,122 @@ function run_test() {
var str;
str = localApp.getParameter(0)
do_check_eq(str, "-test1");
str = localApp.getParameter(1)
do_check_eq(str, "-test2");
str = localApp.getParameter(2)
do_check_eq(str, "-test3");
-
- // FIXME: test round trip integrity for a protocol.
- // FIXME: test round trip integrity for a handler info with a web handler.
+}
- //**************************************************************************//
- // getTypeFromExtension tests
-
+function test_getTypeFromExtension(handlerSvc, localHandler) {
// test nonexistent extension
var lolType = handlerSvc.getTypeFromExtension("lolcat");
do_check_eq(lolType, "");
-
// add a handler for the extension
var lolHandler = mimeSvc.getFromTypeAndExtension("application/lolcat", null);
do_check_false(lolHandler.extensionExists("lolcat"));
+ // add "lolcat" as file extension
+ lolHandler.appendExtension("lolcat");
lolHandler.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
lolHandler.preferredApplicationHandler = localHandler;
lolHandler.alwaysAskBeforeHandling = false;
// store the handler
do_check_false(handlerSvc.exists(lolHandler));
handlerSvc.store(lolHandler);
do_check_true(handlerSvc.exists(lolHandler));
- // Get a file:// string pointing to mimeTypes.rdf
- var rdfFile = HandlerServiceTest._dirSvc.get("UMimTyp", Ci.nsIFile);
- var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
- var rdfFileURI = fileHandler.getURLSpecFromFile(rdfFile);
-
- // Assign a file extenstion to the handler. handlerSvc.store() doesn't
- // actually store any file extensions added with setFileExtensions(), you
- // have to wade into RDF muck to do so.
-
- // Based on toolkit/mozapps/downloads/content/helperApps.js :: addExtension()
- var gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
- var mimeSource = gRDF.GetUnicodeResource("urn:mimetype:application/lolcat");
- var valueProperty = gRDF.GetUnicodeResource("http://home.netscape.com/NC-rdf#fileExtensions");
- var mimeLiteral = gRDF.GetLiteral("lolcat");
-
- var DS = gRDF.GetDataSourceBlocking(rdfFileURI);
- DS.Assert(mimeSource, valueProperty, mimeLiteral, true);
-
-
// test now-existent extension
lolType = handlerSvc.getTypeFromExtension("lolcat");
do_check_eq(lolType, "application/lolcat");
+}
+
+// Test Round-Trip Data Integrity
+function test_roundtripDataIntegrity(handlerSvc, haveDefaultHandlersVersion) {
+ var noMailto = checkMailto();
+
+ // It doesn't matter whether or not this nsIFile is actually executable,
+ // only that it has a path and exists. Since we don't know any executable
+ // that exists on all platforms (except possibly the application being
+ // tested, but there doesn't seem to be a way to get a reference to that
+ // from the directory service), we use the temporary directory itself.
+ var executable = HandlerServiceTest._dirSvc.get("TmpD", Ci.nsIFile);
+ // XXX We could, of course, create an actual executable in the directory:
+ //executable.append("localhandler");
+ //if (!executable.exists())
+ // executable.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o755);
+ var localHandler = configure_localHandler(executable);
+ var webHandler = configure_webHandler();
+ var handlerInfo = configureAndTest_handlerInfo();
+
+ var protoInfo = configureAndTest_protoInfo(noMailto, haveDefaultHandlersVersion);
+ if (haveDefaultHandlersVersion) {
+ test_storeProtoInfoBySvc(protoInfo, handlerSvc);
+ }
+
+ //**************************************************************************//
+ // Test Round-Trip Data Integrity
+
+ // Test round-trip data integrity by setting the properties of the handler
+ // info object to different values, telling the handler service to store the
+ // object, and then retrieving a new info object for the same type and making
+ // sure its properties are identical.
+ handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
+ handlerInfo.preferredApplicationHandler = localHandler;
+ handlerInfo.alwaysAskBeforeHandling = false;
+ handlerSvc.store(handlerInfo);
+
+ test_chekHandlerInfoFromMimeSvc(localHandler);
+
+ test_enumerate(handlerSvc, haveDefaultHandlersVersion);
+
+ test_remove(handlerSvc);
+
+ // Check the store from handlerSvc and receive from mimeSvc behavior
+ test_storeAndReceive(handlerSvc, localHandler, webHandler);
+
+ // handler info command line parameters and equality
+ test_LocalApp(executable);
+
+ //**************************************************************************//
+ // getTypeFromExtension tests and test the ability of saving file extension
+ test_getTypeFromExtension(handlerSvc, localHandler);
// test mailcap entries with needsterminal are ignored on non-Windows non-Mac.
if (mozinfo.os != "win" && mozinfo.os != "mac") {
env.set('PERSONAL_MAILCAP', do_get_file('mailcap').path);
- handlerInfo = mimeSvc.getFromTypeAndExtension("text/plain", null);
+ var handlerInfo = mimeSvc.getFromTypeAndExtension("text/plain", null);
do_check_eq(handlerInfo.preferredAction, Ci.nsIHandlerInfo.useSystemDefault);
do_check_eq(handlerInfo.defaultDescription, "sed");
}
}
+
+
+add_task(function* testHandlerService() {
+
+ // test some default protocol info properties
+ var haveDefaultHandlersVersion = false;
+ try {
+ // If we have a defaultHandlersVersion pref, then assume that we're in the
+ // firefox tree and that we'll also have default handlers.
+ // 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");
+ haveDefaultHandlersVersion = true;
+ } catch (ex) {}
+
+ const kExternalWarningDefault =
+ "network.protocol-handler.warn-external-default";
+ Services.prefs.setBoolPref(kExternalWarningDefault, true);
+
+ // original version : RDF
+ Services.prefs.setBoolPref("browser.handlerSvcJson.enabled", false);
+ test_roundtripDataIntegrity(handlerSvcRdf, haveDefaultHandlersVersion);
+
+ // new version : JSON
+ Services.prefs.setBoolPref("browser.handlerSvcJson.enabled", true);
+ test_roundtripDataIntegrity(handlerSvcJson, haveDefaultHandlersVersion);
+});
--- a/uriloader/exthandler/tests/unit/xpcshell.ini
+++ b/uriloader/exthandler/tests/unit/xpcshell.ini
@@ -3,13 +3,17 @@ head = head_handlerService.js
tail = tail_handlerService.js
run-sequentially = Bug 912235 - Intermittent failures
[test_getTypeFromExtension_ext_to_type_mapping.js]
[test_getTypeFromExtension_with_empty_Content_Type.js]
[test_badMIMEType.js]
[test_handlerService.js]
support-files = mailcap
+
# Bug 676997: test consistently fails on Android
fail-if = os == "android"
[test_punycodeURIs.js]
# Bug 676997: test consistently fails on Android
fail-if = os == "android"
+
+[test_handlerService-json.js]
+support-files = mimeTypes.json