blob: 03286d2aaf3d38b924d96927c51e15066ea4415d [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/print_preview/print_preview_metrics.h"
#include <optional>
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/strcat.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
namespace printing {
namespace {
void ReportPrintSettingHistogram(PrintSettingsBuckets setting) {
// Use macro because this histogram is called multiple times in succession.
UMA_HISTOGRAM_ENUMERATION("PrintPreview.PrintSettings", setting);
}
} // namespace
void ReportNumberOfPrinters(size_t number) {
// Use macro because this histogram is called multiple times in succession.
UMA_HISTOGRAM_COUNTS_1M("PrintPreview.NumberOfPrinters", number);
}
void ReportPrintDocumentTypeHistograms(PrintDocumentTypeBuckets doctype) {
base::UmaHistogramEnumeration("PrintPreview.PrintDocumentType", doctype);
}
void ReportPrintSettingsStats(const base::Value::Dict& print_settings,
const base::Value::Dict& preview_settings,
bool is_pdf) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kTotal);
// Print settings can be categorized into 2 groups: settings that are applied
// via preview generation (page range, selection, headers/footers, background
// graphics, scaling, layout, page size, pages per sheet, fit to page,
// margins, rasterize), and settings that are applied at the printer (color,
// duplex, copies, collate, dpi). The former should be captured from the most
// recent preview request, as some of them are set to dummy values in the
// print ticket. Similarly, settings applied at the printer should be pulled
// from the print ticket, as they may have dummy values in the preview
// request.
const base::Value::List* page_range_array =
preview_settings.FindList(kSettingPageRange);
if (page_range_array && !page_range_array->empty()) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kPageRange);
}
const base::Value::Dict* media_size_value =
preview_settings.FindDict(kSettingMediaSize);
if (media_size_value && !media_size_value->empty()) {
if (media_size_value->FindBool(kSettingMediaSizeIsDefault)
.value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kDefaultMedia);
} else {
ReportPrintSettingHistogram(PrintSettingsBuckets::kNonDefaultMedia);
}
}
std::optional<bool> landscape_opt =
preview_settings.FindBool(kSettingLandscape);
if (landscape_opt.has_value()) {
ReportPrintSettingHistogram(landscape_opt.value()
? PrintSettingsBuckets::kLandscape
: PrintSettingsBuckets::kPortrait);
}
if (print_settings.FindInt(kSettingCopies).value_or(1) > 1) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kCopies);
}
if (preview_settings.FindInt(kSettingPagesPerSheet).value_or(1) != 1) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kPagesPerSheet);
}
if (print_settings.FindBool(kSettingCollate).value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kCollate);
}
std::optional<int> duplex_mode_opt =
print_settings.FindInt(kSettingDuplexMode);
if (duplex_mode_opt.has_value()) {
ReportPrintSettingHistogram(duplex_mode_opt.value()
? PrintSettingsBuckets::kDuplex
: PrintSettingsBuckets::kSimplex);
}
std::optional<int> color_mode_opt = print_settings.FindInt(kSettingColor);
if (color_mode_opt.has_value()) {
mojom::ColorModel color_model =
ColorModeToColorModel(color_mode_opt.value());
bool unknown_color_model =
color_model == mojom::ColorModel::kUnknownColorModel;
if (!unknown_color_model) {
std::optional<bool> is_color = IsColorModelSelected(color_model);
ReportPrintSettingHistogram(is_color.value()
? PrintSettingsBuckets::kColor
: PrintSettingsBuckets::kBlackAndWhite);
}
}
if (preview_settings.FindInt(kSettingMarginsType).value_or(0) != 0) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kNonDefaultMargins);
}
if (preview_settings.FindBool(kSettingHeaderFooterEnabled).value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kHeadersAndFooters);
}
if (preview_settings.FindBool(kSettingShouldPrintBackgrounds)
.value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kCssBackground);
}
if (preview_settings.FindBool(kSettingShouldPrintSelectionOnly)
.value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kSelectionOnly);
}
if (preview_settings.FindBool(kSettingRasterizePdf).value_or(false)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kPrintAsImage);
}
ScalingType scaling_type =
static_cast<ScalingType>(preview_settings.FindInt(kSettingScalingType)
.value_or(ScalingType::DEFAULT));
if (scaling_type == ScalingType::CUSTOM) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kScaling);
}
if (is_pdf) {
if (scaling_type == ScalingType::FIT_TO_PAGE) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kFitToPage);
} else if (scaling_type == ScalingType::FIT_TO_PAPER) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kFitToPaper);
}
}
int dpi_horizontal =
print_settings.FindInt(kSettingDpiHorizontal).value_or(0);
int dpi_vertical = print_settings.FindInt(kSettingDpiVertical).value_or(0);
if (dpi_horizontal > 0 && dpi_vertical > 0) {
std::optional<bool> is_default_opt =
print_settings.FindBool(kSettingDpiDefault);
if (is_default_opt.has_value()) {
ReportPrintSettingHistogram(is_default_opt.value()
? PrintSettingsBuckets::kDefaultDpi
: PrintSettingsBuckets::kNonDefaultDpi);
}
if (dpi_horizontal != dpi_vertical) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kNonSquarePixels);
}
}
#if BUILDFLAG(IS_CHROMEOS)
if (print_settings.FindString(kSettingPinValue)) {
ReportPrintSettingHistogram(PrintSettingsBuckets::kPin);
}
#endif // BUILDFLAG(IS_CHROMEOS)
}
void ReportUserActionHistogram(UserActionBuckets event) {
// Use macro because this histogram is called multiple times in succession.
UMA_HISTOGRAM_ENUMERATION("PrintPreview.UserAction", event);
}
void RecordGetPrintersTimeHistogram(mojom::PrinterType printer_type,
const base::TimeTicks& start_time) {
std::string_view printer_type_metric;
switch (printer_type) {
case mojom::PrinterType::kExtension:
printer_type_metric = "Extension";
break;
case mojom::PrinterType::kPdf:
printer_type_metric = "PDF";
break;
case mojom::PrinterType::kLocal:
printer_type_metric = "Local";
break;
}
CHECK(!printer_type_metric.empty());
base::UmaHistogramCustomTimes(
base::StrCat({"PrintPreview.GetPrintersTime.", printer_type_metric}),
/*sample=*/base::TimeTicks::Now() - start_time,
/*min=*/base::Milliseconds(1),
/*max=*/base::Minutes(1), /*buckets=*/50);
}
} // namespace printing