guest_os_engagement_metrics_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/guest_os/guest_os_engagement_metrics.h"
  5. #include <algorithm>
  6. #include <string>
  7. #include <utility>
  8. #include "base/test/metrics/histogram_tester.h"
  9. #include "base/test/simple_test_clock.h"
  10. #include "base/test/simple_test_tick_clock.h"
  11. #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
  12. #include "chromeos/dbus/power/fake_power_manager_client.h"
  13. #include "chromeos/dbus/power_manager/idle.pb.h"
  14. #include "components/guest_os/guest_os_prefs.h"
  15. #include "components/prefs/testing_pref_service.h"
  16. #include "components/session_manager/core/session_manager.h"
  17. #include "content/public/test/browser_task_environment.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "ui/aura/test/test_windows.h"
  20. namespace guest_os {
  21. namespace {
  22. constexpr char kUmaName[] = "Foo";
  23. constexpr char kPrefPrefix[] = "Bar";
  24. constexpr char kHistogramTotal[] = "Total";
  25. constexpr char kHistogramForeground[] = "Foreground";
  26. constexpr char kHistogramBackground[] = "Background";
  27. constexpr char kHistogramActiveTotal[] = "FooTotal";
  28. class GuestOsEngagementMetricsTest : public testing::Test {
  29. protected:
  30. GuestOsEngagementMetricsTest() = default;
  31. GuestOsEngagementMetricsTest(const GuestOsEngagementMetricsTest&) = delete;
  32. GuestOsEngagementMetricsTest& operator=(const GuestOsEngagementMetricsTest&) =
  33. delete;
  34. void SetUp() override {
  35. chromeos::PowerManagerClient::InitializeFake();
  36. ash::SessionManagerClient::InitializeFakeInMemory();
  37. pref_service_ = std::make_unique<TestingPrefServiceSimple>();
  38. matched_window_.reset(aura::test::CreateTestWindowWithId(0, nullptr));
  39. non_matched_window_.reset(aura::test::CreateTestWindowWithId(0, nullptr));
  40. prefs::RegisterEngagementProfilePrefs(pref_service_->registry(),
  41. kPrefPrefix);
  42. // The code doesn't work for correctly for a clock just at the epoch so
  43. // advance by a day first.
  44. test_clock_.Advance(base::Days(1));
  45. CreateEngagementMetrics();
  46. SetSessionState(session_manager::SessionState::ACTIVE);
  47. }
  48. void TearDown() override {
  49. engagement_metrics_.reset();
  50. non_matched_window_.reset();
  51. matched_window_.reset();
  52. pref_service_.reset();
  53. ash::SessionManagerClient::Shutdown();
  54. chromeos::PowerManagerClient::Shutdown();
  55. }
  56. GuestOsEngagementMetrics* engagement_metrics() {
  57. return engagement_metrics_.get();
  58. }
  59. void SetSessionState(session_manager::SessionState state) {
  60. session_manager_.SetSessionState(state);
  61. }
  62. void SetScreenDimmed(bool is_screen_dimmed) {
  63. power_manager::ScreenIdleState screen_idle_state;
  64. screen_idle_state.set_dimmed(is_screen_dimmed);
  65. static_cast<chromeos::FakePowerManagerClient*>(
  66. chromeos::PowerManagerClient::Get())
  67. ->SendScreenIdleStateChanged(screen_idle_state);
  68. }
  69. void AdvanceSeconds(int seconds) {
  70. test_tick_clock_.Advance(base::Seconds(seconds));
  71. }
  72. void FocusMatchedWindow() {
  73. engagement_metrics()->OnWindowActivated(
  74. wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT,
  75. matched_window_.get(), nullptr);
  76. }
  77. void FocusNonMatchedWindow() {
  78. engagement_metrics()->OnWindowActivated(
  79. wm::ActivationChangeObserver::ActivationReason::INPUT_EVENT,
  80. non_matched_window_.get(), nullptr);
  81. }
  82. void TriggerRecordEngagementTimeToUma() {
  83. // Trigger UMA record by changing to next day.
  84. test_clock_.Advance(base::Days(1));
  85. engagement_metrics_->OnSessionStateChanged();
  86. }
  87. void ExpectTime(const std::string& histogram, int seconds) {
  88. tester_.ExpectTimeBucketCount("Foo.EngagementTime." + histogram,
  89. base::Seconds(seconds), 1);
  90. }
  91. void DestroyEngagementMetrics() { engagement_metrics_.reset(); }
  92. void CreateEngagementMetrics() {
  93. engagement_metrics_ =
  94. GuestOsEngagementMetrics::GetEngagementMetricsForTesting(
  95. pref_service_.get(),
  96. base::BindRepeating(&GuestOsEngagementMetricsTest::MatchWindow,
  97. base::Unretained(this)),
  98. kPrefPrefix, kUmaName, &test_clock_, &test_tick_clock_);
  99. }
  100. private:
  101. bool MatchWindow(const aura::Window* window) {
  102. return window == matched_window_.get();
  103. }
  104. content::BrowserTaskEnvironment task_environment_;
  105. session_manager::SessionManager session_manager_;
  106. base::SimpleTestTickClock test_tick_clock_;
  107. base::SimpleTestClock test_clock_;
  108. base::HistogramTester tester_;
  109. std::unique_ptr<TestingPrefServiceSimple> pref_service_;
  110. std::unique_ptr<aura::Window> matched_window_;
  111. std::unique_ptr<aura::Window> non_matched_window_;
  112. std::unique_ptr<GuestOsEngagementMetrics> engagement_metrics_;
  113. };
  114. TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeSessionLocked) {
  115. SetSessionState(session_manager::SessionState::LOCKED);
  116. AdvanceSeconds(1);
  117. SetSessionState(session_manager::SessionState::ACTIVE);
  118. AdvanceSeconds(5);
  119. SetSessionState(session_manager::SessionState::LOCKED);
  120. AdvanceSeconds(10);
  121. TriggerRecordEngagementTimeToUma();
  122. ExpectTime(kHistogramTotal, 5);
  123. ExpectTime(kHistogramForeground, 0);
  124. ExpectTime(kHistogramBackground, 0);
  125. ExpectTime(kHistogramActiveTotal, 0);
  126. }
  127. TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeScreenDimmed) {
  128. SetScreenDimmed(true);
  129. AdvanceSeconds(1);
  130. SetScreenDimmed(false);
  131. AdvanceSeconds(5);
  132. SetScreenDimmed(true);
  133. AdvanceSeconds(10);
  134. TriggerRecordEngagementTimeToUma();
  135. ExpectTime(kHistogramTotal, 5);
  136. ExpectTime(kHistogramForeground, 0);
  137. ExpectTime(kHistogramBackground, 0);
  138. ExpectTime(kHistogramActiveTotal, 0);
  139. }
  140. TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeChangeFocus) {
  141. FocusMatchedWindow();
  142. AdvanceSeconds(2);
  143. FocusNonMatchedWindow();
  144. AdvanceSeconds(4);
  145. FocusMatchedWindow();
  146. AdvanceSeconds(10);
  147. FocusNonMatchedWindow();
  148. AdvanceSeconds(20);
  149. // No background time is recorded as background activity is based on calls to
  150. // SetBackgroundActive and not background windows.
  151. TriggerRecordEngagementTimeToUma();
  152. ExpectTime(kHistogramTotal, 36);
  153. ExpectTime(kHistogramForeground, 12);
  154. ExpectTime(kHistogramBackground, 0);
  155. ExpectTime(kHistogramActiveTotal, 12);
  156. }
  157. TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeBackgroundActive) {
  158. AdvanceSeconds(10);
  159. engagement_metrics()->SetBackgroundActive(true);
  160. AdvanceSeconds(5);
  161. engagement_metrics()->SetBackgroundActive(false);
  162. AdvanceSeconds(1);
  163. TriggerRecordEngagementTimeToUma();
  164. ExpectTime(kHistogramTotal, 16);
  165. ExpectTime(kHistogramForeground, 0);
  166. ExpectTime(kHistogramBackground, 5);
  167. ExpectTime(kHistogramActiveTotal, 5);
  168. }
  169. TEST_F(GuestOsEngagementMetricsTest,
  170. RecordEngagementTimeBackgroundAndForeground) {
  171. AdvanceSeconds(1);
  172. engagement_metrics()->SetBackgroundActive(true);
  173. AdvanceSeconds(2);
  174. FocusMatchedWindow();
  175. AdvanceSeconds(4);
  176. FocusNonMatchedWindow();
  177. AdvanceSeconds(10);
  178. engagement_metrics()->SetBackgroundActive(false);
  179. AdvanceSeconds(20);
  180. TriggerRecordEngagementTimeToUma();
  181. ExpectTime(kHistogramTotal, 37);
  182. ExpectTime(kHistogramForeground, 4);
  183. ExpectTime(kHistogramBackground, 12);
  184. ExpectTime(kHistogramActiveTotal, 16);
  185. }
  186. TEST_F(GuestOsEngagementMetricsTest, RecordEngagementTimeIfDestroyed) {
  187. AdvanceSeconds(1); // Total
  188. engagement_metrics()->SetBackgroundActive(true);
  189. FocusMatchedWindow();
  190. AdvanceSeconds(1); // Total + foreground + active
  191. DestroyEngagementMetrics();
  192. AdvanceSeconds(1); // Nothing
  193. CreateEngagementMetrics();
  194. engagement_metrics()->SetBackgroundActive(true);
  195. FocusNonMatchedWindow();
  196. AdvanceSeconds(1); // Total + background + active
  197. TriggerRecordEngagementTimeToUma();
  198. ExpectTime(kHistogramTotal, 3);
  199. ExpectTime(kHistogramForeground, 1);
  200. ExpectTime(kHistogramBackground, 1);
  201. ExpectTime(kHistogramActiveTotal, 2);
  202. }
  203. } // namespace
  204. } // namespace guest_os