Bug 1441598: Don't try and send messages to PrintProgressDialogChild when printing is complete. r=jwatt
authorBob Owen <bobowencode@gmail.com>
Mon, 05 Mar 2018 08:22:14 +0000
changeset 406545 b47e9371891215b7f5bb5e7ec26485f51b4e477c
parent 406544 ed9129a6115596564bffe8b855ef014d42eec646
child 406546 0036938db4fe34793e96184998e5df543a6a4fec
push id33570
push usercsabou@mozilla.com
push dateMon, 05 Mar 2018 18:12:27 +0000
treeherdermozilla-central@0ef34a9ec4fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1441598
milestone60.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 1441598: Don't try and send messages to PrintProgressDialogChild when printing is complete. r=jwatt
layout/printing/nsPrintJob.cpp
toolkit/components/printing/content/printUtils.js
toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp
toolkit/components/printingui/nsPrintProgress.cpp
--- a/layout/printing/nsPrintJob.cpp
+++ b/layout/printing/nsPrintJob.cpp
@@ -3517,26 +3517,28 @@ nsPrintJob::StartPagePrintTimer(const Un
 
   return mPagePrintTimer->Start(aPO.get());
 }
 
 /*=============== nsIObserver Interface ======================*/
 NS_IMETHODIMP
 nsPrintJob::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-
-  rv = InitPrintDocConstruction(true);
+  // Only process a null topic which means the progress dialog is open.
+  if (aTopic) {
+    return NS_OK;
+  }
+
+  nsresult rv = InitPrintDocConstruction(true);
   if (!mIsDoingPrinting && mPrtPreview) {
     RefPtr<nsPrintData> printDataOfPrintPreview = mPrtPreview;
     printDataOfPrintPreview->OnEndPrinting();
   }
 
   return rv;
-
 }
 
 //---------------------------------------------------------------
 //-- PLEvent Notification
 //---------------------------------------------------------------
 class nsPrintCompletionEvent : public Runnable {
 public:
   explicit nsPrintCompletionEvent(nsIDocumentViewerPrint* docViewerPrint)
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -385,16 +385,21 @@ var PrintUtils = {
     }
     return printSettings;
   },
 
   // This observer is called once the progress dialog has been "opened"
   _obsPP:
   {
     observe(aSubject, aTopic, aData) {
+      // Only process a null topic which means the progress dialog is open.
+      if (aTopic) {
+        return;
+      }
+
       // delay the print preview to show the content of the progress dialog
       setTimeout(function() { PrintUtils.enterPrintPreview(); }, 0);
     },
 
     QueryInterface(iid) {
       if (iid.equals(Ci.nsIObserver) ||
           iid.equals(Ci.nsISupportsWeakReference) ||
           iid.equals(Ci.nsISupports))
--- a/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp
+++ b/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp
@@ -94,18 +94,23 @@ PrintProgressDialogParent::Recv__delete_
 }
 
 // nsIObserver
 NS_IMETHODIMP
 PrintProgressDialogParent::Observe(nsISupports *aSubject, const char *aTopic,
                                    const char16_t *aData)
 {
   if (mActive) {
-    if (aTopic && !strcmp(aTopic, "cancelled")) {
-      Unused << SendCancelledCurrentJob();
+    if (aTopic) {
+      if (!strcmp(aTopic, "cancelled")) {
+        Unused << SendCancelledCurrentJob();
+      } else if (!strcmp(aTopic, "completed")) {
+        // Once printing is complete don't send any messages to the child.
+        mActive = false;
+      }
     } else {
       Unused << SendDialogOpened();
     }
   } else {
     NS_WARNING("The print progress dialog finished opening, but communications "
                "with the child have been closed.");
   }
 
--- a/toolkit/components/printingui/nsPrintProgress.cpp
+++ b/toolkit/components/printingui/nsPrintProgress.cpp
@@ -175,32 +175,48 @@ NS_IMETHODIMP nsPrintProgress::DoneIniti
   if (m_observer) {
     m_observer->Observe(nullptr, nullptr, nullptr);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
 {
+  if (XRE_IsE10sParentProcess() &&
+      aStateFlags & nsIWebProgressListener::STATE_STOP) {
+    // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
+    // so we let it know that printing has completed, because it might mean that
+    // its PrintProgressDialogChild has already been deleted.
+    m_observer->Observe(nullptr, "completed", nullptr);
+  }
+
   m_pendingStateFlags = aStateFlags;
   m_pendingStateValue = aStatus;
 
   uint32_t count = m_listenerList.Count();
   for (uint32_t i = count - 1; i < count; i --)
   {
     nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
     if (progressListener)
       progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
 {
+  if (XRE_IsE10sParentProcess() && aCurSelfProgress &&
+      aCurSelfProgress >= aMaxSelfProgress) {
+    // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
+    // so we let it know that printing has completed, because it might mean that
+    // its PrintProgressDialogChild has already been deleted.
+    m_observer->Observe(nullptr, "completed", nullptr);
+  }
+
   uint32_t count = m_listenerList.Count();
   for (uint32_t i = count - 1; i < count; i --)
   {
     nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
     if (progressListener)
       progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
   }