1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/mojo/services/playback_events_recorder.h"
7 #include "base/metrics/user_metrics.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "base/test/task_environment.h"
10 #include "base/time/time.h"
11 #include "testing/gtest/include/gtest/gtest.h"
15 constexpr base::TimeDelta kSecond = base::Seconds(1);
17 class PlaybackEventsRecorderTest : public testing::Test {
19 PlaybackEventsRecorderTest()
20 : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
21 base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
22 time_base_ = base::TimeTicks::Now();
24 base::SetRecordActionTaskRunner(
25 task_environment_.GetMainThreadTaskRunner());
26 action_callback_ = base::BindRepeating(
27 &PlaybackEventsRecorderTest::OnAction, base::Unretained(this));
28 base::AddActionCallback(action_callback_);
31 ~PlaybackEventsRecorderTest() override {
32 base::RemoveActionCallback(action_callback_);
40 bool operator==(const Event& other) const {
41 return time == other.time && name == other.name;
45 void OnAction(const std::string& name, base::TimeTicks time) {
46 recorded_events_.push_back({time, name});
49 void ExpectEvents(const std::vector<Event>& expected) {
50 EXPECT_EQ(recorded_events_.size(), expected.size());
51 size_t end = std::min(recorded_events_.size(), expected.size());
52 for (size_t i = 0; i < end; ++i) {
54 EXPECT_EQ(recorded_events_[i].time, expected[i].time);
55 EXPECT_EQ(recorded_events_[i].name, expected[i].name);
59 base::test::TaskEnvironment task_environment_;
61 base::SimpleTestTickClock test_clock_;
62 base::TimeTicks time_base_;
64 base::ActionCallback action_callback_;
65 PlaybackEventsRecorder recorder_;
66 std::vector<Event> recorded_events_;
69 TEST_F(PlaybackEventsRecorderTest, PlayPause) {
70 recorder_.OnNaturalSizeChanged(gfx::Size(640, 480));
71 recorder_.OnPlaying();
72 task_environment_.AdvanceClock(2 * kSecond);
76 // VideoResolution value should be encoded as (640 << 16) + 480.
77 {time_base_, "WebEngine.Media.VideoResolution:41943520"},
78 {time_base_, "WebEngine.Media.Playing"},
79 {time_base_ + 2 * kSecond, "WebEngine.Media.Pause"},
83 TEST_F(PlaybackEventsRecorderTest, Error) {
84 recorder_.OnPlaying();
85 task_environment_.AdvanceClock(2 * kSecond);
86 recorder_.OnError(PIPELINE_ERROR_DECODE);
89 {time_base_, "WebEngine.Media.Playing"},
90 {time_base_ + 2 * kSecond, "WebEngine.Media.Error:3"},
94 TEST_F(PlaybackEventsRecorderTest, Buffering) {
95 recorder_.OnPlaying();
96 recorder_.OnBufferingComplete();
97 task_environment_.AdvanceClock(2 * kSecond);
98 recorder_.OnBuffering();
99 task_environment_.AdvanceClock(3 * kSecond);
100 recorder_.OnBufferingComplete();
103 {time_base_, "WebEngine.Media.Playing"},
104 {time_base_ + 5 * kSecond,
105 "WebEngine.Media.PlayTimeBeforeAutoPause:2000"},
106 {time_base_ + 5 * kSecond, "WebEngine.Media.AutoPauseTime:3000"},
110 TEST_F(PlaybackEventsRecorderTest, Bitrate) {
111 recorder_.OnPlaying();
112 recorder_.OnBufferingComplete();
114 PipelineStatistics stats;
115 recorder_.OnPipelineStatistics(stats);
117 for (int i = 0; i < 5; ++i) {
118 stats.audio_bytes_decoded += 5000;
119 stats.video_bytes_decoded += 10000;
121 task_environment_.AdvanceClock(kSecond);
122 recorder_.OnPipelineStatistics(stats);
126 {time_base_, "WebEngine.Media.Playing"},
127 {time_base_ + 5 * kSecond, "WebEngine.Media.AudioBitrate:40"},
128 {time_base_ + 5 * kSecond, "WebEngine.Media.VideoBitrate:80"},
132 TEST_F(PlaybackEventsRecorderTest, BitrateAfterPause) {
133 recorder_.OnPlaying();
134 recorder_.OnBufferingComplete();
136 PipelineStatistics stats;
137 recorder_.OnPipelineStatistics(stats);
139 for (int i = 0; i < 3; ++i) {
140 stats.audio_bytes_decoded += 5000;
141 stats.video_bytes_decoded += 10000;
143 task_environment_.AdvanceClock(kSecond);
144 recorder_.OnPipelineStatistics(stats);
147 recorder_.OnPaused();
148 task_environment_.AdvanceClock(10 * kSecond);
149 recorder_.OnPlaying();
151 for (int i = 0; i < 3; ++i) {
152 stats.audio_bytes_decoded += 5000;
153 stats.video_bytes_decoded += 10000;
155 task_environment_.AdvanceClock(kSecond);
156 recorder_.OnPipelineStatistics(stats);
160 {time_base_, "WebEngine.Media.Playing"},
161 {time_base_ + 3 * kSecond, "WebEngine.Media.Pause"},
162 {time_base_ + 13 * kSecond, "WebEngine.Media.Playing"},
163 {time_base_ + 16 * kSecond, "WebEngine.Media.AudioBitrate:40"},
164 {time_base_ + 16 * kSecond, "WebEngine.Media.VideoBitrate:80"},
168 TEST_F(PlaybackEventsRecorderTest, BitrateAfterBuffering) {
169 recorder_.OnPlaying();
170 recorder_.OnBufferingComplete();
172 PipelineStatistics stats;
173 recorder_.OnPipelineStatistics(stats);
175 for (int i = 0; i < 3; ++i) {
176 stats.audio_bytes_decoded += 5000;
177 stats.video_bytes_decoded += 10000;
179 task_environment_.AdvanceClock(kSecond);
180 recorder_.OnPipelineStatistics(stats);
183 recorder_.OnBuffering();
184 task_environment_.AdvanceClock(10 * kSecond);
185 recorder_.OnBufferingComplete();
187 for (int i = 0; i < 3; ++i) {
188 stats.audio_bytes_decoded += 5000;
189 stats.video_bytes_decoded += 10000;
191 task_environment_.AdvanceClock(kSecond);
192 recorder_.OnPipelineStatistics(stats);
196 {time_base_, "WebEngine.Media.Playing"},
197 {time_base_ + 13 * kSecond,
198 "WebEngine.Media.PlayTimeBeforeAutoPause:3000"},
199 {time_base_ + 13 * kSecond, "WebEngine.Media.AutoPauseTime:10000"},
200 {time_base_ + 16 * kSecond, "WebEngine.Media.AudioBitrate:40"},
201 {time_base_ + 16 * kSecond, "WebEngine.Media.VideoBitrate:80"},