Bug 981539 - Ensure there is always a transfer object instance available in nsExternalAppHandler::OnSaveComplete for e10s. r=bz
authorGhislain 'Aus' Lacroix <glacroix@mozilla.com>
Fri, 04 Apr 2014 08:32:07 -0700
changeset 195779 b07cc963d7a1fe6248211b22c25720417733555b
parent 195778 6e1d2814d4dbf5a2db5d1e59797b62d0d0fdfce6
child 195780 ef9ec6d75f13dc65b3679bb01c71798d7fe08a68
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs981539
milestone31.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 981539 - Ensure there is always a transfer object instance available in nsExternalAppHandler::OnSaveComplete for e10s. r=bz
uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2001,16 +2001,20 @@ nsExternalAppHandler::OnDataAvailable(ns
     }
   }
   return rv;
 }
 
 NS_IMETHODIMP nsExternalAppHandler::OnStopRequest(nsIRequest *request, nsISupports *aCtxt,
                                                   nsresult aStatus)
 {
+  LOG(("nsExternalAppHandler::OnStopRequest\n"
+       "  mCanceled=%d, mTransfer=0x%p, aStatus=0x%08X\n",
+       mCanceled, mTransfer.get(), aStatus));
+
   mStopRequestIssued = true;
 
   // Cancel if the request did not complete successfully.
   if (!mCanceled && NS_FAILED(aStatus))
   {
     // Send error notification.
     nsAutoString tempFilePath;
     if (mTempFile)
@@ -2033,27 +2037,43 @@ nsExternalAppHandler::OnTargetChange(nsI
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver *aSaver,
                                      nsresult aStatus)
 {
+  LOG(("nsExternalAppHandler::OnSaveComplete\n"
+       "  aSaver=0x%p, aStatus=0x%08X, mCanceled=%d, mTransfer=0x%p\n",
+       aSaver, aStatus, mCanceled, mTransfer.get()));
+
   if (!mCanceled) {
     // Save the hash
     (void)mSaver->GetSha256Hash(mHash);
     (void)mSaver->GetSignatureInfo(getter_AddRefs(mSignatureInfo));
     // Free the reference that the saver keeps on us, even if we couldn't get
     // the hash.
     mSaver = nullptr;
   
     if (NS_FAILED(aStatus)) {
       nsAutoString path;
       mTempFile->GetPath(path);
+
+      // It may happen when e10s is enabled that there will be no transfer
+      // object available to communicate status as expected by the system.
+      // Let's try and create a temporary transfer object to take care of this
+      // for us, we'll fall back to using the prompt service if we absolutely
+      // have to.
+      if (!mTransfer) {
+        nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
+        // We don't care if this fails.
+        CreateFailedTransfer(channel && NS_UsePrivateBrowsing(channel));
+      }
+
       SendStatusChange(kWriteError, aStatus, nullptr, path);
       if (!mCanceled)
         Cancel(aStatus);
       return NS_OK;
     }
   }
 
   // Notify the transfer object that we are done if the user has chosen an
@@ -2109,16 +2129,18 @@ NS_IMETHODIMP nsExternalAppHandler::GetS
 NS_IMETHODIMP nsExternalAppHandler::GetSuggestedFileName(nsAString& aSuggestedFileName)
 {
   aSuggestedFileName = mSuggestedFileName;
   return NS_OK;
 }
 
 nsresult nsExternalAppHandler::CreateTransfer()
 {
+  LOG(("nsExternalAppHandler::CreateTransfer"));
+
   MOZ_ASSERT(NS_IsMainThread(), "Must create transfer on main thread");
   // We are back from the helper app dialog (where the user chooses to save or
   // open), but we aren't done processing the load. in this case, throw up a
   // progress dialog so the user can see what's going on.
   // Also, release our reference to mDialog. We don't need it anymore, and we
   // need to break the reference cycle.
   mDialog = nullptr;
   if (!mDialogProgressListener) {