blob: e1a3e31764d986e3d3af7365ac8763e08d03003e [file] [log] [blame]
// Copyright 2017 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/ash/printing/printer_event_tracker.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
namespace ash {
namespace {
// Convert from string to PdfVersion.
metrics::PrinterEventProto::PdfVersion PdfVersionFromString(
const std::string& in) {
if (in == "adobe-1.3") {
return metrics::PrinterEventProto::ADOBE_1_3;
} else if (in == "adobe-1.4") {
return metrics::PrinterEventProto::ADOBE_1_4;
} else if (in == "adobe-1.5") {
return metrics::PrinterEventProto::ADOBE_1_5;
} else if (in == "adobe-1.6") {
return metrics::PrinterEventProto::ADOBE_1_6;
} else if (in == "adobe-1.7") {
return metrics::PrinterEventProto::ADOBE_1_7;
} else if (in == "iso-15930-1_2001") {
return metrics::PrinterEventProto::ISO_15930_1_2001;
} else if (in == "iso-15930-3_2002") {
return metrics::PrinterEventProto::ISO_15930_3_2002;
} else if (in == "iso-15930-4_2003") {
return metrics::PrinterEventProto::ISO_15930_4_2003;
} else if (in == "iso-15930-6_2003") {
return metrics::PrinterEventProto::ISO_15930_6_2003;
} else if (in == "iso-15930-7_2010") {
return metrics::PrinterEventProto::ISO_15930_7_2010;
} else if (in == "iso-15930-8_2010") {
return metrics::PrinterEventProto::ISO_15930_8_2010;
} else if (in == "iso-16612-2:2010") {
return metrics::PrinterEventProto::ISO_16612_2_2010;
} else if (in == "iso-19005-1_2005") {
return metrics::PrinterEventProto::ISO_19005_1_2005;
} else if (in == "iso-19005-2_2011") {
return metrics::PrinterEventProto::ISO_19005_2_2011;
} else if (in == "iso-19005-3_2012") {
return metrics::PrinterEventProto::ISO_19005_3_2012;
} else if (in == "iso-23504-1_202") {
return metrics::PrinterEventProto::ISO_23504_1_2020;
} else if (in == "iso-32000-1_2008") {
return metrics::PrinterEventProto::ISO_32000_1_2008;
} else if (in == "iso-32000-2_2017") {
return metrics::PrinterEventProto::ISO_32000_2_2017;
} else if (in == "pwg-5102.3") {
return metrics::PrinterEventProto::PWG_5102_3;
}
return metrics::PrinterEventProto::PDF_VERSION_UNKNOWN;
}
// Convert from string to IppFeature.
metrics::PrinterEventProto::IppFeature IppFeatureFromString(
const std::string& in) {
if (in == "adf") {
return metrics::PrinterEventProto::ADF;
} else if (in == "film-reader") {
return metrics::PrinterEventProto::FILM_READER;
} else if (in == "platen") {
return metrics::PrinterEventProto::PLATEN;
} else if (in == "document-object") {
return metrics::PrinterEventProto::DOCUMENT_OBJECT;
} else if (in == "faxout") {
return metrics::PrinterEventProto::FAXOUT;
} else if (in == "icc-color-matching") {
return metrics::PrinterEventProto::ICC_COLOR_MATCHING;
} else if (in == "infrastructure-printer") {
return metrics::PrinterEventProto::INFRASTRUCTURE_PRINTER;
} else if (in == "ipp-3d") {
return metrics::PrinterEventProto::IPP_3D;
} else if (in == "ipp-everywhere") {
return metrics::PrinterEventProto::IPP_EVERYWHERE;
} else if (in == "ipp-everywhere-server") {
return metrics::PrinterEventProto::IPP_EVERYWHERE_SERVER;
} else if (in == "job-release") {
return metrics::PrinterEventProto::JOB_RELEASE;
} else if (in == "job-save") {
return metrics::PrinterEventProto::JOB_SAVE;
} else if (in == "job-storage") {
return metrics::PrinterEventProto::JOB_STORAGE;
} else if (in == "none") {
return metrics::PrinterEventProto::NONE;
} else if (in == "page-overrides") {
return metrics::PrinterEventProto::PAGE_OVERRIDES;
} else if (in == "print-policy") {
return metrics::PrinterEventProto::PRINT_POLICY;
} else if (in == "production") {
return metrics::PrinterEventProto::PRODUCTION;
} else if (in == "proof-and-suspend") {
return metrics::PrinterEventProto::PROOF_AND_SUSPEND;
} else if (in == "proof-print") {
return metrics::PrinterEventProto::PROOF_PRINT;
} else if (in == "resource-object") {
return metrics::PrinterEventProto::RESOURCE_OBJECT;
} else if (in == "scan") {
return metrics::PrinterEventProto::SCAN;
} else if (in == "subscription-object") {
return metrics::PrinterEventProto::SUBSCRIPTION_OBJECT;
} else if (in == "system-object") {
return metrics::PrinterEventProto::SYSTEM_OBJECT;
} else if (in == "wfds-print-1.0") {
return metrics::PrinterEventProto::WFDS_PRINT_1_0;
} else if (in == "airprint-1.6") {
return metrics::PrinterEventProto::AIRPRINT_1_6;
} else if (in == "airprint-1.7") {
return metrics::PrinterEventProto::AIRPRINT_1_7;
} else if (in == "airprint-1.8") {
return metrics::PrinterEventProto::AIRPRINT_1_8;
} else if (in == "airprint-2.1") {
return metrics::PrinterEventProto::AIRPRINT_2_1;
}
return metrics::PrinterEventProto::IPP_FEATURE_UNKNOWN;
}
// Set the event_type on |event| based on |mode|.
void SetEventType(metrics::PrinterEventProto* event,
PrinterEventTracker::SetupMode mode) {
switch (mode) {
case PrinterEventTracker::kUnknownMode:
event->set_event_type(metrics::PrinterEventProto::UNKNOWN);
break;
case PrinterEventTracker::kUser:
event->set_event_type(metrics::PrinterEventProto::SETUP_MANUAL);
break;
case PrinterEventTracker::kAutomatic:
event->set_event_type(metrics::PrinterEventProto::SETUP_AUTOMATIC);
break;
}
}
// Populate PPD information in |event| based on |ppd|.
void SetPpdInfo(metrics::PrinterEventProto* event,
const chromeos::Printer::PpdReference& ppd) {
if (!ppd.user_supplied_ppd_url.empty()) {
event->set_user_ppd(true);
} else if (!ppd.effective_make_and_model.empty()) {
event->set_ppd_identifier(ppd.effective_make_and_model);
}
// PPD information is not populated for autoconfigured printers.
}
// Add information to |event| specific to |usb_printer|.
void SetUsbInfo(metrics::PrinterEventProto* event,
const chromeos::PrinterSearchData& ppd_search_data) {
event->set_usb_vendor_id(ppd_search_data.usb_vendor_id);
event->set_usb_model_id(ppd_search_data.usb_product_id);
event->set_usb_printer_manufacturer(ppd_search_data.usb_manufacturer);
event->set_usb_printer_model(ppd_search_data.usb_model);
}
// Add information to the |event| that only network printers have.
void SetNetworkPrinterInfo(metrics::PrinterEventProto* event,
const chromeos::Printer& printer) {
if (!printer.make_and_model().empty()) {
event->set_ipp_make_and_model(printer.make_and_model());
}
}
// Add information to the `event` that only IPP printers have.
void SetIppPrinterInfo(metrics::PrinterEventProto* event,
const chromeos::IppPrinterInfo& info) {
if (!info.document_formats.empty()) {
event->mutable_document_format_supported()->Assign(
info.document_formats.begin(), info.document_formats.end());
}
if (!info.document_format_preferred.empty()) {
event->set_document_format_preferred(info.document_format_preferred);
}
if (!info.document_format_default.empty()) {
event->set_document_format_default(info.document_format_default);
}
if (!info.urf_supported.empty()) {
event->mutable_urf_supported()->Assign(info.urf_supported.begin(),
info.urf_supported.end());
}
if (!info.pdf_versions.empty()) {
for (const auto& version : info.pdf_versions) {
event->add_pdf_versions_supported(PdfVersionFromString(version));
}
}
if (!info.ipp_features.empty()) {
for (const auto& feature : info.ipp_features) {
event->add_ipp_features_supported(IppFeatureFromString(feature));
}
}
if (!info.mopria_certified.empty()) {
event->set_mopria_certified(info.mopria_certified);
}
if (!info.printer_kind.empty()) {
event->mutable_printer_kind()->Assign(info.printer_kind.begin(),
info.printer_kind.end());
}
}
} // namespace
PrinterEventTracker::PrinterEventTracker() = default;
PrinterEventTracker::~PrinterEventTracker() = default;
void PrinterEventTracker::set_logging(bool logging) {
base::AutoLock l(lock_);
logging_ = logging;
}
void PrinterEventTracker::RecordUsbPrinterInstalled(
const chromeos::Printer::PpdReference& ppd_reference,
const chromeos::PrinterSearchData& ppd_search_data,
SetupMode mode) {
base::AutoLock l(lock_);
if (!logging_) {
return;
}
metrics::PrinterEventProto event;
SetEventType(&event, mode);
SetPpdInfo(&event, ppd_reference);
SetUsbInfo(&event, ppd_search_data);
events_.push_back(event);
}
void PrinterEventTracker::RecordIppPrinterInstalled(
const chromeos::Printer& printer,
SetupMode mode,
const std::optional<chromeos::IppPrinterInfo>& ipp_printer_info) {
base::AutoLock l(lock_);
if (!logging_) {
return;
}
metrics::PrinterEventProto event;
SetEventType(&event, mode);
SetPpdInfo(&event, printer.ppd_reference());
SetNetworkPrinterInfo(&event, printer);
if (ipp_printer_info.has_value()) {
SetIppPrinterInfo(&event, ipp_printer_info.value());
}
events_.push_back(event);
}
void PrinterEventTracker::RecordUsbSetupAbandoned(
const chromeos::PrinterSearchData& ppd_search_data) {
base::AutoLock l(lock_);
if (!logging_) {
return;
}
metrics::PrinterEventProto event;
event.set_event_type(metrics::PrinterEventProto::SETUP_ABANDONED);
SetUsbInfo(&event, ppd_search_data);
events_.push_back(event);
}
void PrinterEventTracker::RecordSetupAbandoned(
const chromeos::Printer& printer) {
base::AutoLock l(lock_);
if (!logging_) {
return;
}
metrics::PrinterEventProto event;
event.set_event_type(metrics::PrinterEventProto::SETUP_ABANDONED);
SetNetworkPrinterInfo(&event, printer);
events_.push_back(event);
}
void PrinterEventTracker::RecordPrinterRemoved(
const chromeos::Printer& printer) {
base::AutoLock l(lock_);
if (!logging_) {
return;
}
metrics::PrinterEventProto event;
event.set_event_type(metrics::PrinterEventProto::PRINTER_DELETED);
SetNetworkPrinterInfo(&event, printer);
SetPpdInfo(&event, printer.ppd_reference());
events_.push_back(event);
}
void PrinterEventTracker::FlushPrinterEvents(
std::vector<metrics::PrinterEventProto>* events) {
base::AutoLock l(lock_);
events->swap(events_);
events_.clear();
}
} // namespace ash