Commit e556609b authored by Jonathan Watt's avatar Jonathan Watt
Browse files

Bug 1600623. Add telemetry probes for print dialog/preview opens/cancels and...

Bug 1600623. Add telemetry probes for print dialog/preview opens/cancels and print target type. r=bobowen,mbalfanz a=jcristau

The probes collect counts for:

 - print preview open, and exit without print
 - print dialog opened from print preview, and cancelled
 - print dialog opened without print preview, and cancelled
 - silent prints
 - print target
   - PDF file
   - XPS file
   - other (probably print to physical printer, but we can never be sure)

There is some overlap with the existing PRINT_* probes, but I think we should
keep those in place temporarily until we confirm that the new probes produce
numbers that are consistent with the old probes.

This patch only adds 'print target' probes for Windows and macOS.

I use nsDeviceContextSpec*::Init() to collect the 'print target' telemetry
because the way we initialize settings from prefs (and the way macOS works in
particular) make it difficult to reliably determine the target type earlier in
the print process for all possible entry points into the printing code.

Differential Revision: https://phabricator.services.mozilla.com/D78033
parent 26cd233f
......@@ -10,6 +10,7 @@
#include "mozilla/PresShell.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/Telemetry.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
......@@ -3341,6 +3342,8 @@ nsDocumentViewer::PrintPreview(nsIPrintSettings* aPrintSettings,
return rv;
}
mPrintJob = printJob;
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_PREVIEW_OPENED, 1);
}
if (autoBeforeAndAfterPrint && printJob->HasPrintCallbackCanvas()) {
// Postpone the 'afterprint' event until after the mozPrintCallback
......@@ -3521,6 +3524,10 @@ nsDocumentViewer::ExitPrintPreview() {
return NS_OK;
}
if (!mPrintJob->HasEverPrinted()) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_PREVIEW_CANCELLED, 1);
}
# ifdef NS_PRINT_PREVIEW
mPrintJob->TurnScriptingOn(true);
mPrintJob->Destroy();
......
......@@ -17,6 +17,7 @@
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/CustomEvent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Telemetry.h"
#include "nsIBrowserChild.h"
#include "nsIOService.h"
#include "nsIScriptGlobalObject.h"
......@@ -846,6 +847,19 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
if (!aIsPrintPreview) {
domWin = mOriginalDoc->GetWindow();
NS_ENSURE_TRUE(domWin, NS_ERROR_FAILURE);
if (printSilently) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_SILENT_PRINT, 1);
} else {
if (mIsDoingPrintPreview) {
Telemetry::ScalarAdd(
Telemetry::ScalarID::PRINTING_DIALOG_OPENED_VIA_PREVIEW, 1);
} else {
Telemetry::ScalarAdd(
Telemetry::ScalarID::PRINTING_DIALOG_OPENED_WITHOUT_PREVIEW,
1);
}
}
}
// Platforms not implementing a given dialog for the service may
......@@ -856,6 +870,24 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
//
rv = printPromptService->ShowPrintDialog(domWin,
printData->mPrintSettings);
if (!aIsPrintPreview) {
if (rv == NS_ERROR_ABORT) {
// When printing silently we can't get here since the user doesn't
// have the opportunity to cancel printing.
if (mIsDoingPrintPreview) {
Telemetry::ScalarAdd(
Telemetry::ScalarID::PRINTING_DIALOG_VIA_PREVIEW_CANCELLED,
1);
} else {
Telemetry::ScalarAdd(
Telemetry::ScalarID::
PRINTING_DIALOG_WITHOUT_PREVIEW_CANCELLED,
1);
}
}
}
//
// ShowPrintDialog triggers an event loop which means we can't assume
// that the state of this->{anything} matches the state we've checked
......@@ -2546,6 +2578,9 @@ void nsPrintJob::PageDone(nsresult aResult) {
//---------------------------------------------------------------------
void nsPrintJob::SetIsPrinting(bool aIsPrinting) {
mIsDoingPrinting = aIsPrinting;
if (aIsPrinting) {
mHasEverPrinted = true;
}
// Calling SetIsPrinting while in print preview confuses the document viewer
// This is safe because we prevent exiting print preview while printing
if (!mIsDoingPrintPreview && mDocViewerPrint) {
......
......@@ -113,6 +113,7 @@ class nsPrintJob final : public nsIObserver,
bool IsDoingPrint() const { return mIsDoingPrinting; }
bool IsDoingPrintPreview() const { return mIsDoingPrintPreview; }
bool HasEverPrinted() const { return mHasEverPrinted; }
bool IsIFrameSelected();
bool IsRangeSelection();
/// If the returned value is not greater than zero, an error occurred.
......@@ -299,6 +300,7 @@ class nsPrintJob final : public nsIObserver,
bool mIsCreatingPrintPreview = false;
bool mIsDoingPrinting = false;
bool mIsDoingPrintPreview = false;
bool mHasEverPrinted = false;
bool mProgressDialogIsShown = false;
bool mDidLoadDataForPrinting = false;
bool mIsDestroying = false;
......
......@@ -3374,6 +3374,70 @@ unknowncontenttype:
# The following section contains scalars for printing.
printing:
dialog_opened_without_preview:
bug_numbers:
- 1600623
description: >
A counter incremented every time the print dialog is opened without
opening print preview.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
dialog_without_preview_cancelled:
bug_numbers:
- 1600623
description: >
A counter incremented every time a print dialog that was opened without
print preview is cancelled.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
dialog_opened_via_preview:
bug_numbers:
- 1600623
description: >
A counter incremented every time the print dialog is opened from print
preview.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
dialog_via_preview_cancelled:
bug_numbers:
- 1600623
description: >
A counter incremented every time a print dialog opened from print preview
is cancelled.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
error:
bug_numbers:
- 1630105
......@@ -3401,6 +3465,79 @@ printing:
kind: uint
notification_emails:
- jaws@mozilla.com
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'main'
preview_opened:
bug_numbers:
- 1600623
description: >
A counter incremented every time the user initiates print preview.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
preview_cancelled:
bug_numbers:
- 1600623
description: >
A counter incremented every time a print preview session exits without
printing.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
silent_print:
bug_numbers:
- 1600623
description: >
A counter incremented every time a silent print (a print without a
print settings dialog being opened) is initiated. This happens when
extensions invoke ExtensionAPI.tabs.saveAsPDF, for example, or when the
print.always_print_silent pref is set.
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
record_in_processes:
- 'content'
target_type:
bug_numbers:
- 1600623
description: >
A counter incremented every time the user prints to a certain target
type. For the most part, the 'unknown' count will be prints to a
physical printer, but we can't know for sure since third party drivers
could also be print to file drivers.
keyed: true
keys:
- 'pdf_file'
- 'xps_file'
- 'unknown'
expires: never
kind: uint
notification_emails:
- jwatt@jwatt.org
release_channel_collection: opt-out
products:
- 'firefox'
......
......@@ -16,6 +16,7 @@
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Telemetry.h"
#include "nsCocoaUtils.h"
#include "nsCRT.h"
......@@ -207,6 +208,29 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIWidget* aWidget, nsIPrintSettings* a
}
#endif
int16_t outputFormat;
aPS->GetOutputFormat(&outputFormat);
if (outputFormat == nsIPrintSettings::kOutputFormatPDF) {
// We don't actually currently support/use kOutputFormatPDF on mac, but
// this is for completeness in case we add that (we probably need to in
// order to support adding links into saved PDFs, for example).
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, NS_LITERAL_STRING("pdf_file"),
1);
} else {
PMDestinationType destination;
OSStatus status = ::PMSessionGetDestinationType(mPrintSession, mPrintSettings, &destination);
if (status == noErr &&
(destination == kPMDestinationFile || destination == kPMDestinationPreview ||
destination == kPMDestinationProcessPDF)) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, NS_LITERAL_STRING("pdf_file"),
1);
} else {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, NS_LITERAL_STRING("unknown"),
1);
}
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
......
......@@ -11,6 +11,7 @@
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Telemetry.h"
#include <winspool.h>
......@@ -125,6 +126,65 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
bool aIsPrintPreview) {
mPrintSettings = aPrintSettings;
// Get the Printer Name to be used and output format.
nsAutoString printerName;
if (mPrintSettings) {
mPrintSettings->GetOutputFormat(&mOutputFormat);
mPrintSettings->GetPrinterName(printerName);
}
// If there is no name then use the default printer
if (printerName.IsEmpty()) {
GlobalPrinters::GetInstance()->GetDefaultPrinterName(printerName);
}
// Gather telemetry on the print target type.
//
// Unfortunately, if we're not using our own internal save-to-pdf codepaths,
// there isn't a good way to determine whether a print is going to be to a
// physical printer or to a file or some other non-physical output. We do our
// best by checking for what seems to be the most common save-to-PDF virtual
// printers.
//
// We use StringBeginsWith below, since printer names are often followed by a
// version number or other product differentiating string. (True for doPDF,
// novaPDF, PDF-XChange and Soda PDF, for example.)
if (mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
NS_LITERAL_STRING("pdf_file"), 1);
} else if (StringBeginsWith(printerName,
NS_LITERAL_STRING("Microsoft Print to PDF")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("Adobe PDF")) ||
StringBeginsWith(printerName,
NS_LITERAL_STRING("Bullzip PDF Printer")) ||
StringBeginsWith(printerName,
NS_LITERAL_STRING("CutePDF Writer")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("doPDF")) ||
StringBeginsWith(printerName,
NS_LITERAL_STRING("Foxit Reader PDF Printer")) ||
StringBeginsWith(printerName,
NS_LITERAL_STRING("Nitro PDF Creator")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("novaPDF")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("PDF-XChange")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("PDF24 PDF")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("PDFCreator")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("PrimoPDF")) ||
StringBeginsWith(printerName, NS_LITERAL_STRING("Soda PDF")) ||
StringBeginsWith(printerName,
NS_LITERAL_STRING("Solid PDF Creator")) ||
StringBeginsWith(
printerName,
NS_LITERAL_STRING("Universal Document Converter"))) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
NS_LITERAL_STRING("pdf_file"), 1);
} else if (printerName.EqualsLiteral("Microsoft XPS Document Writer")) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
NS_LITERAL_STRING("xps_file"), 1);
} else {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
NS_LITERAL_STRING("unknown"), 1);
}
nsresult rv = NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
if (aPrintSettings) {
#ifdef MOZ_ENABLE_SKIA_PDF
......@@ -137,7 +197,6 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
// If we're in the child and printing via the parent or we're printing to
// PDF we only need information from the print settings.
mPrintSettings->GetOutputFormat(&mOutputFormat);
if ((XRE_IsContentProcess() &&
Preferences::GetBool("print.print_via_parent")) ||
mOutputFormat == nsIPrintSettings::kOutputFormatPDF) {
......@@ -181,17 +240,6 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
PR_PL(("***** nsDeviceContextSpecWin::Init - aPrintSettingswas NULL!\n"));
}
// Get the Printer Name to be used and output format.
nsAutoString printerName;
if (mPrintSettings) {
mPrintSettings->GetPrinterName(printerName);
}
// If there is no name then use the default printer
if (printerName.IsEmpty()) {
GlobalPrinters::GetInstance()->GetDefaultPrinterName(printerName);
}
if (printerName.IsEmpty()) {
return rv;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment