// Copyright 2015 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 "ash/shelf/shelf_button_pressed_metric_tracker.h" #include #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_button_pressed_metric_tracker_test_api.h" #include "ash/shelf/shelf_view_test_api.h" #include "ash/test/ash_test_base.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" #include "base/test/simple_test_tick_clock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/event.h" #include "ui/events/test/test_event.h" #include "ui/views/controls/button/button.h" namespace ash { namespace { // A simple light weight test double dummy for a views::Button. class DummyButton : public views::Button { public: DummyButton(); DummyButton(const DummyButton&) = delete; DummyButton& operator=(const DummyButton&) = delete; }; DummyButton::DummyButton() : views::Button(views::Button::PressedCallback()) {} // Test fixture for the ShelfButtonPressedMetricTracker class. Relies on // AshTestBase to initilize the UserMetricsRecorder and it's dependencies. class ShelfButtonPressedMetricTrackerTest : public AshTestBase { public: static const char* kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName; ShelfButtonPressedMetricTrackerTest(); ShelfButtonPressedMetricTrackerTest( const ShelfButtonPressedMetricTrackerTest&) = delete; ShelfButtonPressedMetricTrackerTest& operator=( const ShelfButtonPressedMetricTrackerTest&) = delete; ~ShelfButtonPressedMetricTrackerTest() override; // AshTestBase: void SetUp() override; void TearDown() override; // Calls ButtonPressed on the test target with the given |event| // and dummy values for the |sender| and |performed_action| parameters. void ButtonPressed(const ui::Event& event); // Calls ButtonPressed on the test target with the given |performed_action| // and dummy values for the |event| and |sender| parameters. void ButtonPressed(ShelfAction performed_action); // Calls ButtonPressed on the test target with the given |sender| and // |performed_action| and a dummy value for the |event| parameter. void ButtonPressed(const views::Button* sender, ShelfAction performed_action); protected: // The test target. Not owned. ShelfButtonPressedMetricTracker* metric_tracker_; // The TickClock injected in to the test target. base::SimpleTestTickClock tick_clock_; }; const char* ShelfButtonPressedMetricTrackerTest:: kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName = ShelfButtonPressedMetricTracker:: kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName; ShelfButtonPressedMetricTrackerTest::ShelfButtonPressedMetricTrackerTest() = default; ShelfButtonPressedMetricTrackerTest::~ShelfButtonPressedMetricTrackerTest() = default; void ShelfButtonPressedMetricTrackerTest::SetUp() { AshTestBase::SetUp(); Shelf* shelf = GetPrimaryShelf(); ShelfViewTestAPI shelf_view_test_api(shelf->GetShelfViewForTesting()); metric_tracker_ = shelf_view_test_api.shelf_button_pressed_metric_tracker(); ShelfButtonPressedMetricTrackerTestAPI test_api(metric_tracker_); test_api.SetTickClock(&tick_clock_); // Ensure the TickClock->NowTicks() doesn't return base::TimeTicks because // ShelfButtonPressedMetricTracker interprets that value as unset. tick_clock_.Advance(base::Milliseconds(100)); } void ShelfButtonPressedMetricTrackerTest::TearDown() { AshTestBase::TearDown(); } void ShelfButtonPressedMetricTrackerTest::ButtonPressed( const ui::Event& event) { const DummyButton kDummyButton; metric_tracker_->ButtonPressed(event, &kDummyButton, SHELF_ACTION_NONE); } void ShelfButtonPressedMetricTrackerTest::ButtonPressed( ShelfAction performed_action) { const ui::test::TestEvent kDummyEvent(ui::ET_GESTURE_TAP); const DummyButton kDummyButton; metric_tracker_->ButtonPressed(kDummyEvent, &kDummyButton, performed_action); } void ShelfButtonPressedMetricTrackerTest::ButtonPressed( const views::Button* sender, ShelfAction performed_action) { const ui::test::TestEvent kDummyEvent(ui::ET_GESTURE_TAP); metric_tracker_->ButtonPressed(kDummyEvent, sender, performed_action); } } // namespace // Verifies that a Launcher_ButtonPressed_Mouse UMA user action is recorded when // a button is pressed by a mouse event. TEST_F(ShelfButtonPressedMetricTrackerTest, Launcher_ButtonPressed_MouseIsRecordedWhenIconActivatedByMouse) { const ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), base::TimeTicks(), 0, 0); base::UserActionTester user_action_tester; ButtonPressed(mouse_event); EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_ButtonPressed_Mouse")); } // Verifies that a Launcher_ButtonPressed_Touch UMA user action is recorded when // a button is pressed by a touch event. TEST_F(ShelfButtonPressedMetricTrackerTest, Launcher_ButtonPressed_MouseIsRecordedWhenIconActivatedByTouch) { const ui::TouchEvent touch_event( ui::ET_GESTURE_TAP, gfx::Point(), base::TimeTicks(), ui::PointerDetails(ui::EventPointerType::kTouch, 0)); base::UserActionTester user_action_tester; ButtonPressed(touch_event); EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_ButtonPressed_Touch")); } // Verifies that a Launcher_LaunchTask UMA user action is recorded when // pressing a button causes a new window to be created. TEST_F(ShelfButtonPressedMetricTrackerTest, Launcher_LaunchTaskIsRecordedWhenNewWindowIsCreated) { base::UserActionTester user_action_tester; ButtonPressed(SHELF_ACTION_NEW_WINDOW_CREATED); EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_LaunchTask")); } // Verifies that a Launcher_MinimizeTask UMA user action is recorded when // pressing a button causes an existing window to be minimized. TEST_F(ShelfButtonPressedMetricTrackerTest, Launcher_MinimizeTaskIsRecordedWhenWindowIsMinimized) { base::UserActionTester user_action_tester; ButtonPressed(SHELF_ACTION_WINDOW_MINIMIZED); EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_MinimizeTask")); } // Verifies that a Launcher_SwitchTask UMA user action is recorded when // pressing a button causes an existing window to be activated. TEST_F(ShelfButtonPressedMetricTrackerTest, Launcher_SwitchTaskIsRecordedWhenExistingWindowIsActivated) { base::UserActionTester user_action_tester; ButtonPressed(SHELF_ACTION_WINDOW_ACTIVATED); EXPECT_EQ(1, user_action_tester.GetActionCount("Launcher_SwitchTask")); } // Verify that a window activation action will record a data point if it was // subsequent to a minimize action. TEST_F(ShelfButtonPressedMetricTrackerTest, VerifyDataRecordedAfterMinimizedAndSubsequentActivatedAction) { const DummyButton kDummyButton; base::HistogramTester histogram_tester; ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 0); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 1); } // Verify that a multiple window activation actions will record a single data // point if they are subsequent to a minimize action. TEST_F(ShelfButtonPressedMetricTrackerTest, VerifyDataRecordedAfterMinimizedAndMultipleSubsequentActivatedActions) { const DummyButton kDummyButton; base::HistogramTester histogram_tester; ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 1); } // Verify that a window activation action will not record a data point if it was // not subsequent to a minimize action. TEST_F(ShelfButtonPressedMetricTrackerTest, VerifyDataRecordedAfterMinimizedAndNonSubsequentActivatedAction) { const DummyButton kDummyButton; base::HistogramTester histogram_tester; ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); ButtonPressed(&kDummyButton, SHELF_ACTION_APP_LIST_SHOWN); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 0); } // Verify no data is recorded if a second source button is pressed in between // subsequent minimized and activated actions on the same source. TEST_F(ShelfButtonPressedMetricTrackerTest, VerifyDataRecordedAfterMinimizedButtonA) { const DummyButton kDummyButton; const DummyButton kSecondDummyButton; base::HistogramTester histogram_tester; ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); ButtonPressed(&kSecondDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 0); } // Verify the data value recorded when a window activation action is subsequent // to a minimize action. TEST_F(ShelfButtonPressedMetricTrackerTest, VerifyTheValueRecordedBySubsequentMinimizedAndActivateActions) { const int kTimeDeltaInMilliseconds = 17; const DummyButton kDummyButton; base::HistogramTester histogram_tester; ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_MINIMIZED); tick_clock_.Advance(base::Milliseconds(kTimeDeltaInMilliseconds)); ButtonPressed(&kDummyButton, SHELF_ACTION_WINDOW_ACTIVATED); histogram_tester.ExpectTotalCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, 1); histogram_tester.ExpectBucketCount( kTimeBetweenWindowMinimizedAndActivatedActionsHistogramName, kTimeDeltaInMilliseconds, 1); } } // namespace ash