Bug 441636 - Add support for DBus Handler Apps r=biesi
author"Brad Lassey" <blassey@mozilla.com>
Fri, 25 Jul 2008 12:36:07 -0400
changeset 16237 26c8643ce48302359fa2ee095425638aef4a1034
parent 16236 fcdfa3729ed5128a5b6a0808d71357cb9f86011f
child 16238 a9d6442f4b1e87cb3f9ab753a4fb734800624ca1
child 16241 e73711d2e5e67226dd534742af167f2e42ec4a33
push idunknown
push userunknown
push dateunknown
reviewersbiesi
bugs441636
milestone1.9.1a2pre
Bug 441636 - Add support for DBus Handler Apps r=biesi
docshell/build/Makefile.in
docshell/build/nsDocShellModule.cpp
netwerk/mime/public/nsIMIMEInfo.idl
toolkit/library/Makefile.in
toolkit/mozapps/handling/content/dialog.js
uriloader/exthandler/Makefile.in
uriloader/exthandler/nsCExternalHandlerService.idl
uriloader/exthandler/nsDBusHandlerApp.cpp
uriloader/exthandler/nsDBusHandlerApp.h
uriloader/exthandler/nsHandlerService.js
--- a/docshell/build/Makefile.in
+++ b/docshell/build/Makefile.in
@@ -133,8 +133,12 @@ endif
 
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS		+= $(call EXPAND_LIBNAME, shell32 ole32)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 EXTRA_DSO_LDOPTS	+= $(TK_LIBS)
 endif
+
+ifdef MOZ_ENABLE_DBUS
+ EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS)
+endif
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -51,16 +51,17 @@
 // uriloader
 #include "nsURILoader.h"
 #include "nsDocLoader.h"
 #include "nsOSHelperAppService.h"
 #include "nsExternalProtocolHandler.h"
 #include "nsPrefetchService.h"
 #include "nsOfflineCacheUpdate.h"
 #include "nsLocalHandlerApp.h"
+#include "nsDBusHandlerApp.h"
 
 // session history
 #include "nsSHEntry.h"
 #include "nsSHistory.h"
 #include "nsSHTransaction.h"
 
 // global history
 #include "nsGlobalHistoryAdapter.h"
@@ -107,16 +108,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsURILoad
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDocLoader, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsOSHelperAppService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalProtocolHandler)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefetchService, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheUpdateService,
                                          nsOfflineCacheUpdateService::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
 NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
 
 #if defined(XP_MAC) || defined(XP_MACOSX)
 #include "nsInternetConfigService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsInternetConfigService)
 #endif
 
 // session history
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
@@ -231,16 +233,18 @@ static const nsModuleComponentInfo gDocS
   {  NS_PREFETCHSERVICE_CLASSNAME, NS_PREFETCHSERVICE_CID, NS_PREFETCHSERVICE_CONTRACTID,
      nsPrefetchServiceConstructor, },
   { NS_OFFLINECACHEUPDATESERVICE_CLASSNAME, NS_OFFLINECACHEUPDATESERVICE_CID, NS_OFFLINECACHEUPDATESERVICE_CONTRACTID,
     nsOfflineCacheUpdateServiceConstructor, },
   { NS_OFFLINECACHEUPDATE_CLASSNAME, NS_OFFLINECACHEUPDATE_CID, NS_OFFLINECACHEUPDATE_CONTRACTID,
     nsOfflineCacheUpdateConstructor, },
   { "Local Application Handler App", NS_LOCALHANDLERAPP_CID, 
     NS_LOCALHANDLERAPP_CONTRACTID, PlatformLocalHandlerApp_tConstructor, },
+  { "DBus Handler App", NS_DBUSHANDLERAPP_CID,
+      NS_DBUSHANDLERAPP_CONTRACTID, nsDBusHandlerAppConstructor},
 
 #if defined(XP_MAC) || defined(XP_MACOSX)
   { "Internet Config Service", NS_INTERNETCONFIGSERVICE_CID, NS_INTERNETCONFIGSERVICE_CONTRACTID,
     nsInternetConfigServiceConstructor, },
 #endif
         
     // session history
    { "nsSHEntry", NS_SHENTRY_CID,
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -315,8 +315,45 @@ interface nsIWebHandlerApp : nsIHandlerA
 
     /**
      * Template used to construct the URI to GET.  Template is expected to have
      * a %s in it, and the escaped URI to be handled is inserted in place of 
      * that %s, as per the HTML5 spec.
      */
     attribute AUTF8String uriTemplate;
 };
+
+/**
+ * nsIDBusHandlerApp represents local applications launched by DBus a message
+ * invoking a method taking a single string argument descibing a URI
+ */
+[scriptable, uuid(1ffc274b-4cbf-4bb5-a635-05ad2cbb6534)]
+interface nsIDBusHandlerApp : nsIHandlerApp {
+
+    /**
+     * Service defines the dbus service that should handle this protocol.
+     * If its not set,  NS_ERROR_FAILURE will be returned by LaunchWithURI
+     */
+    attribute AUTF8String service;
+    
+    /**
+     * Objpath defines the object path of the dbus service that should handle 
+     * this protocol. If its not set,  NS_ERROR_FAILURE will be returned 
+     * by LaunchWithURI
+     */
+    attribute AUTF8String objectPath;
+
+    /**
+     * DBusInterface defines the interface of the dbus service that should 
+     * handle this protocol. If its not set,  NS_ERROR_FAILURE will be  
+     * returned by LaunchWithURI
+     */
+    attribute AUTF8String dBusInterface;
+    
+    /**
+     * Method defines the dbus method that should be invoked to handle this 
+     * protocol. If its not set,  NS_ERROR_FAILURE will be returned by 
+     * LaunchWithURI
+     */
+    attribute AUTF8String method;
+    
+};
+
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -202,16 +202,20 @@ EXTRA_DSO_LDOPTS += \
 	-framework SystemConfiguration \
 	-framework QuickTime \
 	-framework IOKit \
 	-lcrypto \
 	$(TK_LIBS) \
 	$(NULL)
 endif
 
+ifdef MOZ_ENABLE_DBUS
+EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS)
+endif
+
 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(MOZ_XFT_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS) -lgthread-2.0
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
 ifdef NS_OSSO
 EXTRA_DSO_LDOPTS += -llocation -lgpsbt -losso
 endif
--- a/toolkit/mozapps/handling/content/dialog.js
+++ b/toolkit/mozapps/handling/content/dialog.js
@@ -156,16 +156,19 @@ var dialog = {
           }
           catch (e) {
             iconURI = uri.prePath + "/favicon.ico";
           }
           elm.setAttribute("image", iconURI);
         }
         elm.setAttribute("description", uri.prePath);
       }
+      else if (app instanceof Ci.nsIDBusHandlerApp){
+	  elm.setAttribute("description", app.method);  
+      }
       else
         throw "unknown handler type";
 
       items.insertBefore(elm, this._itemChoose);
       if (preferredHandler && app == preferredHandler)
         this.selectedItem = elm;
     }
 
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -147,16 +147,22 @@ endif
 CPPSRCS	= \
 	nsExternalHelperAppService.cpp	\
 	nsExternalProtocolHandler.cpp \
 	nsMIMEInfoImpl.cpp \
 	nsLocalHandlerApp.cpp \
 	$(OSHELPER) \
 	$(NULL)
 
+ifdef MOZ_ENABLE_DBUS
+CPPSRCS += nsDBusHandlerApp.cpp
+LOCAL_INCLUDES   += $(TK_CFLAGS) $(MOZ_DBUS_GLIB_CFLAGS)
+EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS)
+endif
+
 ifeq ($(OS_ARCH),WINNT WINCE)
 OS_LIBS		+= shell32.lib
 GARBAGE		+= nsOSHelperAppService.cpp $(srcdir)/nsOSHelperAppService.cpp \
              nsMIMEInfoWin.cpp $(srcdir)/nsMIMEInfoWin.cpp
 endif
 
 EXTRA_COMPONENTS = \
   nsHandlerService.js \
--- a/uriloader/exthandler/nsCExternalHandlerService.idl
+++ b/uriloader/exthandler/nsCExternalHandlerService.idl
@@ -70,16 +70,23 @@ nsIExternalHelperAppService
 /* 9fa83ce7-d0ab-4ed3-938e-afafee435670 */
 #define NS_BLOCKEDEXTERNALPROTOCOLHANDLER_CID	\
 { 0x9fa83ce7, 0xd0ab, 0x4ed3, {0x93, 0x8e, 0xaf, 0xaf, 0xee, 0x43, 0x56, 0x70 } }
 
 /* bc0017e3-2438-47be-a567-41db58f17627 */
 #define NS_LOCALHANDLERAPP_CID \
 { 0xbc0017e3, 0x2438, 0x47be, {0xa5, 0x67, 0x41, 0xdb, 0x58, 0xf1, 0x76, 0x27 } }
 
+/*6c3c274b-4cbf-4bb5-a635-05ad2cbb6535*/
+#define NS_DBUSHANDLERAPP_CID \
+{ 0x6c3c274b, 0x4cbf, 0x4bb5, {0xa6, 0x35, 0x05, 0xad, 0x2c, 0xbb, 0x65, 0x35 } }
+
+#define NS_DBUSHANDLERAPP_CONTRACTID \
+"@mozilla.org/uriloader/dbus-handler-app;1"
+
 #define NS_LOCALHANDLERAPP_CONTRACTID \
 "@mozilla.org/uriloader/local-handler-app;1"
 
 #define NS_WEBHANDLERAPP_CONTRACTID \
 "@mozilla.org/uriloader/web-handler-app;1"
 
 %}
 
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsDBusHandlerApp.cpp
@@ -0,0 +1,230 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim:expandtab:shiftwidth=2:tabstop=2:cin:
+ * ***** 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 the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is 
+ * the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Lassey <blassey@mozila.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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  <dbus/dbus.h>
+#include "nsDBusHandlerApp.h"
+#include "nsIURI.h"
+#include "nsIGenericFactory.h"
+#include "nsIClassInfoImpl.h"
+#include "nsCOMPtr.h"
+
+#ifdef NS_OSSO
+#include <libosso.h>
+
+#define APP_LAUNCH_BANNER_SERVICE           "com.nokia.hildon-desktop"
+#define APP_LAUNCH_BANNER_METHOD_INTERFACE  "com.nokia.hildon.hdwm.startupnotification"
+#define APP_LAUNCH_BANNER_METHOD_PATH       "/com/nokia/hildon/hdwm"
+#define APP_LAUNCH_BANNER_METHOD            "starting"
+#endif
+
+
+// XXX why does nsMIMEInfoImpl have a threadsafe nsISupports?  do we need one 
+// here too?
+NS_IMPL_ISUPPORTS2_CI(nsDBusHandlerApp, nsIDBusHandlerApp, nsIHandlerApp)
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsIHandlerApp
+
+NS_IMETHODIMP nsDBusHandlerApp::GetName(nsAString& aName)
+{
+  aName.Assign(mName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDBusHandlerApp::SetName(const nsAString & aName)
+{
+  mName.Assign(aName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDBusHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *_retval)
+{
+  NS_ENSURE_ARG_POINTER(aHandlerApp);
+  
+  // If the handler app isn't a dbus handler app, then it's not the same app.
+  nsCOMPtr<nsIDBusHandlerApp> dbusHandlerApp = do_QueryInterface(aHandlerApp);
+  if (!dbusHandlerApp) {
+    *_retval = PR_FALSE;
+    return NS_OK;
+  }
+  nsCAutoString service;
+  nsCAutoString method;
+  
+  nsresult rv = dbusHandlerApp->GetService(service);
+  if (NS_FAILED(rv)) {
+    *_retval = PR_FALSE;
+    return NS_OK;
+  }
+  rv = dbusHandlerApp->GetMethod(method);
+  if (NS_FAILED(rv)) {
+    *_retval = PR_FALSE;
+    return NS_OK;
+  }
+  
+  *_retval = service.Equals(mService) && method.Equals(mMethod);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDBusHandlerApp::LaunchWithURI(nsIURI *aURI,
+                                nsIInterfaceRequestor *aWindowContext)
+{
+  nsCAutoString spec;
+  nsresult rv = aURI->GetAsciiSpec(spec);
+  NS_ENSURE_SUCCESS(rv,rv);
+  const char* uri = spec.get(); 
+  
+  DBusError err;
+  dbus_error_init(&err);
+  
+  DBusConnection  *connection;
+  connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
+  if (dbus_error_is_set(&err)) { 
+    dbus_error_free(&err); 
+    return NS_ERROR_FAILURE;
+  }
+  if (nsnull == connection) { 
+    return NS_ERROR_FAILURE; 
+  }
+  dbus_connection_set_exit_on_disconnect(connection,false);
+  
+  DBusMessage* msg;
+  msg = dbus_message_new_method_call(mService.get(), 
+                                     mObjpath.get(), 
+                                     mInterface.get(), 
+                                     mMethod.get());
+  
+  if (!msg) {
+    return NS_ERROR_FAILURE;
+  }
+  dbus_message_set_no_reply(msg, PR_TRUE);
+  
+  DBusMessageIter iter;
+  dbus_message_iter_init_append(msg, &iter);
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uri);
+  
+  if (dbus_connection_send(connection, msg, NULL)) {
+    dbus_connection_flush(connection);
+    dbus_message_unref(msg);
+#ifdef NS_OSSO
+    msg = dbus_message_new_method_call (APP_LAUNCH_BANNER_SERVICE,
+                                        APP_LAUNCH_BANNER_METHOD_PATH,
+                                        APP_LAUNCH_BANNER_METHOD_INTERFACE,
+                                        APP_LAUNCH_BANNER_METHOD);
+    
+    if (msg) {
+      const char* service = mService.get();
+      if (dbus_message_append_args(msg,
+                                   DBUS_TYPE_STRING, 
+                                   &service,
+                                   DBUS_TYPE_INVALID)) {
+        if (dbus_connection_send(connection, msg, NULL)) {
+          dbus_connection_flush(connection);
+        }
+        dbus_message_unref(msg);
+      }
+    }
+#endif
+  } else {
+    dbus_message_unref(msg);
+    return NS_ERROR_FAILURE;		    
+  }
+  return NS_OK;
+  
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsIDBusHandlerApp
+
+/* attribute AUTF8String service; */
+NS_IMETHODIMP nsDBusHandlerApp::GetService(nsACString & aService)
+{
+  aService.Assign(mService);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDBusHandlerApp::SetService(const nsACString & aService)
+{
+  mService.Assign(aService);
+  return NS_OK;
+}
+
+/* attribute AUTF8String method; */
+NS_IMETHODIMP nsDBusHandlerApp::GetMethod(nsACString & aMethod)
+{
+  aMethod.Assign(mMethod);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDBusHandlerApp::SetMethod(const nsACString & aMethod)
+{
+  mMethod.Assign(aMethod);
+  return NS_OK;
+}
+
+/* attribute AUTF8String interface; */
+NS_IMETHODIMP nsDBusHandlerApp::GetDBusInterface(nsACString & aInterface)
+{
+  aInterface.Assign(mInterface);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDBusHandlerApp::SetDBusInterface(const nsACString & aInterface)
+{
+  mInterface.Assign(aInterface);
+  return NS_OK;
+}
+
+/* attribute AUTF8String objpath; */
+NS_IMETHODIMP nsDBusHandlerApp::GetObjectPath(nsACString & aObjpath)
+{
+  aObjpath.Assign(mObjpath);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDBusHandlerApp::SetObjectPath(const nsACString & aObjpath)
+{
+  mObjpath.Assign(aObjpath);
+  return NS_OK;
+}
+
+NS_DECL_CLASSINFO(nsDBusHandlerApp)
+
+
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsDBusHandlerApp.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim:expandtab:shiftwidth=2:tabstop=2:cin:
+ * ***** 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 the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is 
+ * the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 __nsDBusHandlerAppImpl_h__
+#define __nsDBusHandlerAppImpl_h__
+
+#include "nsString.h"
+#include "nsIMIMEInfo.h"
+
+class nsDBusHandlerApp : public nsIDBusHandlerApp
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIHANDLERAPP
+  NS_DECL_NSIDBUSHANDLERAPP
+
+  nsDBusHandlerApp() { }
+
+  virtual ~nsDBusHandlerApp() { }
+
+protected:
+  nsString mName;
+  nsCString mService;
+  nsCString mMethod;
+  nsCString mInterface;
+  nsCString mObjpath;
+
+};
+#endif
--- a/uriloader/exthandler/nsHandlerService.js
+++ b/uriloader/exthandler/nsHandlerService.js
@@ -767,21 +767,29 @@ HandlerService.prototype = {
     // a local hander or a web handler), so if the new handler is a local
     // handler, then we remove any web handler properties and vice versa.
     // This is unnecessary but harmless for possible handlers.
 
     if (aHandlerApp instanceof Ci.nsILocalHandlerApp) {
       this._setLiteral(aHandlerAppID, NC_PATH, aHandlerApp.executable.path);
       this._removeTarget(aHandlerAppID, NC_URI_TEMPLATE);
     }
-    else {
+    else if(aHandlerApp instanceof Ci.nsIWebHandlerApp){
       aHandlerApp.QueryInterface(Ci.nsIWebHandlerApp);
       this._setLiteral(aHandlerAppID, NC_URI_TEMPLATE, aHandlerApp.uriTemplate);
       this._removeTarget(aHandlerAppID, NC_PATH);
     }
+    else if(aHandlerApp instanceof Ci.nsIDBusHandlerApp){
+      aHandlerApp.QueryInterface(Ci.nsIDBusHandlerApp);
+      
+    }
+    else {
+	throw "unknown handler type";
+    }
+	
   },
 
   _storeAlwaysAsk: function HS__storeAlwaysAsk(aHandlerInfo) {
     var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
     this._setLiteral(infoID,
                      NC_ALWAYS_ASK,
                      aHandlerInfo.alwaysAskBeforeHandling ? "true" : "false");
   },
@@ -957,21 +965,27 @@ HandlerService.prototype = {
    *
    * @param aHandlerApp  {nsIHandlerApp}   the handler app object
    */
   _getPossibleHandlerAppID: function HS__getPossibleHandlerAppID(aHandlerApp) {
     var handlerAppID = "urn:handler:";
 
     if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
       handlerAppID += "local:" + aHandlerApp.executable.path;
-    else {
+    else if(aHandlerApp instanceof Ci.nsIWebHandlerApp){
       aHandlerApp.QueryInterface(Ci.nsIWebHandlerApp);
       handlerAppID += "web:" + aHandlerApp.uriTemplate;
     }
-
+    else if(aHandlerApp instanceof Ci.nsIDBusHandlerApp){
+      aHandlerApp.QueryInterface(Ci.nsIDBusHandlerApp);
+      handlerAppID += "dbus:" + aHandlerApp.service + " " + aHandlerApp.method + " " + aHandlerApp.uriTemplate;
+    }else{
+	throw "unknown handler type";
+    }
+    
     return handlerAppID;
   },
 
   /**
    * Get the list of types for the given class, creating the list if it doesn't
    * already exist. The class can be either CLASS_MIMEINFO or CLASS_PROTOCOLINFO
    * (i.e. the result of a call to _getClass).
    *