Bug 1432651 part 1 - Pass the RemotePrintJobChild through from TabChild::RecvPrint to nsPrintJob::DoCommonPrint. r=bobowen
Currently RemotePrintJobChild instances are created in two places, one of
those being under TabChild::RecvPrint. Currently we pass the
RemotePrintJobChild through to nsPrintJob::DoCommonPrint via the
nsIPrintSettings. This patch lays part of the groundwork for disentangling
RemotePrintJobChild from nsPrintSettings by passing it directly and having
nsPrintJob store a strong ref (in its nsPrintData).
MozReview-Commit-ID: 5i4hbvI6qA0
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -7,16 +7,17 @@
#include "base/basictypes.h"
#include "TabChild.h"
#include "gfxPrefs.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/DocAccessibleChild.h"
#endif
+#include "mozilla/layout/RemotePrintJobChild.h"
#include "Layers.h"
#include "ContentChild.h"
#include "TabParent.h"
#include "mozilla/Preferences.h"
#include "mozilla/BrowserElementParent.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
@@ -2510,17 +2511,18 @@ TabChild::RecvPrint(const uint64_t& aOut
nsCOMPtr<nsIPrintSession> printSession =
do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_OK();
}
printSettings->SetPrintSession(printSession);
printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
- rv = webBrowserPrint->Print(printSettings, nullptr);
+ rv = webBrowserPrint->PrintInternal(printSettings, nullptr,
+ static_cast<RemotePrintJobChild*>(aPrintData.remotePrintJobChild()));
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_OK();
}
#endif
return IPC_OK();
}
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2,16 +2,17 @@
/* 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/. */
/* container for a document and its presentation */
#include "gfxContext.h"
+#include "mozilla/layout/RemotePrintJobChild.h"
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/ServoStyleSet.h"
#include "nsAutoPtr.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsReadableUtils.h"
@@ -3865,16 +3866,24 @@ nsDocViewerFocusListener::Init(nsDocumen
*/
#ifdef NS_PRINTING
NS_IMETHODIMP
nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings,
nsIWebProgressListener* aWebProgressListener)
{
+ return PrintInternal(aPrintSettings, aWebProgressListener, nullptr);
+}
+
+NS_IMETHODIMP
+nsDocumentViewer::PrintInternal(nsIPrintSettings* aPrintSettings,
+ nsIWebProgressListener* aWebProgressListener,
+ layout::RemotePrintJobChild* aRemotePrintJob)
+{
// Printing XUL documents is not supported.
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
if (xulDoc) {
return NS_ERROR_FAILURE;
}
if (!mContainer) {
PR_PL(("Container was destroyed yet we are still trying to use it!"));
@@ -3956,17 +3965,17 @@ nsDocumentViewer::Print(nsIPrintSettings
// Postpone the 'afterprint' event until after the mozPrintCallback
// callbacks have been called:
mAutoBeforeAndAfterPrint = autoBeforeAndAfterPrint;
}
dom::Element* root = mDocument->GetRootElement();
if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdisallowselectionprint)) {
printJob->SetDisallowSelectionPrint(true);
}
- rv = printJob->Print(aPrintSettings, aWebProgressListener);
+ rv = printJob->Print(aPrintSettings, aWebProgressListener, aRemotePrintJob);
if (NS_FAILED(rv)) {
OnDonePrinting();
}
return rv;
}
NS_IMETHODIMP
nsDocumentViewer::PrintPreview(nsIPrintSettings* aPrintSettings,
--- a/layout/printing/nsPrintData.h
+++ b/layout/printing/nsPrintData.h
@@ -3,16 +3,17 @@
/* 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/. */
#ifndef nsPrintData_h___
#define nsPrintData_h___
#include "mozilla/Attributes.h"
+#include "mozilla/layout/RemotePrintJobChild.h"
#include "mozilla/UniquePtr.h"
// Interfaces
#include "nsDeviceContext.h"
#include "nsIPrintProgressParams.h"
#include "nsIPrintSettings.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"
@@ -35,16 +36,17 @@ class nsIWebProgressListener;
// to print while a page is still loading. If they start printing and pause
// at the print dialog and then the page comes in, we then abort printing
// because the document is no longer stable.
//
//------------------------------------------------------------------------
class nsPrintData {
public:
typedef enum {eIsPrinting, eIsPrintPreview } ePrintDataType;
+ typedef mozilla::layout::RemotePrintJobChild RemotePrintJobChild;
explicit nsPrintData(ePrintDataType aType);
NS_INLINE_DECL_REFCOUNTING(nsPrintData)
// Listener Helper Methods
void OnEndPrinting();
void OnStartPrinting();
@@ -61,16 +63,18 @@ public:
mozilla::UniquePtr<nsPrintObject> mPrintObject;
nsCOMArray<nsIWebProgressListener> mPrintProgressListeners;
nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams;
nsCOMPtr<nsPIDOMWindowOuter> mCurrentFocusWin; // cache a pointer to the currently focused window
+ RefPtr<RemotePrintJobChild> mRemotePrintJob;
+
// Array of non-owning pointers to all the nsPrintObjects owned by this
// nsPrintData. This includes this->mPrintObject, as well as all of its
// mKids (and their mKids, etc.)
nsTArray<nsPrintObject*> mPrintDocList;
bool mIsIFrameSelected;
bool mIsParentAFrameSet;
bool mOnStartSent;
--- a/layout/printing/nsPrintJob.cpp
+++ b/layout/printing/nsPrintJob.cpp
@@ -620,25 +620,26 @@ static void DumpLayoutData(const char* a
#endif
//--------------------------------------------------------------------------------
nsresult
nsPrintJob::CommonPrint(bool aIsPrintPreview,
nsIPrintSettings* aPrintSettings,
nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob,
nsIDOMDocument* aDoc)
{
// Callers must hold a strong reference to |this| to ensure that we stay
// alive for the duration of this method, because our main owning reference
// (on nsDocumentViewer) might be cleared during this function (if we cause
// script to run and it cancels the print operation).
nsresult rv = DoCommonPrint(aIsPrintPreview, aPrintSettings,
- aWebProgressListener, aDoc);
+ aWebProgressListener, aRemotePrintJob, aDoc);
if (NS_FAILED(rv)) {
if (aIsPrintPreview) {
mIsCreatingPrintPreview = false;
SetIsPrintPreview(false);
} else {
SetIsPrinting(false);
}
if (mProgressDialogIsShown)
@@ -651,16 +652,17 @@ nsPrintJob::CommonPrint(bool
return rv;
}
nsresult
nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
nsIPrintSettings* aPrintSettings,
nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob,
nsIDOMDocument* aDoc)
{
nsresult rv;
if (aIsPrintPreview) {
// The WebProgressListener can be QI'ed to nsIPrintingPromptService
// then that means the progress dialog is already being shown.
nsCOMPtr<nsIPrintingPromptService> pps(do_QueryInterface(aWebProgressListener));
@@ -674,16 +676,18 @@ nsPrintJob::DoCommonPrint(bool
}
// Grab the new instance with local variable to guarantee that it won't be
// deleted during this method.
mPrt = new nsPrintData(aIsPrintPreview ? nsPrintData::eIsPrintPreview :
nsPrintData::eIsPrinting);
RefPtr<nsPrintData> printData = mPrt;
+ printData->mRemotePrintJob = aRemotePrintJob;
+
// if they don't pass in a PrintSettings, then get the Global PS
printData->mPrintSettings = aPrintSettings;
if (!printData->mPrintSettings) {
rv = GetGlobalPrintSettings(getter_AddRefs(printData->mPrintSettings));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = CheckForPrinters(printData->mPrintSettings);
@@ -1027,26 +1031,28 @@ nsPrintJob::DoCommonPrint(bool
scriptSuppressor.Disconnect();
return NS_OK;
}
//---------------------------------------------------------------------------------
NS_IMETHODIMP
nsPrintJob::Print(nsIPrintSettings* aPrintSettings,
- nsIWebProgressListener* aWebProgressListener)
+ nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob)
{
// If we have a print preview document, use that instead of the original
// mDocument. That way animated images etc. get printed using the same state
// as in print preview.
nsCOMPtr<nsIDOMDocument> doc =
do_QueryInterface(mPrtPreview && mPrtPreview->mPrintObject ?
mPrtPreview->mPrintObject->mDocument : mDocument);
- return CommonPrint(false, aPrintSettings, aWebProgressListener, doc);
+ return CommonPrint(false, aPrintSettings, aWebProgressListener,
+ aRemotePrintJob, doc);
}
NS_IMETHODIMP
nsPrintJob::PrintPreview(nsIPrintSettings* aPrintSettings,
mozIDOMWindowProxy* aChildDOMWin,
nsIWebProgressListener* aWebProgressListener)
{
// Get the DocShell and see if it is busy
@@ -1065,17 +1071,18 @@ nsPrintJob::PrintPreview(nsIPrintSetting
auto* window = nsPIDOMWindowOuter::From(aChildDOMWin);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDocument> doc = window->GetDoc();
NS_ENSURE_STATE(doc);
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
MOZ_ASSERT(domDoc);
// Document is not busy -- go ahead with the Print Preview
- return CommonPrint(true, aPrintSettings, aWebProgressListener, domDoc);
+ return CommonPrint(true, aPrintSettings, aWebProgressListener,
+ /*aRemotePrintJob*/ nullptr, domDoc);
}
//----------------------------------------------------------------------------------
NS_IMETHODIMP
nsPrintJob::GetIsFramesetDocument(bool* aIsFramesetDocument)
{
nsCOMPtr<nsIDocShell> webContainer(do_QueryReferent(mContainer));
*aIsFramesetDocument = IsParentAFrameSet(webContainer);
--- a/layout/printing/nsPrintJob.h
+++ b/layout/printing/nsPrintJob.h
@@ -27,41 +27,50 @@
class nsPagePrintTimer;
class nsIDocShell;
class nsIDocument;
class nsIDocumentViewerPrint;
class nsPrintObject;
class nsIDocShell;
class nsIPageSequenceFrame;
+namespace mozilla {
+namespace layout {
+class RemotePrintJobChild;
+}
+}
+
/**
* A print job may be instantiated either for printing to an actual physical
* printer, or for creating a print preview.
*/
class nsPrintJob final : public nsIObserver
, public nsIWebProgressListener
, public nsSupportsWeakReference
{
public:
+ typedef mozilla::layout::RemotePrintJobChild RemotePrintJobChild;
+
static nsresult GetGlobalPrintSettings(nsIPrintSettings** aPrintSettings);
static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
nsPrintJob() = default;
// nsISupports interface...
NS_DECL_ISUPPORTS
// nsIObserver
NS_DECL_NSIOBSERVER
NS_DECL_NSIWEBPROGRESSLISTENER
// Old nsIWebBrowserPrint methods; not cleaned up yet
NS_IMETHOD Print(nsIPrintSettings* aPrintSettings,
- nsIWebProgressListener* aWebProgressListener);
+ nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob);
NS_IMETHOD PrintPreview(nsIPrintSettings* aPrintSettings,
mozIDOMWindowProxy* aChildDOMWin,
nsIWebProgressListener* aWebProgressListener);
NS_IMETHOD GetIsFramesetDocument(bool *aIsFramesetDocument);
NS_IMETHOD GetIsIFrameSelected(bool *aIsIFrameSelected);
NS_IMETHOD GetIsRangeSelection(bool *aIsRangeSelection);
NS_IMETHOD GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected);
NS_IMETHOD GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages);
@@ -191,20 +200,22 @@ public:
private:
nsPrintJob& operator=(const nsPrintJob& aOther) = delete;
~nsPrintJob();
nsresult CommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob,
nsIDOMDocument* aDoc);
nsresult DoCommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
nsIWebProgressListener* aWebProgressListener,
+ RemotePrintJobChild* aRemotePrintJob,
nsIDOMDocument* aDoc);
void FirePrintCompletionEvent();
void DisconnectPagePrintTimer();
nsresult AfterNetworkPrint(bool aHandleError);
--- a/toolkit/components/browser/nsIWebBrowserPrint.idl
+++ b/toolkit/components/browser/nsIWebBrowserPrint.idl
@@ -1,16 +1,26 @@
/* -*- Mode: IDL; tab-width: 4; 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 "nsISupports.idl"
+%{ C++
+namespace mozilla {
+namespace layout {
+class RemotePrintJobChild;
+}
+}
+%}
+
+[ptr] native RemotePrintJobChildPtr(mozilla::layout::RemotePrintJobChild);
+
interface mozIDOMWindowProxy;
interface nsIPrintSettings;
interface nsIWebProgressListener;
/**
* nsIWebBrowserPrint corresponds to the main interface
* for printing an embedded Gecko web browser window/document
*/
@@ -87,16 +97,29 @@ interface nsIWebBrowserPrint : nsISuppor
* then the global PS will be used.
* @param aWPListener - is updated during the print
* @return void
*/
void print(in nsIPrintSettings aThePrintSettings,
in nsIWebProgressListener aWPListener);
/**
+ * The same as print(), but only callable from native code, and with an
+ * additional parameter to pass in a RemotePrintJobChild if the caller
+ * already has one.
+ *
+ * @param aRemotePrintJob - A RemotePrintJobChild. Must not be null when
+ * called from the parent process and printing via the parent is
+ * enabled.
+ */
+ [noscript] void printInternal(in nsIPrintSettings aThePrintSettings,
+ in nsIWebProgressListener aWPListener,
+ in RemotePrintJobChildPtr aRemotePrintJob);
+
+ /**
* Print Preview the specified DOM window
*
* @param aThePrintSettings - Printer Settings for the print preview, if aThePrintSettings is null
* then the global PS will be used.
* @param aChildDOMWin - DOM Window to be print previewed.
* @param aWPListener - is updated during the printpreview
* @return void
*/
--- a/toolkit/components/printingui/ipc/PrintDataUtils.cpp
+++ b/toolkit/components/printingui/ipc/PrintDataUtils.cpp
@@ -91,16 +91,24 @@ MockWebBrowserPrint::GetPrintPreviewNumP
NS_IMETHODIMP
MockWebBrowserPrint::Print(nsIPrintSettings* aThePrintSettings,
nsIWebProgressListener* aWPListener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
+MockWebBrowserPrint::PrintInternal(nsIPrintSettings* aThePrintSettings,
+ nsIWebProgressListener* aWPListener,
+ layout::RemotePrintJobChild* aRemoteJob)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
MockWebBrowserPrint::PrintPreview(nsIPrintSettings* aThePrintSettings,
mozIDOMWindowProxy* aChildDOMWin,
nsIWebProgressListener* aWPListener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP