webrtc_browsertest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright (c) 2012 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
5#include "base/command_line.h"
6#include "base/strings/stringprintf.h"
7#include "base/values.h"
8#include "content/browser/media/webrtc_internals.h"
9#include "content/browser/web_contents/web_contents_impl.h"
10#include "content/public/common/content_switches.h"
11#include "content/public/test/browser_test_utils.h"
12#include "content/public/test/content_browser_test_utils.h"
13#include "content/public/test/test_utils.h"
14#include "content/shell/browser/shell.h"
15#include "content/test/webrtc_content_browsertest_base.h"
16#include "media/audio/audio_manager.h"
17#include "net/test/embedded_test_server/embedded_test_server.h"
18
19#if defined(OS_WIN)
20#include "base/win/windows_version.h"
21#endif
22
23#if defined (OS_ANDROID) || defined(THREAD_SANITIZER)
24// Just do the bare minimum of audio checking on Android and under TSAN since
25// it's a bit sensitive to device performance.
26static const char kUseLenientAudioChecking[] = "true";
27#else
28static const char kUseLenientAudioChecking[] = "false";
29#endif
30
31namespace content {
32
33class WebRtcBrowserTest : public WebRtcContentBrowserTest,
34                          public testing::WithParamInterface<bool> {
35 public:
36  WebRtcBrowserTest() {}
37  virtual ~WebRtcBrowserTest() {}
38
39  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
40    WebRtcContentBrowserTest::SetUpCommandLine(command_line);
41
42    bool enable_audio_track_processing = GetParam();
43    if (enable_audio_track_processing)
44      command_line->AppendSwitch(switches::kEnableAudioTrackProcessing);
45  }
46
47  // Convenience function since most peerconnection-call.html tests just load
48  // the page, kick off some javascript and wait for the title to change to OK.
49  void MakeTypicalPeerConnectionCall(const std::string& javascript) {
50    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
51
52    GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
53    NavigateToURL(shell(), url);
54
55    DisableOpusIfOnAndroid();
56    ExecuteJavascriptAndWaitForOk(javascript);
57  }
58
59  void DisableOpusIfOnAndroid() {
60#if defined (OS_ANDROID)
61    // Always force iSAC 16K on Android for now (Opus is broken).
62    EXPECT_EQ("isac-forced",
63              ExecuteJavascriptAndReturnResult("forceIsac16KInSdp();"));
64#endif
65  }
66};
67
68static const bool kRunTestsWithFlag[] = { false, true };
69INSTANTIATE_TEST_CASE_P(WebRtcBrowserTests,
70                        WebRtcBrowserTest,
71                        testing::ValuesIn(kRunTestsWithFlag));
72
73#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
74// Timing out on ARM linux bot: http://crbug.com/238490
75#define MAYBE_CanSetupDefaultVideoCall DISABLED_CanSetupDefaultVideoCall
76#else
77#define MAYBE_CanSetupDefaultVideoCall CanSetupDefaultVideoCall
78#endif
79
80// These tests will make a complete PeerConnection-based call and verify that
81// video is playing for the call.
82IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CanSetupDefaultVideoCall) {
83  MakeTypicalPeerConnectionCall(
84      "callAndExpectResolution({video: true}, 640, 480);");
85}
86
87IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, CanSetupVideoCallWith1To1AspecRatio) {
88  const std::string javascript =
89      "callAndExpectResolution({video: {mandatory: {minWidth: 320,"
90      " maxWidth: 320, minHeight: 320, maxHeight: 320}}}, 320, 320);";
91  MakeTypicalPeerConnectionCall(javascript);
92}
93
94#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
95// Timing out on ARM linux, see http://crbug.com/240376
96#define MAYBE_CanSetupAudioAndVideoCall DISABLED_CanSetupAudioAndVideoCall
97#else
98#define MAYBE_CanSetupAudioAndVideoCall CanSetupAudioAndVideoCall
99#endif
100
101IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CanSetupAudioAndVideoCall) {
102  MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
103}
104
105IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_CanSetupCallAndSendDtmf) {
106  MakeTypicalPeerConnectionCall("callAndSendDtmf(\'123,abc\');");
107}
108
109// TODO(phoglund): this test fails because the peer connection state will be
110// stable in the second negotiation round rather than have-local-offer.
111// http://crbug.com/293125.
112IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
113                       DISABLED_CanMakeEmptyCallThenAddStreamsAndRenegotiate) {
114  const char* kJavascript =
115      "callEmptyThenAddOneStreamAndRenegotiate({video: true, audio: true});";
116  MakeTypicalPeerConnectionCall(kJavascript);
117}
118
119// Below 2 test will make a complete PeerConnection-based call between pc1 and
120// pc2, and then use the remote stream to setup a call between pc3 and pc4, and
121// then verify that video is received on pc3 and pc4.
122// Flaky on win xp. http://crbug.com/304775
123#if defined(OS_WIN)
124#define MAYBE_CanForwardRemoteStream DISABLED_CanForwardRemoteStream
125#define MAYBE_CanForwardRemoteStream720p DISABLED_CanForwardRemoteStream720p
126#else
127#define MAYBE_CanForwardRemoteStream CanForwardRemoteStream
128#define MAYBE_CanForwardRemoteStream720p CanForwardRemoteStream720p
129#endif
130IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CanForwardRemoteStream) {
131#if defined (OS_ANDROID)
132  // This test fails on Nexus 5 devices.
133  // TODO: see http://crbug.com/362437 and http://crbug.com/359389
134  // for details.
135  CommandLine::ForCurrentProcess()->AppendSwitch(
136      switches::kDisableWebRtcHWDecoding);
137#endif
138  MakeTypicalPeerConnectionCall(
139      "callAndForwardRemoteStream({video: true, audio: false});");
140}
141
142IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CanForwardRemoteStream720p) {
143#if defined (OS_ANDROID)
144  // This test fails on Nexus 5 devices.
145  // TODO: see http://crbug.com/362437 and http://crbug.com/359389
146  // for details.
147  CommandLine::ForCurrentProcess()->AppendSwitch(
148      switches::kDisableWebRtcHWDecoding);
149#endif
150  const std::string javascript = GenerateGetUserMediaCall(
151      "callAndForwardRemoteStream", 1280, 1280, 720, 720, 10, 30);
152  MakeTypicalPeerConnectionCall(javascript);
153}
154
155// This test will make a complete PeerConnection-based call but remove the
156// MSID and bundle attribute from the initial offer to verify that
157// video is playing for the call even if the initiating client don't support
158// MSID. http://tools.ietf.org/html/draft-alvestrand-rtcweb-msid-02
159#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
160// Timing out on ARM linux, see http://crbug.com/240373
161#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
162        DISABLED_CanSetupAudioAndVideoCallWithoutMsidAndBundle
163#else
164#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
165        CanSetupAudioAndVideoCallWithoutMsidAndBundle
166#endif
167IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
168                       MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle) {
169  MakeTypicalPeerConnectionCall("callWithoutMsidAndBundle();");
170}
171
172// This test will modify the SDP offer to an unsupported codec, which should
173// cause SetLocalDescription to fail.
174#if defined(USE_OZONE)
175// Disabled for Ozone, see http://crbug.com/315392#c15
176#define MAYBE_NegotiateUnsupportedVideoCodec\
177    DISABLED_NegotiateUnsupportedVideoCodec
178#else
179#define MAYBE_NegotiateUnsupportedVideoCodec NegotiateUnsupportedVideoCodec
180#endif
181
182IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
183                       MAYBE_NegotiateUnsupportedVideoCodec) {
184  MakeTypicalPeerConnectionCall("negotiateUnsupportedVideoCodec();");
185}
186
187// This test will modify the SDP offer to use no encryption, which should
188// cause SetLocalDescription to fail.
189#if defined(USE_OZONE)
190// Disabled for Ozone, see http://crbug.com/315392#c15
191#define MAYBE_NegotiateNonCryptoCall DISABLED_NegotiateNonCryptoCall
192#else
193#define MAYBE_NegotiateNonCryptoCall NegotiateNonCryptoCall
194#endif
195
196IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_NegotiateNonCryptoCall) {
197  MakeTypicalPeerConnectionCall("negotiateNonCryptoCall();");
198}
199
200// This test can negotiate an SDP offer that includes a b=AS:xx to control
201// the bandwidth for audio and video
202IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, NegotiateOfferWithBLine) {
203  MakeTypicalPeerConnectionCall("negotiateOfferWithBLine();");
204}
205
206// This test will make a complete PeerConnection-based call using legacy SDP
207// settings: GIce, external SDES, and no BUNDLE.
208#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
209// Timing out on ARM linux, see http://crbug.com/240373
210#define MAYBE_CanSetupLegacyCall DISABLED_CanSetupLegacyCall
211#else
212#define MAYBE_CanSetupLegacyCall CanSetupLegacyCall
213#endif
214
215IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CanSetupLegacyCall) {
216  MakeTypicalPeerConnectionCall("callWithLegacySdp();");
217}
218
219// This test will make a PeerConnection-based call and test an unreliable text
220// dataChannel.
221// TODO(mallinath) - Remove this test after rtp based data channel is disabled.
222IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, CallWithDataOnly) {
223  MakeTypicalPeerConnectionCall("callWithDataOnly();");
224}
225
226IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, CallWithSctpDataOnly) {
227  MakeTypicalPeerConnectionCall("callWithSctpDataOnly();");
228}
229
230#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
231// Timing out on ARM linux bot: http://crbug.com/238490
232#define MAYBE_CallWithDataAndMedia DISABLED_CallWithDataAndMedia
233#else
234#define MAYBE_CallWithDataAndMedia CallWithDataAndMedia
235#endif
236
237// This test will make a PeerConnection-based call and test an unreliable text
238// dataChannel and audio and video tracks.
239// TODO(mallinath) - Remove this test after rtp based data channel is disabled.
240IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CallWithDataAndMedia) {
241  MakeTypicalPeerConnectionCall("callWithDataAndMedia();");
242}
243
244
245#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
246// Timing out on ARM linux bot: http://crbug.com/238490
247#define MAYBE_CallWithSctpDataAndMedia DISABLED_CallWithSctpDataAndMedia
248#else
249#define MAYBE_CallWithSctpDataAndMedia CallWithSctpDataAndMedia
250#endif
251
252IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
253                       MAYBE_CallWithSctpDataAndMedia) {
254  MakeTypicalPeerConnectionCall("callWithSctpDataAndMedia();");
255}
256
257#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
258// Timing out on ARM linux bot: http://crbug.com/238490
259#define MAYBE_CallWithDataAndLaterAddMedia DISABLED_CallWithDataAndLaterAddMedia
260#else
261// Temporarily disable the test on all platforms. http://crbug.com/293252
262#define MAYBE_CallWithDataAndLaterAddMedia DISABLED_CallWithDataAndLaterAddMedia
263#endif
264
265// This test will make a PeerConnection-based call and test an unreliable text
266// dataChannel and later add an audio and video track.
267IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CallWithDataAndLaterAddMedia) {
268  MakeTypicalPeerConnectionCall("callWithDataAndLaterAddMedia();");
269}
270
271#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
272// Timing out on ARM linux bot: http://crbug.com/238490
273#define MAYBE_CallWithNewVideoMediaStream DISABLED_CallWithNewVideoMediaStream
274#else
275#define MAYBE_CallWithNewVideoMediaStream CallWithNewVideoMediaStream
276#endif
277
278// This test will make a PeerConnection-based call and send a new Video
279// MediaStream that has been created based on a MediaStream created with
280// getUserMedia.
281IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CallWithNewVideoMediaStream) {
282  MakeTypicalPeerConnectionCall("callWithNewVideoMediaStream();");
283}
284
285// This test will make a PeerConnection-based call and send a new Video
286// MediaStream that has been created based on a MediaStream created with
287// getUserMedia. When video is flowing, the VideoTrack is removed and an
288// AudioTrack is added instead.
289// TODO(phoglund): This test is manual since not all buildbots has an audio
290// input.
291IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_CallAndModifyStream) {
292  MakeTypicalPeerConnectionCall(
293      "callWithNewVideoMediaStreamLaterSwitchToAudio();");
294}
295
296IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, AddTwoMediaStreamsToOnePC) {
297  MakeTypicalPeerConnectionCall("addTwoMediaStreamsToOneConnection();");
298}
299
300IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
301                       EstablishAudioVideoCallAndMeasureOutputLevel) {
302  if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
303    // Bots with no output devices will force the audio code into a different
304    // path where it doesn't manage to set either the low or high latency path.
305    // This test will compute useless values in that case, so skip running on
306    // such bots (see crbug.com/326338).
307    LOG(INFO) << "Missing output devices: skipping test...";
308    return;
309  }
310
311  ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
312      switches::kUseFakeDeviceForMediaStream))
313          << "Must run with fake devices since the test will explicitly look "
314          << "for the fake device signal.";
315
316  MakeTypicalPeerConnectionCall(base::StringPrintf(
317      "callAndEnsureAudioIsPlaying(%s);", kUseLenientAudioChecking));
318}
319
320IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
321                       EstablishAudioVideoCallAndVerifyMutingWorks) {
322  if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
323    // See comment on EstablishAudioVideoCallAndMeasureOutputLevel.
324    LOG(INFO) << "Missing output devices: skipping test...";
325    return;
326  }
327
328  ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
329      switches::kUseFakeDeviceForMediaStream))
330          << "Must run with fake devices since the test will explicitly look "
331          << "for the fake device signal.";
332
333  MakeTypicalPeerConnectionCall(base::StringPrintf(
334      "callAndEnsureAudioTrackMutingWorks(%s);", kUseLenientAudioChecking));
335}
336
337IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
338                       EstablishAudioVideoCallAndVerifyUnmutingWorks) {
339  if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
340    // See comment on EstablishAudioVideoCallAndMeasureOutputLevel.
341    LOG(INFO) << "Missing output devices: skipping test...";
342    return;
343  }
344
345  ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
346      switches::kUseFakeDeviceForMediaStream))
347          << "Must run with fake devices since the test will explicitly look "
348          << "for the fake device signal.";
349
350  MakeTypicalPeerConnectionCall(base::StringPrintf(
351      "callAndEnsureAudioTrackUnmutingWorks(%s);", kUseLenientAudioChecking));
352}
353
354IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, CallAndVerifyVideoMutingWorks) {
355  MakeTypicalPeerConnectionCall("callAndEnsureVideoTrackMutingWorks();");
356}
357
358#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
359// Timing out on ARM linux bot: http://crbug.com/238490
360#define MAYBE_CallWithAecDump DISABLED_CallWithAecDump
361#else
362#define MAYBE_CallWithAecDump CallWithAecDump
363#endif
364
365// This tests will make a complete PeerConnection-based call, verify that
366// video is playing for the call, and verify that a non-empty AEC dump file
367// exists. The AEC dump is enabled through webrtc-internals. The HTML and
368// Javascript is bypassed since it would trigger a file picker dialog. Instead,
369// the dialog callback FileSelected() is invoked directly. In fact, there's
370// never a webrtc-internals page opened at all since that's not needed.
371IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_CallWithAecDump) {
372  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
373
374  // We must navigate somewhere first so that the render process is created.
375  NavigateToURL(shell(), GURL(""));
376
377  base::FilePath dump_file;
378  ASSERT_TRUE(CreateTemporaryFile(&dump_file));
379
380  // This fakes the behavior of another open tab with webrtc-internals, and
381  // enabling AEC dump in that tab.
382  WebRTCInternals::GetInstance()->FileSelected(dump_file, -1, NULL);
383
384  GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
385  NavigateToURL(shell(), url);
386  DisableOpusIfOnAndroid();
387  ExecuteJavascriptAndWaitForOk("call({video: true, audio: true});");
388
389  EXPECT_TRUE(base::PathExists(dump_file));
390  int64 file_size = 0;
391  EXPECT_TRUE(base::GetFileSize(dump_file, &file_size));
392  EXPECT_GT(file_size, 0);
393
394  base::DeleteFile(dump_file, false);
395}
396
397#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
398// Timing out on ARM linux bot: http://crbug.com/238490
399#define MAYBE_CallWithAecDumpEnabledThenDisabled DISABLED_CallWithAecDumpEnabledThenDisabled
400#else
401#define MAYBE_CallWithAecDumpEnabledThenDisabled CallWithAecDumpEnabledThenDisabled
402#endif
403
404// As above, but enable and disable dump before starting a call. The file should
405// be created, but should be empty.
406IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
407                       MAYBE_CallWithAecDumpEnabledThenDisabled) {
408  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
409
410  // We must navigate somewhere first so that the render process is created.
411  NavigateToURL(shell(), GURL(""));
412
413  base::FilePath dump_file;
414  ASSERT_TRUE(CreateTemporaryFile(&dump_file));
415
416  // This fakes the behavior of another open tab with webrtc-internals, and
417  // enabling AEC dump in that tab, then disabling it.
418  WebRTCInternals::GetInstance()->FileSelected(dump_file, -1, NULL);
419  WebRTCInternals::GetInstance()->DisableAecDump();
420
421  GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
422  NavigateToURL(shell(), url);
423  DisableOpusIfOnAndroid();
424  ExecuteJavascriptAndWaitForOk("call({video: true, audio: true});");
425
426  EXPECT_TRUE(base::PathExists(dump_file));
427  int64 file_size = 0;
428  EXPECT_TRUE(base::GetFileSize(dump_file, &file_size));
429  EXPECT_EQ(0, file_size);
430
431  base::DeleteFile(dump_file, false);
432}
433
434}  // namespace content
435