[M120 Migration][MM][CAPI] Fix the logic for media using capi player.
[platform/framework/web/chromium-efl.git] / media / mojo / services / mojo_video_encoder_metrics_provider_service_unittest.cc
1 // Copyright 2023 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.
4
5 #include <stddef.h>
6 #include <memory>
7
8 #include "media/mojo/services/mojo_video_encoder_metrics_provider_service.h"
9
10 #include "base/run_loop.h"
11 #include "base/test/metrics/histogram_tester.h"
12 #include "base/test/test_message_loop.h"
13 #include "components/ukm/test_ukm_recorder.h"
14 #include "mojo/public/cpp/bindings/remote.h"
15 #include "services/metrics/public/cpp/ukm_builders.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19
20 using UkmEntry = ukm::builders::Media_VideoEncoderMetrics;
21
22 using ::testing::TestWithParam;
23 using ::testing::ValuesIn;
24
25 namespace media {
26 namespace {
27 constexpr char kTestURL[] = "https://test.google.com/";
28
29 std::tuple<std::unique_ptr<ukm::TestAutoSetUkmRecorder>,
30            mojo::Remote<mojom::VideoEncoderMetricsProvider>>
31 Create(const std::string& url) {
32   auto test_recorder = std::make_unique<ukm::TestAutoSetUkmRecorder>();
33   ukm::SourceId source_id = test_recorder->GetNewSourceID();
34   test_recorder->UpdateSourceURL(source_id, GURL(url));
35   mojo::Remote<mojom::VideoEncoderMetricsProvider> provider;
36   MojoVideoEncoderMetricsProviderService::Create(
37       source_id, provider.BindNewPipeAndPassReceiver());
38   return {std::move(test_recorder), std::move(provider)};
39 }
40 }  // namespace
41
42 class MojoVideoEncoderMetricsProviderServiceTest
43     : public TestWithParam<testing::tuple<uint64_t,
44                                           mojom::VideoEncoderUseCase,
45                                           VideoCodecProfile,
46                                           gfx::Size,
47                                           bool,
48                                           SVCScalabilityMode,
49                                           EncoderStatus::Codes>> {
50  public:
51   MojoVideoEncoderMetricsProviderServiceTest() = default;
52   ~MojoVideoEncoderMetricsProviderServiceTest() override = default;
53
54  protected:
55   base::TestMessageLoop message_loop_;
56 };
57
58 TEST_F(MojoVideoEncoderMetricsProviderServiceTest, Create_NoUKMReport) {
59   auto [test_recorder, provider] = Create(kTestURL);
60   provider.reset();
61   base::RunLoop().RunUntilIdle();
62   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
63   EXPECT_TRUE(entries.empty());
64 }
65
66 #define EXPECT_UKM(name, value) \
67   test_recorder->ExpectEntryMetric(entry, name, value)
68
69 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
70        CreateAndInitialize_ReportUKM) {
71   auto [test_recorder, provider] = Create(kTestURL);
72   constexpr uint64_t kEncoderId = 0;
73   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
74   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
75   constexpr gfx::Size kEncodeSize(1200, 700);
76   constexpr bool kIsHardwareEncoder = true;
77   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
78   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
79                        kIsHardwareEncoder, kSVCMode);
80   provider.reset();
81   base::RunLoop().RunUntilIdle();
82
83   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
84   ASSERT_EQ(1u, entries.size());
85   const auto* entry = entries[0];
86   EXPECT_UKM(UkmEntry::kHeightName, kEncodeSize.height());
87   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
88   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 0);
89   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
90   EXPECT_UKM(UkmEntry::kStatusName,
91              static_cast<int64_t>(EncoderStatus::Codes::kOk));
92   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
93   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
94   EXPECT_UKM(UkmEntry::kWidthName, kEncodeSize.width());
95 }
96
97 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
98        CreateAndInitializeAndComplete_ReportUKM) {
99   auto [test_recorder, provider] = Create(kTestURL);
100   constexpr uint64_t kEncoderId = 0;
101   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
102   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
103   constexpr gfx::Size kEncodeSize(1200, 700);
104   constexpr bool kIsHardwareEncoder = true;
105   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
106   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
107                        kIsHardwareEncoder, kSVCMode);
108   provider->Complete(kEncoderId);
109   base::RunLoop().RunUntilIdle();
110
111   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
112   ASSERT_EQ(1u, entries.size());
113   const auto* entry = entries[0];
114   EXPECT_UKM(UkmEntry::kHeightName, kEncodeSize.height());
115   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
116   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 0);
117   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
118   EXPECT_UKM(UkmEntry::kStatusName,
119              static_cast<int64_t>(EncoderStatus::Codes::kOk));
120   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
121   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
122   EXPECT_UKM(UkmEntry::kWidthName, kEncodeSize.width());
123   provider.reset();
124 }
125
126 TEST_F(
127     MojoVideoEncoderMetricsProviderServiceTest,
128     CreateAndInitializeAndSetSmallNumberEncodedFrameCount_ReportUKMWithOneBucket) {
129   auto [test_recorder, provider] = Create(kTestURL);
130   constexpr uint64_t kEncoderId = 0;
131   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
132   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
133   constexpr gfx::Size kEncodeSize(1200, 700);
134   constexpr bool kIsHardwareEncoder = true;
135   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
136   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
137                        kIsHardwareEncoder, kSVCMode);
138   provider->SetEncodedFrameCount(kEncoderId, 10);
139   provider.reset();
140   base::RunLoop().RunUntilIdle();
141
142   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
143   ASSERT_EQ(1u, entries.size());
144   const auto* entry = entries[0];
145   EXPECT_UKM(UkmEntry::kHeightName, kEncodeSize.height());
146   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
147   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 1u);
148   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
149   EXPECT_UKM(UkmEntry::kStatusName,
150              static_cast<int64_t>(EncoderStatus::Codes::kOk));
151   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
152   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
153   EXPECT_UKM(UkmEntry::kWidthName, kEncodeSize.width());
154 }
155
156 TEST_P(MojoVideoEncoderMetricsProviderServiceTest,
157        CreateAndInitializeAndSetEncodedFrameCount_ReportUKM) {
158   auto [test_recorder, provider] = Create(kTestURL);
159   auto encoder_id = std::get<0>(GetParam());
160   auto encoder_use_case = std::get<1>(GetParam());
161   auto codec_profile = std::get<2>(GetParam());
162   auto encode_size = std::get<3>(GetParam());
163   auto is_hardware_encoder = std::get<4>(GetParam());
164   auto svc_mode = std::get<5>(GetParam());
165   media::EncoderStatus encoder_status(std::get<6>(GetParam()));
166   constexpr uint64_t kNumEncodedFrames = 100;
167   provider->Initialize(encoder_id, encoder_use_case, codec_profile, encode_size,
168                        is_hardware_encoder, svc_mode);
169   provider->SetEncodedFrameCount(encoder_id, kNumEncodedFrames);
170   if (!encoder_status.is_ok()) {
171     provider->SetError(encoder_id, encoder_status);
172   }
173   provider.reset();
174   base::RunLoop().RunUntilIdle();
175
176   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
177   ASSERT_EQ(1u, entries.size());
178   const auto* entry = entries[0];
179   const uint64_t expected_height = encode_size.height() / 100 * 100;
180   const uint64_t expected_width = encode_size.width() / 100 * 100;
181   EXPECT_UKM(UkmEntry::kHeightName, expected_height);
182   EXPECT_UKM(UkmEntry::kIsHardwareName, is_hardware_encoder);
183   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, kNumEncodedFrames);
184   EXPECT_UKM(UkmEntry::kProfileName, codec_profile);
185   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(svc_mode));
186   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(encoder_use_case));
187   EXPECT_UKM(UkmEntry::kWidthName, expected_width);
188   EXPECT_UKM(UkmEntry::kStatusName,
189              static_cast<int64_t>(encoder_status.code()));
190 }
191
192 TEST_P(MojoVideoEncoderMetricsProviderServiceTest,
193        CreateAndInitializeAndSetEncodedFrameCount_ReportUMA) {
194   base::HistogramTester histogram_tester;
195   auto [test_recorder, provider] = Create(kTestURL);
196   auto encoder_id = std::get<0>(GetParam());
197   auto encoder_use_case = std::get<1>(GetParam());
198   auto codec_profile = std::get<2>(GetParam());
199   auto encode_size = std::get<3>(GetParam());
200   auto is_hardware_encoder = std::get<4>(GetParam());
201   auto svc_mode = std::get<5>(GetParam());
202   media::EncoderStatus encoder_status(std::get<6>(GetParam()));
203   constexpr uint64_t kNumEncodedFrames = 100;
204   provider->Initialize(encoder_id, encoder_use_case, codec_profile, encode_size,
205                        is_hardware_encoder, svc_mode);
206   provider->SetEncodedFrameCount(encoder_id, kNumEncodedFrames);
207   if (!encoder_status.is_ok()) {
208     provider->SetError(encoder_id, encoder_status);
209   }
210   provider.reset();
211   base::RunLoop().RunUntilIdle();
212
213   std::string uma_prefix = "Media.VideoEncoder.";
214   switch (encoder_use_case) {
215     case mojom::VideoEncoderUseCase::kCastMirroring:
216       uma_prefix += "CastMirroring.";
217       break;
218     case mojom::VideoEncoderUseCase::kMediaRecorder:
219       uma_prefix += "MediaRecorder.";
220       break;
221     case mojom::VideoEncoderUseCase::kWebCodecs:
222       uma_prefix += "WebCodecs.";
223       break;
224     case mojom::VideoEncoderUseCase::kWebRTC:
225       uma_prefix += "WebRTC.";
226       break;
227   }
228
229 #define EXPECT_UMA(name, value)                                           \
230   do {                                                                    \
231     histogram_tester.ExpectUniqueSample(base::StrCat({uma_prefix, name}), \
232                                         value, 1);                        \
233   } while (0)
234
235   EXPECT_UMA("Profile", codec_profile);
236   EXPECT_UMA("SVC", svc_mode);
237   EXPECT_UMA("HW", is_hardware_encoder);
238   EXPECT_UMA("Width", encode_size.width());
239   EXPECT_UMA("Height", encode_size.height());
240   EXPECT_UMA("Area", encode_size.GetArea() / 100);
241   EXPECT_UMA("Status", encoder_status.code());
242
243 #undef EXPECT_UMA
244 }
245
246 INSTANTIATE_TEST_SUITE_P(
247     All,
248     MojoVideoEncoderMetricsProviderServiceTest,
249     ::testing::Combine(ValuesIn(std::vector<uint64_t>{12ul, 100ul}),
250                        ValuesIn({
251                            mojom::VideoEncoderUseCase::kCastMirroring,
252                            mojom::VideoEncoderUseCase::kMediaRecorder,
253                            mojom::VideoEncoderUseCase::kWebCodecs,
254                            mojom::VideoEncoderUseCase::kWebRTC,
255                        }),
256                        ValuesIn({
257                            H264PROFILE_MAIN,
258                            VP8PROFILE_ANY,
259                            VP9PROFILE_MIN,
260                            AV1PROFILE_PROFILE_HIGH,
261                        }),
262                        ValuesIn({
263                            gfx::Size(640, 360),
264                            gfx::Size(1280, 720),
265                        }),
266                        ::testing::Bool(),
267                        ValuesIn({
268                            SVCScalabilityMode::kL1T1,
269                            SVCScalabilityMode::kL3T3Key,
270                        }),
271                        ValuesIn({
272                            EncoderStatus::Codes::kOk,
273                            EncoderStatus::Codes::kEncoderFailedEncode,
274                        })));
275
276 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
277        InitializeWithVerfiyLargeResoloution_ReportCappedResolutionUKM) {
278   auto [test_recorder, provider] = Create(kTestURL);
279   constexpr uint64_t kEncoderId = 0;
280   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
281   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
282   constexpr gfx::Size k16kEncodeSize(15360, 8640);
283   constexpr bool kIsHardwareEncoder = true;
284   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
285   constexpr uint64_t kNumEncodedFrames = 100;
286   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile,
287                        k16kEncodeSize, kIsHardwareEncoder, kSVCMode);
288   provider->SetEncodedFrameCount(kEncoderId, kNumEncodedFrames);
289   provider.reset();
290   base::RunLoop().RunUntilIdle();
291
292   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
293   ASSERT_EQ(1u, entries.size());
294   const auto* entry = entries[0];
295   constexpr uint64_t kHeight = 8200;
296   constexpr uint64_t kWidth = 8200;
297   EXPECT_UKM(UkmEntry::kHeightName, kHeight);
298   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
299   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, kNumEncodedFrames);
300   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
301   EXPECT_UKM(UkmEntry::kStatusName,
302              static_cast<int64_t>(EncoderStatus::Codes::kOk));
303   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
304   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
305   EXPECT_UKM(UkmEntry::kWidthName, kWidth);
306 }
307
308 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
309        CallSetEncodedFrameCounts_ReportUKMWithTheLastEncodedFrameCount) {
310   auto [test_recorder, provider] = Create(kTestURL);
311   constexpr uint64_t kEncoderId = 0;
312   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
313   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
314   constexpr gfx::Size kEncodeSize(1920, 1080);
315   constexpr bool kIsHardwareEncoder = true;
316   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
317   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
318                        kIsHardwareEncoder, kSVCMode);
319   provider->SetEncodedFrameCount(kEncoderId, 100);
320   provider->SetEncodedFrameCount(kEncoderId, 200);
321   provider->SetEncodedFrameCount(kEncoderId, 300);
322   provider.reset();
323   base::RunLoop().RunUntilIdle();
324
325   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
326   ASSERT_EQ(1u, entries.size());
327   const auto* entry = entries[0];
328   constexpr uint64_t kHeight = kEncodeSize.height() / 100 * 100;
329   constexpr uint64_t kWidth = kEncodeSize.width() / 100 * 100;
330   EXPECT_UKM(UkmEntry::kHeightName, kHeight);
331   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
332   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 300);
333   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
334   EXPECT_UKM(UkmEntry::kStatusName,
335              static_cast<int64_t>(EncoderStatus::Codes::kOk));
336   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
337   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
338   EXPECT_UKM(UkmEntry::kWidthName, kWidth);
339 }
340
341 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
342        CreateAndInitializeAndCallSetErrors_ReportUKMWithTheFirstError) {
343   auto [test_recorder, provider] = Create(kTestURL);
344   constexpr uint64_t kEncoderId = 0;
345   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
346   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
347   constexpr gfx::Size kEncodeSize(1920, 1080);
348   constexpr bool kIsHardwareEncoder = true;
349   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
350   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
351                        kIsHardwareEncoder, kSVCMode);
352   provider->SetError(kEncoderId,
353                      {EncoderStatus::Codes::kEncoderMojoConnectionError,
354                       "mojo connection is disclosed"});
355   provider->SetError(kEncoderId, {EncoderStatus::Codes::kEncoderFailedEncode,
356                                   "Encoder failed"});
357   provider.reset();
358   base::RunLoop().RunUntilIdle();
359
360   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
361   ASSERT_EQ(1u, entries.size());
362   const auto* entry = entries[0];
363   constexpr uint64_t kHeight = kEncodeSize.height() / 100 * 100;
364   constexpr uint64_t kWidth = kEncodeSize.width() / 100 * 100;
365   EXPECT_UKM(UkmEntry::kHeightName, kHeight);
366   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
367   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 0u);
368   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
369   EXPECT_UKM(
370       UkmEntry::kStatusName,
371       static_cast<int64_t>(EncoderStatus::Codes::kEncoderMojoConnectionError));
372   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
373   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
374   EXPECT_UKM(UkmEntry::kWidthName, kWidth);
375 }
376
377 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
378        CallErrorAndNoCallSetEncodedFramesCount_ReportUKMWithTheFirstError) {
379   auto [test_recorder, provider] = Create(kTestURL);
380   constexpr uint64_t kEncoderId = 0;
381   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
382   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
383   constexpr gfx::Size kEncodeSize(1920, 1080);
384   constexpr bool kIsHardwareEncoder = true;
385   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
386   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
387                        kIsHardwareEncoder, kSVCMode);
388   provider->SetError(kEncoderId,
389                      {EncoderStatus::Codes::kEncoderMojoConnectionError,
390                       "mojo connection is disclosed"});
391   provider->SetError(kEncoderId, {EncoderStatus::Codes::kEncoderFailedEncode,
392                                   "Encoder failed"});
393   provider.reset();
394   base::RunLoop().RunUntilIdle();
395
396   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
397   ASSERT_EQ(1u, entries.size());
398   const auto* entry = entries[0];
399   constexpr uint64_t kHeight = kEncodeSize.height() / 100 * 100;
400   constexpr uint64_t kWidth = kEncodeSize.width() / 100 * 100;
401   EXPECT_UKM(UkmEntry::kHeightName, kHeight);
402   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
403   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 0);
404   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
405   EXPECT_UKM(
406       UkmEntry::kStatusName,
407       static_cast<int64_t>(EncoderStatus::Codes::kEncoderMojoConnectionError));
408   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
409   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
410   EXPECT_UKM(UkmEntry::kWidthName, kWidth);
411 }
412
413 TEST_F(
414     MojoVideoEncoderMetricsProviderServiceTest,
415     CallSetEncodedFrameCountsAndSetError_ReportUKMWithTheFirstErrorAndTheLastEncodedFrameCount) {
416   auto [test_recorder, provider] = Create(kTestURL);
417   constexpr uint64_t kEncoderId = 0;
418   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
419   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
420   constexpr gfx::Size kEncodeSize(1920, 1080);
421   constexpr bool kIsHardwareEncoder = true;
422   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
423   provider->Initialize(kEncoderId, kEncoderUseCase, kCodecProfile, kEncodeSize,
424                        kIsHardwareEncoder, kSVCMode);
425   provider->SetEncodedFrameCount(kEncoderId, 100);
426   provider->SetEncodedFrameCount(kEncoderId, 200);
427   provider->SetEncodedFrameCount(kEncoderId, 300);
428   provider->SetError(kEncoderId, {EncoderStatus::Codes::kEncoderFailedEncode,
429                                   "Encoder failed"});
430   provider->SetError(kEncoderId, {EncoderStatus::Codes::kEncoderIllegalState,
431                                   "Encoder illegal state"});
432   provider->SetEncodedFrameCount(kEncoderId, 400);
433   provider.reset();
434   base::RunLoop().RunUntilIdle();
435
436   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
437   ASSERT_EQ(1u, entries.size());
438   const auto* entry = entries[0];
439   constexpr uint64_t kHeight = kEncodeSize.height() / 100 * 100;
440   constexpr uint64_t kWidth = kEncodeSize.width() / 100 * 100;
441   EXPECT_UKM(UkmEntry::kHeightName, kHeight);
442   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
443   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 400);
444   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
445   EXPECT_UKM(UkmEntry::kStatusName,
446              static_cast<int64_t>(EncoderStatus::Codes::kEncoderFailedEncode));
447   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
448   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
449   EXPECT_UKM(UkmEntry::kWidthName, kWidth);
450 }
451
452 TEST_F(MojoVideoEncoderMetricsProviderServiceTest,
453        CreateAndTwoInitializeAndSetEncodedFrameCounts_ReportTwoUKMs) {
454   const struct {
455     mojom::VideoEncoderUseCase use_case;
456     VideoCodecProfile profile;
457     gfx::Size size;
458     bool is_hardware;
459     SVCScalabilityMode svc_mode;
460     EncoderStatus::Codes status;
461     uint64_t num_encoded_frames;
462   } kMetricsCases[] = {
463       {
464           mojom::VideoEncoderUseCase::kWebRTC,
465           VP9PROFILE_PROFILE0,
466           gfx::Size(600, 300),
467           true,
468           SVCScalabilityMode::kL2T3Key,
469           EncoderStatus::Codes::kEncoderIllegalState,
470           100,
471       },
472       {
473           mojom::VideoEncoderUseCase::kMediaRecorder,
474           H264PROFILE_HIGH,
475           gfx::Size(1200, 700),
476           /*is_hardware=*/true,
477           SVCScalabilityMode::kL2T3Key,
478           EncoderStatus::Codes::kOk,
479           300,
480       },
481   };
482   constexpr uint64_t kEncoderId = 0;
483   auto [test_recorder, provider] = Create(kTestURL);
484   for (const auto& metrics : kMetricsCases) {
485     provider->Initialize(kEncoderId, metrics.use_case, metrics.profile,
486                          metrics.size, metrics.is_hardware, metrics.svc_mode);
487     provider->SetEncodedFrameCount(kEncoderId, metrics.num_encoded_frames);
488     if (metrics.status != EncoderStatus::Codes::kOk) {
489       provider->SetError(kEncoderId, metrics.status);
490     }
491   }
492   provider.reset();
493   base::RunLoop().RunUntilIdle();
494
495   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
496   ASSERT_EQ(std::size(kMetricsCases), entries.size());
497   for (size_t i = 0; i < entries.size(); ++i) {
498     const auto* entry = entries[i];
499     const auto& metrics = kMetricsCases[i];
500     EXPECT_UKM(UkmEntry::kHeightName, metrics.size.height());
501     EXPECT_UKM(UkmEntry::kIsHardwareName, metrics.is_hardware);
502     EXPECT_UKM(UkmEntry::kNumEncodedFramesName, metrics.num_encoded_frames);
503     EXPECT_UKM(UkmEntry::kProfileName, metrics.profile);
504     EXPECT_UKM(UkmEntry::kStatusName, static_cast<int64_t>(metrics.status));
505     EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(metrics.svc_mode));
506     EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(metrics.use_case));
507     EXPECT_UKM(UkmEntry::kWidthName, metrics.size.width());
508   }
509 }
510
511 TEST_F(MojoVideoEncoderMetricsProviderServiceTest, HandleTwoEncoders) {
512   const struct {
513     uint64_t encoder_id;
514     mojom::VideoEncoderUseCase use_case;
515     VideoCodecProfile profile;
516     gfx::Size size;
517     bool is_hardware;
518     SVCScalabilityMode svc_mode;
519     EncoderStatus::Codes status;
520     uint64_t num_encoded_frames;
521   } kMetricsCases[] = {
522       {
523           0,
524           mojom::VideoEncoderUseCase::kWebRTC,
525           VP9PROFILE_PROFILE0,
526           gfx::Size(600, 300),
527           true,
528           SVCScalabilityMode::kL2T3Key,
529           EncoderStatus::Codes::kEncoderIllegalState,
530           100,
531       },
532       {
533           1,
534           mojom::VideoEncoderUseCase::kMediaRecorder,
535           H264PROFILE_HIGH,
536           gfx::Size(1200, 700),
537           /*is_hardware=*/true,
538           SVCScalabilityMode::kL2T3Key,
539           EncoderStatus::Codes::kOk,
540           300,
541       },
542   };
543   auto [test_recorder, provider] = Create(kTestURL);
544   for (const auto& metrics : kMetricsCases) {
545     provider->Initialize(metrics.encoder_id, metrics.use_case, metrics.profile,
546                          metrics.size, metrics.is_hardware, metrics.svc_mode);
547   }
548   for (const auto& metrics : kMetricsCases) {
549     provider->SetEncodedFrameCount(metrics.encoder_id,
550                                    metrics.num_encoded_frames);
551   }
552   for (const auto& metrics : kMetricsCases) {
553     if (metrics.status != EncoderStatus::Codes::kOk) {
554       provider->SetError(metrics.encoder_id, metrics.status);
555     }
556   }
557   for (const auto& metrics : kMetricsCases) {
558     provider->Complete(metrics.encoder_id);
559   }
560   provider.reset();
561   base::RunLoop().RunUntilIdle();
562
563   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
564   ASSERT_EQ(std::size(kMetricsCases), entries.size());
565   for (size_t i = 0; i < entries.size(); ++i) {
566     const auto* entry = entries[i];
567     const auto& metrics = kMetricsCases[i];
568     EXPECT_UKM(UkmEntry::kHeightName, metrics.size.height());
569     EXPECT_UKM(UkmEntry::kIsHardwareName, metrics.is_hardware);
570     EXPECT_UKM(UkmEntry::kNumEncodedFramesName, metrics.num_encoded_frames);
571     EXPECT_UKM(UkmEntry::kProfileName, metrics.profile);
572     EXPECT_UKM(UkmEntry::kStatusName, static_cast<int64_t>(metrics.status));
573     EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(metrics.svc_mode));
574     EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(metrics.use_case));
575     EXPECT_UKM(UkmEntry::kWidthName, metrics.size.width());
576   }
577 }
578
579 TEST_F(MojoVideoEncoderMetricsProviderServiceTest, IgnoreUnknownEncoderIds) {
580   auto [test_recorder, provider] = Create(kTestURL);
581   constexpr uint64_t kKnownEncoderId = 123;
582   constexpr uint64_t kUnknownEncoderId = 321;
583   constexpr auto kEncoderUseCase = mojom::VideoEncoderUseCase::kWebRTC;
584   constexpr auto kCodecProfile = VP9PROFILE_PROFILE0;
585   constexpr gfx::Size kEncodeSize(1200, 700);
586   constexpr bool kIsHardwareEncoder = true;
587   constexpr auto kSVCMode = SVCScalabilityMode::kL1T3;
588   provider->Initialize(kKnownEncoderId, kEncoderUseCase, kCodecProfile,
589                        kEncodeSize, kIsHardwareEncoder, kSVCMode);
590   provider->SetEncodedFrameCount(kUnknownEncoderId, 100);
591   provider->SetError(kUnknownEncoderId,
592                      EncoderStatus::Codes::kEncoderFailedEncode);
593   provider->Complete(kUnknownEncoderId);
594
595   provider->Complete(kKnownEncoderId);
596   // This should be ignored as Complete() is already called.
597   provider->SetError(kKnownEncoderId,
598                      EncoderStatus::Codes::kEncoderFailedEncode);
599
600   provider.reset();
601   base::RunLoop().RunUntilIdle();
602
603   const auto entries = test_recorder->GetEntriesByName(UkmEntry::kEntryName);
604   ASSERT_EQ(1u, entries.size());
605   const auto* entry = entries[0];
606   EXPECT_UKM(UkmEntry::kHeightName, kEncodeSize.height());
607   EXPECT_UKM(UkmEntry::kIsHardwareName, kIsHardwareEncoder);
608   EXPECT_UKM(UkmEntry::kNumEncodedFramesName, 0);
609   EXPECT_UKM(UkmEntry::kProfileName, kCodecProfile);
610   EXPECT_UKM(UkmEntry::kStatusName,
611              static_cast<int64_t>(EncoderStatus::Codes::kOk));
612   EXPECT_UKM(UkmEntry::kSVCModeName, static_cast<int64_t>(kSVCMode));
613   EXPECT_UKM(UkmEntry::kUseCaseName, static_cast<int64_t>(kEncoderUseCase));
614   EXPECT_UKM(UkmEntry::kWidthName, kEncodeSize.width());
615 }
616 #undef EXPECT_UKM
617 }  // namespace media