Bug 388701 - nsExternalHelperAppService::GetProtocolHandlerInfo should get OS Specific implementation. r=cbiesinger, sr=dmose
authorsdwilsh@shawnwilsher.com
Sun, 22 Jul 2007 11:40:24 -0700
changeset 3752 87a732bc89e18999a22ab3981ba38cc66f5a0c00
parent 3751 34f8c970d8b1d2a1996545860eb43b981ca5a7a5
child 3753 dd302708f38df4027e40607dea20692b49b046ee
push idunknown
push userunknown
push dateunknown
reviewerscbiesinger, dmose
bugs388701
milestone1.9a7pre
Bug 388701 - nsExternalHelperAppService::GetProtocolHandlerInfo should get OS Specific implementation. r=cbiesinger, sr=dmose
uriloader/exthandler/beos/nsOSHelperAppService.cpp
uriloader/exthandler/beos/nsOSHelperAppService.h
uriloader/exthandler/mac/nsOSHelperAppService.cpp
uriloader/exthandler/mac/nsOSHelperAppService.h
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/exthandler/nsExternalHelperAppService.h
uriloader/exthandler/unix/nsOSHelperAppService.cpp
uriloader/exthandler/unix/nsOSHelperAppService.h
uriloader/exthandler/win/nsOSHelperAppService.cpp
uriloader/exthandler/win/nsOSHelperAppService.h
--- a/uriloader/exthandler/beos/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/beos/nsOSHelperAppService.cpp
@@ -259,8 +259,30 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
   if (!mi)
     return nsnull;
   NS_ADDREF(mi);
   if (!aFileExt.IsEmpty())
     mi->AppendExtension(aFileExt);
 
   return mi;
 }
+
+already_AddRefed<nsIHandlerInfo>
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+{
+  NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
+
+  PRBool exists;
+  nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
+                                        &exists);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  nsMIMEInfoBeOS *handlerInfo = new nsMIMEInfoBeOS();
+  NS_ENSURE_TRUE(handlerInfo, nsnull);
+  NS_ADDREF(handlerInfo);
+
+  nsAutoString desc;
+  GetApplicationDescription(aScheme, desc);
+  handlerInfo->SetDefaultDescription(desc);
+
+  return handlerInfo;
+}
+
--- a/uriloader/exthandler/beos/nsOSHelperAppService.h
+++ b/uriloader/exthandler/beos/nsOSHelperAppService.h
@@ -49,16 +49,17 @@ class nsMIMEInfoBeOS;
 
 class nsOSHelperAppService : public nsExternalHelperAppService
 {
 public:
 	nsOSHelperAppService();
 	virtual ~nsOSHelperAppService();
 
 	already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool *aFound);
+	already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
 
 	// override nsIExternalProtocolService methods
 	nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
 	nsresult LoadUriInternal(nsIURI * aURL);
 
 protected:
 	nsresult SetMIMEInfoForType(const char *aMIMEType, nsMIMEInfoBeOS **_retval);
 	nsresult GetMimeInfoFromExtension(const char *aFileExt, nsMIMEInfoBeOS **_retval);
--- a/uriloader/exthandler/mac/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.cpp
@@ -328,16 +328,37 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
 
     if (!aFileExt.IsEmpty())
       mimeInfo->AppendExtension(aFileExt);
   }
   
   return mimeInfo;
 }
 
+already_AddRefed<nsIHandlerInfo>
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+{
+  NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
+
+  PRBool exists;
+  nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
+                                        &exists);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  nsMIMEInfoMac *handlerInfo = new nsMIMEInfoMac();
+  NS_ENSURE_TRUE(handlerInfo, nsnull);
+  NS_ADDREF(handlerInfo);
+
+  nsAutoString desc;
+  GetApplicationDescription(aScheme, desc);
+  handlerInfo->SetDefaultDescription(desc);
+
+  return handlerInfo;
+}
+
 // we never want to use a hard coded value for the creator and file type for the mac. always look these values up
 // from internet config.
 void nsOSHelperAppService::UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo)
 {
   PRUint32 macCreatorType;
   PRUint32 macFileType;
   aMIMEInfo->GetMacType(&macFileType);
   aMIMEInfo->GetMacCreator(&macCreatorType);
--- a/uriloader/exthandler/mac/nsOSHelperAppService.h
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.h
@@ -57,16 +57,17 @@ public:
 
   // override nsIExternalProtocolService methods
   NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
   nsresult LoadUriInternal(nsIURI * aURL);
   
   // method overrides --> used to hook the mime service into internet config....
   NS_IMETHOD GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo);
   already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool * aFound);
+  already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
 
   // GetFileTokenForPath must be implemented by each platform. 
   // platformAppPath --> a platform specific path to an application that we got out of the 
   //                     rdf data source. This can be a mac file spec, a unix path or a windows path depending on the platform
   // aFile --> an nsIFile representation of that platform application path.
   virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath, nsIFile ** aFile);
 
   nsresult OSProtocolHandlerExists(const char * aScheme,
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1471,28 +1471,36 @@ nsExternalHelperAppService::GetProtocolH
 
   // XXX enterprise customers should be able to turn this support off with a
   // single master pref (maybe use one of the "exposed" prefs here?)
 
   // nsIMIMEInfo is a superset of nsIHandlerInfo.  Furthermore, nsMimeInfoImpl
   // and subclasses have lots of good platform specific-knowledge of local
   // applications which we might need later.  For now, just use nsMIMEInfoImpl
   // instead of implementating a separate nsIHandlerInfo object.
-  nsMIMEInfoImpl *mimeInfo = new nsMIMEInfoImpl;
-  if (!mimeInfo) {
-    return NS_ERROR_OUT_OF_MEMORY;    
+  *aHandlerInfo = GetProtocolInfoFromOS(aScheme).get();
+  if (!aHandlerInfo) {
+    // Either it knows nothing, or we ran out of memory
+    return NS_ERROR_FAILURE;
   }
-  NS_ADDREF(*aHandlerInfo = mimeInfo);
-     
+
   nsresult rv = FillProtoInfoForSchemeFromDS(aScheme, *aHandlerInfo);     
-  if (NS_FAILED(rv)) {
+  if (NS_ERROR_NOT_AVAILABLE == rv) {
+    // We don't know it, so we always ask the user.  By the time we call this
+    // method, we already have checked if we should open this protocol and ask
+    // the user, so these defaults are OK.
+    // XXX this is a bit different than the MIME system, so we may want to look
+    //     into this more in the future.
+    (*aHandlerInfo)->SetPreferredAction(nsIHandlerInfo::useSystemDefault);
+    (*aHandlerInfo)->SetAlwaysAskBeforeHandling(PR_TRUE);
+  } else if (NS_FAILED(rv)) {
     NS_RELEASE(*aHandlerInfo);
     return rv;
   }
-  
+
   return NS_OK;
 }
  
 // XPCOM profile change observer
 NS_IMETHODIMP
 nsExternalHelperAppService::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData )
 {
   if (!strcmp(aTopic, "profile-before-change")) {
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -191,16 +191,25 @@ public:
    *         returning one is an out-of-memory error.
    *         If null, the value of aFound is unspecified.
    */
   virtual already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
                                                           const nsACString& aFileExt,
                                                           PRBool     * aFound) = 0;
 
   /**
+   * Given a scheme, looks up the protocol info from the OS.  This should be
+   * overridden by each OS's implementation.
+   *
+   * @param aScheme The protocol scheme we are looking for.
+   * @return An nsIHanderInfo for the protocol.
+   */
+  virtual already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme) = 0;
+
+  /**
    * Given a string identifying an application, create an nsIFile representing
    * it. This function should look in $PATH for the application.
    * The base class implementation will first try to interpret platformAppPath
    * as an absolute path, and if that fails it will look for a file next to the
    * mozilla executable. Subclasses can override this method if they want a
    * different behaviour.
    * @param platformAppPath A platform specific path to an application that we
    *                        got out of the rdf data source. This can be a mac
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -1668,14 +1668,35 @@ nsOSHelperAppService::GetMIMEInfoFromOS(
     // Copy the attributes of retval onto miByExt, to return it
     retval->CopyBasicDataTo(miByExt);
 
     miByExt.swap(retval);
   }
   return retval;
 }
 
+already_AddRefed<nsIHandlerInfo>
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+{
+  NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
+
+  PRBool exists;
+  nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
+                                        &exists);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  nsMIMEInfoImpl *handlerInfo = new nsMIMEInfoImpl();
+  NS_ENSURE_TRUE(handlerInfo, nsnull);
+  NS_ADDREF(handlerInfo);
+
+  nsAutoString desc;
+  GetApplicationDescription(aScheme, desc);
+  handlerInfo->SetDefaultDescription(desc);
+
+  return handlerInfo;
+}
+
 void
 nsOSHelperAppService::FixFilePermissions(nsILocalFile* aFile)
 {
   aFile->SetPermissions(mPermissions); 
 }
 
--- a/uriloader/exthandler/unix/nsOSHelperAppService.h
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.h
@@ -56,16 +56,17 @@ class nsOSHelperAppService : public nsEx
 public:
   nsOSHelperAppService();
   virtual ~nsOSHelperAppService();
 
   // method overrides for mime.types and mime.info look up steps
   already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMimeType,
                                                   const nsACString& aFileExt,
                                                   PRBool     *aFound);
+  already_AddRefed<nsIHanderInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
 
   // override nsIExternalProtocolService methods
   nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
   nsresult LoadUriInternal(nsIURI * aURL);
   NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
 
   // GetFileTokenForPath must be implemented by each platform. 
   // platformAppPath --> a platform specific path to an application that we got out of the 
--- a/uriloader/exthandler/win/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp
@@ -582,8 +582,30 @@ already_AddRefed<nsIMIMEInfo> nsOSHelper
     nsCOMPtr<nsIFile> defaultApp;
     nsAutoString desc;
     miByExt->GetDefaultDescription(desc);
 
     mi->SetDefaultDescription(desc);
   }
   return mi;
 }
+
+already_AddRefed<nsIHandlerInfo>
+nsOSHelperAppService::GetProtocolInfoFromOS(const nsACString &aScheme)
+{
+  NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
+
+  PRBool exists;
+  nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(),
+                                        &exists);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+
+  nsMIMEInfoWin *handlerInfo = new nsMIMEInfoWin();
+  NS_ENSURE_TRUE(handlerInfo, nsnull);
+  NS_ADDREF(handlerInfo);
+
+  nsAutoString desc;
+  GetApplicationDescription(aScheme, desc);
+  handlerInfo->SetDefaultDescription(desc);
+
+  return handlerInfo;
+}
+
--- a/uriloader/exthandler/win/nsOSHelperAppService.h
+++ b/uriloader/exthandler/win/nsOSHelperAppService.h
@@ -58,16 +58,17 @@ public:
 
   // override nsIExternalProtocolService methods
   nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
   nsresult LoadUriInternal(nsIURI * aURL);
   NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
 
   // method overrides for windows registry look up steps....
   already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool *aFound);
+  already_AddRefed<nsIHandlerInfo> GetProtocolInfoFromOS(const nsACString &aScheme);
 
   /** Get the string value of a registry value and store it in result.
    * @return PR_TRUE on success, PR_FALSE on failure
    */
   static PRBool GetValueString(HKEY hKey, const PRUnichar* pValueName, nsAString& result);
 
 protected:
   nsresult GetDefaultAppInfo(const nsAString& aTypeName, nsAString& aDefaultDescription, nsIFile** aDefaultApplication);