| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/printing/printer_event_tracker.h" |
| |
| #include "base/macros.h" |
| #include "base/time/time.h" |
| #include "chromeos/printing/printer_configuration.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/metrics_proto/printer_event.pb.h" |
| |
| namespace chromeos { |
| namespace { |
| |
| 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"; |
| |
| class PrinterEventTrackerTest : public testing::Test { |
| public: |
| PrinterEventTrackerTest() = default; |
| ~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; |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(PrinterEventTrackerTest); |
| }; |
| |
| 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); |
| |
| 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); |
| |
| 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); |
| |
| 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; |
| |
| tracker_.RecordIppPrinterInstalled(test_printer, PrinterEventTracker::kUser); |
| |
| 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_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; |
| |
| tracker_.RecordIppPrinterInstalled( |
| test_printer, PrinterEventTracker::SetupMode::kAutomatic); |
| |
| 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()); |
| // 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::SetupMode::kUser); |
| |
| 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.printer.set_manufacturer(kUsbManufacturer); |
| usb_printer.printer.set_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.printer.set_manufacturer(kUsbManufacturer); |
| usb_printer.printer.set_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 chromeos |