Bug 1156742 Part 10: Allow RemotePrintJob to influence nsPagePrintTimer. r=roc
☠☠ backed out by 9bdfae920430 ☠ ☠
authorBob Owen <bobowencode@gmail.com>
Mon, 21 Dec 2015 20:33:13 +0000
changeset 277222 5fe429ee880c8b5626ea89306b94068173b6d203
parent 277221 dedca8fb19b04dc66928bf97f2db6dbdc39253b4
child 277223 dd52947f73c624f99e4838e0a26779d7ae074a61
push id29819
push usercbook@mozilla.com
push dateTue, 22 Dec 2015 10:47:17 +0000
treeherdermozilla-central@ad16863d1d45 [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)