Bug 613080 - External URL handler service. r=bz a=blocking-fennec
authorAlex Pakhotin <alexp@mozilla.com>
Tue, 23 Nov 2010 15:40:46 -0800
changeset 59260 9d578b3cff8395c417ddd1f62047c81a6d80b972
parent 59259 6246b6c7fff6ea667181ae7cc79981f0631418ca
child 59261 cf153d8167458ffa12eef3259094be6936d942b6
push id17588
push userblassey@mozilla.com
push dateWed, 15 Dec 2010 20:42:28 +0000
treeherdermozilla-central@cf153d816745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, blocking-fennec
bugs613080
milestone2.0b9pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 613080 - External URL handler service. r=bz a=blocking-fennec
docshell/build/nsDocShellCID.h
docshell/build/nsDocShellModule.cpp
embedding/android/GeckoAppShell.java
uriloader/exthandler/Makefile.in
uriloader/exthandler/android/nsAndroidHandlerApp.cpp
uriloader/exthandler/android/nsExternalURLHandlerService.cpp
uriloader/exthandler/android/nsExternalURLHandlerService.h
uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
uriloader/exthandler/android/nsMIMEInfoAndroid.h
uriloader/exthandler/android/nsOSHelperAppService.cpp
uriloader/exthandler/nsIExternalURLHandlerService.idl
widget/src/android/AndroidBridge.cpp
widget/src/android/AndroidBridge.h
--- a/docshell/build/nsDocShellCID.h
+++ b/docshell/build/nsDocShellCID.h
@@ -73,16 +73,24 @@
 
 /**
  * Contract ID to obtain the IHistory interface.  This is a non-scriptable
  * interface used to interact with history in an asynchronous manner.
  */
 #define NS_IHISTORY_CONTRACTID "@mozilla.org/browser/history;1"
 
 /**
+ * A contract for a service that is used for finding
+ * platform-specific applications for handling particular URLs.
+ *
+ * @implements nsIExternalURLHandlerService
+ */
+#define NS_EXTERNALURLHANDLERSERVICE_CONTRACTID "@mozilla.org/uriloader/external-url-handler-service;1"
+
+/**
  * An observer service topic that can be listened to to catch creation
  * of content browsing areas (both toplevel ones and subframes).  The
  * subject of the notification will be the nsIWebNavigation being
  * created.  At this time the additional data wstring is not defined
  * to be anything in particular.
  */
 #define NS_WEBNAVIGATION_CREATE "webnavigation-create"
 
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -55,16 +55,19 @@
 #include "nsOfflineCacheUpdate.h"
 #include "nsLocalHandlerApp.h"
 #ifdef MOZ_ENABLE_DBUS
 #include "nsDBusHandlerApp.h"
 #endif 
 #if defined(ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
 #include "nsExternalSharingAppService.h"
 #endif
+#if defined(ANDROID)
+#include "nsExternalURLHandlerService.h"
+#endif
 
 // session history
 #include "nsSHEntry.h"
 #include "nsSHistory.h"
 #include "nsSHTransaction.h"
 
 // download history
 #include "nsDownloadHistory.h"
@@ -111,16 +114,19 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
 NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
 #ifdef MOZ_ENABLE_DBUS
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
 #endif 
 #if defined(ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalSharingAppService)
 #endif
+#if defined(ANDROID)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalURLHandlerService)
+#endif
 
 // session history
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHTransaction)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHistory)
 
 // download history
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadHistory)
@@ -138,16 +144,19 @@ NS_DEFINE_NAMED_CID(NS_OFFLINECACHEUPDAT
 NS_DEFINE_NAMED_CID(NS_OFFLINECACHEUPDATE_CID);
 NS_DEFINE_NAMED_CID(NS_LOCALHANDLERAPP_CID);
 #ifdef MOZ_ENABLE_DBUS
 NS_DEFINE_NAMED_CID(NS_DBUSHANDLERAPP_CID);
 #endif
 #if defined(ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
 NS_DEFINE_NAMED_CID(NS_EXTERNALSHARINGAPPSERVICE_CID);
 #endif
+#if defined(ANDROID)
+NS_DEFINE_NAMED_CID(NS_EXTERNALURLHANDLERSERVICE_CID);
+#endif
 NS_DEFINE_NAMED_CID(NS_SHENTRY_CID);
 NS_DEFINE_NAMED_CID(NS_HISTORYENTRY_CID);
 NS_DEFINE_NAMED_CID(NS_SHTRANSACTION_CID);
 NS_DEFINE_NAMED_CID(NS_SHISTORY_CID);
 NS_DEFINE_NAMED_CID(NS_SHISTORY_INTERNAL_CID);
 NS_DEFINE_NAMED_CID(NS_DOWNLOADHISTORY_CID);
 
 
@@ -165,16 +174,19 @@ const mozilla::Module::CIDEntry kDocShel
   { &kNS_OFFLINECACHEUPDATE_CID, false, NULL, nsOfflineCacheUpdateConstructor },
   { &kNS_LOCALHANDLERAPP_CID, false, NULL, PlatformLocalHandlerApp_tConstructor },
 #ifdef MOZ_ENABLE_DBUS
   { &kNS_DBUSHANDLERAPP_CID, false, NULL, nsDBusHandlerAppConstructor },
 #endif
 #if defined(ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
   { &kNS_EXTERNALSHARINGAPPSERVICE_CID, false, NULL, nsExternalSharingAppServiceConstructor },
 #endif
+#if defined(ANDROID)
+  { &kNS_EXTERNALURLHANDLERSERVICE_CID, false, NULL, nsExternalURLHandlerServiceConstructor },
+#endif
   { &kNS_SHENTRY_CID, false, NULL, nsSHEntryConstructor },
   { &kNS_HISTORYENTRY_CID, false, NULL, nsSHEntryConstructor },
   { &kNS_SHTRANSACTION_CID, false, NULL, nsSHTransactionConstructor },
   { &kNS_SHISTORY_CID, false, NULL, nsSHistoryConstructor },
   { &kNS_SHISTORY_INTERNAL_CID, false, NULL, nsSHistoryConstructor },
   { &kNS_DOWNLOADHISTORY_CID, false, NULL, nsDownloadHistoryConstructor },
   { NULL }
 };
@@ -210,16 +222,19 @@ const mozilla::Module::ContractIDEntry k
   { NS_OFFLINECACHEUPDATE_CONTRACTID, &kNS_OFFLINECACHEUPDATE_CID },
   { NS_LOCALHANDLERAPP_CONTRACTID, &kNS_LOCALHANDLERAPP_CID },
 #ifdef MOZ_ENABLE_DBUS
   { NS_DBUSHANDLERAPP_CONTRACTID, &kNS_DBUSHANDLERAPP_CID },
 #endif
 #if defined(ANDROID) || defined(MOZ_ENABLE_MEEGOTOUCHSHARE)
   { NS_EXTERNALSHARINGAPPSERVICE_CONTRACTID, &kNS_EXTERNALSHARINGAPPSERVICE_CID },
 #endif
+#if defined(ANDROID)
+  { NS_EXTERNALURLHANDLERSERVICE_CONTRACTID, &kNS_EXTERNALURLHANDLERSERVICE_CID },
+#endif
   { NS_SHENTRY_CONTRACTID, &kNS_SHENTRY_CID },
   { NS_HISTORYENTRY_CONTRACTID, &kNS_HISTORYENTRY_CID },
   { NS_SHTRANSACTION_CONTRACTID, &kNS_SHTRANSACTION_CID },
   { NS_SHISTORY_CONTRACTID, &kNS_SHISTORY_CID },
   { NS_SHISTORY_INTERNAL_CONTRACTID, &kNS_SHISTORY_INTERNAL_CID },
   { NS_DOWNLOADHISTORY_CONTRACTID, &kNS_DOWNLOADHISTORY_CID },
   { NULL }
 };
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -381,19 +381,20 @@ class GeckoAppShell
     
     static String[] getHandlersForMimeType(String aMimeType, String aAction) {
         Intent intent = getIntentForActionString(aAction);
         if (aMimeType != null && aMimeType.length() > 0)
             intent.setType(aMimeType);
         return getHandlersForIntent(intent);
     }
 
-    static String[] getHandlersForProtocol(String aScheme, String aAction) {
+    static String[] getHandlersForURL(String aURL, String aAction) {
+        // aURL may contain the whole URL or just the protocol
+        Uri uri = aURL.indexOf(':') >= 0 ? Uri.parse(aURL) : new Uri.Builder().scheme(aURL).build();
         Intent intent = getIntentForActionString(aAction);
-        Uri uri = new Uri.Builder().scheme(aScheme).build();
         intent.setData(uri);
         return getHandlersForIntent(intent);
     }
 
     static String[] getHandlersForIntent(Intent intent) {
         PackageManager pm = 
             GeckoApp.surfaceView.getContext().getPackageManager();
         List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -103,16 +103,18 @@ OSHELPER	+= nsGNOMERegistry.cpp
 OSHELPER  += nsMIMEInfoUnix.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 OSHELPER += nsMIMEInfoAndroid.cpp
 OSHELPER += nsAndroidHandlerApp.cpp
 OSHELPER += nsExternalSharingAppService.cpp
 EXPORTS += nsExternalSharingAppService.h
+OSHELPER += nsExternalURLHandlerService.cpp
+EXPORTS += nsExternalURLHandlerService.h
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
 OSHELPER += nsGNOMERegistry.cpp
 OSHELPER += nsMIMEInfoUnix.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
@@ -142,16 +144,17 @@ EXPORTS += \
 XPIDLSRCS = \
 	nsCExternalHandlerService.idl	\
 	nsIExternalProtocolService.idl \
 	nsIExternalHelperAppService.idl	\
 	nsIHelperAppLauncherDialog.idl \
 	nsIContentDispatchChooser.idl \
 	nsIHandlerService.idl	\
 	nsIExternalSharingAppService.idl \
+	nsIExternalURLHandlerService.idl \
 	$(NULL)
 
 CPPSRCS	= \
 	nsExternalHelperAppService.cpp	\
 	nsExternalProtocolHandler.cpp \
 	nsMIMEInfoImpl.cpp \
 	nsLocalHandlerApp.cpp \
 	$(OSHELPER) \
--- a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
+++ b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp
@@ -34,18 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAndroidHandlerApp.h"
 #include "AndroidBridge.h"
 
 
-NS_IMPL_ISUPPORTS1(nsAndroidHandlerApp, nsISharingHandlerApp)
-
+NS_IMPL_ISUPPORTS2(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp)
 
 nsAndroidHandlerApp::nsAndroidHandlerApp(const nsAString& aName,
                                          const nsAString& aDescription,
                                          const nsAString& aPackageName,
                                          const nsAString& aClassName,
                                          const nsACString& aMimeType,
                                          const nsAString& aAction) :
 mName(aName), mDescription(aDescription), mPackageName(aPackageName),
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalURLHandlerService.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com>
+ *
+ * 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
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsExternalURLHandlerService.h"
+#include "nsMIMEInfoAndroid.h"
+
+NS_IMPL_ISUPPORTS1(nsExternalURLHandlerService, nsIExternalURLHandlerService)
+
+nsExternalURLHandlerService::nsExternalURLHandlerService()
+{
+}
+
+nsExternalURLHandlerService::~nsExternalURLHandlerService()
+{
+}
+
+NS_IMETHODIMP
+nsExternalURLHandlerService::GetURLHandlerInfoFromOS(nsIURI *aURL,
+                                                     PRBool *found,
+                                                     nsIHandlerInfo **info)
+{
+  nsCString uriSpec;
+  aURL->GetSpec(uriSpec);
+  return nsMIMEInfoAndroid::GetMimeInfoForURL(uriSpec, found, info);
+}
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/android/nsExternalURLHandlerService.h
@@ -0,0 +1,58 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com>
+ *
+ * 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
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef NSEXTERNALURLHANDLERSERVICE_H
+#define NSEXTERNALURLHANDLERSERVICE_H
+
+#include "nsIExternalURLHandlerService.h"
+
+// {4BF1F8EF-D947-4BA3-9CD3-8C9A54A63A1C}
+#define NS_EXTERNALURLHANDLERSERVICE_CID \
+    {0x4bf1f8ef, 0xd947, 0x4ba3, {0x9c, 0xd3, 0x8c, 0x9a, 0x54, 0xa6, 0x3a, 0x1c}}
+
+class nsExternalURLHandlerService : public nsIExternalURLHandlerService
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIEXTERNALURLHANDLERSERVICE
+
+    nsExternalURLHandlerService();
+private:
+    ~nsExternalURLHandlerService();
+};
+
+#endif // NSEXTERNALURLHANDLERSERVICE_H
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
@@ -101,36 +101,39 @@ nsMIMEInfoAndroid::GetMimeInfoForFileExt
 {
   nsCString mimeType;
   if (mozilla::AndroidBridge::Bridge())
     mozilla::AndroidBridge::Bridge()->
       GetMimeTypeFromExtensions(aFileExt, mimeType);
   return GetMimeInfoForMimeType(mimeType, aMimeInfo);
 }
 
+/**
+ * Returns MIME info for the aURL, which may contain the whole URL or only a protocol
+ */
 nsresult
-nsMIMEInfoAndroid::GetMimeInfoForProtocol(const nsACString &aScheme,
-                                          PRBool *found,
-                                          nsIHandlerInfo **info)
+nsMIMEInfoAndroid::GetMimeInfoForURL(const nsACString &aURL,
+                                     PRBool *found,
+                                     nsIHandlerInfo **info)
 {
   const nsCString &emptyC = EmptyCString();
   mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge();
   nsMIMEInfoAndroid *mimeinfo = new nsMIMEInfoAndroid(emptyC);
   NS_ADDREF(*info = mimeinfo);
   *found = PR_TRUE;
   
   if (!bridge) {
     // we don't have access to the bridge, so just assume we can handle
     // the protocol for now and let the system deal with it
     return NS_OK;
   }
 
   nsIHandlerApp* systemDefault = nsnull;
-  bridge->GetHandlersForProtocol(nsCAutoString(aScheme).get(), 
-                                 mimeinfo->mHandlerApps, &systemDefault);
+  bridge->GetHandlersForURL(nsCAutoString(aURL).get(), 
+                            mimeinfo->mHandlerApps, &systemDefault);
   
   if (systemDefault)
     mimeinfo->mPrefApp = systemDefault;
 
 
   PRUint32 len;
   mimeinfo->mHandlerApps->GetLength(&len);
   if (len == 1) {
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.h
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.h
@@ -45,19 +45,20 @@ class nsMIMEInfoAndroid : public nsIMIME
 {
 public:
   static PRBool
   GetMimeInfoForMimeType(const nsACString& aMimeType, 
                          nsMIMEInfoAndroid** aMimeInfo);
   static PRBool
   GetMimeInfoForFileExt(const nsACString& aFileExt, 
                         nsMIMEInfoAndroid** aMimeInfo);
+
   static nsresult 
-  GetMimeInfoForProtocol(const nsACString &aScheme, PRBool *found,
-                         nsIHandlerInfo **info);
+  GetMimeInfoForURL(const nsACString &aURL, PRBool *found,
+                    nsIHandlerInfo **info);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMIMEINFO
   NS_DECL_NSIHANDLERINFO
 
   nsMIMEInfoAndroid(const nsACString& aMIMEType);
 
 protected:
--- a/uriloader/exthandler/android/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/android/nsOSHelperAppService.cpp
@@ -70,25 +70,25 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
 
     return mimeInfo.forget();
 }
 
 nsresult
 nsOSHelperAppService::OSProtocolHandlerExists(const char* aScheme,
                                               PRBool* aExists)
 {
-    *aExists = mozilla::AndroidBridge::Bridge()->GetHandlersForProtocol(aScheme);    
+    *aExists = mozilla::AndroidBridge::Bridge()->GetHandlersForURL(aScheme);    
     return NS_OK;
 }
 
 nsresult nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
                                       PRBool *found,
                                       nsIHandlerInfo **info)
 {
-    return nsMIMEInfoAndroid::GetMimeInfoForProtocol(aScheme, found, info);
+    return nsMIMEInfoAndroid::GetMimeInfoForURL(aScheme, found, info);
 }
 
 nsIHandlerApp*
 nsOSHelperAppService::CreateAndroidHandlerApp(const nsAString& aName,
                                               const nsAString& aDescription,
                                               const nsAString& aPackageName,
                                               const nsAString& aClassName, 
                                               const nsACString& aMimeType,
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsIExternalURLHandlerService.idl
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com>
+ *
+ * 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
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIMIMEInfo.idl"
+
+/**
+ * The external URL handler service is used for finding
+ * platform-specific applications for handling particular URLs.
+ */
+
+[scriptable, uuid(56c5c7d3-6fd3-43f8-9429-4397e111453a)]
+interface nsIExternalURLHandlerService : nsISupports
+{
+  /**
+   * Given a URL, looks up the handler info from the OS. This should be
+   * overridden by each OS's implementation.
+   *
+   * @param aURL The URL we are looking for.
+   * @param aFound  Was an OS default handler for this URL found?
+   * @return  An nsIHanderInfo for the protocol.
+   */
+  nsIHandlerInfo getURLHandlerInfoFromOS(in nsIURI aURL,
+                                         out boolean aFound);
+
+};
--- a/widget/src/android/AndroidBridge.cpp
+++ b/widget/src/android/AndroidBridge.cpp
@@ -102,17 +102,17 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
     jEnableAccelerometer = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableAccelerometer", "(Z)V");
     jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V");
     jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V");
     jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V");
     jNotifyAppShellReady = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onAppShellReady", "()V");
     jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V");
     jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
-    jGetHandlersForProtocol = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForProtocol", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
+    jGetHandlersForURL = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
     jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
     jGetMimeTypeFromExtensions = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
     jMoveTaskToBack = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "moveTaskToBack", "()V");
     jGetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getClipboardText", "()Ljava/lang/String;");
     jSetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setClipboardText", "(Ljava/lang/String;)V");
     jShowAlertNotification = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
     jShowFilePicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showFilePicker", "(Ljava/lang/String;)Ljava/lang/String;");
     jAlertsProgressListener_OnProgress = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "alertsProgressListener_OnProgress", "(Ljava/lang/String;JJLjava/lang/String;)V");
@@ -347,30 +347,30 @@ AndroidBridge::GetHandlersForMimeType(co
 
     getHandlersFromStringArray(mJNIEnv, arr, len, aHandlersArray, 
                                aDefaultApp, aAction,
                                nsDependentCString(aMimeType));
     return PR_TRUE;
 }
 
 PRBool
-AndroidBridge::GetHandlersForProtocol(const char *aScheme,
+AndroidBridge::GetHandlersForURL(const char *aURL,
                                       nsIMutableArray* aHandlersArray,
                                       nsIHandlerApp **aDefaultApp,
                                       const nsAString& aAction)
 {
     AutoLocalJNIFrame jniFrame;
-    NS_ConvertUTF8toUTF16 wScheme(aScheme);
+    NS_ConvertUTF8toUTF16 wScheme(aURL);
     jstring jstrScheme = mJNIEnv->NewString(wScheme.get(), wScheme.Length());
     const PRUnichar* wAction;
     PRUint32 actionLen = NS_StringGetData(aAction, &wAction);
     jstring jstrAction = mJNIEnv->NewString(wAction, actionLen);
 
     jobject obj = mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass,
-                                                  jGetHandlersForProtocol,
+                                                  jGetHandlersForURL,
                                                   jstrScheme, jstrAction);
     jobjectArray arr = static_cast<jobjectArray>(obj);
     if (!arr)
         return PR_FALSE;
 
     jsize len = mJNIEnv->GetArrayLength(arr);
 
     if (!aHandlersArray)
--- a/widget/src/android/AndroidBridge.h
+++ b/widget/src/android/AndroidBridge.h
@@ -121,20 +121,20 @@ public:
 
     void NotifyXreExit();
 
     void ScheduleRestart();
 
     void SetSurfaceView(jobject jobj);
     AndroidGeckoSurfaceView& SurfaceView() { return mSurfaceView; }
 
-    PRBool GetHandlersForProtocol(const char *aScheme, 
-                                  nsIMutableArray* handlersArray = nsnull,
-                                  nsIHandlerApp **aDefaultApp = nsnull,
-                                  const nsAString& aAction = EmptyString());
+    PRBool GetHandlersForURL(const char *aURL, 
+                             nsIMutableArray* handlersArray = nsnull,
+                             nsIHandlerApp **aDefaultApp = nsnull,
+                             const nsAString& aAction = EmptyString());
 
     PRBool GetHandlersForMimeType(const char *aMimeType,
                                   nsIMutableArray* handlersArray = nsnull,
                                   nsIHandlerApp **aDefaultApp = nsnull,
                                   const nsAString& aAction = EmptyString());
 
     PRBool OpenUriExternal(const nsACString& aUriSpec, const nsACString& aMimeType,
                            const nsAString& aPackageName = EmptyString(),
@@ -239,17 +239,17 @@ protected:
     jmethodID jEnableAccelerometer;
     jmethodID jEnableLocation;
     jmethodID jReturnIMEQueryResult;
     jmethodID jNotifyAppShellReady;
     jmethodID jNotifyXreExit;
     jmethodID jScheduleRestart;
     jmethodID jGetOutstandingDrawEvents;
     jmethodID jGetHandlersForMimeType;
-    jmethodID jGetHandlersForProtocol;
+    jmethodID jGetHandlersForURL;
     jmethodID jOpenUriExternal;
     jmethodID jGetMimeTypeFromExtensions;
     jmethodID jMoveTaskToBack;
     jmethodID jGetClipboardText;
     jmethodID jSetClipboardText;
     jmethodID jShowAlertNotification;
     jmethodID jShowFilePicker;
     jmethodID jAlertsProgressListener_OnProgress;