Bug 949991 - [Download Manager] Nothing happens if you try to download a file while the device is connected as USB. r=bz
authorGhislain 'Aus' Lacroix <glacroix@mozilla.com>
Thu, 06 Mar 2014 12:42:07 -0800
changeset 189569 422267c7c845dd5cd0ca43233abfd5b4ccbb0fef
parent 189568 3369e99042ce8e74414258bd8c6b55775e244a50
child 189570 6aed8a1c3b28436f6d6d5b1ccc71c45b6c9d49a5
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs949991
milestone30.0a1
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 949991 - [Download Manager] Nothing happens if you try to download a file while the device is connected as USB. r=bz
uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -342,18 +342,18 @@ static nsresult GetDownloadDirectory(nsI
   nsString storageName;
   nsDOMDeviceStorage::GetDefaultStorageName(NS_LITERAL_STRING("sdcard"),
                                             storageName);
   NS_ENSURE_TRUE(!storageName.IsEmpty(), NS_ERROR_FAILURE);
 
   DeviceStorageFile dsf(NS_LITERAL_STRING("sdcard"),
                         storageName,
                         NS_LITERAL_STRING("downloads"));
-  NS_ENSURE_TRUE(dsf.mFile, NS_ERROR_FAILURE);
-  NS_ENSURE_TRUE(dsf.IsAvailable(), NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(dsf.mFile, NS_ERROR_FILE_ACCESS_DENIED);
+  NS_ENSURE_TRUE(dsf.IsAvailable(), NS_ERROR_FILE_ACCESS_DENIED);
 
   bool alreadyThere;
   nsresult rv = dsf.mFile->Exists(&alreadyThere);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!alreadyThere) {
     rv = dsf.mFile->Create(nsIFile::DIRECTORY_TYPE, 0770);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -1811,18 +1811,18 @@ void nsExternalAppHandler::SendStatusCha
           break;
         case kLaunchError:
           msgId.AssignLiteral("launchError");
           break;
         }
         break;
     }
     PR_LOG(nsExternalHelperAppService::mLog, PR_LOG_ERROR,
-        ("Error: %s, type=%i, listener=0x%p, rv=0x%08X\n",
-         NS_LossyConvertUTF16toASCII(msgId).get(), type, mDialogProgressListener.get(), rv));
+        ("Error: %s, type=%i, listener=0x%p, transfer=0x%p, rv=0x%08X\n",
+         NS_LossyConvertUTF16toASCII(msgId).get(), type, mDialogProgressListener.get(), mTransfer.get(), rv));
     PR_LOG(nsExternalHelperAppService::mLog, PR_LOG_ERROR,
         ("       path='%s'\n", NS_ConvertUTF16toUTF8(path).get()));
 
     // Get properties file bundle and extract status string.
     nsCOMPtr<nsIStringBundleService> stringService =
         mozilla::services::GetStringBundleService();
     if (stringService)
     {
@@ -1838,26 +1838,65 @@ void nsExternalAppHandler::SendStatusCha
                 // We have a listener, let it handle the error.
                 mDialogProgressListener->OnStatusChange(nullptr, (type == kReadError) ? aRequest : nullptr, rv, msgText);
               } else if (mTransfer) {
                 mTransfer->OnStatusChange(nullptr, (type == kReadError) ? aRequest : nullptr, rv, msgText);
               }
               else
               if (XRE_GetProcessType() == GeckoProcessType_Default) {
                 // We don't have a listener.  Simply show the alert ourselves.
-                nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mWindowContext));
+                nsresult qiRv;
+                nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mWindowContext, &qiRv));
                 nsXPIDLString title;
                 bundle->FormatStringFromName(MOZ_UTF16("title"),
                                              strings,
                                              1,
                                              getter_Copies(title));
-                if (prompter)
+
+                PR_LOG(nsExternalHelperAppService::mLog, PR_LOG_DEBUG,
+                       ("mWindowContext=0x%p, prompter=0x%p, qi rv=0x%08X, title='%s', msg='%s'",
+                       mWindowContext.get(),
+                       prompter.get(),
+                       qiRv,
+                       NS_ConvertUTF16toUTF8(title).get(),
+                       NS_ConvertUTF16toUTF8(msgText).get()));
+
+                // If we didn't have a prompter we will try and get a window
+                // instead, get it's docshell and use it to alert the user.
+                if (!prompter)
                 {
-                  prompter->Alert(title, msgText);
+                  nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(mWindowContext));
+                  if (!window || !window->GetDocShell())
+                  {
+                    return;
+                  }
+
+                  prompter = do_GetInterface(window->GetDocShell(), &qiRv);
+
+                  PR_LOG(nsExternalHelperAppService::mLog, PR_LOG_DEBUG,
+                         ("No prompter from mWindowContext, using DocShell, " \
+                          "window=0x%p, docShell=0x%p, " \
+                          "prompter=0x%p, qi rv=0x%08X",
+                          window.get(),
+                          window->GetDocShell(),
+                          prompter.get(),
+                          qiRv));
+
+                  // If we still don't have a prompter, there's nothing else we
+                  // can do so just return.
+                  if (!prompter)
+                  {
+                    PR_LOG(nsExternalHelperAppService::mLog, PR_LOG_ERROR,
+                           ("No prompter from DocShell, no way to alert user"));
+                    return;
+                  }
                 }
+
+                // We should always have a prompter at this point.
+                prompter->Alert(title, msgText);
               }
             }
         }
     }
 }
 
 NS_IMETHODIMP
 nsExternalAppHandler::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt,