| // Copyright 2019 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 "components/guest_os/guest_os_engagement_metrics.h" |
| |
| #include <algorithm> |
| #include <string> |
| #include <utility> |
| |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/simple_test_clock.h" |
| #include "base/test/simple_test_tick_clock.h" |
| #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h" |
| #include "chromeos/dbus/power/fake_power_manager_client.h" |
| #include "chromeos/dbus/power_manager/idle.pb.h" |
| #include "components/guest_os/guest_os_prefs.h" |
| #include "components/prefs/testing_pref_service.h" |
| #include "components/session_manager/core/session_manager.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/aura/test/test_windows.h" |
| |
| namespace guest_os { |
| namespace { |
| |
| constexpr char kUmaName[] = "Foo"; |
| constexpr char kPrefPrefix[] = "Bar"; |
| |
| constexpr char kHistogramTotal[] = "Total"; |
| constexpr char kHistogramForeground[] = "Foreground"; |
| constexpr char kHistogramBackground[] = "Background"; |
| constexpr char kHistogramActiveTotal[] = "FooTotal"; |
| |
| class GuestOsEngagementMetricsTest : public testing::Test { |
| protected: |
| GuestOsEngagementMetricsTest() = default; |
| |
| GuestOsEngagementMetricsTest(const GuestOsEngagementMetricsTest&) = delete; |
| GuestOsEngagementMetricsTest& operator=(const GuestOsEngagementMetricsTest&) = |
| delete; |
| |
| void SetUp() override { |
| chromeos::PowerManagerClient::InitializeFake(); |
| ash::SessionManagerClient::InitializeFakeInMemory(); |
| pref_service_ = std::make_unique<TestingPrefServiceSimple>(); |
| |
| matched_window_.reset(aura::test::CreateTestWindowWithId(0, nullptr)); |
| non_matched_window_.reset(aura::test::CreateTestWindowWithId(0, nullptr)); |
| |
| prefs::RegisterEngagementProfilePrefs(pref_service_->registry(), |
| kPrefPrefix); |
| |
| // The code doesn't work for correctly for a clock just at the epoch so |
| // advance by a day first. |
| test_clock_.Advance(base::Days(1)); |
| CreateEngagementMetrics(); |
| SetSessionState(session_manager::SessionState::ACTIVE); |
| } |
| |
| void TearDown() override { |
| engagement_metrics_.reset(); |
| non_matched_window_.reset(); |
| matched_window_.reset(); |
| pref_service_.reset(); |
| ash::SessionManagerClient::Shutdown(); |
| chromeos::PowerManagerClient::Shutdown(); |
| } |
| |
| GuestOsEngagementMetrics* engagement_metrics() { |
| return engagement_metrics_.get(); |
| } |
| |
| void SetSessionState(session_manager::SessionState state) { |
| session_manager_.SetSessionState(state); |
| } |
| |
| void SetScreenDimmed(bool is_screen_dimmed) { |
| power_manager::ScreenIdleState screen_idle_state; |
| screen_idle_state.set_dimmed(is_screen_dimmed); |
| static_cast<chromeos::FakePowerManagerClient*>( |
| chromeos::PowerManagerClient::Get()) |
| ->SendScreenIdleStateChanged(screen_idle_state); |
| } |
| |
| void AdvanceSeconds(int seconds) { |
| test_tick_clock_.Advance(base::Seconds(seconds)); |
| } |
| |
| void FocusMatchedWindow() { |
| engagement_metrics()->OnWindowActivated( |
| wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT, |
| matched_window_.get(), nullptr); |
| } |
| |
| void FocusNonMatchedWindow() { |
| engagement_metrics()->OnWindowActivated( |
| wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT, |
| non_matched_window_.get(), nullptr); |
| } |
| |
| void TriggerRecordEngagementTimeToUma() { |
| // Trigger UMA record by changing to next day. |
| test_clock_.Advance(base::Days(1)); |
| engagement_metrics_->OnSessionStateChanged(); |
| } |
| |
| void ExpectTime(const std::string& histogram, int seconds) { |
| tester_.ExpectTimeBucketCount("Foo.EngagementTime." + histogram, |
| base::Seconds(seconds), 1); |
| } |
| |
| void DestroyEngagementMetrics() { engagement_metrics_.reset(); } |
| |
| void CreateEngagementMetrics() { |
| engagement_metrics_ = |
| GuestOsEngagementMetrics::GetEngagementMetricsForTesting( |
| pref_service_.get(), |
| base::BindRepeating(&GuestOsEngagementMetricsTest::MatchWindow, |
| base::Unretained(this)), |
| kPrefPrefix, kUmaName, &test_clock_, &test_tick_clock_); |
| } |
| |
| private: |
| bool MatchWindow(const aura::Window* window) { |
| return window == matched_window_.get(); |
| } |
| |
| content::BrowserTaskEnvironment task_environment_; |
| session_manager::SessionManager session_manager_; |
| |
| base::SimpleTestTickClock test_tick_clock_; |
| base::SimpleTestClock test_clock_; |
| |
| base::HistogramTester tester_; |
| |
| std::unique_ptr<TestingPrefServiceSimple> pref_service_; |
| |
| std::unique_ptr<aura::Window> matched_window_; |
| std::unique_ptr<aura::Window> non_matched_window_; |
| |
| std::unique_ptr<GuestOsEngagementMetrics> engagement_metrics_; |
| }; |
| |
| TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeSessionLocked) { |
| SetSessionState(session_manager::SessionState::LOCKED); |
| AdvanceSeconds(1); |
| SetSessionState(session_manager::SessionState::ACTIVE); |
| AdvanceSeconds(5); |
| SetSessionState(session_manager::SessionState::LOCKED); |
| AdvanceSeconds(10); |
| |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 5); |
| ExpectTime(kHistogramForeground, 0); |
| ExpectTime(kHistogramBackground, 0); |
| ExpectTime(kHistogramActiveTotal, 0); |
| } |
| |
| TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeScreenDimmed) { |
| SetScreenDimmed(true); |
| AdvanceSeconds(1); |
| SetScreenDimmed(false); |
| AdvanceSeconds(5); |
| SetScreenDimmed(true); |
| AdvanceSeconds(10); |
| |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 5); |
| ExpectTime(kHistogramForeground, 0); |
| ExpectTime(kHistogramBackground, 0); |
| ExpectTime(kHistogramActiveTotal, 0); |
| } |
| |
| TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeChangeFocus) { |
| FocusMatchedWindow(); |
| AdvanceSeconds(2); |
| FocusNonMatchedWindow(); |
| AdvanceSeconds(4); |
| FocusMatchedWindow(); |
| AdvanceSeconds(10); |
| FocusNonMatchedWindow(); |
| AdvanceSeconds(20); |
| |
| // No background time is recorded as background activity is based on calls to |
| // SetBackgroundActive and not background windows. |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 36); |
| ExpectTime(kHistogramForeground, 12); |
| ExpectTime(kHistogramBackground, 0); |
| ExpectTime(kHistogramActiveTotal, 12); |
| } |
| |
| TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeBackgroundActive) { |
| AdvanceSeconds(10); |
| engagement_metrics()->SetBackgroundActive(true); |
| AdvanceSeconds(5); |
| engagement_metrics()->SetBackgroundActive(false); |
| AdvanceSeconds(1); |
| |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 16); |
| ExpectTime(kHistogramForeground, 0); |
| ExpectTime(kHistogramBackground, 5); |
| ExpectTime(kHistogramActiveTotal, 5); |
| } |
| |
| TEST_F(GuestOsEngagementMetricsTest, |
| RecordEngagementTimeBackgroundAndForeground) { |
| AdvanceSeconds(1); |
| engagement_metrics()->SetBackgroundActive(true); |
| AdvanceSeconds(2); |
| FocusMatchedWindow(); |
| AdvanceSeconds(4); |
| FocusNonMatchedWindow(); |
| AdvanceSeconds(10); |
| engagement_metrics()->SetBackgroundActive(false); |
| AdvanceSeconds(20); |
| |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 37); |
| ExpectTime(kHistogramForeground, 4); |
| ExpectTime(kHistogramBackground, 12); |
| ExpectTime(kHistogramActiveTotal, 16); |
| } |
| |
| TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeIfDestroyed) { |
| AdvanceSeconds(1); // Total |
| engagement_metrics()->SetBackgroundActive(true); |
| FocusMatchedWindow(); |
| AdvanceSeconds(1); // Total + foreground + active |
| |
| DestroyEngagementMetrics(); |
| |
| AdvanceSeconds(1); // Nothing |
| |
| CreateEngagementMetrics(); |
| engagement_metrics()->SetBackgroundActive(true); |
| FocusNonMatchedWindow(); |
| AdvanceSeconds(1); // Total + background + active |
| |
| TriggerRecordEngagementTimeToUma(); |
| ExpectTime(kHistogramTotal, 3); |
| ExpectTime(kHistogramForeground, 1); |
| ExpectTime(kHistogramBackground, 1); |
| ExpectTime(kHistogramActiveTotal, 2); |
| } |
| |
| } // namespace |
| } // namespace guest_os |