Bug 1156742 Part 10: Allow RemotePrintJob to influence nsPagePrintTimer. r=roc
authorBob Owen <bobowencode@gmail.com>
Tue, 05 Jan 2016 10:08:57 +0000
changeset 278498 e42b8b6de581f8ca772c30a588e54e31a1e88347
parent 278497 f9f91b619a87c5c7142a396b62a5f90145fb3811
child 278499 5167c1c18e405265666d670082789156b50d9cb4
push id29852
push userkwierso@gmail.com
push dateWed, 06 Jan 2016 00:03:27 +0000
treeherdermozilla-central@dd6d447fc6e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1156742
milestone46.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 1156742 Part 10: Allow RemotePrintJob to influence nsPagePrintTimer. r=roc Adds a new timer for the RemotePrintJob to notify the nsPagePrintTimer when the last page has finished printing in the parent. Changed the page delay timer to reset the watch dog count on every page to prevent timeouts due to remote printing.
layout/printing/ipc/RemotePrintJobChild.cpp
layout/printing/ipc/RemotePrintJobChild.h
layout/printing/nsPagePrintTimer.cpp
layout/printing/nsPagePrintTimer.h
layout/printing/nsPrintEngine.cpp
--- a/layout/printing/ipc/RemotePrintJobChild.cpp
+++ b/layout/printing/ipc/RemotePrintJobChild.cpp
@@ -2,50 +2,64 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RemotePrintJobChild.h"
 
 #include "mozilla/unused.h"
+#include "nsPagePrintTimer.h"
 
 namespace mozilla {
 namespace layout {
 
 RemotePrintJobChild::RemotePrintJobChild()
 {
   MOZ_COUNT_CTOR(RemotePrintJobChild);
 }
 
 bool
 RemotePrintJobChild::RecvPageProcessed()
 {
-  NS_NOTREACHED("RemotePrintJobChild::RecvPageProcessed not implemented!");
-  return false;
+  MOZ_ASSERT(mPagePrintTimer);
+
+  mPagePrintTimer->RemotePrintFinished();
+  return true;
 }
 
 bool
 RemotePrintJobChild::RecvAbortPrint(const nsresult& aRv)
 {
   NS_NOTREACHED("RemotePrintJobChild::RecvAbortPrint not implemented!");
   return false;
 }
+
 void
 RemotePrintJobChild::ProcessPage(Shmem& aStoredPage)
 {
+  MOZ_ASSERT(mPagePrintTimer);
+
+  mPagePrintTimer->WaitForRemotePrint();
   Unused << SendProcessPage(aStoredPage);
 }
 
+void
+RemotePrintJobChild::SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer)
+{
+  MOZ_ASSERT(aPagePrintTimer);
+
+  mPagePrintTimer = aPagePrintTimer;
+}
+
 RemotePrintJobChild::~RemotePrintJobChild()
 {
   MOZ_COUNT_DTOR(RemotePrintJobChild);
 }
 
 void
 RemotePrintJobChild::ActorDestroy(ActorDestroyReason aWhy)
 {
+  mPagePrintTimer = nullptr;
 }
 
 } // namespace layout
 } // namespace mozilla
-
-
--- a/layout/printing/ipc/RemotePrintJobChild.h
+++ b/layout/printing/ipc/RemotePrintJobChild.h
@@ -6,16 +6,18 @@
 
 #ifndef mozilla_layout_RemotePrintJobChild_h
 #define mozilla_layout_RemotePrintJobChild_h
 
 #include "mozilla/layout/PRemotePrintJobChild.h"
 
 #include "mozilla/RefPtr.h"
 
+class nsPagePrintTimer;
+
 namespace mozilla {
 namespace layout {
 
 class RemotePrintJobChild final : public PRemotePrintJobChild
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(RemotePrintJobChild)
 
@@ -24,16 +26,20 @@ public:
   void ActorDestroy(ActorDestroyReason aWhy) final;
 
   bool RecvPageProcessed() final;
 
   bool RecvAbortPrint(const nsresult& aRv) final;
 
   void ProcessPage(Shmem& aStoredPage);
 
+  void SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer);
+
 private:
   ~RemotePrintJobChild() final;
+
+  RefPtr<nsPagePrintTimer> mPagePrintTimer;
 };
 
 } // namespace layout
 } // namespace mozilla
 
 #endif // mozilla_layout_RemotePrintJobChild_h
--- a/layout/printing/nsPagePrintTimer.cpp
+++ b/layout/printing/nsPagePrintTimer.cpp
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsPagePrintTimer.h"
+
+#include "mozilla/unused.h"
 #include "nsIContentViewer.h"
 #include "nsIServiceManager.h"
 #include "nsPrintEngine.h"
 
 NS_IMPL_ISUPPORTS_INHERITED(nsPagePrintTimer, nsRunnable, nsITimerCallback)
 
 nsPagePrintTimer::~nsPagePrintTimer()
 {
@@ -113,52 +115,87 @@ NS_IMETHODIMP
 nsPagePrintTimer::Notify(nsITimer *timer)
 {
   // When finished there may be still pending notifications, which we can just
   // ignore.
   if (mDone) {
     return NS_OK;
   }
 
-  // There are three things that call Notify with different values for timer:
+  // There are four things that call Notify with different values for timer:
   // 1) the delay between pages (timer == mTimer)
   // 2) canvasPrintState done (timer == null)
   // 3) the watch dog timer (timer == mWatchDogTimer)
-  if (timer && timer == mWatchDogTimer) {
+  // 4) the waiting for remote print "timer" (timer == mWaitingForRemotePrint)
+  if (!timer) {
+    // Reset the counter since a mozPrintCallback has finished.
+    mWatchDogCount = 0;
+  } else if (timer == mTimer) {
+    // Reset the watchdog timer before the start of every page.
+    mWatchDogCount = 0;
+    mTimer = nullptr;
+  } else if (timer == mWaitingForRemotePrint) {
+    mWaitingForRemotePrint = nullptr;
+
+    // If we are still waiting for the page delay timer, don't let the
+    // notification from the remote print job trigger the next page.
+    if (mTimer) {
+      return NS_OK;
+    }
+  } else if (timer == mWatchDogTimer) {
     mWatchDogCount++;
     if (mWatchDogCount > WATCH_DOG_MAX_COUNT) {
       Fail();
       return NS_OK;
     }
-  } else if(!timer) {
-    // Reset the counter since a mozPrintCallback has finished.
-    mWatchDogCount = 0;
   }
 
   if (mDocViewerPrint) {
     bool donePrePrint = mPrintEngine->PrePrintPage();
 
-    if (donePrePrint) {
+    if (donePrePrint && !mWaitingForRemotePrint) {
       StopWatchDogTimer();
       NS_DispatchToMainThread(this);
     } else {
       // Start the watch dog if we're waiting for preprint to ensure that if any
       // mozPrintCallbacks take to long we error out.
       StartWatchDogTimer();
     }
 
   }
   return NS_OK;
 }
 
+
+void
+nsPagePrintTimer::WaitForRemotePrint()
+{
+  nsresult result;
+  mWaitingForRemotePrint = do_CreateInstance("@mozilla.org/timer;1", &result);
+  if (NS_FAILED(result)) {
+    NS_WARNING("Failed to wait for remote print, we might time-out.");
+    mWaitingForRemotePrint = nullptr;
+  }
+}
+
+void
+nsPagePrintTimer::RemotePrintFinished()
+{
+  if (!mWaitingForRemotePrint) {
+    return;
+  }
+
+  mozilla::Unused <<
+    mWaitingForRemotePrint->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT);
+}
+
 nsresult 
 nsPagePrintTimer::Start(nsPrintObject* aPO)
 {
   mPrintObj = aPO;
-  mWatchDogCount = 0;
   mDone = false;
   return StartTimer(false);
 }
 
 
 void  
 nsPagePrintTimer::Stop()
 {
--- a/layout/printing/nsPagePrintTimer.h
+++ b/layout/printing/nsPagePrintTimer.h
@@ -42,28 +42,32 @@ public:
   NS_DECL_NSITIMERCALLBACK
 
   nsresult Start(nsPrintObject* aPO);
 
   NS_IMETHOD Run() override;
 
   void Stop();
 
+  void WaitForRemotePrint();
+  void RemotePrintFinished();
+
 private:
   ~nsPagePrintTimer();
 
   nsresult StartTimer(bool aUseDelay);
   nsresult StartWatchDogTimer();
   void     StopWatchDogTimer();
   void     Fail();
 
   nsPrintEngine*             mPrintEngine;
   nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
   nsCOMPtr<nsITimer>         mTimer;
   nsCOMPtr<nsITimer>         mWatchDogTimer;
+  nsCOMPtr<nsITimer>         mWaitingForRemotePrint;
   uint32_t                   mDelay;
   uint32_t                   mFiringCount;
   nsPrintObject *            mPrintObj;
   uint32_t                   mWatchDogCount;
   bool                       mDone;
 
   static const uint32_t WATCH_DOG_INTERVAL  = 1000;
   static const uint32_t WATCH_DOG_MAX_COUNT = 10;
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -70,16 +70,17 @@ static const char kPrintingPromptService
 
 // FrameSet
 #include "nsIDocument.h"
 
 // Focus
 #include "nsISelectionController.h"
 
 // Misc
+#include "mozilla/layout/RemotePrintJobChild.h"
 #include "nsISupportsUtils.h"
 #include "nsIScriptContext.h"
 #include "nsIDOMDocument.h"
 #include "nsISelectionListener.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMRange.h"
 #include "nsContentCID.h"
 #include "nsLayoutCID.h"
@@ -3477,16 +3478,26 @@ nsPrintEngine::StartPagePrintTimer(nsPri
     // Get the delay time in between the printing of each page
     // this gives the user more time to press cancel
     int32_t printPageDelay = 50;
     mPrt->mPrintSettings->GetPrintPageDelay(&printPageDelay);
 
     RefPtr<nsPagePrintTimer> timer =
       new nsPagePrintTimer(this, mDocViewerPrint, printPageDelay);
     timer.forget(&mPagePrintTimer);
+
+    nsCOMPtr<nsIPrintSession> printSession;
+    nsresult rv = mPrt->mPrintSettings->GetPrintSession(getter_AddRefs(printSession));
+    if (NS_SUCCEEDED(rv) && printSession) {
+      RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
+      printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
+      if (NS_SUCCEEDED(rv) && remotePrintJob) {
+        remotePrintJob->SetPagePrintTimer(mPagePrintTimer);
+      }
+    }
   }
 
   return mPagePrintTimer->Start(aPO);
 }
 
 /*=============== nsIObserver Interface ======================*/
 NS_IMETHODIMP 
 nsPrintEngine::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData)