File: video_conference_ukm_helper_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,096 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (279 lines) | stat: -rw-r--r-- 11,372 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/video_conference/video_conference_ukm_helper.h"

#include <memory>
#include <vector>

#include "base/logging.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/test/browser_task_environment.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace video_conference {

namespace {
constexpr int kDuration10ms = 10;
constexpr int kDuration17ms = 17;
constexpr int kDuration20ms = 20;
constexpr int kDuration24ms = 24;
constexpr int kDuration70ms = 70;
}  // namespace

using UkmEntry = ukm::builders::VideoConferencingEvent;

class FakeVideoConferenceUkmHelper : public VideoConferenceUkmHelper {
 public:
  explicit FakeVideoConferenceUkmHelper(ukm::TestUkmRecorder* ukm_recorder)
      : VideoConferenceUkmHelper(ukm_recorder,
                                 /*source_id=*/ukm_recorder->GetNewSourceID()) {
  }

  FakeVideoConferenceUkmHelper(const FakeVideoConferenceUkmHelper&) = delete;
  FakeVideoConferenceUkmHelper& operator=(const FakeVideoConferenceUkmHelper&) =
      delete;

  ukm::SourceId source_id() const { return source_id_; }
};

class VideoConferenceUkmHelperTest : public testing::Test {
 public:
  VideoConferenceUkmHelperTest() = default;

  VideoConferenceUkmHelperTest(const VideoConferenceUkmHelperTest&) = delete;
  VideoConferenceUkmHelperTest& operator=(const VideoConferenceUkmHelperTest&) =
      delete;
  ~VideoConferenceUkmHelperTest() override = default;

  void UpdateCapturing(FakeVideoConferenceUkmHelper* ukm_helper,
                       VideoConferenceMediaType device,
                       bool is_capturing) {
    // The update to the helper has to be sent before updating the state.
    ukm_helper->RegisterCapturingUpdate(device, is_capturing);
  }

  content::BrowserTaskEnvironment& task_environment() {
    return task_environment_;
  }

 private:
  content::BrowserTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
};

// Tests capturing a media device correctly sets DidCapture<Device> metrics
// values in recorded entries.
TEST_F(VideoConferenceUkmHelperTest, DidCaptureDevice) {
  ukm::TestUkmRecorder ukm_recorder;

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper1 =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start capturing device(s).
  UpdateCapturing(ukm_helper1.get(), VideoConferenceMediaType::kCamera, true);

  // Wait 10 milliseconds.
  task_environment().FastForwardBy(base::Milliseconds(kDuration10ms));

  // Stop capturing all devices.
  UpdateCapturing(ukm_helper1.get(), VideoConferenceMediaType::kCamera, false);

  // Destroy ukm_helper1 thus triggering it to record metrics in its destructor.
  ukm_helper1.reset();

  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kDidCaptureCameraName, true);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kDidCaptureMicrophoneName, false);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kDidCaptureScreenName, false);

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper2 =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start capturing all devices.
  UpdateCapturing(ukm_helper2.get(), VideoConferenceMediaType::kCamera, true);
  UpdateCapturing(ukm_helper2.get(), VideoConferenceMediaType::kMicrophone,
                  true);

  // Wait 10 milliseconds.
  task_environment().FastForwardBy(base::Milliseconds(kDuration10ms));

  // Stop capturing all devices.
  UpdateCapturing(ukm_helper2.get(), VideoConferenceMediaType::kCamera, false);
  UpdateCapturing(ukm_helper2.get(), VideoConferenceMediaType::kMicrophone,
                  false);

  // Destroy ukm_helper2 thus triggering it to record metrics in its destructor.
  ukm_helper2.reset();

  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[1],
      UkmEntry::kDidCaptureCameraName, true);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[1],
      UkmEntry::kDidCaptureMicrophoneName, true);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[1],
      UkmEntry::kDidCaptureScreenName, false);

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper3 =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start capturing all devices.
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kCamera, true);
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kMicrophone,
                  true);
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kScreen, true);

  // Wait 10 milliseconds.
  task_environment().FastForwardBy(base::Milliseconds(kDuration10ms));

  // Stop capturing all devices.
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kCamera, false);
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kMicrophone,
                  false);
  UpdateCapturing(ukm_helper3.get(), VideoConferenceMediaType::kScreen, false);

  // Destroy ukm_helper3 thus triggering it to record metrics in its destructor.
  ukm_helper3.reset();

  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[2],
      UkmEntry::kDidCaptureCameraName, true);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[2],
      UkmEntry::kDidCaptureMicrophoneName, true);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[2],
      UkmEntry::kDidCaptureScreenName, true);
}

// Tests media device capture durations.
TEST_F(VideoConferenceUkmHelperTest, CaptureDurations) {
  ukm::TestUkmRecorder ukm_recorder;

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start and stop capturing camera.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kCamera, true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration17ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kCamera, false);

  // Start and stop capturing microphone.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kMicrophone,
                  true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration24ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kMicrophone,
                  false);

  // Start and stop capturing screen.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kScreen, true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration70ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kScreen, false);

  // Destroy ukm_helper thus triggering it to record metrics in its destructor.
  ukm_helper.reset();

  // Here the expected value is 10ms even though the true duration was 17ms due
  // to all durations being bucketed using
  // `ukm::GetSemanticBucketMinForDurationTiming`.
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kCameraCaptureDurationName, kDuration10ms);
  // Here again the expected duration is 20ms instead of 24ms to test bucketing.
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kMicrophoneCaptureDurationName, kDuration20ms);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kScreenCaptureDurationName, kDuration70ms);
}

// Tests total duration equals the time duration from the creation of the
// VideoConferenceUkmHelper to its destruction.
TEST_F(VideoConferenceUkmHelperTest, TotalDuration) {
  ukm::TestUkmRecorder ukm_recorder;

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start and stop capturing camera.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kCamera, true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration10ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kCamera, false);

  // Start and stop capturing microphone.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kMicrophone,
                  true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration20ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kMicrophone,
                  false);

  // Start and stop capturing screen.
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kScreen, true);
  task_environment().FastForwardBy(base::Milliseconds(kDuration70ms));
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kScreen, false);

  // Destroy ukm_helper thus triggering it to record metrics in its destructor.
  ukm_helper.reset();

  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kTotalDurationName,
      kDuration10ms + kDuration20ms + kDuration70ms);
}

// Tests that the destructor correctly includes any pending media devices whose
// durations were being tracked even if a stop capture signal did not arrive for
// them.
TEST_F(VideoConferenceUkmHelperTest, DestructorIncludesPendingCaptures) {
  ukm::TestUkmRecorder ukm_recorder;

  // Create a FakeVideoConferenceUkmHelper
  std::unique_ptr<FakeVideoConferenceUkmHelper> ukm_helper =
      std::make_unique<FakeVideoConferenceUkmHelper>(&ukm_recorder);

  // Start capturing media devices
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kCamera, true);
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kMicrophone,
                  true);
  UpdateCapturing(ukm_helper.get(), VideoConferenceMediaType::kScreen, true);

  // Wait
  task_environment().FastForwardBy(base::Milliseconds(kDuration20ms));

  // Destroy the VideoConferenceUkmHelper and trigger its destructor.
  ukm_helper.reset();

  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kCameraCaptureDurationName, kDuration20ms);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kMicrophoneCaptureDurationName, kDuration20ms);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kScreenCaptureDurationName, kDuration20ms);
  ukm_recorder.ExpectEntryMetric(
      ukm_recorder.GetEntriesByName(UkmEntry::kEntryName)[0],
      UkmEntry::kTotalDurationName, kDuration20ms);
}

}  // namespace video_conference