Bug 591081 - Keep using nsExternalAppHandler in the child process after forwarding download request, r=dwitte, a=blocking-fennec2.0b1
authorBrian Crowder <crowder@fiverocks.com>
Mon, 13 Sep 2010 11:37:00 -0700
changeset 53716 a2d78881240cfbc09dbebde875f8527a729012ae
parent 53715 4906e07c0970aa429c19e0c15b4b26eb17f7e216
child 53717 68033b993ed7b430fb89bad85a60f974262bb109
push idunknown
push userunknown
push dateunknown
reviewersdwitte, blocking-fennec2.0b1
bugs591081
milestone2.0b6pre
Bug 591081 - Keep using nsExternalAppHandler in the child process after forwarding download request, r=dwitte, a=blocking-fennec2.0b1
uriloader/exthandler/ExternalHelperAppChild.cpp
uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/uriloader/exthandler/ExternalHelperAppChild.cpp
+++ b/uriloader/exthandler/ExternalHelperAppChild.cpp
@@ -84,35 +84,37 @@ ExternalHelperAppChild::OnDataAvailable(
 
 //////////////////////////////////////////////////////////////////////////////
 // nsIRequestObserver
 //////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 ExternalHelperAppChild::OnStartRequest(nsIRequest *request, nsISupports *ctx)
 {
-  // FIXME: Eventually we should implement this:
-  // mHandler->OnStartRequest(request, ctx);
+  nsresult rv = mHandler->OnStartRequest(request, ctx);
+  NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
+
   nsCString entityID;
   nsCOMPtr<nsIResumableChannel> resumable(do_QueryInterface(request));
   if (resumable)
     resumable->GetEntityID(entityID);
   SendOnStartRequest(entityID);
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 ExternalHelperAppChild::OnStopRequest(nsIRequest *request,
                                       nsISupports *ctx,
                                       nsresult status)
 {
-  // FIXME: Eventually we should implement this:
-  // mHandler->OnStopRequest(request, ctx, status);
+  nsresult rv = mHandler->OnStopRequest(request, ctx, status);
   SendOnStopRequest(status);
+
+  NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
   return NS_OK;
 }
 
 
 bool
 ExternalHelperAppChild::RecvCancel(const nsresult& aStatus)
 {
   mStatus = aStatus;
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -714,28 +714,23 @@ NS_IMETHODIMP nsExternalHelperAppService
     pc = child->SendPExternalHelperAppConstructor(IPC::URI(uri),
                                                   nsCString(aMimeContentType),
                                                   disp,
                                                   aForceSave, contentLength);
     ExternalHelperAppChild *childListener = static_cast<ExternalHelperAppChild *>(pc);
 
     NS_ADDREF(*aStreamListener = childListener);
 
-    // FIXME:  Eventually we'll use this original listener to finish up client-side
-    // work, such as closing a no-longer-needed window.  (Bug 588255)
-    // nsExternalAppHandler * handler = new nsExternalAppHandler(nsnull,
-    //                                                           EmptyCString(),
-    //                                                           aWindowContext,
-    //                                                           fileName,
-    //                                                           reason,
-    //                                                           aForceSave);
-    // if (!handler)
-    //   return NS_ERROR_OUT_OF_MEMORY;
-    //
-    // childListener->SetHandler(handler);
+    nsRefPtr<nsExternalAppHandler> handler =
+      new nsExternalAppHandler(nsnull, EmptyCString(), aWindowContext, fileName,
+                               reason, aForceSave);
+    if (!handler)
+      return NS_ERROR_OUT_OF_MEMORY;
+    
+    childListener->SetHandler(handler);
 
     return NS_OK;
   }
 #endif // MOZ_IPC
 
   if (channel) {
     // Check if we have a POST request, in which case we don't want to use
     // the url's extension
@@ -1573,31 +1568,16 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
   }
 
   // Now get the URI
   if (aChannel)
   {
     aChannel->GetURI(getter_AddRefs(mSourceUrl));
   }
 
-  rv = SetUpTempFile(aChannel);
-  if (NS_FAILED(rv)) {
-    mCanceled = PR_TRUE;
-    request->Cancel(rv);
-    nsAutoString path;
-    if (mTempFile)
-      mTempFile->GetPath(path);
-    SendStatusChange(kWriteError, rv, request, path);
-    return NS_OK;
-  }
-
-  // Extract mime type for later use below.
-  nsCAutoString MIMEType;
-  mMimeInfo->GetMIMEType(MIMEType);
-
   // retarget all load notifications to our docloader instead of the original window's docloader...
   RetargetLoadNotifications(request);
 
   // Check to see if there is a refresh header on the original channel.
   if (mOriginalChannel) {
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mOriginalChannel));
     if (httpChannel) {
       nsCAutoString refreshHeader;
@@ -1608,16 +1588,32 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
       }
     }
   }
 
   // Close the underlying DOMWindow if there is no refresh header
   // and it was opened specifically for the download
   MaybeCloseWindow();
 
+  // At this point, the child process has done everything it can usefully do
+  // for OnStartRequest.
+  if (XRE_GetProcessType() == GeckoProcessType_Content)
+     return NS_OK;
+
+  rv = SetUpTempFile(aChannel);
+  if (NS_FAILED(rv)) {
+    mCanceled = PR_TRUE;
+    request->Cancel(rv);
+    nsAutoString path;
+    if (mTempFile)
+      mTempFile->GetPath(path);
+    SendStatusChange(kWriteError, rv, request, path);
+    return NS_OK;
+  }
+
   nsCOMPtr<nsIEncodedChannel> encChannel = do_QueryInterface( aChannel );
   if (encChannel) 
   {
     // Turn off content encoding conversions if needed
     PRBool applyConversion = PR_TRUE;
 
     nsCOMPtr<nsIURL> sourceURL(do_QueryInterface(mSourceUrl));
     if (sourceURL)
@@ -1682,16 +1678,19 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
     NS_ASSERTION(gExtProtSvc, "Service gone away!?");
 
     PRBool mimeTypeIsInDatastore = PR_FALSE;
     nsCOMPtr<nsIHandlerService> handlerSvc = do_GetService(NS_HANDLERSERVICE_CONTRACTID);
     if (handlerSvc)
       handlerSvc->Exists(mMimeInfo, &mimeTypeIsInDatastore);
     if (!handlerSvc || !mimeTypeIsInDatastore)
     {
+      nsCAutoString MIMEType;
+      mMimeInfo->GetMIMEType(MIMEType);
+
       if (!GetNeverAskFlagFromPref(NEVER_ASK_FOR_SAVE_TO_DISK_PREF, MIMEType.get()))
       {
         // Don't need to ask after all.
         alwaysAsk = PR_FALSE;
         // Make sure action matches pref (save to disk).
         mMimeInfo->SetPreferredAction(nsIMIMEInfo::saveToDisk);
       }
       else if (!GetNeverAskFlagFromPref(NEVER_ASK_FOR_OPEN_FILE_PREF, MIMEType.get()))