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/files/file_util.h"
7#include "base/strings/stringprintf.h"
8#include "base/threading/platform_thread.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/test/webrtc_content_browsertest_base.h"
15#include "media/audio/audio_manager.h"
16#include "media/base/media_switches.h"
17#include "net/test/embedded_test_server/embedded_test_server.h"
18
19namespace {
20
21#if defined (OS_ANDROID) || defined(THREAD_SANITIZER)
22// Just do the bare minimum of audio checking on Android and under TSAN since
23// it's a bit sensitive to device performance.
24const char kUseLenientAudioChecking[] = "true";
25#else
26const char kUseLenientAudioChecking[] = "false";
27#endif
28
29}  // namespace
30
31namespace content {
32
33#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
34// Renderer crashes under Android ASAN: https://crbug.com/408496.
35#define MAYBE_WebRtcBrowserTest DISABLED_WebRtcBrowserTest
36#elif defined(OS_ANDROID) && defined(__aarch64__)
37// Failures on ARM64 Android: http://crbug.com/408179.
38#define MAYBE_WebRtcBrowserTest DISABLED_WebRtcBrowserTest
39#else
40#define MAYBE_WebRtcBrowserTest WebRtcBrowserTest
41#endif
42
43class MAYBE_WebRtcBrowserTest : public WebRtcContentBrowserTest {
44 public:
45  MAYBE_WebRtcBrowserTest() {}
46  virtual ~MAYBE_WebRtcBrowserTest() {}
47
48  // Convenience function since most peerconnection-call.html tests just load
49  // the page, kick off some javascript and wait for the title to change to OK.
50  void MakeTypicalPeerConnectionCall(const std::string& javascript) {
51    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
52
53    GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
54    NavigateToURL(shell(), url);
55
56    DisableOpusIfOnAndroid();
57    ExecuteJavascriptAndWaitForOk(javascript);
58  }
59
60  // Convenience method for making calls that detect if audio os playing (which
61  // has some special prerequisites, such that there needs to be an audio output
62  // device on the executing machine).
63  void MakeAudioDetectingPeerConnectionCall(const std::string& javascript) {
64    if (!media::AudioManager::Get()->HasAudioOutputDevices()) {
65      // Bots with no output devices will force the audio code into a state
66      // where it doesn't manage to set either the low or high latency path.
67      // This test will compute useless values in that case, so skip running on
68      // such bots (see crbug.com/326338).
69      LOG(INFO) << "Missing output devices: skipping test...";
70      return;
71    }
72
73    ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
74        switches::kUseFakeDeviceForMediaStream))
75            << "Must run with fake devices since the test will explicitly look "
76            << "for the fake device signal.";
77
78    MakeTypicalPeerConnectionCall(javascript);
79  }
80};
81
82#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
83// Timing out on ARM linux bot: http://crbug.com/238490
84#define MAYBE_CanSetupDefaultVideoCall DISABLED_CanSetupDefaultVideoCall
85// Flaky on TSAN v2. http://crbug.com/408006
86#elif defined(THREAD_SANITIZER)
87#define MAYBE_CanSetupDefaultVideoCall DISABLED_CanSetupDefaultVideoCall
88#else
89#define MAYBE_CanSetupDefaultVideoCall CanSetupDefaultVideoCall
90#endif
91
92// These tests will make a complete PeerConnection-based call and verify that
93// video is playing for the call.
94IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
95                       MAYBE_CanSetupDefaultVideoCall) {
96  MakeTypicalPeerConnectionCall(
97      "callAndExpectResolution({video: true}, 640, 480);");
98}
99
100// Flaky on TSAN v2. http://crbug.com/408006
101#if defined(THREAD_SANITIZER)
102#define MAYBE_CanSetupVideoCallWith1To1AspectRatio \
103  DISABLED_CanSetupVideoCallWith1To1AspectRatio
104#else
105#define MAYBE_CanSetupVideoCallWith1To1AspectRatio \
106  CanSetupVideoCallWith1To1AspectRatio
107#endif
108IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
109                       MAYBE_CanSetupVideoCallWith1To1AspectRatio) {
110  const std::string javascript =
111      "callAndExpectResolution({video: {mandatory: {minWidth: 320,"
112      " maxWidth: 320, minHeight: 320, maxHeight: 320}}}, 320, 320);";
113  MakeTypicalPeerConnectionCall(javascript);
114}
115
116#if defined(OS_ANDROID) && defined(ARCH_CPU_ARM64)
117// Failing on ARM64 Android bot: http://crbug.com/408179
118#define MAYBE_CanSetupVideoCallWith16To9AspectRatio \
119  DISABLED_CanSetupVideoCallWith16To9AspectRatio
120// Flaky on TSAN v2. http://crbug.com/408006
121#elif defined(THREAD_SANITIZER)
122#define MAYBE_CanSetupVideoCallWith16To9AspectRatio \
123  DISABLED_CanSetupVideoCallWith16To9AspectRatio
124#else
125#define MAYBE_CanSetupVideoCallWith16To9AspectRatio \
126  CanSetupVideoCallWith16To9AspectRatio
127#endif
128IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
129                       MAYBE_CanSetupVideoCallWith16To9AspectRatio) {
130  const std::string javascript =
131      "callAndExpectResolution({video: {mandatory: {minWidth: 640,"
132      " maxWidth: 640, minAspectRatio: 1.777}}}, 640, 360);";
133  MakeTypicalPeerConnectionCall(javascript);
134}
135
136// Flaky on TSAN v2. http://crbug.com/408006
137#if defined(THREAD_SANITIZER)
138#define MAYBE_CanSetupVideoCallWith4To3AspectRatio \
139  DISABLED_CanSetupVideoCallWith4To3AspectRatio
140#else
141#define MAYBE_CanSetupVideoCallWith4To3AspectRatio \
142  CanSetupVideoCallWith4To3AspectRatio
143#endif
144IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
145                       MAYBE_CanSetupVideoCallWith4To3AspectRatio) {
146  const std::string javascript =
147      "callAndExpectResolution({video: {mandatory: {minWidth: 960,"
148      "maxAspectRatio: 1.333}}}, 960, 720);";
149  MakeTypicalPeerConnectionCall(javascript);
150}
151
152// Flaky on TSAN v2. http://crbug.com/408006
153#if defined(THREAD_SANITIZER)
154#define MAYBE_CanSetupVideoCallAndDisableLocalVideo \
155  DISABLED_CanSetupVideoCallAndDisableLocalVideo
156#else
157#define MAYBE_CanSetupVideoCallAndDisableLocalVideo \
158  CanSetupVideoCallAndDisableLocalVideo
159#endif
160IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
161                       MAYBE_CanSetupVideoCallAndDisableLocalVideo) {
162  const std::string javascript =
163      "callAndDisableLocalVideo({video: true});";
164  MakeTypicalPeerConnectionCall(javascript);
165}
166
167#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
168// Timing out on ARM linux, see http://crbug.com/240376
169#define MAYBE_CanSetupAudioAndVideoCall DISABLED_CanSetupAudioAndVideoCall
170#else
171#define MAYBE_CanSetupAudioAndVideoCall CanSetupAudioAndVideoCall
172#endif
173
174IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
175                       MAYBE_CanSetupAudioAndVideoCall) {
176  MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
177}
178
179IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
180                       MANUAL_CanSetupCallAndSendDtmf) {
181  MakeTypicalPeerConnectionCall("callAndSendDtmf(\'123,abc\');");
182}
183
184// TODO(phoglund): this test fails because the peer connection state will be
185// stable in the second negotiation round rather than have-local-offer.
186// http://crbug.com/293125.
187IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
188                       DISABLED_CanMakeEmptyCallThenAddStreamsAndRenegotiate) {
189  const char* kJavascript =
190      "callEmptyThenAddOneStreamAndRenegotiate({video: true, audio: true});";
191  MakeTypicalPeerConnectionCall(kJavascript);
192}
193
194// Below 2 test will make a complete PeerConnection-based call between pc1 and
195// pc2, and then use the remote stream to setup a call between pc3 and pc4, and
196// then verify that video is received on pc3 and pc4.
197// The stream sent from pc3 to pc4 is the stream received on pc1.
198// The stream sent from pc4 to pc3 is cloned from stream the stream received
199// on pc2.
200// Flaky on win xp. http://crbug.com/304775
201#if defined(OS_WIN)
202#define MAYBE_CanForwardRemoteStream DISABLED_CanForwardRemoteStream
203#define MAYBE_CanForwardRemoteStream720p DISABLED_CanForwardRemoteStream720p
204#else
205#define MAYBE_CanForwardRemoteStream CanForwardRemoteStream
206// Flaky on TSAN v2. http://crbug.com/373637
207#if defined(THREAD_SANITIZER)
208#define MAYBE_CanForwardRemoteStream720p DISABLED_CanForwardRemoteStream720p
209#else
210#define MAYBE_CanForwardRemoteStream720p CanForwardRemoteStream720p
211#endif
212#endif
213IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MAYBE_CanForwardRemoteStream) {
214#if defined (OS_ANDROID)
215  // This test fails on Nexus 5 devices.
216  // TODO(henrika): see http://crbug.com/362437 and http://crbug.com/359389
217  // for details.
218  base::CommandLine::ForCurrentProcess()->AppendSwitch(
219      switches::kDisableWebRtcHWDecoding);
220#endif
221  MakeTypicalPeerConnectionCall(
222      "callAndForwardRemoteStream({video: true, audio: false});");
223}
224
225IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
226                       MAYBE_CanForwardRemoteStream720p) {
227#if defined (OS_ANDROID)
228  // This test fails on Nexus 5 devices.
229  // TODO(henrika): see http://crbug.com/362437 and http://crbug.com/359389
230  // for details.
231  base::CommandLine::ForCurrentProcess()->AppendSwitch(
232      switches::kDisableWebRtcHWDecoding);
233#endif
234  const std::string javascript = GenerateGetUserMediaCall(
235      "callAndForwardRemoteStream", 1280, 1280, 720, 720, 10, 30);
236  MakeTypicalPeerConnectionCall(javascript);
237}
238
239IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
240                       NoCrashWhenConnectChromiumSinkToRemoteTrack) {
241  MakeTypicalPeerConnectionCall("ConnectChromiumSinkToRemoteAudioTrack();");
242}
243
244// This test will make a complete PeerConnection-based call but remove the
245// MSID and bundle attribute from the initial offer to verify that
246// video is playing for the call even if the initiating client don't support
247// MSID. http://tools.ietf.org/html/draft-alvestrand-rtcweb-msid-02
248#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
249// Timing out on ARM linux, see http://crbug.com/240373
250#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
251        DISABLED_CanSetupAudioAndVideoCallWithoutMsidAndBundle
252#else
253#define MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle\
254        CanSetupAudioAndVideoCallWithoutMsidAndBundle
255#endif
256IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
257                       MAYBE_CanSetupAudioAndVideoCallWithoutMsidAndBundle) {
258  MakeTypicalPeerConnectionCall("callWithoutMsidAndBundle();");
259}
260
261// This test will modify the SDP offer to an unsupported codec, which should
262// cause SetLocalDescription to fail.
263IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
264                       NegotiateUnsupportedVideoCodec) {
265  MakeTypicalPeerConnectionCall("negotiateUnsupportedVideoCodec();");
266}
267
268// This test will modify the SDP offer to use no encryption, which should
269// cause SetLocalDescription to fail.
270IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, NegotiateNonCryptoCall) {
271  MakeTypicalPeerConnectionCall("negotiateNonCryptoCall();");
272}
273
274// This test can negotiate an SDP offer that includes a b=AS:xx to control
275// the bandwidth for audio and video
276IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, NegotiateOfferWithBLine) {
277  MakeTypicalPeerConnectionCall("negotiateOfferWithBLine();");
278}
279
280// This test will make a complete PeerConnection-based call using legacy SDP
281// settings: GIce, external SDES, and no BUNDLE.
282#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
283// Timing out on ARM linux, see http://crbug.com/240373
284#define MAYBE_CanSetupLegacyCall DISABLED_CanSetupLegacyCall
285#else
286#define MAYBE_CanSetupLegacyCall CanSetupLegacyCall
287#endif
288
289IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MAYBE_CanSetupLegacyCall) {
290  MakeTypicalPeerConnectionCall("callWithLegacySdp();");
291}
292
293// This test will make a PeerConnection-based call and test an unreliable text
294// dataChannel.
295// TODO(mallinath) - Remove this test after rtp based data channel is disabled.
296IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CallWithDataOnly) {
297  MakeTypicalPeerConnectionCall("callWithDataOnly();");
298}
299
300#if defined(MEMORY_SANITIZER)
301// Fails under MemorySanitizer: http://crbug.com/405951
302#define MAYBE_CallWithSctpDataOnly DISABLED_CallWithSctpDataOnly
303#else
304#define MAYBE_CallWithSctpDataOnly CallWithSctpDataOnly
305#endif
306IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MAYBE_CallWithSctpDataOnly) {
307  MakeTypicalPeerConnectionCall("callWithSctpDataOnly();");
308}
309
310#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
311// Timing out on ARM linux bot: http://crbug.com/238490
312#define MAYBE_CallWithDataAndMedia DISABLED_CallWithDataAndMedia
313#else
314#define MAYBE_CallWithDataAndMedia CallWithDataAndMedia
315#endif
316
317// This test will make a PeerConnection-based call and test an unreliable text
318// dataChannel and audio and video tracks.
319// TODO(mallinath) - Remove this test after rtp based data channel is disabled.
320IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, DISABLED_CallWithDataAndMedia) {
321  MakeTypicalPeerConnectionCall("callWithDataAndMedia();");
322}
323
324
325#if (defined(OS_LINUX) && !defined(OS_CHROMEOS) && \
326     defined(ARCH_CPU_ARM_FAMILY)) || defined(MEMORY_SANITIZER)
327// Timing out on ARM linux bot: http://crbug.com/238490
328// Fails under MemorySanitizer: http://crbug.com/405951
329#define MAYBE_CallWithSctpDataAndMedia DISABLED_CallWithSctpDataAndMedia
330#else
331#define MAYBE_CallWithSctpDataAndMedia CallWithSctpDataAndMedia
332#endif
333
334IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
335                       MAYBE_CallWithSctpDataAndMedia) {
336  MakeTypicalPeerConnectionCall("callWithSctpDataAndMedia();");
337}
338
339#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
340// Timing out on ARM linux bot: http://crbug.com/238490
341#define MAYBE_CallWithDataAndLaterAddMedia DISABLED_CallWithDataAndLaterAddMedia
342#else
343// Temporarily disable the test on all platforms. http://crbug.com/293252
344#define MAYBE_CallWithDataAndLaterAddMedia DISABLED_CallWithDataAndLaterAddMedia
345#endif
346
347// This test will make a PeerConnection-based call and test an unreliable text
348// dataChannel and later add an audio and video track.
349IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
350                       MAYBE_CallWithDataAndLaterAddMedia) {
351  MakeTypicalPeerConnectionCall("callWithDataAndLaterAddMedia();");
352}
353
354#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
355// Timing out on ARM linux bot: http://crbug.com/238490
356#define MAYBE_CallWithNewVideoMediaStream DISABLED_CallWithNewVideoMediaStream
357#else
358#define MAYBE_CallWithNewVideoMediaStream CallWithNewVideoMediaStream
359#endif
360
361// This test will make a PeerConnection-based call and send a new Video
362// MediaStream that has been created based on a MediaStream created with
363// getUserMedia.
364IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
365                       MAYBE_CallWithNewVideoMediaStream) {
366  MakeTypicalPeerConnectionCall("callWithNewVideoMediaStream();");
367}
368
369// This test will make a PeerConnection-based call and send a new Video
370// MediaStream that has been created based on a MediaStream created with
371// getUserMedia. When video is flowing, the VideoTrack is removed and an
372// AudioTrack is added instead.
373// TODO(phoglund): This test is manual since not all buildbots has an audio
374// input.
375IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MANUAL_CallAndModifyStream) {
376  MakeTypicalPeerConnectionCall(
377      "callWithNewVideoMediaStreamLaterSwitchToAudio();");
378}
379
380IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, AddTwoMediaStreamsToOnePC) {
381  MakeTypicalPeerConnectionCall("addTwoMediaStreamsToOneConnection();");
382}
383
384IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
385                       EstablishAudioVideoCallAndEnsureAudioIsPlaying) {
386  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
387      "callAndEnsureAudioIsPlaying(%s, {audio:true, video:true});",
388      kUseLenientAudioChecking));
389}
390
391IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
392                       EstablishAudioOnlyCallAndEnsureAudioIsPlaying) {
393  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
394      "callAndEnsureAudioIsPlaying(%s, {audio:true});",
395      kUseLenientAudioChecking));
396}
397
398IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
399                       EstablishAudioVideoCallAndVerifyRemoteMutingWorks) {
400  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
401      "callAndEnsureRemoteAudioTrackMutingWorks(%s);",
402      kUseLenientAudioChecking));
403}
404
405IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
406                       EstablishAudioVideoCallAndVerifyLocalMutingWorks) {
407  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
408      "callAndEnsureLocalAudioTrackMutingWorks(%s);",
409      kUseLenientAudioChecking));
410}
411
412IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
413                       EnsureLocalVideoMuteDoesntMuteAudio) {
414  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
415      "callAndEnsureLocalVideoMutingDoesntMuteAudio(%s);",
416      kUseLenientAudioChecking));
417}
418
419IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
420                       EnsureRemoteVideoMuteDoesntMuteAudio) {
421  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
422      "callAndEnsureRemoteVideoMutingDoesntMuteAudio(%s);",
423      kUseLenientAudioChecking));
424}
425
426// Flaky on TSAN v2: http://crbug.com/373637
427#if defined(THREAD_SANITIZER)
428#define MAYBE_EstablishAudioVideoCallAndVerifyUnmutingWorks\
429        DISABLED_EstablishAudioVideoCallAndVerifyUnmutingWorks
430#else
431#define MAYBE_EstablishAudioVideoCallAndVerifyUnmutingWorks\
432        EstablishAudioVideoCallAndVerifyUnmutingWorks
433#endif
434IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
435                       MAYBE_EstablishAudioVideoCallAndVerifyUnmutingWorks) {
436  MakeAudioDetectingPeerConnectionCall(base::StringPrintf(
437      "callAndEnsureAudioTrackUnmutingWorks(%s);", kUseLenientAudioChecking));
438}
439
440IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CallAndVerifyVideoMutingWorks) {
441  MakeTypicalPeerConnectionCall("callAndEnsureVideoTrackMutingWorks();");
442}
443
444IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CreateOfferWithOfferOptions) {
445  MakeTypicalPeerConnectionCall("testCreateOfferOptions();");
446}
447
448}  // namespace content
449