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
content / browser / media / webaudio / audio_context_manager_browsertest.cc [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/mock_web_contents_observer.h"
#include "content/shell/browser/shell.h"
#include "media/base/media_switches.h"
#include "net/dns/mock_host_resolver.h"
#include "services/metrics/public/cpp/ukm_builders.h"
namespace {
class Waiter : public content::WebContentsObserver {
public:
explicit Waiter(content::WebContents* web_contents)
: WebContentsObserver(web_contents) {}
Waiter(const Waiter&) = delete;
Waiter& operator=(const Waiter&) = delete;
void Wait() {
base::RunLoop run_loop;
quit_closure_ = run_loop.QuitClosure();
run_loop.Run();
}
void AudioContextPlaybackStarted(const AudioContextId&) final {
quit_closure_.Run();
}
void AudioContextPlaybackStopped(const AudioContextId&) final {
quit_closure_.Run();
}
private:
base::RepeatingClosure quit_closure_;
};
} // namespace
class AudioContextManagerTest : public content::ContentBrowserTest {
public:
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
content::SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(
switches::kAutoplayPolicy,
switches::autoplay::kNoUserGestureRequiredPolicy);
}
void PlayPause() {
Waiter waiter(shell()->web_contents());
testing::NiceMock<content::MockWebContentsObserver> mock_observer(
shell()->web_contents());
EXPECT_CALL(mock_observer, AudioContextPlaybackStarted(testing::_))
.Times(1);
EXPECT_CALL(mock_observer, AudioContextPlaybackStopped(testing::_))
.Times(1);
// Set gain to 1 to start audible audio and verify we got the
// playback started message.
ASSERT_TRUE(ExecJs(shell()->web_contents(), "gain.gain.value = 1;"));
waiter.Wait();
// Set gain to 0 to stop audible audio and verify we got the
// playback stopped message.
ASSERT_TRUE(ExecJs(shell()->web_contents(), "gain.gain.value = 0;"));
waiter.Wait();
}
};
// Flaky on Linux: crbug.com/941219
// Flaky on Mac: crbug.com/941219
// Flaky on Fuchsia: crbug.com/941219
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_FUCHSIA)
#define MAYBE_AudioContextPlaybackRecorded DISABLED_AudioContextPlaybackRecorded
#else
#define MAYBE_AudioContextPlaybackRecorded AudioContextPlaybackRecorded
#endif
IN_PROC_BROWSER_TEST_F(AudioContextManagerTest,
MAYBE_AudioContextPlaybackRecorded) {
EXPECT_TRUE(NavigateToURL(
shell(), content::GetTestUrl("media/webaudio/", "playback-test.html")));
PlayPause();
}
// Flaky on Linux: crbug.com/941219
// Flaky on Android: crbug.com/941219
// Flaky on Mac: crbug.com/941219
// Flaky on Fuchsia: crbug.com/941219
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
BUILDFLAG(IS_MAC) || BUILDFLAG(IS_FUCHSIA)
#define MAYBE_AudioContextPlaybackTimeUkm DISABLED_AudioContextPlaybackTimeUkm
#else
#define MAYBE_AudioContextPlaybackTimeUkm AudioContextPlaybackTimeUkm
#endif
IN_PROC_BROWSER_TEST_F(AudioContextManagerTest,
MAYBE_AudioContextPlaybackTimeUkm) {
ukm::TestAutoSetUkmRecorder test_ukm_recorder;
using Entry = ukm::builders::Media_WebAudio_AudioContext_AudibleTime;
GURL url = embedded_test_server()->GetURL(
"example.com", "/media/webaudio/playback-test.html");
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ(0u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
// Play/pause something audible, it should lead to new Ukm entry.
PlayPause();
EXPECT_EQ(1u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
// Playback must have been recorded.
{
auto ukm_entries = test_ukm_recorder.GetEntriesByName(Entry::kEntryName);
ASSERT_EQ(1u, ukm_entries.size());
auto* entry = ukm_entries[0].get();
// The test doesn't check the URL because not the full Ukm stack is
// running in //content.
EXPECT_TRUE(
test_ukm_recorder.EntryHasMetric(entry, Entry::kAudibleTimeName));
EXPECT_GE(*test_ukm_recorder.GetEntryMetric(entry, Entry::kAudibleTimeName),
0);
EXPECT_TRUE(
test_ukm_recorder.EntryHasMetric(entry, Entry::kIsMainFrameName));
test_ukm_recorder.ExpectEntryMetric(entry, Entry::kIsMainFrameName, true);
}
// Play/pause again and check that there is a new entry.
PlayPause();
EXPECT_EQ(2u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
}