| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/metrics/demo_session_metrics_recorder.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "ash/constants/app_types.h" |
| #include "ash/metrics/user_metrics_recorder.h" |
| #include "ash/public/cpp/shelf_types.h" |
| #include "ash/public/cpp/window_properties.h" |
| #include "ash/shelf/home_button.h" |
| #include "ash/shelf/shelf.h" |
| #include "ash/shelf/shelf_navigation_widget.h" |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "ash/wm/window_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/timer/mock_timer.h" |
| #include "components/app_constants/constants.h" |
| #include "extensions/common/constants.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/aura/client/window_types.h" |
| #include "ui/aura/test/test_window_delegate.h" |
| #include "ui/aura/window.h" |
| #include "ui/wm/public/activation_client.h" |
| |
| namespace ash { |
| namespace { |
| |
| // Tests app usage recorded by DemoSessionMetricsRecorder. |
| // Mocks out the timer to control the sampling cycle. Tests will create and |
| // activate different window types to test that samples are attributed to the |
| // correct apps. Tests will also fire the timer continuously without user |
| // activity to simulate idle time and verify that idle samples are dropped. |
| class DemoSessionMetricsRecorderTest : public AshTestBase { |
| public: |
| DemoSessionMetricsRecorderTest() |
| : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} |
| |
| DemoSessionMetricsRecorderTest(const DemoSessionMetricsRecorderTest&) = |
| delete; |
| DemoSessionMetricsRecorderTest& operator=( |
| const DemoSessionMetricsRecorderTest&) = delete; |
| |
| ~DemoSessionMetricsRecorderTest() override = default; |
| |
| // AshTestBase: |
| void SetUp() override { |
| AshTestBase::SetUp(); |
| |
| // Create mock timer to be passed into DemoSessionMetricsRecorder. |
| std::unique_ptr<base::RepeatingTimer> mock_timer = |
| std::make_unique<base::MockRepeatingTimer>(); |
| // Store a pointer to the timer before moving it. |
| mock_timer_ = static_cast<base::MockRepeatingTimer*>(mock_timer.get()); |
| metrics_recorder_ = |
| std::make_unique<DemoSessionMetricsRecorder>(std::move(mock_timer)); |
| |
| histogram_tester_ = std::make_unique<base::HistogramTester>(); |
| } |
| |
| void TearDown() override { |
| metrics_recorder_.reset(); |
| AshTestBase::TearDown(); |
| } |
| |
| // Fires the timer, if it's running. (If it's stopped, we can assume any |
| // amount of time passes here.) |
| void FireTimer() { |
| if (mock_timer_->IsRunning()) |
| mock_timer_->Fire(); |
| } |
| |
| // Simulates user activity. |
| void SendUserActivity() { metrics_recorder_->OnUserActivity(nullptr); } |
| |
| void ClearHistograms() { |
| histogram_tester_ = std::make_unique<base::HistogramTester>(); |
| } |
| |
| // Clears the metrics recorder and the timer to simulate the session ending. |
| void DeleteMetricsRecorder() { |
| mock_timer_ = nullptr; |
| metrics_recorder_.reset(); |
| } |
| |
| // Creates a browser window. |
| std::unique_ptr<aura::Window> CreateBrowserWindow() { |
| std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( |
| aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 0, |
| gfx::Rect(0, 0, 10, 10))); |
| window->SetProperty(aura::client::kAppType, |
| static_cast<int>(ash::AppType::BROWSER)); |
| return window; |
| } |
| |
| // Creates a browser window associated with a hosted app. |
| std::unique_ptr<aura::Window> CreateHostedAppBrowserWindow( |
| const std::string& app_id) { |
| std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( |
| aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 0, |
| gfx::Rect(0, 0, 10, 10))); |
| window->SetProperty(aura::client::kAppType, |
| static_cast<int>(ash::AppType::BROWSER)); |
| window->SetProperty( |
| kShelfIDKey, |
| new std::string(ShelfID(app_id, std::string()).Serialize())); |
| return window; |
| } |
| |
| // Creates a normal Chrome platform app window. |
| std::unique_ptr<aura::Window> CreateChromeAppWindow( |
| const std::string& app_id) { |
| std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( |
| aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 0, |
| gfx::Rect(0, 0, 10, 10))); |
| window->SetProperty(aura::client::kAppType, |
| static_cast<int>(ash::AppType::CHROME_APP)); |
| window->SetProperty( |
| kShelfIDKey, |
| new std::string(ShelfID(app_id, std::string()).Serialize())); |
| return window; |
| } |
| |
| // Creates a normal ARC++ app window. |
| std::unique_ptr<aura::Window> CreateArcWindow( |
| const std::string& package_name) { |
| std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate( |
| aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), 0, |
| gfx::Rect(0, 0, 10, 10))); |
| window->SetProperty(aura::client::kAppType, |
| static_cast<int>(ash::AppType::ARC_APP)); |
| |
| // ARC++ shelf app IDs are hashes of package_name#activity_name formatted as |
| // extension IDs. The point is that they are opaque to the metrics recorder. |
| const std::string app_id = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; |
| window->SetProperty( |
| kShelfIDKey, |
| new std::string(ShelfID(app_id, std::string()).Serialize())); |
| if (!package_name.empty()) |
| window->SetProperty(kArcPackageNameKey, package_name); |
| return window; |
| } |
| |
| // Creates a popup type window. |
| std::unique_ptr<aura::Window> CreatePopupWindow() { |
| std::unique_ptr<aura::Window> window( |
| CreateTestWindowInShellWithDelegateAndType( |
| aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), |
| aura::client::WINDOW_TYPE_POPUP, 0, gfx::Rect(0, 0, 10, 10))); |
| return window; |
| } |
| |
| // Simulates user clicking on home button. |
| void ClickOnHomeButtion() { |
| AshTestBase::LeftClickOn( |
| AshTestBase::GetPrimaryShelf()->navigation_widget()->GetHomeButton()); |
| } |
| |
| // Simulates user clicking on the test window. |
| void ClickMouseOnTestWindow() { |
| ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), |
| CreateBrowserWindow().get()); |
| generator.ClickLeftButton(); |
| } |
| |
| // Simulates user pressing the screen on the test window. |
| void GesturePressWindow() { |
| ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), |
| CreateBrowserWindow().get()); |
| generator.GestureTapAt(gfx::Point(0, 0)); |
| } |
| |
| protected: |
| // Captures histograms. |
| std::unique_ptr<base::HistogramTester> histogram_tester_; |
| |
| // The test target. |
| std::unique_ptr<DemoSessionMetricsRecorder> metrics_recorder_; |
| |
| // Owned by metics_recorder_. |
| raw_ptr<base::MockRepeatingTimer, DanglingUntriaged> mock_timer_ = nullptr; |
| }; |
| |
| // Verify samples are correct when one app window is active. |
| TEST_F(DemoSessionMetricsRecorderTest, ActiveApp) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kHighlightsAppId); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 5; i++) |
| FireTimer(); |
| |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectUniqueSample( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kHighlights, 5); |
| } |
| |
| // Verify samples are correct when multiple browser windows become active. |
| TEST_F(DemoSessionMetricsRecorderTest, BrowserWindows) { |
| std::unique_ptr<aura::Window> browser_window = CreateBrowserWindow(); |
| std::unique_ptr<aura::Window> browser_window2 = CreateBrowserWindow(); |
| |
| // Browser windows should all be treated as the same type. |
| wm::ActivateWindow(browser_window.get()); |
| FireTimer(); |
| wm::ActivateWindow(browser_window2.get()); |
| FireTimer(); |
| FireTimer(); |
| |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectUniqueSample( |
| "DemoMode.ActiveApp", DemoSessionMetricsRecorder::DemoModeApp::kBrowser, |
| 3); |
| } |
| |
| // Verify samples are correct when multiple windows types become active. |
| TEST_F(DemoSessionMetricsRecorderTest, AppTypes) { |
| std::unique_ptr<aura::Window> browser_window = CreateBrowserWindow(); |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| std::unique_ptr<aura::Window> hosted_app_browser_window = |
| CreateHostedAppBrowserWindow(extension_misc::kYoutubeAppId); |
| std::unique_ptr<aura::Window> arc_window = |
| CreateArcWindow("com.google.Photos"); |
| |
| wm::ActivateWindow(browser_window.get()); |
| FireTimer(); |
| SendUserActivity(); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", DemoSessionMetricsRecorder::DemoModeApp::kBrowser, |
| 1); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| FireTimer(); |
| FireTimer(); |
| SendUserActivity(); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 2); |
| |
| wm::ActivateWindow(hosted_app_browser_window.get()); |
| FireTimer(); |
| FireTimer(); |
| FireTimer(); |
| SendUserActivity(); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", DemoSessionMetricsRecorder::DemoModeApp::kYouTube, |
| 3); |
| |
| wm::ActivateWindow(arc_window.get()); |
| FireTimer(); |
| FireTimer(); |
| FireTimer(); |
| FireTimer(); |
| SendUserActivity(); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 4); |
| |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 10); |
| } |
| |
| // Verify samples are correct when multiple windows types become active. |
| TEST_F(DemoSessionMetricsRecorderTest, ActiveAppAfterDelayedArcPackageName) { |
| // Create an ARC window with an empty package name. |
| std::unique_ptr<aura::Window> arc_window = CreateArcWindow(""); |
| |
| wm::ActivateWindow(arc_window.get()); |
| FireTimer(); |
| SendUserActivity(); |
| |
| // There should be no app activity recorded yet, because there was |
| // no package name in the ARC window. |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| |
| // Set the package name after window creation/activation. |
| arc_window->SetProperty(kArcPackageNameKey, |
| new std::string("com.google.Photos")); |
| |
| // Trigger sample reporting by sending user activity. |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 1); |
| |
| // Set the package name again. The count shouldn't change because |
| // after getting the package name once, we stop observing the |
| // window. |
| arc_window->SetProperty(kArcPackageNameKey, |
| new std::string("com.google.Photos")); |
| // Trigger sample reporting by sending user activity. |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 1); |
| |
| // Delete the window. |
| arc_window.reset(); |
| |
| // Trigger sample reporting by sending user activity. |
| SendUserActivity(); |
| |
| // The count should not be affected. |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 1); |
| } |
| |
| // Verify popup windows are categorized as kOtherWindow. |
| TEST_F(DemoSessionMetricsRecorderTest, PopupWindows) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| std::unique_ptr<aura::Window> popup_window = CreatePopupWindow(); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 5; i++) |
| FireTimer(); |
| |
| wm::ActivateWindow(popup_window.get()); |
| for (int i = 0; i < 3; i++) |
| FireTimer(); |
| |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 5); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kOtherWindow, 3); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 8); |
| } |
| |
| // Verify unknown apps are categorized as "other" Chrome/ARC apps. |
| TEST_F(DemoSessionMetricsRecorderTest, OtherApps) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); |
| std::unique_ptr<aura::Window> arc_window = CreateArcWindow("com.foo.bar"); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| FireTimer(); |
| |
| wm::ActivateWindow(arc_window.get()); |
| FireTimer(); |
| FireTimer(); |
| |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kOtherChromeApp, 1); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kOtherArcApp, 2); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 3); |
| } |
| |
| // Verify samples are discarded after no user activity. |
| TEST_F(DemoSessionMetricsRecorderTest, DiscardAfterInactivity) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| std::unique_ptr<aura::Window> arc_window = |
| CreateChromeAppWindow("com.google.Photos"); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 5; i++) |
| FireTimer(); |
| |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectUniqueSample( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 5); |
| ClearHistograms(); |
| |
| // Have no user activity for 20 seconds. |
| for (int i = 0; i < 20; i++) |
| FireTimer(); |
| |
| // After user activity, the active window from the idle time isn't reported. |
| SendUserActivity(); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| } |
| |
| // Verify sample collection resumes after user activity. |
| TEST_F(DemoSessionMetricsRecorderTest, ResumeAfterActivity) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| |
| // Have no user activity for 20 seconds. |
| for (int i = 0; i < 20; i++) |
| FireTimer(); |
| |
| // Now send user activity. |
| SendUserActivity(); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| |
| // Sample collection should resume. |
| for (int i = 0; i < 5; i++) |
| FireTimer(); |
| SendUserActivity(); |
| histogram_tester_->ExpectUniqueSample( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 5); |
| } |
| |
| // Verify window activation during idle time doesn't trigger reporting. |
| TEST_F(DemoSessionMetricsRecorderTest, ActivateWindowWhenIdle) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| std::unique_ptr<aura::Window> chrome_app_window2 = |
| CreateChromeAppWindow(extension_misc::kGoogleKeepAppId); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| |
| // Even if the active window changes, which can happen automatically, these |
| // samples shouldn't be reported. |
| for (int i = 0; i < 10; i++) |
| FireTimer(); |
| wm::ActivateWindow(chrome_app_window2.get()); |
| for (int i = 0; i < 10; i++) |
| FireTimer(); |
| |
| SendUserActivity(); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, RepeatedUserActivity) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| std::unique_ptr<aura::Window> arc_window = |
| CreateArcWindow("com.google.Photos"); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| |
| FireTimer(); |
| SendUserActivity(); |
| SendUserActivity(); |
| |
| // Switching between windows in between samples isn't recorded, even with user |
| // action. |
| FireTimer(); |
| SendUserActivity(); |
| wm::ActivateWindow(arc_window.get()); |
| SendUserActivity(); |
| wm::ActivateWindow(chrome_app_window.get()); |
| SendUserActivity(); |
| |
| FireTimer(); |
| wm::ActivateWindow(arc_window.get()); |
| SendUserActivity(); |
| SendUserActivity(); |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectUniqueSample( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 3); |
| } |
| |
| // Verify remaining samples are recorded on exit. |
| TEST_F(DemoSessionMetricsRecorderTest, RecordOnExit) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kGoogleKeepAppId); |
| std::unique_ptr<aura::Window> arc_window = |
| CreateArcWindow("com.google.Photos"); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 2; i++) |
| FireTimer(); |
| wm::ActivateWindow(arc_window.get()); |
| for (int i = 0; i < 4; i++) |
| FireTimer(); |
| |
| DeleteMetricsRecorder(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGoogleKeepChromeApp, 2); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 4); |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 6); |
| } |
| |
| // Verify remaining samples are not recorded on exit because the user became |
| // idle. |
| TEST_F(DemoSessionMetricsRecorderTest, IgnoreOnIdleExit) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kFilesManagerAppId); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 10; i++) |
| FireTimer(); |
| SendUserActivity(); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.ActiveApp", DemoSessionMetricsRecorder::DemoModeApp::kFiles, |
| 10); |
| ClearHistograms(); |
| |
| for (int i = 0; i < 20; i++) |
| FireTimer(); |
| |
| DeleteMetricsRecorder(); |
| |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| } |
| |
| // Verify remaining samples are not recorded on exit when the user was idle the |
| // whole time. |
| TEST_F(DemoSessionMetricsRecorderTest, IgnoreOnIdleSession) { |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kHighlightsAppId); |
| |
| wm::ActivateWindow(chrome_app_window.get()); |
| for (int i = 0; i < 20; i++) |
| FireTimer(); |
| |
| DeleteMetricsRecorder(); |
| |
| histogram_tester_->ExpectTotalCount("DemoMode.ActiveApp", 0); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, UniqueAppsLaunchedOnDeletion) { |
| // Activate each window twice. Despite activating each twice, |
| // the count should only be incremented once per unique app. |
| std::unique_ptr<aura::Window> chrome_app_window = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| wm::ActivateWindow(chrome_app_window.get()); |
| wm::DeactivateWindow(chrome_app_window.get()); |
| wm::ActivateWindow(chrome_app_window.get()); |
| |
| std::unique_ptr<aura::Window> chrome_browser_window = |
| CreateChromeAppWindow(app_constants::kChromeAppId); |
| wm::ActivateWindow(chrome_browser_window.get()); |
| wm::DeactivateWindow(chrome_browser_window.get()); |
| wm::ActivateWindow(chrome_browser_window.get()); |
| |
| std::unique_ptr<aura::Window> arc_window_1 = |
| CreateArcWindow("com.google.Photos"); |
| wm::ActivateWindow(arc_window_1.get()); |
| wm::DeactivateWindow(arc_window_1.get()); |
| wm::ActivateWindow(arc_window_1.get()); |
| |
| std::unique_ptr<aura::Window> arc_window_2 = |
| CreateArcWindow("com.google.Maps"); |
| wm::ActivateWindow(arc_window_2.get()); |
| wm::DeactivateWindow(arc_window_2.get()); |
| wm::ActivateWindow(arc_window_2.get()); |
| |
| // Popup windows shouldn't be counted at all. |
| std::unique_ptr<aura::Window> popup_window = CreatePopupWindow(); |
| wm::ActivateWindow(popup_window.get()); |
| wm::DeactivateWindow(popup_window.get()); |
| wm::ActivateWindow(popup_window.get()); |
| |
| DeleteMetricsRecorder(); |
| |
| histogram_tester_->ExpectUniqueSample("DemoMode.UniqueAppsLaunched", 4, 1); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, |
| NoUniqueAppsLaunchedOnMissingArcPackageName) { |
| // Create an ARC window with no package name set yet |
| std::unique_ptr<aura::Window> arc_window_1 = CreateArcWindow(""); |
| wm::ActivateWindow(arc_window_1.get()); |
| |
| DeleteMetricsRecorder(); |
| |
| // There shuld be no unique apps reported if there was no package name. |
| histogram_tester_->ExpectUniqueSample("DemoMode.UniqueAppsLaunched", 0, 1); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, |
| UniqueAppsLaunchedOnDelayedArcPackageName) { |
| // Create an ARC window with no package name set yet. |
| std::unique_ptr<aura::Window> arc_window_1 = CreateArcWindow(""); |
| wm::ActivateWindow(arc_window_1.get()); |
| |
| // Set the package name after window creation/activation. |
| arc_window_1->SetProperty(kArcPackageNameKey, |
| new std::string("com.google.Photos")); |
| |
| // Set the package name again. This shouldn't cause a double-recording |
| // of the stat. |
| arc_window_1->SetProperty(kArcPackageNameKey, |
| new std::string("com.google.Photos")); |
| |
| // Delete the window. |
| arc_window_1.reset(); |
| |
| std::unique_ptr<aura::Window> arc_window_2 = |
| CreateArcWindow("com.google.Maps"); |
| wm::ActivateWindow(arc_window_2.get()); |
| |
| DeleteMetricsRecorder(); |
| |
| // There should be 2 unique apps reported. |
| histogram_tester_->ExpectUniqueSample("DemoMode.UniqueAppsLaunched", 2, 1); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, NoUniqueAppsLaunchedOnDeletion) { |
| DeleteMetricsRecorder(); |
| |
| // There should be no samples if the recorder is deleted with 0 unique apps |
| // launched. |
| histogram_tester_->ExpectUniqueSample("DemoMode.UniqueAppsLaunched", 0, 1); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, AppLaunched) { |
| // Activate each window twice. Despite activating each twice, |
| // the sample should only be incremented once per unique app, except |
| // for apps for which we don't have enums, which all get recorded |
| // as "other" apps. |
| |
| // Chrome browser window |
| std::unique_ptr<aura::Window> chrome_browser_window = |
| CreateChromeAppWindow(app_constants::kChromeAppId); |
| wm::ActivateWindow(chrome_browser_window.get()); |
| wm::DeactivateWindow(chrome_browser_window.get()); |
| wm::ActivateWindow(chrome_browser_window.get()); |
| |
| // Chrome apps |
| std::unique_ptr<aura::Window> chrome_app_window_1 = |
| CreateChromeAppWindow(extension_misc::kCalculatorAppId); |
| wm::ActivateWindow(chrome_app_window_1.get()); |
| wm::DeactivateWindow(chrome_app_window_1.get()); |
| wm::ActivateWindow(chrome_app_window_1.get()); |
| |
| // The following 2 activations should get recorded as kOtherChromeApp |
| std::unique_ptr<aura::Window> chrome_app_window_2 = |
| CreateChromeAppWindow("otherappid2"); |
| wm::ActivateWindow(chrome_app_window_2.get()); |
| wm::DeactivateWindow(chrome_app_window_2.get()); |
| wm::ActivateWindow(chrome_app_window_2.get()); |
| |
| std::unique_ptr<aura::Window> chrome_app_window_3 = |
| CreateChromeAppWindow("otherappid3"); |
| wm::ActivateWindow(chrome_app_window_3.get()); |
| wm::DeactivateWindow(chrome_app_window_3.get()); |
| wm::ActivateWindow(chrome_app_window_3.get()); |
| |
| // ARC Apps |
| std::unique_ptr<aura::Window> arc_window_1 = |
| CreateArcWindow("com.google.Photos"); |
| wm::ActivateWindow(arc_window_1.get()); |
| wm::DeactivateWindow(arc_window_1.get()); |
| wm::ActivateWindow(arc_window_1.get()); |
| |
| std::unique_ptr<aura::Window> arc_window_2 = |
| CreateArcWindow("com.google.Sheets"); |
| wm::ActivateWindow(arc_window_2.get()); |
| wm::DeactivateWindow(arc_window_2.get()); |
| wm::ActivateWindow(arc_window_2.get()); |
| |
| // The following 2 activations should get recorded as kOtherArcApp |
| std::unique_ptr<aura::Window> arc_window_3 = |
| CreateArcWindow("com.some.other.App3"); |
| wm::ActivateWindow(arc_window_3.get()); |
| wm::DeactivateWindow(arc_window_3.get()); |
| wm::ActivateWindow(arc_window_3.get()); |
| |
| std::unique_ptr<aura::Window> arc_window_4 = |
| CreateArcWindow("com.some.other.App4"); |
| wm::ActivateWindow(arc_window_4.get()); |
| wm::DeactivateWindow(arc_window_4.get()); |
| wm::ActivateWindow(arc_window_4.get()); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", DemoSessionMetricsRecorder::DemoModeApp::kBrowser, |
| 1); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", |
| DemoSessionMetricsRecorder::DemoModeApp::kCalculator, 1); |
| // We should see 2 "other chrome apps" |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", |
| DemoSessionMetricsRecorder::DemoModeApp::kOtherChromeApp, 2); |
| |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", |
| DemoSessionMetricsRecorder::DemoModeApp::kGooglePhotos, 1); |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", |
| DemoSessionMetricsRecorder::DemoModeApp::kGoogleSheetsAndroidApp, 1); |
| // We should see 2 "other arc apps" |
| histogram_tester_->ExpectBucketCount( |
| "DemoMode.AppLaunched", |
| DemoSessionMetricsRecorder::DemoModeApp::kOtherArcApp, 2); |
| } |
| |
| TEST_F(DemoSessionMetricsRecorderTest, DwellTime) { |
| // Simulate user activity for 10 seconds. |
| SendUserActivity(); |
| |
| task_environment()->FastForwardBy(base::Seconds(5)); |
| SendUserActivity(); |
| |
| task_environment()->FastForwardBy(base::Seconds(5)); |
| SendUserActivity(); |
| |
| // Simulate a session "timing out" after 60 seconds. |
| task_environment()->FastForwardBy(base::Seconds(60)); |
| DeleteMetricsRecorder(); |
| |
| // The recorded dwell time should be 10 seconds. |
| histogram_tester_->ExpectUniqueSample("DemoMode.DwellTime", 10, 1); |
| } |
| |
| // Within the demo session, test user clicks the home button on shelf, clicks on |
| // the test window twice and presses the screen, then the UserClickesAndPresses |
| // should be 4. |
| TEST_F(DemoSessionMetricsRecorderTest, |
| UserClicksAndPressesEqualsThreeInDemoSession) { |
| TestSessionControllerClient* session = |
| AshTestBase::GetSessionControllerClient(); |
| session->SetIsDemoSession(); |
| |
| ClickMouseOnTestWindow(); |
| ClickMouseOnTestWindow(); |
| ClickOnHomeButtion(); |
| GesturePressWindow(); |
| |
| ash::Shell::Get()->metrics()->OnShellShuttingDown(); |
| |
| // The recorded count UserInteracted should be 4, with one sample recorded. |
| histogram_tester_->ExpectUniqueSample( |
| DemoSessionMetricsRecorder::kUserClicksAndPressesMetric, 4, 1); |
| } |
| |
| // Within the demo session, test user does not do any clicks/presses, then the |
| // UserClickesAndPresses should be 0. |
| TEST_F(DemoSessionMetricsRecorderTest, |
| UserClicksAndPressesEqualsZeroInDemoSession) { |
| TestSessionControllerClient* session = |
| AshTestBase::GetSessionControllerClient(); |
| session->SetIsDemoSession(); |
| |
| ash::Shell::Get()->metrics()->OnShellShuttingDown(); |
| |
| // The recorded count UserInteracted should be 0, with one sample recorded. |
| histogram_tester_->ExpectUniqueSample( |
| DemoSessionMetricsRecorder::kUserClicksAndPressesMetric, 0, 1); |
| } |
| |
| // Out of demo session, test user clicks the home button on shelf, clicks on the |
| // test window twice and presses the screen, then the UserClickesAndPresses |
| // should be 0. |
| TEST_F(DemoSessionMetricsRecorderTest, |
| UserClicksAndPressesEqualsZeroOutOfDemoSession) { |
| ClickMouseOnTestWindow(); |
| ClickOnHomeButtion(); |
| GesturePressWindow(); |
| |
| ash::Shell::Get()->metrics()->OnShellShuttingDown(); |
| |
| // The recorded count UserInteracted should be 0, and metric should contain 0 |
| // sample. |
| histogram_tester_->ExpectUniqueSample( |
| DemoSessionMetricsRecorder::kUserClicksAndPressesMetric, 0, 0); |
| } |
| |
| } // namespace |
| } // namespace ash |