1 // Copyright 2018 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 <string>
6 
7 #include "base/strings/stringprintf.h"
8 #include "build/build_config.h"
9 #include "chrome/browser/media/webrtc/webrtc_browsertest_base.h"
10 #include "chrome/common/chrome_switches.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/content_switches.h"
13 #include "content/public/test/browser_test.h"
14 #include "content/public/test/browser_test_utils.h"
15 #include "media/base/media_switches.h"
16 
17 #if defined(OS_MAC)
18 #include "base/mac/mac_util.h"
19 #endif
20 
21 #if defined(OS_CHROMEOS)
22 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
23 #include "chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set.h"
24 #endif
25 
26 namespace {
27 
28 static const char kMainHtmlPage[] = "/webrtc/webrtc_getdisplaymedia_test.html";
29 
30 struct TestConfig {
31   const char* display_surface;
32   const char* logical_surface;
33   const char* cursor;
34 };
35 
36 }  // namespace
37 
38 // Base class for top level tests for getDisplayMedia().
39 class WebRtcGetDisplayMediaBrowserTest : public WebRtcTestBase {
40  public:
SetUpInProcessBrowserTestFixture()41   void SetUpInProcessBrowserTestFixture() override {
42     DetectErrorsInJavaScript();
43   }
44 
RunGetDisplayMedia(content::WebContents * tab,const std::string & constraints,bool is_fake_ui=false)45   void RunGetDisplayMedia(content::WebContents* tab,
46                           const std::string& constraints,
47                           bool is_fake_ui = false) {
48     std::string result;
49     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
50         tab->GetMainFrame(),
51         base::StringPrintf("runGetDisplayMedia(%s);", constraints.c_str()),
52         &result));
53 #if defined(OS_MAC)
54     // Starting from macOS 10.15, screen capture requires system permissions
55     // that are disabled by default. The permission is reported as granted
56     // if the fake UI is used.
57     EXPECT_EQ(result, base::mac::IsAtMostOS10_14() || is_fake_ui
58                           ? "getdisplaymedia-success"
59                           : "getdisplaymedia-failure");
60 #else
61     EXPECT_EQ(result, "getdisplaymedia-success");
62 #endif
63   }
64 };
65 
66 // Top level test for getDisplayMedia(). Pops picker Ui and selects desktop
67 // capture by default.
68 class WebRtcGetDisplayMediaBrowserTestWithPicker
69     : public WebRtcGetDisplayMediaBrowserTest {
70  public:
SetUpCommandLine(base::CommandLine * command_line)71   void SetUpCommandLine(base::CommandLine* command_line) override {
72     command_line->AppendSwitch(
73         switches::kEnableExperimentalWebPlatformFeatures);
74 #if defined(OS_CHROMEOS)
75     command_line->AppendSwitchASCII(switches::kAutoSelectDesktopCaptureSource,
76                                     "Display");
77 #else
78     command_line->AppendSwitchASCII(switches::kAutoSelectDesktopCaptureSource,
79                                     "Entire screen");
80 #endif  // defined(OS_CHROMEOS)
81   }
82 };
83 
84 // Real desktop capture is flaky on below platforms.
85 #if defined(OS_WIN)
86 #define MAYBE_GetDisplayMediaVideo DISABLED_GetDisplayMediaVideo
87 #else
88 #define MAYBE_GetDisplayMediaVideo GetDisplayMediaVideo
89 #endif  // defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,MAYBE_GetDisplayMediaVideo)90 IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,
91                        MAYBE_GetDisplayMediaVideo) {
92   ASSERT_TRUE(embedded_test_server()->Start());
93 
94   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
95   std::string constraints("{video:true}");
96   RunGetDisplayMedia(tab, constraints);
97 }
98 
99 #if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,GetDisplayMediaVideoWithDlp)100 IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,
101                        GetDisplayMediaVideoWithDlp) {
102   ASSERT_TRUE(embedded_test_server()->Start());
103 
104   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
105   std::string constraints("{video:true}");
106   RunGetDisplayMedia(tab, constraints);
107 
108   std::string result;
109   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
110       tab->GetMainFrame(), "waitVideoUnmuted();", &result));
111   EXPECT_EQ(result, "unmuted");
112 
113   const policy::DlpContentRestrictionSet kScreenShareRestricted(
114       policy::DlpContentRestriction::kScreenShare);
115   const policy::DlpContentRestrictionSet kEmptyRestrictionSet;
116 
117   policy::DlpContentManager* dlp_content_manager =
118       policy::DlpContentManager::Get();
119   dlp_content_manager->OnConfidentialityChanged(tab, kScreenShareRestricted);
120   content::WaitForLoadStop(tab);
121 
122   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
123       tab->GetMainFrame(), "waitVideoMuted();", &result));
124   EXPECT_EQ(result, "muted");
125 
126   dlp_content_manager->OnConfidentialityChanged(tab, kEmptyRestrictionSet);
127 
128   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
129       tab->GetMainFrame(), "waitVideoUnmuted();", &result));
130   EXPECT_EQ(result, "unmuted");
131 }
132 #endif  // defined(OS_CHROMEOS)
133 
134 // Real desktop capture is flaky on below platforms.
135 #if defined(OS_WIN)
136 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
137 // On linux debug bots, it's flaky as well.
138 #elif (defined(OS_LINUX) && !defined(NDEBUG))
139 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
140 // On linux asan bots, it's flaky as well - msan and other rel bot are fine.
141 #elif (defined(OS_LINUX) && defined(ADDRESS_SANITIZER))
142 #define MAYBE_GetDisplayMediaVideoAndAudio DISABLED_GetDisplayMediaVideoAndAudio
143 #else
144 #define MAYBE_GetDisplayMediaVideoAndAudio GetDisplayMediaVideoAndAudio
145 #endif  // defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,MAYBE_GetDisplayMediaVideoAndAudio)146 IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker,
147                        MAYBE_GetDisplayMediaVideoAndAudio) {
148   ASSERT_TRUE(embedded_test_server()->Start());
149 
150   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
151   std::string constraints("{video:true, audio:true}");
152   RunGetDisplayMedia(tab, constraints);
153 }
154 
155 // Top level test for getDisplayMedia(). Skips picker UI and uses fake device
156 // with specified type.
157 class WebRtcGetDisplayMediaBrowserTestWithFakeUI
158     : public WebRtcGetDisplayMediaBrowserTest,
159       public testing::WithParamInterface<TestConfig> {
160  public:
WebRtcGetDisplayMediaBrowserTestWithFakeUI()161   WebRtcGetDisplayMediaBrowserTestWithFakeUI() {
162     test_config_ = GetParam();
163   }
164 
SetUpCommandLine(base::CommandLine * command_line)165   void SetUpCommandLine(base::CommandLine* command_line) override {
166     command_line->AppendSwitch(
167         switches::kEnableExperimentalWebPlatformFeatures);
168     command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
169     command_line->RemoveSwitch(switches::kUseFakeDeviceForMediaStream);
170     command_line->AppendSwitchASCII(
171         switches::kUseFakeDeviceForMediaStream,
172         base::StringPrintf("display-media-type=%s",
173                            test_config_.display_surface));
174   }
175 
176  protected:
177   TestConfig test_config_;
178 };
179 
IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,GetDisplayMediaVideo)180 IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,
181                        GetDisplayMediaVideo) {
182   ASSERT_TRUE(embedded_test_server()->Start());
183 
184   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
185   std::string constraints("{video:true}");
186   RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true);
187 
188   std::string result;
189   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
190       tab->GetMainFrame(), "getDisplaySurfaceSetting();", &result));
191   EXPECT_EQ(result, test_config_.display_surface);
192 
193   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
194       tab->GetMainFrame(), "getLogicalSurfaceSetting();", &result));
195   EXPECT_EQ(result, test_config_.logical_surface);
196 
197   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
198       tab->GetMainFrame(), "getCursorSetting();", &result));
199   EXPECT_EQ(result, test_config_.cursor);
200 }
201 
IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,GetDisplayMediaVideoAndAudio)202 IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,
203                        GetDisplayMediaVideoAndAudio) {
204   ASSERT_TRUE(embedded_test_server()->Start());
205 
206   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
207   std::string constraints("{video:true, audio:true}");
208   RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true);
209 
210   std::string result;
211   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
212       tab->GetMainFrame(), "hasAudioTrack();", &result));
213   EXPECT_EQ(result, "true");
214 }
215 
IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,GetDisplayMediaWithConstraints)216 IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI,
217                        GetDisplayMediaWithConstraints) {
218   ASSERT_TRUE(embedded_test_server()->Start());
219 
220   content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage);
221   const int kMaxWidth = 200;
222   const int kMaxFrameRate = 6;
223   const std::string& constraints =
224       base::StringPrintf("{video: {width: {max: %d}, frameRate: {max: %d}}}",
225                          kMaxWidth, kMaxFrameRate);
226   RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true);
227 
228   std::string result;
229   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
230       tab->GetMainFrame(), "getWidthSetting();", &result));
231   EXPECT_EQ(result, base::StringPrintf("%d", kMaxWidth));
232 
233   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
234       tab->GetMainFrame(), "getFrameRateSetting();", &result));
235   EXPECT_EQ(result, base::StringPrintf("%d", kMaxFrameRate));
236 }
237 
238 INSTANTIATE_TEST_SUITE_P(All,
239                          WebRtcGetDisplayMediaBrowserTestWithFakeUI,
240                          testing::Values(TestConfig{"monitor", "true", "never"},
241                                          TestConfig{"window", "true", "never"},
242                                          TestConfig{"browser", "true",
243                                                     "never"}));
244