ambient_multi_screen_metrics_recorder_unittest.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright 2022 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 "ash/ambient/metrics/ambient_multi_screen_metrics_recorder.h"
  5. #include <string>
  6. #include "ash/constants/ambient_animation_theme.h"
  7. #include "base/strings/strcat.h"
  8. #include "base/strings/string_piece.h"
  9. #include "base/test/metrics/histogram_tester.h"
  10. #include "base/test/task_environment.h"
  11. #include "base/time/time.h"
  12. #include "cc/test/skia_common.h"
  13. #include "testing/gmock/include/gmock/gmock.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. #include "ui/gfx/canvas.h"
  16. #include "ui/gfx/geometry/size.h"
  17. #include "ui/lottie/animation.h"
  18. namespace ash {
  19. namespace {
  20. using ::testing::Eq;
  21. } // namespace
  22. class AmbientMultiScreenMetricsRecorderTest : public ::testing::Test {
  23. protected:
  24. struct Harness {
  25. static constexpr gfx::Size kTestSize = gfx::Size(100, 100);
  26. static constexpr base::TimeDelta kTotalAnimationDuration =
  27. base::Seconds(10);
  28. explicit Harness(AmbientAnimationTheme theme)
  29. : recorder(theme),
  30. animation_1(cc::CreateSkottie(kTestSize,
  31. kTotalAnimationDuration.InSecondsF())),
  32. animation_2(cc::CreateSkottie(kTestSize,
  33. kTotalAnimationDuration.InSecondsF())) {
  34. }
  35. // In the real code, AmbientMultiScreenMetricsRecorder outlives the
  36. // animations, so simulate that in tests here.
  37. AmbientMultiScreenMetricsRecorder recorder;
  38. lottie::Animation animation_1;
  39. lottie::Animation animation_2;
  40. gfx::Canvas canvas;
  41. };
  42. base::test::TaskEnvironment task_environment_{
  43. base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  44. };
  45. class AmbientMultiScreenMetricsRecorderTestForAllThemes
  46. : public AmbientMultiScreenMetricsRecorderTest,
  47. public ::testing::WithParamInterface<AmbientAnimationTheme> {
  48. protected:
  49. std::string GetMetricNameForTheme(base::StringPiece prefix) {
  50. return base::StrCat({prefix, ToString(GetParam())});
  51. }
  52. };
  53. INSTANTIATE_TEST_SUITE_P(AllAnimationThemes,
  54. AmbientMultiScreenMetricsRecorderTestForAllThemes,
  55. testing::Values(AmbientAnimationTheme::kFeelTheBreeze,
  56. AmbientAnimationTheme::kFloatOnBy));
  57. TEST_P(AmbientMultiScreenMetricsRecorderTestForAllThemes, RecordsScreenCount) {
  58. base::HistogramTester histogram_tester;
  59. {
  60. Harness harness(GetParam());
  61. harness.recorder.RegisterScreen(&harness.animation_1);
  62. harness.animation_1.Start();
  63. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  64. Harness::kTestSize);
  65. }
  66. histogram_tester.ExpectUniqueSample(
  67. GetMetricNameForTheme("Ash.AmbientMode.ScreenCount."), /*sample=*/1,
  68. /*expected_bucket_count=*/1);
  69. {
  70. Harness harness(GetParam());
  71. harness.recorder.RegisterScreen(&harness.animation_1);
  72. harness.recorder.RegisterScreen(&harness.animation_2);
  73. harness.animation_1.Start();
  74. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  75. Harness::kTestSize);
  76. harness.animation_2.Start();
  77. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  78. Harness::kTestSize);
  79. }
  80. histogram_tester.ExpectBucketCount(
  81. GetMetricNameForTheme("Ash.AmbientMode.ScreenCount."), /*sample=*/2,
  82. /*expected_count=*/1);
  83. }
  84. TEST_P(AmbientMultiScreenMetricsRecorderTestForAllThemes,
  85. RecordsTimestampOffset) {
  86. static constexpr base::TimeDelta kFrameInterval = base::Milliseconds(100);
  87. base::HistogramTester histogram_tester;
  88. Harness harness(GetParam());
  89. harness.recorder.RegisterScreen(&harness.animation_1);
  90. harness.recorder.RegisterScreen(&harness.animation_2);
  91. harness.animation_1.Start();
  92. harness.animation_2.Start();
  93. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  94. Harness::kTestSize);
  95. // Offset of 0.
  96. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  97. Harness::kTestSize);
  98. task_environment_.FastForwardBy(kFrameInterval);
  99. // Offset of |kFrameInterval|.
  100. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  101. Harness::kTestSize);
  102. // Offset of 0.
  103. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  104. Harness::kTestSize);
  105. histogram_tester.ExpectTimeBucketCount(
  106. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."),
  107. base::TimeDelta(), 2);
  108. histogram_tester.ExpectTimeBucketCount(
  109. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."),
  110. kFrameInterval, 1);
  111. }
  112. TEST_P(AmbientMultiScreenMetricsRecorderTestForAllThemes,
  113. RecordsMeanTimestampOffsetWithDifferentCycleStartOffsets) {
  114. base::HistogramTester histogram_tester;
  115. Harness harness(GetParam());
  116. harness.recorder.RegisterScreen(&harness.animation_1);
  117. harness.recorder.RegisterScreen(&harness.animation_2);
  118. lottie::Animation::PlaybackConfig playback_config(
  119. {{base::TimeDelta(), Harness::kTotalAnimationDuration},
  120. {Harness::kTotalAnimationDuration * .25f,
  121. Harness::kTotalAnimationDuration * .75f}},
  122. /*initial_offset=*/base::TimeDelta(), /*initial_completed_cycles=*/0,
  123. lottie::Animation::Style::kLoop);
  124. harness.animation_1.Start(playback_config);
  125. harness.animation_2.Start(playback_config);
  126. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  127. Harness::kTestSize);
  128. // Offset of 0.
  129. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  130. Harness::kTestSize);
  131. task_environment_.FastForwardBy(Harness::kTotalAnimationDuration / 2);
  132. // Offset of kTotalAnimationDuration / 2.
  133. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  134. Harness::kTestSize);
  135. // Offset of 0.
  136. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  137. Harness::kTestSize);
  138. // Fast forward to just before end of first cycle.
  139. task_environment_.FastForwardBy((Harness::kTotalAnimationDuration / 2) -
  140. base::Milliseconds(100));
  141. // Offset of kTotalAnimationDuration / 2) - 100ms
  142. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  143. Harness::kTestSize);
  144. task_environment_.FastForwardBy(base::Milliseconds(200));
  145. // Fast forward to just after start of second cycle.
  146. // Offset of 200 ms (100 ms before end of first cycle to 100 ms past start of
  147. // second cycle).
  148. harness.animation_2.Paint(&harness.canvas, task_environment_.NowTicks(),
  149. Harness::kTestSize);
  150. // Offset of 0.
  151. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  152. Harness::kTestSize);
  153. histogram_tester.ExpectTimeBucketCount(
  154. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."),
  155. base::TimeDelta(), 3);
  156. histogram_tester.ExpectTimeBucketCount(
  157. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."),
  158. Harness::kTotalAnimationDuration / 2, 2);
  159. histogram_tester.ExpectTimeBucketCount(
  160. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."),
  161. base::Milliseconds(200), 1);
  162. histogram_tester.ExpectTotalCount(
  163. GetMetricNameForTheme("Ash.AmbientMode.MultiScreenOffset."), 6);
  164. }
  165. TEST_P(AmbientMultiScreenMetricsRecorderTestForAllThemes,
  166. DoesNotRecordMeanTimestampOffsetForSingleScreen) {
  167. static constexpr base::TimeDelta kFrameInterval = base::Milliseconds(100);
  168. base::HistogramTester histogram_tester;
  169. Harness harness(GetParam());
  170. harness.recorder.RegisterScreen(&harness.animation_1);
  171. harness.animation_1.Start();
  172. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  173. Harness::kTestSize);
  174. task_environment_.FastForwardBy(kFrameInterval);
  175. harness.animation_1.Paint(&harness.canvas, task_environment_.NowTicks(),
  176. Harness::kTestSize);
  177. histogram_tester.ExpectTotalCount(
  178. "Ash.AmbientMode.MultiScreenOffset.FeelTheBreeze", 0);
  179. }
  180. TEST_F(AmbientMultiScreenMetricsRecorderTest, HandlesNullAnimations) {
  181. base::HistogramTester histogram_tester;
  182. {
  183. AmbientMultiScreenMetricsRecorder recorder(
  184. AmbientAnimationTheme::kSlideshow);
  185. recorder.RegisterScreen(nullptr);
  186. recorder.RegisterScreen(nullptr);
  187. }
  188. histogram_tester.ExpectUniqueSample("Ash.AmbientMode.ScreenCount.SlideShow",
  189. /*sample=*/2,
  190. /*expected_bucket_count=*/1);
  191. histogram_tester.ExpectTotalCount(
  192. "Ash.AmbientMode.MultiScreenOffset.SlideShow", 0);
  193. }
  194. } // namespace ash