Bug 1352348 - add a method to nsExternalHelperAppService that only fetches a string mimetype for an extension, r?bz,paolo draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Thu, 13 Apr 2017 15:45:54 +0100
changeset 565053 666d216ebf7e836424edce59ba42c1a23f7d3367
parent 564527 7de25bf70a4f3e6ed23bbd540f7bfd2eddd75ad1
child 624905 d791926a00836e017c9d19bf20f35fe0520739b8
push id54775
push userbmo:gijskruitbosch+bugs@gmail.com
push dateWed, 19 Apr 2017 12:51:30 +0000
reviewersbz, paolo
bugs1352348
milestone55.0a1
Bug 1352348 - add a method to nsExternalHelperAppService that only fetches a string mimetype for an extension, r?bz,paolo MozReview-Commit-ID: 3p1pakC9g45
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/exthandler/nsExternalHelperAppService.h
uriloader/exthandler/win/nsOSHelperAppService.cpp
uriloader/exthandler/win/nsOSHelperAppService.h
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2718,24 +2718,22 @@ nsExternalHelperAppService::GetTypeFromE
   for (auto& entry : defaultMimeEntries) {
     if (aFileExt.LowerCaseEqualsASCII(entry.mFileExtension)) {
       aContentType = entry.mMimeType;
       return NS_OK;
     }
   }
 
   // Ask OS.
-  bool found = false;
-  nsCOMPtr<nsIMIMEInfo> mi = GetMIMEInfoFromOS(EmptyCString(), aFileExt, &found);
-  if (mi && found) {
-    return mi->GetMIMEType(aContentType);
+  if (GetMIMETypeFromOSForExtension(aFileExt, aContentType)) {
+    return NS_OK;
   }
 
   // Check extras array.
-  found = GetTypeFromExtras(aFileExt, aContentType);
+  bool found = GetTypeFromExtras(aFileExt, aContentType);
   if (found) {
     return NS_OK;
   }
 
   // Try the plugins
   RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
   if (pluginHost &&
       pluginHost->HavePluginForExtension(aFileExt, aContentType)) {
@@ -2924,8 +2922,16 @@ bool nsExternalHelperAppService::GetType
             ++iter;
           }
           start = iter;
       }
   }
 
   return false;
 }
+
+bool
+nsExternalHelperAppService::GetMIMETypeFromOSForExtension(const nsACString& aExtension, nsACString& aMIMEType)
+{
+  bool found = false;
+  nsCOMPtr<nsIMIMEInfo> mimeInfo = GetMIMEInfoFromOS(EmptyCString(), aExtension, &found);
+  return found && mimeInfo && NS_SUCCEEDED(mimeInfo->GetMIMEType(aMIMEType));
+}
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -103,16 +103,25 @@ public:
    *                        application path.
    */
   virtual nsresult GetFileTokenForPath(const char16_t * platformAppPath,
                                        nsIFile ** aFile);
 
   virtual nsresult OSProtocolHandlerExists(const char *aScheme,
                                                        bool *aExists) = 0;
 
+  /**
+   * Given an extension, get a MIME type string. If not overridden by
+   * the OS-specific nsOSHelperAppService, will call into GetMIMEInfoFromOS
+   * with an empty mimetype.
+   * @return true if we successfully found a mimetype.
+   */
+  virtual bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+                                             nsACString& aMIMEType);
+
 protected:
   virtual ~nsExternalHelperAppService();
 
   /**
    * Searches the "extra" array of MIMEInfo objects for an object
    * with a specific type. If found, it will modify the passed-in
    * MIMEInfo. Otherwise, it will return an error and the MIMEInfo
    * will be untouched.
--- a/uriloader/exthandler/win/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp
@@ -390,53 +390,35 @@ nsOSHelperAppService::GetDefaultAppInfo(
   return NS_OK;
 }
 
 already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFlatString& aFileExt, const char *aTypeHint)
 {
   if (aFileExt.IsEmpty())
     return nullptr;
 
-  // windows registry assumes your file extension is going to include the '.'.
-  // so make sure it's there...
+  // Determine the mime type.
+  nsAutoCString typeToUse;
+  if (aTypeHint && *aTypeHint) {
+    typeToUse.Assign(aTypeHint);
+  } else if (!GetMIMETypeFromOSForExtension(NS_ConvertUTF16toUTF8(aFileExt), typeToUse)) {
+    return nullptr;
+  }
+
+  RefPtr<nsMIMEInfoWin> mimeInfo = new nsMIMEInfoWin(typeToUse);
+
+  // windows registry assumes your file extension is going to include the '.',
+  // but our APIs expect it to not be there, so make sure we normalize that bit.
   nsAutoString fileExtToUse;
   if (aFileExt.First() != char16_t('.'))
     fileExtToUse = char16_t('.');
 
   fileExtToUse.Append(aFileExt);
 
-  // Try to get an entry from the windows registry.
-  nsCOMPtr<nsIWindowsRegKey> regKey = 
-    do_CreateInstance("@mozilla.org/windows-registry-key;1");
-  if (!regKey) 
-    return nullptr; 
-
-  nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
-                             fileExtToUse,
-                             nsIWindowsRegKey::ACCESS_QUERY_VALUE);
-  if (NS_FAILED(rv))
-    return nullptr; 
-
-  nsAutoCString typeToUse;
-  if (aTypeHint && *aTypeHint) {
-    typeToUse.Assign(aTypeHint);
-  }
-  else {
-    nsAutoString temp;
-    if (NS_FAILED(regKey->ReadStringValue(NS_LITERAL_STRING("Content Type"),
-                  temp)) || temp.IsEmpty()) {
-      return nullptr; 
-    }
-    // Content-Type is always in ASCII
-    LossyAppendUTF16toASCII(temp, typeToUse);
-  }
-
-  RefPtr<nsMIMEInfoWin> mimeInfo = new nsMIMEInfoWin(typeToUse);
-
-  // don't append the '.'
+  // don't append the '.' for our APIs.
   mimeInfo->AppendExtension(NS_ConvertUTF16toUTF8(Substring(fileExtToUse, 1)));
   mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
 
   nsAutoString appInfo;
   bool found;
 
   // Retrieve the default application for this extension
   if (mAppAssoc) {
@@ -453,18 +435,27 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelp
       CoTaskMemFree(pResult);
     } 
     else {
       found = false;
     }
   } 
   else
   {
-    found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), 
-                                                 appInfo));
+    nsCOMPtr<nsIWindowsRegKey> regKey =
+      do_CreateInstance("@mozilla.org/windows-registry-key;1");
+    if (!regKey)
+      return nullptr;
+    nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
+                               fileExtToUse,
+                               nsIWindowsRegKey::ACCESS_QUERY_VALUE);
+    if (NS_SUCCEEDED(rv)) {
+      found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(),
+                                                   appInfo));
+    }
   }
 
   // Bug 358297 - ignore the default handler, force the user to choose app
   if (appInfo.EqualsLiteral("XPSViewer.Document"))
     found = false;
 
   if (!found) {
     return nullptr;
@@ -592,8 +583,45 @@ nsOSHelperAppService::GetProtocolHandler
 
   nsAutoString desc;
   GetApplicationDescription(aScheme, desc);
   handlerInfo->SetDefaultDescription(desc);
 
   return NS_OK;
 }
 
+bool
+nsOSHelperAppService::GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+                                                    nsACString& aMIMEType)
+{
+  if (aExtension.IsEmpty())
+    return false;
+
+  // windows registry assumes your file extension is going to include the '.'.
+  // so make sure it's there...
+  nsAutoString fileExtToUse;
+  if (aExtension.First() != '.')
+    fileExtToUse = char16_t('.');
+
+  AppendUTF8toUTF16(aExtension, fileExtToUse);
+
+  // Try to get an entry from the windows registry.
+  nsCOMPtr<nsIWindowsRegKey> regKey =
+    do_CreateInstance("@mozilla.org/windows-registry-key;1");
+  if (!regKey)
+    return false;
+
+  nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
+                             fileExtToUse,
+                             nsIWindowsRegKey::ACCESS_QUERY_VALUE);
+  if (NS_FAILED(rv))
+    return false;
+
+  nsAutoString mimeType;
+  if (NS_FAILED(regKey->ReadStringValue(NS_LITERAL_STRING("Content Type"),
+                mimeType)) || mimeType.IsEmpty()) {
+    return false;
+  }
+  // Content-Type is always in ASCII
+  aMIMEType.Truncate();
+  LossyAppendUTF16toASCII(mimeType, aMIMEType);
+  return true;
+}
--- a/uriloader/exthandler/win/nsOSHelperAppService.h
+++ b/uriloader/exthandler/win/nsOSHelperAppService.h
@@ -35,16 +35,18 @@ public:
   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, bool *aFound);
   NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString &aScheme, 
                                           bool *found,
                                           nsIHandlerInfo **_retval);
+  virtual bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+                                             nsACString& aMIMEType) override;
 
   /** Get the string value of a registry value and store it in result.
    * @return true on success, false on failure
    */
   static bool GetValueString(HKEY hKey, const char16_t* pValueName, nsAString& result);
 
 protected:
   nsresult GetDefaultAppInfo(const nsAString& aTypeName, nsAString& aDefaultDescription, nsIFile** aDefaultApplication);