| // Copyright 2021 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/app_list/app_list_feature_usage_metrics.h" |
| |
| #include "ash/app_list/app_list_controller_impl.h" |
| #include "ash/constants/ash_features.h" |
| #include "ash/constants/ash_switches.h" |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "base/command_line.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "chromeos/components/feature_usage/feature_usage_metrics.h" |
| #include "components/user_manager/user_type.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace ash { |
| namespace { |
| |
| // Expanded metric names recorded by FeatureUsageMetrics. |
| constexpr char kClamshellMetric[] = "ChromeOS.FeatureUsage.ClamshellLauncher"; |
| constexpr char kClamshellUsetimeMetric[] = |
| "ChromeOS.FeatureUsage.ClamshellLauncher.Usetime"; |
| constexpr char kTabletMetric[] = "ChromeOS.FeatureUsage.TabletLauncher"; |
| constexpr char kTabletUsetimeMetric[] = |
| "ChromeOS.FeatureUsage.TabletLauncher.Usetime"; |
| |
| // Shorten these identifiers for readability. |
| constexpr int kEligible = |
| static_cast<int>(feature_usage::FeatureUsageMetrics::Event::kEligible); |
| constexpr int kEnabled = |
| static_cast<int>(feature_usage::FeatureUsageMetrics::Event::kEnabled); |
| constexpr int kUsedWithSuccess = static_cast<int>( |
| feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess); |
| |
| // Uses NoSessionAshTestBase because some tests need to simulate kiosk login. |
| // Tests are optionally parameterized by feature ProductivityLauncher. |
| class AppListFeatureUsageMetricsTest |
| : public NoSessionAshTestBase, |
| public testing::WithParamInterface<bool> { |
| public: |
| AppListFeatureUsageMetricsTest() |
| : NoSessionAshTestBase( |
| base::test::TaskEnvironment::TimeSource::MOCK_TIME) { |
| // Support both TEST_F and TEST_P. |
| if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) { |
| feature_list_.InitWithFeatureState(features::kProductivityLauncher, |
| GetParam()); |
| } |
| } |
| ~AppListFeatureUsageMetricsTest() override = default; |
| |
| // Simulates a device that supports tablet mode. |
| void SimulateTabletModeSupport() { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kAshEnableTabletMode); |
| Shell::Get()->tablet_mode_controller()->OnECLidAngleDriverStatusChanged( |
| /*is_supported=*/true); |
| } |
| |
| void FastForwardBy(base::TimeDelta delta) { |
| task_environment()->FastForwardBy(delta); |
| } |
| |
| // Fast forwards the clock past the time when FeatureUsageMetrics reports |
| // its initial set of eligible/enabled metrics. |
| void FastForwardPastMetricsReportingInterval() { |
| FastForwardBy(feature_usage::FeatureUsageMetrics::kInitialInterval); |
| } |
| |
| base::test::ScopedFeatureList feature_list_; |
| base::HistogramTester histograms_; |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(ProductivityLauncher, |
| AppListFeatureUsageMetricsTest, |
| testing::Bool()); |
| |
| TEST_F(AppListFeatureUsageMetricsTest, CountsStartAtZero) { |
| SimulateUserLogin("user@gmail.com"); |
| |
| histograms_.ExpectTotalCount(kClamshellMetric, 0); |
| histograms_.ExpectTotalCount(kClamshellUsetimeMetric, 0); |
| histograms_.ExpectTotalCount(kTabletMetric, 0); |
| histograms_.ExpectTotalCount(kTabletUsetimeMetric, 0); |
| } |
| |
| TEST_F(AppListFeatureUsageMetricsTest, InitialMetricsWithoutTabletModeSupport) { |
| ASSERT_FALSE(Shell::Get()->tablet_mode_controller()->CanEnterTabletMode()); |
| |
| SimulateUserLogin("user@gmail.com"); |
| FastForwardPastMetricsReportingInterval(); |
| |
| histograms_.ExpectBucketCount(kClamshellMetric, kEligible, 1); |
| histograms_.ExpectBucketCount(kClamshellMetric, kEnabled, 1); |
| // Not eligible for tablet mode. |
| histograms_.ExpectBucketCount(kTabletMetric, kEligible, 0); |
| histograms_.ExpectBucketCount(kTabletMetric, kEnabled, 0); |
| } |
| |
| TEST_F(AppListFeatureUsageMetricsTest, InitialMetricsWithTabletModeSupport) { |
| SimulateTabletModeSupport(); |
| ASSERT_TRUE(Shell::Get()->tablet_mode_controller()->CanEnterTabletMode()); |
| |
| SimulateUserLogin("user@gmail.com"); |
| FastForwardPastMetricsReportingInterval(); |
| |
| histograms_.ExpectBucketCount(kClamshellMetric, kEligible, 1); |
| histograms_.ExpectBucketCount(kClamshellMetric, kEnabled, 1); |
| // Eligible for tablet mode. |
| histograms_.ExpectBucketCount(kTabletMetric, kEligible, 1); |
| histograms_.ExpectBucketCount(kTabletMetric, kEnabled, 1); |
| } |
| |
| TEST_F(AppListFeatureUsageMetricsTest, NotEligibleInKioskMode) { |
| SimulateKioskMode(user_manager::USER_TYPE_KIOSK_APP); |
| FastForwardPastMetricsReportingInterval(); |
| |
| histograms_.ExpectBucketCount(kClamshellMetric, kEligible, 0); |
| histograms_.ExpectBucketCount(kClamshellMetric, kEnabled, 0); |
| histograms_.ExpectBucketCount(kTabletMetric, kEligible, 0); |
| histograms_.ExpectBucketCount(kTabletMetric, kEnabled, 0); |
| } |
| |
| TEST_P(AppListFeatureUsageMetricsTest, ShowAndHideLauncherInClamshell) { |
| SimulateUserLogin("user@gmail.com"); |
| Shell::Get()->app_list_controller()->ShowAppList(); |
| histograms_.ExpectBucketCount(kClamshellMetric, kUsedWithSuccess, 1); |
| |
| const base::TimeDelta kUsetime = base::Seconds(2); |
| FastForwardBy(kUsetime); |
| Shell::Get()->app_list_controller()->DismissAppList(); |
| histograms_.ExpectTimeBucketCount(kClamshellUsetimeMetric, kUsetime, 1); |
| |
| // Tablet usage is not recorded. |
| histograms_.ExpectTotalCount(kTabletUsetimeMetric, 0); |
| } |
| |
| TEST_P(AppListFeatureUsageMetricsTest, ShowAndHideLauncherInTablet) { |
| SimulateTabletModeSupport(); |
| ASSERT_TRUE(Shell::Get()->tablet_mode_controller()->CanEnterTabletMode()); |
| SimulateUserLogin("user@gmail.com"); |
| |
| // Entering tablet mode shows the home screen launcher. |
| Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); |
| histograms_.ExpectBucketCount(kTabletMetric, kUsedWithSuccess, 1); |
| |
| const base::TimeDelta kUsetime = base::Seconds(2); |
| FastForwardBy(kUsetime); |
| // Creating a window hides the launcher. |
| std::unique_ptr<views::Widget> widget = CreateTestWidget(); |
| histograms_.ExpectTimeBucketCount(kTabletUsetimeMetric, kUsetime, 1); |
| |
| // Clamshell usage is not recorded. |
| histograms_.ExpectTotalCount(kClamshellUsetimeMetric, 0); |
| } |
| |
| TEST_P(AppListFeatureUsageMetricsTest, |
| EnterTabletModeWithLauncherAndWindowOpen) { |
| SimulateTabletModeSupport(); |
| ASSERT_TRUE(Shell::Get()->tablet_mode_controller()->CanEnterTabletMode()); |
| SimulateUserLogin("user@gmail.com"); |
| std::unique_ptr<views::Widget> widget = CreateTestWidget(); |
| Shell::Get()->app_list_controller()->ShowAppList(); |
| |
| // Entering tablet mode with a window open does not show the launcher. |
| Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); |
| FastForwardBy(base::Seconds(1)); |
| histograms_.ExpectTotalCount(kTabletUsetimeMetric, 0); |
| |
| // Show the tablet launcher for 1 second. |
| Shell::Get()->app_list_controller()->GoHome(GetPrimaryDisplay().id()); |
| FastForwardBy(base::Seconds(1)); |
| Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); |
| |
| // Only 1 second of usage is recorded. |
| histograms_.ExpectTimeBucketCount(kTabletUsetimeMetric, base::Seconds(1), 1); |
| } |
| |
| TEST_P(AppListFeatureUsageMetricsTest, OpenClamshellThenTabletThenExit) { |
| SimulateTabletModeSupport(); |
| SimulateUserLogin("user@gmail.com"); |
| |
| Shell::Get()->app_list_controller()->ShowAppList(); |
| histograms_.ExpectBucketCount(kClamshellMetric, kUsedWithSuccess, 1); |
| |
| // Switching from clamshell to tablet with the launcher open records usage |
| // time for clamshell launcher and starts a tablet launcher usage session. |
| const base::TimeDelta kClamshellUsetime = base::Seconds(1); |
| FastForwardBy(kClamshellUsetime); |
| Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); |
| histograms_.ExpectTimeBucketCount(kClamshellUsetimeMetric, kClamshellUsetime, |
| 1); |
| histograms_.ExpectBucketCount(kTabletMetric, kUsedWithSuccess, 1); |
| |
| // Ending tablet mode records usage time for tablet launcher. |
| const base::TimeDelta kTabletUsetime = base::Seconds(2); |
| FastForwardBy(kTabletUsetime); |
| Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); |
| histograms_.ExpectTimeBucketCount(kTabletUsetimeMetric, kTabletUsetime, 1); |
| } |
| |
| } // namespace |
| } // namespace ash |