blob: ce0fe0990b5a05cc563737aeb81bf06f8d8a7f79 [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 "base/time/time.h"
#include "chromeos/printing/printer_configuration.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/printer_event.pb.h"
namespace ash {
namespace {
using ::chromeos::IppPrinterInfo;
using ::chromeos::Printer;
constexpr int kVendorId = 0x3241;
constexpr int kProductId = 0x1337;
constexpr char kUsbManufacturer[] = "Usb MakesPrinters";
constexpr char kUsbModel[] = "Printer ModelName";
constexpr char kMakeAndModel[] = "Chromium RazLazer X4321er";
constexpr char kEffectiveMakeAndModel[] = "Generic PostScript";
constexpr char kDocumentFormatDefault[] = "Default";
constexpr char kDocumentFormatPreferred[] = "Preferred";
constexpr char kFirstDocumentFormatSupported[] = "First";
constexpr char kSecondDocumentFormatSupported[] = "Second";
constexpr char kFirstUrfSupported[] = "IS4-20";
constexpr char kSecondUrfSupported[] = "W8";
constexpr char kFirstIppFeatureString[] = "adf";
constexpr char kSecondIppFeatureString[] = "platen";
constexpr metrics::PrinterEventProto::IppFeature kFirstIppFeatureSupported =
metrics::PrinterEventProto::ADF;
constexpr metrics::PrinterEventProto::IppFeature kSecondIppFeatureSupported =
metrics::PrinterEventProto::PLATEN;
constexpr char kFirstPdfVersionString[] = "iso-32000-1_2008";
constexpr char kSecondPdfVersionString[] = "adobe-1.4";
constexpr metrics::PrinterEventProto::PdfVersion kFirstPdfVersionSupported =
metrics::PrinterEventProto::ISO_32000_1_2008;
constexpr metrics::PrinterEventProto::PdfVersion kSecondPdfVersionSupported =
metrics::PrinterEventProto::ADOBE_1_4;
constexpr char kMopriaCertified[] = "1.3";
constexpr char kFirstPrinterKind[] = "document";
constexpr char kSecondPrinterKind[] = "photo";
class PrinterEventTrackerTest : public testing::Test {
public:
PrinterEventTrackerTest() = default;
PrinterEventTrackerTest(const PrinterEventTrackerTest&) = delete;
PrinterEventTrackerTest& operator=(const PrinterEventTrackerTest&) = delete;
~PrinterEventTrackerTest() override = default;
protected:
PrinterEventTracker tracker_;
// Returns a copy of the first element recorded by the tracker. Calls Flush
// on the |tracker_|.
std::vector<metrics::PrinterEventProto> GetEvents() {
std::vector<metrics::PrinterEventProto> events;
tracker_.FlushPrinterEvents(&events);
return events;
}
};
TEST_F(PrinterEventTrackerTest, RecordsWhenEnabled) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
tracker_.RecordIppPrinterInstalled(test_printer, PrinterEventTracker::kUser,
chromeos::IppPrinterInfo{});
auto events = GetEvents();
EXPECT_EQ(1U, events.size());
}
TEST_F(PrinterEventTrackerTest, DefaultLoggingOff) {
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
tracker_.RecordIppPrinterInstalled(test_printer,
PrinterEventTracker::kAutomatic,
chromeos::IppPrinterInfo{});
auto events = GetEvents();
EXPECT_TRUE(events.empty());
}
TEST_F(PrinterEventTrackerTest, DoesNotRecordWhileDisabled) {
tracker_.set_logging(false);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
tracker_.RecordIppPrinterInstalled(test_printer,
PrinterEventTracker::kAutomatic,
chromeos::IppPrinterInfo{});
auto events = GetEvents();
EXPECT_TRUE(events.empty());
}
TEST_F(PrinterEventTrackerTest, InstalledIppPrinter) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
IppPrinterInfo ipp_printer_info;
ipp_printer_info.document_format_default = kDocumentFormatDefault;
ipp_printer_info.document_format_preferred = kDocumentFormatPreferred;
ipp_printer_info.document_formats.push_back(kFirstDocumentFormatSupported);
ipp_printer_info.document_formats.push_back(kSecondDocumentFormatSupported);
ipp_printer_info.document_formats.push_back(kDocumentFormatDefault);
ipp_printer_info.document_formats.push_back(kDocumentFormatPreferred);
ipp_printer_info.urf_supported.push_back(kFirstUrfSupported);
ipp_printer_info.urf_supported.push_back(kSecondUrfSupported);
ipp_printer_info.pdf_versions.push_back(kFirstPdfVersionString);
ipp_printer_info.pdf_versions.push_back(kSecondPdfVersionString);
ipp_printer_info.ipp_features.push_back(kFirstIppFeatureString);
ipp_printer_info.ipp_features.push_back(kSecondIppFeatureString);
ipp_printer_info.mopria_certified = kMopriaCertified;
ipp_printer_info.printer_kind.push_back(kFirstPrinterKind);
ipp_printer_info.printer_kind.push_back(kSecondPrinterKind);
tracker_.RecordIppPrinterInstalled(test_printer, PrinterEventTracker::kUser,
ipp_printer_info);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto recorded_event = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_MANUAL,
recorded_event.event_type());
EXPECT_EQ(kMakeAndModel, recorded_event.ipp_make_and_model());
EXPECT_EQ(kEffectiveMakeAndModel, recorded_event.ppd_identifier());
EXPECT_EQ(kDocumentFormatDefault, recorded_event.document_format_default());
EXPECT_EQ(kDocumentFormatPreferred,
recorded_event.document_format_preferred());
EXPECT_THAT(
recorded_event.document_format_supported(),
testing::UnorderedElementsAreArray(
{kFirstDocumentFormatSupported, kSecondDocumentFormatSupported,
kDocumentFormatDefault, kDocumentFormatPreferred}));
EXPECT_THAT(recorded_event.urf_supported(),
testing::UnorderedElementsAreArray(
{kFirstUrfSupported, kSecondUrfSupported}));
EXPECT_THAT(recorded_event.pdf_versions_supported(),
testing::UnorderedElementsAreArray(
{kFirstPdfVersionSupported, kSecondPdfVersionSupported}));
EXPECT_THAT(recorded_event.ipp_features_supported(),
testing::UnorderedElementsAreArray(
{kFirstIppFeatureSupported, kSecondIppFeatureSupported}));
EXPECT_EQ(recorded_event.mopria_certified(), kMopriaCertified);
EXPECT_THAT(recorded_event.printer_kind(),
testing::UnorderedElementsAreArray(
{kFirstPrinterKind, kSecondPrinterKind}));
EXPECT_FALSE(recorded_event.has_usb_printer_manufacturer());
EXPECT_FALSE(recorded_event.has_usb_printer_model());
EXPECT_FALSE(recorded_event.has_usb_vendor_id());
EXPECT_FALSE(recorded_event.has_usb_model_id());
EXPECT_FALSE(recorded_event.user_ppd());
}
TEST_F(PrinterEventTrackerTest, InstalledPrinterAuto) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->autoconf = true;
IppPrinterInfo ipp_printer_info;
ipp_printer_info.document_format_default = kDocumentFormatDefault;
ipp_printer_info.document_format_preferred = kDocumentFormatPreferred;
ipp_printer_info.document_formats.push_back(kFirstDocumentFormatSupported);
ipp_printer_info.document_formats.push_back(kSecondDocumentFormatSupported);
ipp_printer_info.document_formats.push_back(kDocumentFormatDefault);
ipp_printer_info.document_formats.push_back(kDocumentFormatPreferred);
ipp_printer_info.urf_supported.push_back(kFirstUrfSupported);
ipp_printer_info.urf_supported.push_back(kSecondUrfSupported);
ipp_printer_info.pdf_versions.push_back(kFirstPdfVersionString);
ipp_printer_info.pdf_versions.push_back(kSecondPdfVersionString);
ipp_printer_info.ipp_features.push_back(kFirstIppFeatureString);
ipp_printer_info.ipp_features.push_back(kSecondIppFeatureString);
ipp_printer_info.mopria_certified = kMopriaCertified;
ipp_printer_info.printer_kind.push_back(kFirstPrinterKind);
ipp_printer_info.printer_kind.push_back(kSecondPrinterKind);
tracker_.RecordIppPrinterInstalled(
test_printer, PrinterEventTracker::kAutomatic, ipp_printer_info);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto recorded_event = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_AUTOMATIC,
recorded_event.event_type());
EXPECT_EQ(kMakeAndModel, recorded_event.ipp_make_and_model());
EXPECT_EQ(kDocumentFormatDefault, recorded_event.document_format_default());
EXPECT_EQ(kDocumentFormatPreferred,
recorded_event.document_format_preferred());
EXPECT_THAT(
recorded_event.document_format_supported(),
testing::UnorderedElementsAreArray(
{kFirstDocumentFormatSupported, kSecondDocumentFormatSupported,
kDocumentFormatDefault, kDocumentFormatPreferred}));
EXPECT_THAT(recorded_event.urf_supported(),
testing::UnorderedElementsAreArray(
{kFirstUrfSupported, kSecondUrfSupported}));
EXPECT_THAT(recorded_event.pdf_versions_supported(),
testing::UnorderedElementsAreArray(
{kFirstPdfVersionSupported, kSecondPdfVersionSupported}));
EXPECT_THAT(recorded_event.ipp_features_supported(),
testing::UnorderedElementsAreArray(
{kFirstIppFeatureSupported, kSecondIppFeatureSupported}));
EXPECT_EQ(recorded_event.mopria_certified(), kMopriaCertified);
EXPECT_THAT(recorded_event.printer_kind(),
testing::UnorderedElementsAreArray(
{kFirstPrinterKind, kSecondPrinterKind}));
// For autoconf printers, ppd identifier is blank but a successful setup is
// recorded.
EXPECT_FALSE(recorded_event.has_ppd_identifier());
EXPECT_FALSE(recorded_event.has_usb_printer_manufacturer());
EXPECT_FALSE(recorded_event.has_usb_printer_model());
EXPECT_FALSE(recorded_event.has_usb_vendor_id());
EXPECT_FALSE(recorded_event.has_usb_model_id());
EXPECT_FALSE(recorded_event.user_ppd());
}
TEST_F(PrinterEventTrackerTest, InstalledPrinterUserPpd) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.mutable_ppd_reference()->user_supplied_ppd_url =
"file:///i_dont_record_this_field/blah/blah/blah/some_ppd.ppd";
tracker_.RecordIppPrinterInstalled(test_printer, PrinterEventTracker::kUser,
chromeos::IppPrinterInfo{});
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto recorded_event = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_MANUAL,
recorded_event.event_type());
// For user PPDs we just record that it was a user PPD, the value is not
// recorded.
EXPECT_TRUE(recorded_event.user_ppd());
EXPECT_FALSE(recorded_event.has_ppd_identifier());
// This is empty if it was not detected.
EXPECT_FALSE(recorded_event.has_ipp_make_and_model());
// Network printers do not have usb information.
EXPECT_FALSE(recorded_event.has_usb_printer_manufacturer());
EXPECT_FALSE(recorded_event.has_usb_printer_model());
EXPECT_FALSE(recorded_event.has_usb_vendor_id());
EXPECT_FALSE(recorded_event.has_usb_model_id());
}
TEST_F(PrinterEventTrackerTest, InstalledUsbPrinter) {
tracker_.set_logging(true);
PrinterDetector::DetectedPrinter usb_printer;
usb_printer.ppd_search_data.usb_vendor_id = kVendorId;
usb_printer.ppd_search_data.usb_product_id = kProductId;
usb_printer.ppd_search_data.usb_manufacturer = kUsbManufacturer;
usb_printer.ppd_search_data.usb_model = kUsbModel;
usb_printer.printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
tracker_.RecordUsbPrinterInstalled(usb_printer,
PrinterEventTracker::SetupMode::kUser);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto record = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_MANUAL, record.event_type());
EXPECT_EQ(kVendorId, record.usb_vendor_id());
EXPECT_EQ(kProductId, record.usb_model_id());
EXPECT_EQ(kUsbManufacturer, record.usb_printer_manufacturer());
EXPECT_EQ(kUsbModel, record.usb_printer_model());
EXPECT_EQ(kEffectiveMakeAndModel, record.ppd_identifier());
EXPECT_FALSE(record.user_ppd());
// USB doesn't detect this field.
EXPECT_FALSE(record.has_ipp_make_and_model());
}
TEST_F(PrinterEventTrackerTest, AbandonedNetworkPrinter) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
tracker_.RecordSetupAbandoned(test_printer);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto recorded_event = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_ABANDONED,
recorded_event.event_type());
EXPECT_EQ(kMakeAndModel, recorded_event.ipp_make_and_model());
// Abandoned setups should not record a chosen PPD or user PPD.
EXPECT_FALSE(recorded_event.has_user_ppd());
EXPECT_FALSE(recorded_event.has_ppd_identifier());
EXPECT_FALSE(recorded_event.has_usb_printer_manufacturer());
EXPECT_FALSE(recorded_event.has_usb_printer_model());
EXPECT_FALSE(recorded_event.has_usb_vendor_id());
EXPECT_FALSE(recorded_event.has_usb_model_id());
}
TEST_F(PrinterEventTrackerTest, AbandonedUsbPrinter) {
tracker_.set_logging(true);
PrinterDetector::DetectedPrinter usb_printer;
usb_printer.ppd_search_data.usb_vendor_id = kVendorId;
usb_printer.ppd_search_data.usb_product_id = kProductId;
usb_printer.ppd_search_data.usb_manufacturer = kUsbManufacturer;
usb_printer.ppd_search_data.usb_model = kUsbModel;
tracker_.RecordUsbSetupAbandoned(usb_printer);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto record = events.front();
EXPECT_EQ(metrics::PrinterEventProto::SETUP_ABANDONED, record.event_type());
EXPECT_EQ(kVendorId, record.usb_vendor_id());
EXPECT_EQ(kProductId, record.usb_model_id());
EXPECT_EQ(kUsbManufacturer, record.usb_printer_manufacturer());
EXPECT_EQ(kUsbModel, record.usb_printer_model());
EXPECT_FALSE(record.has_user_ppd());
EXPECT_FALSE(record.has_ppd_identifier());
}
TEST_F(PrinterEventTrackerTest, RemovedPrinter) {
tracker_.set_logging(true);
Printer test_printer;
test_printer.set_make_and_model(kMakeAndModel);
test_printer.mutable_ppd_reference()->effective_make_and_model =
kEffectiveMakeAndModel;
tracker_.RecordPrinterRemoved(test_printer);
auto events = GetEvents();
ASSERT_FALSE(events.empty());
metrics::PrinterEventProto recorded_event = events.front();
EXPECT_EQ(metrics::PrinterEventProto::PRINTER_DELETED,
recorded_event.event_type());
// All printers record make and model information here.
EXPECT_EQ(kMakeAndModel, recorded_event.ipp_make_and_model());
// PPD info.
EXPECT_EQ(kEffectiveMakeAndModel, recorded_event.ppd_identifier());
EXPECT_FALSE(recorded_event.user_ppd());
// USB Info is not retained for removed printers.
EXPECT_FALSE(recorded_event.has_usb_printer_manufacturer());
EXPECT_FALSE(recorded_event.has_usb_printer_model());
EXPECT_FALSE(recorded_event.has_usb_vendor_id());
EXPECT_FALSE(recorded_event.has_usb_model_id());
}
} // namespace
} // namespace ash