LCOV - code coverage report
Current view: top level - toolkit/components/printingui/ipc - PrintingParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 4 143 2.8 %
Date: 2017-07-14 16:53:18 Functions: 1 16 6.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/Element.h"
       8             : #include "mozilla/dom/TabParent.h"
       9             : #include "mozilla/Preferences.h"
      10             : #include "mozilla/Unused.h"
      11             : #include "nsIContent.h"
      12             : #include "nsIDocument.h"
      13             : #include "nsIDOMWindow.h"
      14             : #include "nsIPrintingPromptService.h"
      15             : #include "nsIPrintProgressParams.h"
      16             : #include "nsIPrintSettingsService.h"
      17             : #include "nsIServiceManager.h"
      18             : #include "nsServiceManagerUtils.h"
      19             : #include "nsIWebProgressListener.h"
      20             : #include "PrintingParent.h"
      21             : #include "PrintDataUtils.h"
      22             : #include "PrintProgressDialogParent.h"
      23             : #include "PrintSettingsDialogParent.h"
      24             : #include "mozilla/layout/RemotePrintJobParent.h"
      25             : 
      26             : using namespace mozilla;
      27             : using namespace mozilla::dom;
      28             : using namespace mozilla::layout;
      29             : 
      30             : namespace mozilla {
      31             : namespace embedding {
      32             : mozilla::ipc::IPCResult
      33           0 : PrintingParent::RecvShowProgress(PBrowserParent* parent,
      34             :                                  PPrintProgressDialogParent* printProgressDialog,
      35             :                                  PRemotePrintJobParent* remotePrintJob,
      36             :                                  const bool& isForPrinting)
      37             : {
      38           0 :   bool notifyOnOpen = false;
      39             : 
      40           0 :   nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent);
      41           0 :   nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
      42             : 
      43             :   PrintProgressDialogParent* dialogParent =
      44           0 :     static_cast<PrintProgressDialogParent*>(printProgressDialog);
      45           0 :   nsCOMPtr<nsIObserver> observer = do_QueryInterface(dialogParent);
      46             : 
      47           0 :   nsCOMPtr<nsIWebProgressListener> printProgressListener;
      48           0 :   nsCOMPtr<nsIPrintProgressParams> printProgressParams;
      49             : 
      50           0 :   nsresult rv = NS_ERROR_INVALID_ARG;
      51           0 :   if (parentWin && pps) {
      52           0 :     rv = pps->ShowProgress(parentWin, nullptr, nullptr, observer,
      53           0 :                            isForPrinting,
      54           0 :                            getter_AddRefs(printProgressListener),
      55           0 :                            getter_AddRefs(printProgressParams),
      56           0 :                            &notifyOnOpen);
      57             :   }
      58             : 
      59           0 :   if (NS_SUCCEEDED(rv)) {
      60           0 :     if (remotePrintJob) {
      61             :       // If we have a RemotePrintJob use that as a more general forwarder for
      62             :       // print progress listeners.
      63             :       static_cast<RemotePrintJobParent*>(remotePrintJob)
      64           0 :           ->RegisterListener(printProgressListener);
      65             :     } else {
      66           0 :       dialogParent->SetWebProgressListener(printProgressListener);
      67             :     }
      68             : 
      69           0 :     dialogParent->SetPrintProgressParams(printProgressParams);
      70             :   }
      71             : 
      72             :   // NOTE: If we aren't going to observe an event on our observer, we need to
      73             :   // fake one. This takes the form of sending the SendDialogOpened message. This
      74             :   // is safe because the child process proxy will always return `true` for
      75             :   // notifyOnOpen, as the request will always be async when performed across
      76             :   // process boundaries.
      77             :   //
      78             :   // We can pass nullptr for all of the arguments, as all consumers of this
      79             :   // observer don't care about the subject, topic, or data.
      80             :   //
      81             :   // If notifyOnOpen is true, then the ShowProgress call will handle notifying
      82             :   // our observer for us.
      83           0 :   if (!notifyOnOpen) {
      84           0 :     observer->Observe(nullptr, nullptr, nullptr);
      85             :   }
      86           0 :   return IPC_OK();
      87             : }
      88             : 
      89             : nsresult
      90           0 : PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
      91             :                                 const PrintData& aData,
      92             :                                 PrintData* aResult)
      93             : {
      94             :   // If aParent is null this call is just being used to get print settings from
      95             :   // the printer for print preview.
      96           0 :   bool isPrintPreview = !aParent;
      97           0 :   nsCOMPtr<nsPIDOMWindowOuter> parentWin;
      98           0 :   if (aParent) {
      99           0 :     parentWin = DOMWindowFromBrowserParent(aParent);
     100           0 :     if (!parentWin) {
     101           0 :       return NS_ERROR_FAILURE;
     102             :     }
     103             :   }
     104             : 
     105           0 :   nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
     106           0 :   if (!pps) {
     107           0 :     return NS_ERROR_FAILURE;
     108             :   }
     109             : 
     110             :   // The initSettings we got can be wrapped using
     111             :   // PrintDataUtils' MockWebBrowserPrint, which implements enough of
     112             :   // nsIWebBrowserPrint to keep the dialogs happy.
     113           0 :   nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
     114             : 
     115             :   // Use the existing RemotePrintJob and its settings, if we have one, to make
     116             :   // sure they stay current.
     117             :   RemotePrintJobParent* remotePrintJob =
     118           0 :     static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent());
     119           0 :   nsCOMPtr<nsIPrintSettings> settings;
     120             :   nsresult rv;
     121           0 :   if (remotePrintJob) {
     122           0 :     settings = remotePrintJob->GetPrintSettings();
     123             :   } else {
     124           0 :     rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
     125           0 :     NS_ENSURE_SUCCESS(rv, rv);
     126             :   }
     127             : 
     128             :   // We only want to use the print silently setting from the parent.
     129             :   bool printSilently;
     130           0 :   rv = settings->GetPrintSilent(&printSilently);
     131           0 :   NS_ENSURE_SUCCESS(rv, rv);
     132             : 
     133           0 :   rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
     134           0 :   NS_ENSURE_SUCCESS(rv, rv);
     135             : 
     136           0 :   rv = settings->SetPrintSilent(printSilently);
     137           0 :   NS_ENSURE_SUCCESS(rv, rv);
     138             : 
     139           0 :   nsXPIDLString printerName;
     140           0 :   settings->GetPrinterName(getter_Copies(printerName));
     141             : #ifdef MOZ_X11
     142             :   // Requesting the default printer name on Linux has been removed in the child,
     143             :   // because it was causing a sandbox violation (see Bug 1329216).
     144             :   // If no printer name is set at this point, use the print settings service
     145             :   // to get the default printer name.
     146           0 :   if (printerName.IsEmpty()) {
     147           0 :     mPrintSettingsSvc->GetDefaultPrinterName(getter_Copies(printerName));
     148           0 :     settings->SetPrinterName(printerName);
     149             :   }
     150           0 :   mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
     151             : #endif
     152             : 
     153             :   // If this is for print preview or we are printing silently then we just need
     154             :   // to initialize the print settings with anything specific from the printer.
     155           0 :   if (isPrintPreview || printSilently ||
     156           0 :       Preferences::GetBool("print.always_print_silent", printSilently)) {
     157           0 :     settings->SetIsInitializedFromPrinter(false);
     158           0 :     mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
     159             :   } else {
     160           0 :     rv = pps->ShowPrintDialog(parentWin, wbp, settings);
     161           0 :     NS_ENSURE_SUCCESS(rv, rv);
     162             :   }
     163             : 
     164           0 :   if (isPrintPreview) {
     165             :     // For print preview we don't want a RemotePrintJob just the settings.
     166           0 :     rv = mPrintSettingsSvc->SerializeToPrintData(settings, nullptr, aResult);
     167             :   } else {
     168           0 :     rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
     169           0 :                                           aResult);
     170             :   }
     171             : 
     172           0 :   return rv;
     173             : }
     174             : 
     175             : mozilla::ipc::IPCResult
     176           0 : PrintingParent::RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
     177             :                                     PBrowserParent* aParent,
     178             :                                     const PrintData& aData)
     179             : {
     180           0 :   PrintData resultData;
     181           0 :   nsresult rv = ShowPrintDialog(aParent, aData, &resultData);
     182             : 
     183             :   // The child has been spinning an event loop while waiting
     184             :   // to hear about the print settings. We return the results
     185             :   // with an async message which frees the child process from
     186             :   // its nested event loop.
     187           0 :   if (NS_FAILED(rv)) {
     188           0 :     mozilla::Unused << aDialog->Send__delete__(aDialog, rv);
     189             :   } else {
     190           0 :     mozilla::Unused << aDialog->Send__delete__(aDialog, resultData);
     191             :   }
     192           0 :   return IPC_OK();
     193             : }
     194             : 
     195             : mozilla::ipc::IPCResult
     196           0 : PrintingParent::RecvSavePrintSettings(const PrintData& aData,
     197             :                                       const bool& aUsePrinterNamePrefix,
     198             :                                       const uint32_t& aFlags,
     199             :                                       nsresult* aResult)
     200             : {
     201           0 :   nsCOMPtr<nsIPrintSettings> settings;
     202           0 :   *aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
     203           0 :   NS_ENSURE_SUCCESS(*aResult, IPC_OK());
     204             : 
     205           0 :   *aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
     206           0 :   NS_ENSURE_SUCCESS(*aResult, IPC_OK());
     207             : 
     208           0 :   *aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings,
     209           0 :                                                         aUsePrinterNamePrefix,
     210           0 :                                                         aFlags);
     211             : 
     212           0 :   return IPC_OK();
     213             : }
     214             : 
     215             : PPrintProgressDialogParent*
     216           0 : PrintingParent::AllocPPrintProgressDialogParent()
     217             : {
     218           0 :   PrintProgressDialogParent* actor = new PrintProgressDialogParent();
     219           0 :   NS_ADDREF(actor); // De-ref'd in the __delete__ handler for
     220             :                     // PrintProgressDialogParent.
     221           0 :   return actor;
     222             : }
     223             : 
     224             : bool
     225           0 : PrintingParent::DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* doomed)
     226             : {
     227             :   // We can't just delete the PrintProgressDialogParent since somebody might
     228             :   // still be holding a reference to it as nsIObserver, so just decrement the
     229             :   // refcount instead.
     230           0 :   PrintProgressDialogParent* actor = static_cast<PrintProgressDialogParent*>(doomed);
     231           0 :   NS_RELEASE(actor);
     232           0 :   return true;
     233             : }
     234             : 
     235             : PPrintSettingsDialogParent*
     236           0 : PrintingParent::AllocPPrintSettingsDialogParent()
     237             : {
     238           0 :   return new PrintSettingsDialogParent();
     239             : }
     240             : 
     241             : bool
     242           0 : PrintingParent::DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aDoomed)
     243             : {
     244           0 :   delete aDoomed;
     245           0 :   return true;
     246             : }
     247             : 
     248             : PRemotePrintJobParent*
     249           0 : PrintingParent::AllocPRemotePrintJobParent()
     250             : {
     251           0 :   MOZ_ASSERT_UNREACHABLE("No default constructors for implementations.");
     252             :   return nullptr;
     253             : }
     254             : 
     255             : bool
     256           0 : PrintingParent::DeallocPRemotePrintJobParent(PRemotePrintJobParent* aDoomed)
     257             : {
     258           0 :   delete aDoomed;
     259           0 :   return true;
     260             : }
     261             : 
     262             : void
     263           0 : PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
     264             : {
     265           0 : }
     266             : 
     267             : nsPIDOMWindowOuter*
     268           0 : PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent)
     269             : {
     270           0 :   if (!parent) {
     271           0 :     return nullptr;
     272             :   }
     273             : 
     274           0 :   TabParent* tabParent = TabParent::GetFrom(parent);
     275           0 :   if (!tabParent) {
     276           0 :     return nullptr;
     277             :   }
     278             : 
     279           0 :   nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
     280           0 :   if (!frameElement) {
     281           0 :     return nullptr;
     282             :   }
     283             : 
     284           0 :   nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
     285           0 :   if (!frame) {
     286           0 :     return nullptr;
     287             :   }
     288             : 
     289           0 :   nsCOMPtr<nsPIDOMWindowOuter> parentWin = frame->OwnerDoc()->GetWindow();
     290           0 :   if (!parentWin) {
     291           0 :     return nullptr;
     292             :   }
     293             : 
     294           0 :   return parentWin;
     295             : }
     296             : 
     297             : nsresult
     298           0 : PrintingParent::SerializeAndEnsureRemotePrintJob(
     299             :   nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
     300             :   layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData)
     301             : {
     302           0 :   MOZ_ASSERT(aPrintData);
     303             : 
     304             :   nsresult rv;
     305           0 :   nsCOMPtr<nsIPrintSettings> printSettings;
     306           0 :   if (aPrintSettings) {
     307           0 :     printSettings = aPrintSettings;
     308             :   } else {
     309           0 :     rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
     310           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     311           0 :       return rv;
     312             :     }
     313             :   }
     314             : 
     315           0 :   rv = mPrintSettingsSvc->SerializeToPrintData(printSettings, nullptr,
     316           0 :                                                aPrintData);
     317           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     318           0 :     return rv;
     319             :   }
     320             : 
     321             :   RemotePrintJobParent* remotePrintJob;
     322           0 :   if (aRemotePrintJob) {
     323           0 :     remotePrintJob = aRemotePrintJob;
     324           0 :     aPrintData->remotePrintJobParent() = remotePrintJob;
     325             :   } else {
     326           0 :     remotePrintJob = new RemotePrintJobParent(aPrintSettings);
     327           0 :     aPrintData->remotePrintJobParent() =
     328           0 :       SendPRemotePrintJobConstructor(remotePrintJob);
     329             :   }
     330           0 :   if (aListener) {
     331           0 :     remotePrintJob->RegisterListener(aListener);
     332             :   }
     333             : 
     334           0 :   return NS_OK;
     335             : }
     336             : 
     337           1 : PrintingParent::PrintingParent()
     338             : {
     339             :   mPrintSettingsSvc =
     340           1 :     do_GetService("@mozilla.org/gfx/printsettings-service;1");
     341           1 :   MOZ_ASSERT(mPrintSettingsSvc);
     342           1 : }
     343             : 
     344           0 : PrintingParent::~PrintingParent()
     345             : {
     346           0 : }
     347             : 
     348             : } // namespace embedding
     349             : } // namespace mozilla
     350             : 

Generated by: LCOV version 1.13