1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/printing/nsPagePrintTimer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,180 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsPagePrintTimer.h" 1.10 +#include "nsIContentViewer.h" 1.11 +#include "nsIServiceManager.h" 1.12 +#include "nsPrintEngine.h" 1.13 + 1.14 +NS_IMPL_ISUPPORTS_INHERITED(nsPagePrintTimer, nsRunnable, nsITimerCallback) 1.15 + 1.16 +nsPagePrintTimer::~nsPagePrintTimer() 1.17 +{ 1.18 + // "Destroy" the document viewer; this normally doesn't actually 1.19 + // destroy it because of the IncrementDestroyRefCount call below 1.20 + // XXX This is messy; the document viewer should use a single approach 1.21 + // to keep itself alive during printing 1.22 + nsCOMPtr<nsIContentViewer> cv(do_QueryInterface(mDocViewerPrint)); 1.23 + if (cv) { 1.24 + cv->Destroy(); 1.25 + } 1.26 +} 1.27 + 1.28 +nsresult 1.29 +nsPagePrintTimer::StartTimer(bool aUseDelay) 1.30 +{ 1.31 + nsresult result; 1.32 + mTimer = do_CreateInstance("@mozilla.org/timer;1", &result); 1.33 + if (NS_FAILED(result)) { 1.34 + NS_WARNING("unable to start the timer"); 1.35 + } else { 1.36 + uint32_t delay = 0; 1.37 + if (aUseDelay) { 1.38 + if (mFiringCount < 10) { 1.39 + // Longer delay for the few first pages. 1.40 + delay = mDelay + ((10 - mFiringCount) * 100); 1.41 + } else { 1.42 + delay = mDelay; 1.43 + } 1.44 + } 1.45 + mTimer->InitWithCallback(this, delay, nsITimer::TYPE_ONE_SHOT); 1.46 + } 1.47 + return result; 1.48 +} 1.49 + 1.50 +nsresult 1.51 +nsPagePrintTimer::StartWatchDogTimer() 1.52 +{ 1.53 + nsresult result; 1.54 + if (mWatchDogTimer) { 1.55 + mWatchDogTimer->Cancel(); 1.56 + } 1.57 + mWatchDogTimer = do_CreateInstance("@mozilla.org/timer;1", &result); 1.58 + if (NS_FAILED(result)) { 1.59 + NS_WARNING("unable to start the timer"); 1.60 + } else { 1.61 + // Instead of just doing one timer for a long period do multiple so we 1.62 + // can check if the user cancelled the printing. 1.63 + mWatchDogTimer->InitWithCallback(this, WATCH_DOG_INTERVAL, 1.64 + nsITimer::TYPE_ONE_SHOT); 1.65 + } 1.66 + return result; 1.67 +} 1.68 + 1.69 +void 1.70 +nsPagePrintTimer::StopWatchDogTimer() 1.71 +{ 1.72 + if (mWatchDogTimer) { 1.73 + mWatchDogTimer->Cancel(); 1.74 + mWatchDogTimer = nullptr; 1.75 + } 1.76 +} 1.77 + 1.78 +//nsRunnable 1.79 +NS_IMETHODIMP 1.80 +nsPagePrintTimer::Run() 1.81 +{ 1.82 + bool initNewTimer = true; 1.83 + // Check to see if we are done 1.84 + // inRange will be true if a page is actually printed 1.85 + bool inRange; 1.86 + bool donePrinting; 1.87 + 1.88 + // donePrinting will be true if it completed successfully or 1.89 + // if the printing was cancelled 1.90 + donePrinting = mPrintEngine->PrintPage(mPrintObj, inRange); 1.91 + if (donePrinting) { 1.92 + // now clean up print or print the next webshell 1.93 + if (mPrintEngine->DonePrintingPages(mPrintObj, NS_OK)) { 1.94 + initNewTimer = false; 1.95 + mDone = true; 1.96 + } 1.97 + } 1.98 + 1.99 + // Note that the Stop() destroys this after the print job finishes 1.100 + // (The PrintEngine stops holding a reference when DonePrintingPages 1.101 + // returns true.) 1.102 + Stop(); 1.103 + if (initNewTimer) { 1.104 + ++mFiringCount; 1.105 + nsresult result = StartTimer(inRange); 1.106 + if (NS_FAILED(result)) { 1.107 + mDone = true; // had a failure.. we are finished.. 1.108 + mPrintEngine->SetIsPrinting(false); 1.109 + } 1.110 + } 1.111 + return NS_OK; 1.112 +} 1.113 + 1.114 +// nsITimerCallback 1.115 +NS_IMETHODIMP 1.116 +nsPagePrintTimer::Notify(nsITimer *timer) 1.117 +{ 1.118 + // When finished there may be still pending notifications, which we can just 1.119 + // ignore. 1.120 + if (mDone) { 1.121 + return NS_OK; 1.122 + } 1.123 + 1.124 + // There are three things that call Notify with different values for timer: 1.125 + // 1) the delay between pages (timer == mTimer) 1.126 + // 2) canvasPrintState done (timer == null) 1.127 + // 3) the watch dog timer (timer == mWatchDogTimer) 1.128 + if (timer && timer == mWatchDogTimer) { 1.129 + mWatchDogCount++; 1.130 + if (mWatchDogCount > WATCH_DOG_MAX_COUNT) { 1.131 + Fail(); 1.132 + return NS_OK; 1.133 + } 1.134 + } else if(!timer) { 1.135 + // Reset the counter since a mozPrintCallback has finished. 1.136 + mWatchDogCount = 0; 1.137 + } 1.138 + 1.139 + if (mDocViewerPrint) { 1.140 + bool donePrePrint = mPrintEngine->PrePrintPage(); 1.141 + 1.142 + if (donePrePrint) { 1.143 + StopWatchDogTimer(); 1.144 + NS_DispatchToMainThread(this); 1.145 + } else { 1.146 + // Start the watch dog if we're waiting for preprint to ensure that if any 1.147 + // mozPrintCallbacks take to long we error out. 1.148 + StartWatchDogTimer(); 1.149 + } 1.150 + 1.151 + } 1.152 + return NS_OK; 1.153 +} 1.154 + 1.155 +nsresult 1.156 +nsPagePrintTimer::Start(nsPrintObject* aPO) 1.157 +{ 1.158 + mPrintObj = aPO; 1.159 + mWatchDogCount = 0; 1.160 + mDone = false; 1.161 + return StartTimer(false); 1.162 +} 1.163 + 1.164 + 1.165 +void 1.166 +nsPagePrintTimer::Stop() 1.167 +{ 1.168 + if (mTimer) { 1.169 + mTimer->Cancel(); 1.170 + mTimer = nullptr; 1.171 + } 1.172 + StopWatchDogTimer(); 1.173 +} 1.174 + 1.175 +void 1.176 +nsPagePrintTimer::Fail() 1.177 +{ 1.178 + mDone = true; 1.179 + Stop(); 1.180 + if (mPrintEngine) { 1.181 + mPrintEngine->CleanupOnFailure(NS_OK, false); 1.182 + } 1.183 +}