Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / tab_capture / tab_capture_apitest.cc
blob790832930078058f794a192e3b226967043dc93f
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.
5 #include "base/basictypes.h"
6 #include "base/command_line.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/time/time.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/tab_helper.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
15 #include "chrome/browser/ui/tabs/tab_utils.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/chrome_version_info.h"
18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/test/browser_test_utils.h"
21 #include "content/public/test/test_utils.h"
22 #include "extensions/browser/extension_registry.h"
23 #include "extensions/common/switches.h"
24 #include "extensions/test/extension_test_message_listener.h"
25 #include "extensions/test/result_catcher.h"
27 #if defined(OS_WIN)
28 #include "base/win/windows_version.h"
29 #endif
31 namespace extensions {
33 namespace {
35 const char kExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
37 class TabCaptureApiTest : public ExtensionApiTest {
38 public:
39 void SetUpCommandLine(base::CommandLine* command_line) override {
40 ExtensionApiTest::SetUpCommandLine(command_line);
41 // Specify smallish window size to make testing of tab capture less CPU
42 // intensive.
43 command_line->AppendSwitchASCII(::switches::kWindowSize, "300,300");
46 void AddExtensionToCommandLineWhitelist() {
47 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
48 switches::kWhitelistedExtensionID, kExtensionId);
51 protected:
52 void SimulateMouseClickInCurrentTab() {
53 content::SimulateMouseClick(
54 browser()->tab_strip_model()->GetActiveWebContents(),
56 blink::WebMouseEvent::ButtonLeft);
60 class TabCaptureApiPixelTest : public TabCaptureApiTest {
61 public:
62 void SetUp() override {
63 if (!IsTooIntensiveForThisPlatform())
64 EnablePixelOutput();
65 TabCaptureApiTest::SetUp();
68 protected:
69 bool IsTooIntensiveForThisPlatform() const {
70 #if defined(OS_WIN)
71 if (base::win::GetVersion() < base::win::VERSION_VISTA)
72 return true;
73 #endif
75 // The tests are too slow to succeed with OSMesa on the bots.
76 if (UsingOSMesa())
77 return true;
79 #if defined(NDEBUG)
80 return false;
81 #else
82 // TODO(miu): Look into enabling these tests for the Debug build bots once
83 // they prove to be stable again on the Release bots.
84 // http://crbug.com/396413
85 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
86 "run-tab-capture-api-pixel-tests");
87 #endif
91 // Tests API behaviors, including info queries, and constraints violations.
92 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, ApiTests) {
93 AddExtensionToCommandLineWhitelist();
94 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "api_tests.html")) << message_;
97 // Tests that tab capture video frames can be received in a VIDEO element.
98 IN_PROC_BROWSER_TEST_F(TabCaptureApiPixelTest, EndToEndWithoutRemoting) {
99 if (IsTooIntensiveForThisPlatform()) {
100 LOG(WARNING) << "Skipping this CPU-intensive test on this platform/build.";
101 return;
103 AddExtensionToCommandLineWhitelist();
104 ASSERT_TRUE(RunExtensionSubtest(
105 "tab_capture", "end_to_end.html?method=local&colorDeviation=10"))
106 << message_;
109 // Tests that video frames are captured, transported via WebRTC, and finally
110 // received in a VIDEO element. More allowance is provided for color deviation
111 // because of the additional layers of video processing performed within
112 // WebRTC.
113 IN_PROC_BROWSER_TEST_F(TabCaptureApiPixelTest, EndToEndThroughWebRTC) {
114 if (IsTooIntensiveForThisPlatform()) {
115 LOG(WARNING) << "Skipping this CPU-intensive test on this platform/build.";
116 return;
118 AddExtensionToCommandLineWhitelist();
119 ASSERT_TRUE(RunExtensionSubtest(
120 "tab_capture", "end_to_end.html?method=webrtc&colorDeviation=50"))
121 << message_;
124 // http://crbug.com/177163
125 #if defined(OS_WIN) && !defined(NDEBUG)
126 #define MAYBE_GetUserMediaTest DISABLED_GetUserMediaTest
127 #else
128 #define MAYBE_GetUserMediaTest GetUserMediaTest
129 #endif
130 // Tests that getUserMedia() is NOT a way to start tab capture.
131 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_GetUserMediaTest) {
132 ExtensionTestMessageListener listener("ready", true);
134 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "get_user_media_test.html"))
135 << message_;
137 EXPECT_TRUE(listener.WaitUntilSatisfied());
139 content::OpenURLParams params(GURL("about:blank"), content::Referrer(),
140 NEW_FOREGROUND_TAB,
141 ui::PAGE_TRANSITION_LINK, false);
142 content::WebContents* web_contents = browser()->OpenURL(params);
144 content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
145 ASSERT_TRUE(main_frame);
146 listener.Reply(base::StringPrintf("web-contents-media-stream://%i:%i",
147 main_frame->GetProcess()->GetID(),
148 main_frame->GetRoutingID()));
150 ResultCatcher catcher;
151 catcher.RestrictToBrowserContext(browser()->profile());
152 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
155 // http://crbug.com/177163
156 #if defined(OS_WIN) && !defined(NDEBUG)
157 #define MAYBE_ActiveTabPermission DISABLED_ActiveTabPermission
158 #else
159 #define MAYBE_ActiveTabPermission ActiveTabPermission
160 #endif
161 // Make sure tabCapture.capture only works if the tab has been granted
162 // permission via an extension icon click or the extension is whitelisted.
163 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_ActiveTabPermission) {
164 ExtensionTestMessageListener before_open_tab("ready1", true);
165 ExtensionTestMessageListener before_grant_permission("ready2", true);
166 ExtensionTestMessageListener before_open_new_tab("ready3", true);
167 ExtensionTestMessageListener before_whitelist_extension("ready4", true);
169 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
170 "active_tab_permission_test.html"))
171 << message_;
173 // Open a new tab and make sure capture is denied.
174 EXPECT_TRUE(before_open_tab.WaitUntilSatisfied());
175 content::OpenURLParams params(GURL("http://google.com"), content::Referrer(),
176 NEW_FOREGROUND_TAB,
177 ui::PAGE_TRANSITION_LINK, false);
178 content::WebContents* web_contents = browser()->OpenURL(params);
179 before_open_tab.Reply("");
181 // Grant permission and make sure capture succeeds.
182 EXPECT_TRUE(before_grant_permission.WaitUntilSatisfied());
183 const Extension* extension = ExtensionRegistry::Get(
184 web_contents->GetBrowserContext())->enabled_extensions().GetByID(
185 kExtensionId);
186 TabHelper::FromWebContents(web_contents)
187 ->active_tab_permission_granter()->GrantIfRequested(extension);
188 before_grant_permission.Reply("");
190 // Open a new tab and make sure capture is denied.
191 EXPECT_TRUE(before_open_new_tab.WaitUntilSatisfied());
192 browser()->OpenURL(params);
193 before_open_new_tab.Reply("");
195 // Add extension to whitelist and make sure capture succeeds.
196 EXPECT_TRUE(before_whitelist_extension.WaitUntilSatisfied());
197 AddExtensionToCommandLineWhitelist();
198 before_whitelist_extension.Reply("");
200 ResultCatcher catcher;
201 catcher.RestrictToBrowserContext(browser()->profile());
202 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
205 // http://crbug.com/177163
206 #if defined(OS_WIN) && !defined(NDEBUG)
207 #define MAYBE_FullscreenEvents DISABLED_FullscreenEvents
208 #else
209 #define MAYBE_FullscreenEvents FullscreenEvents
210 #endif
211 // Tests that fullscreen transitions during a tab capture session dispatch
212 // events to the onStatusChange listener. The test loads a page that toggles
213 // fullscreen mode, using the Fullscreen Javascript API, in response to mouse
214 // clicks.
215 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_FullscreenEvents) {
216 AddExtensionToCommandLineWhitelist();
218 ExtensionTestMessageListener capture_started("tab_capture_started", false);
219 ExtensionTestMessageListener entered_fullscreen("entered_fullscreen", false);
221 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "fullscreen_test.html"))
222 << message_;
223 EXPECT_TRUE(capture_started.WaitUntilSatisfied());
225 // Click on the page to trigger the Javascript that will toggle the tab into
226 // fullscreen mode.
227 SimulateMouseClickInCurrentTab();
228 EXPECT_TRUE(entered_fullscreen.WaitUntilSatisfied());
230 // Click again to exit fullscreen mode.
231 SimulateMouseClickInCurrentTab();
233 // Wait until the page examines its results and calls chrome.test.succeed().
234 ResultCatcher catcher;
235 catcher.RestrictToBrowserContext(browser()->profile());
236 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
239 // Times out on Win dbg bots: http://crbug.com/177163
240 // Flaky on MSan bots: http://crbug.com/294431
241 #if (defined(OS_WIN) && !defined(NDEBUG)) || defined(MEMORY_SANITIZER)
242 #define MAYBE_GrantForChromePages DISABLED_GrantForChromePages
243 #else
244 #define MAYBE_GrantForChromePages GrantForChromePages
245 #endif
246 // Make sure tabCapture API can be granted for Chrome:// pages.
247 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_GrantForChromePages) {
248 ExtensionTestMessageListener before_open_tab("ready1", true);
249 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
250 "active_tab_chrome_pages.html"))
251 << message_;
252 EXPECT_TRUE(before_open_tab.WaitUntilSatisfied());
254 // Open a tab on a chrome:// page and make sure we can capture.
255 content::OpenURLParams params(GURL("chrome://version"), content::Referrer(),
256 NEW_FOREGROUND_TAB,
257 ui::PAGE_TRANSITION_LINK, false);
258 content::WebContents* web_contents = browser()->OpenURL(params);
259 const Extension* extension = ExtensionRegistry::Get(
260 web_contents->GetBrowserContext())->enabled_extensions().GetByID(
261 kExtensionId);
262 TabHelper::FromWebContents(web_contents)
263 ->active_tab_permission_granter()->GrantIfRequested(extension);
264 before_open_tab.Reply("");
266 ResultCatcher catcher;
267 catcher.RestrictToBrowserContext(browser()->profile());
268 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
271 // http://crbug.com/177163
272 #if defined(OS_WIN) && !defined(NDEBUG)
273 #define MAYBE_CaptureInSplitIncognitoMode DISABLED_CaptureInSplitIncognitoMode
274 #else
275 #define MAYBE_CaptureInSplitIncognitoMode CaptureInSplitIncognitoMode
276 #endif
277 // Tests that a tab in incognito mode can be captured.
278 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_CaptureInSplitIncognitoMode) {
279 AddExtensionToCommandLineWhitelist();
280 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
281 "start_tab_capture.html",
282 kFlagEnableIncognito | kFlagUseIncognito))
283 << message_;
286 // http://crbug.com/177163
287 #if defined(OS_WIN) && !defined(NDEBUG)
288 #define MAYBE_Constraints DISABLED_Constraints
289 #else
290 #define MAYBE_Constraints Constraints
291 #endif
292 // Tests that valid constraints allow tab capture to start, while invalid ones
293 // do not.
294 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_Constraints) {
295 AddExtensionToCommandLineWhitelist();
296 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "constraints.html"))
297 << message_;
300 // http://crbug.com/177163
301 #if defined(OS_WIN) && !defined(NDEBUG)
302 #define MAYBE_TabIndicator DISABLED_TabIndicator
303 #else
304 #define MAYBE_TabIndicator TabIndicator
305 #endif
306 // Tests that the tab indicator (in the tab strip) is shown during tab capture.
307 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_TabIndicator) {
308 ASSERT_EQ(TAB_MEDIA_STATE_NONE,
309 chrome::GetTabMediaStateForContents(
310 browser()->tab_strip_model()->GetActiveWebContents()));
312 // Run an extension test that just turns on tab capture, which should cause
313 // the indicator to turn on.
314 AddExtensionToCommandLineWhitelist();
315 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "start_tab_capture.html"))
316 << message_;
318 // A TabStripModelObserver that quits the MessageLoop whenever the UI's model
319 // is sent an event that changes the indicator status.
320 class IndicatorChangeObserver : public TabStripModelObserver {
321 public:
322 explicit IndicatorChangeObserver(Browser* browser)
323 : last_media_state_(chrome::GetTabMediaStateForContents(
324 browser->tab_strip_model()->GetActiveWebContents())) {}
326 TabMediaState last_media_state() const { return last_media_state_; }
328 void TabChangedAt(content::WebContents* contents,
329 int index,
330 TabChangeType change_type) override {
331 const TabMediaState media_state =
332 chrome::GetTabMediaStateForContents(contents);
333 const bool has_changed = media_state != last_media_state_;
334 last_media_state_ = media_state;
335 if (has_changed) {
336 base::MessageLoop::current()->PostTask(
337 FROM_HERE, base::MessageLoop::QuitClosure());
341 private:
342 TabMediaState last_media_state_;
345 // Run the browser until the indicator turns on.
346 IndicatorChangeObserver observer(browser());
347 browser()->tab_strip_model()->AddObserver(&observer);
348 const base::TimeTicks start_time = base::TimeTicks::Now();
349 while (observer.last_media_state() != TAB_MEDIA_STATE_CAPTURING) {
350 if (base::TimeTicks::Now() - start_time >
351 base::TimeDelta::FromSeconds(10)) {
352 EXPECT_EQ(TAB_MEDIA_STATE_CAPTURING, observer.last_media_state());
353 browser()->tab_strip_model()->RemoveObserver(&observer);
354 return;
356 content::RunMessageLoop();
358 browser()->tab_strip_model()->RemoveObserver(&observer);
361 } // namespace
363 } // namespace extensions