1 // Copyright 2013 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.
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/media/fake_desktop_media_list.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/test/browser_test_utils.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/test/embedded_test_server/embedded_test_server.h"
20 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
22 namespace extensions {
29 content::DesktopMediaID selected_source;
32 // Following flags are set by FakeDesktopMediaPicker when it's created and
38 class FakeDesktopMediaPicker : public DesktopMediaPicker {
40 explicit FakeDesktopMediaPicker(TestFlags* expectation)
41 : expectation_(expectation),
43 expectation_->picker_created = true;
45 ~FakeDesktopMediaPicker() override { expectation_->picker_deleted = true; }
47 // DesktopMediaPicker interface.
48 void Show(content::WebContents* web_contents,
49 gfx::NativeWindow context,
50 gfx::NativeWindow parent,
51 const base::string16& app_name,
52 const base::string16& target_name,
53 scoped_ptr<DesktopMediaList> model,
54 const DoneCallback& done_callback) override {
55 if (!expectation_->cancelled) {
56 // Post a task to call the callback asynchronously.
57 base::ThreadTaskRunnerHandle::Get()->PostTask(
59 base::Bind(&FakeDesktopMediaPicker::CallCallback,
60 weak_factory_.GetWeakPtr(), done_callback));
62 // If we expect the dialog to be cancelled then store the callback to
63 // retain reference to the callback handler.
64 done_callback_ = done_callback;
69 void CallCallback(DoneCallback done_callback) {
70 done_callback.Run(expectation_->selected_source);
73 TestFlags* expectation_;
74 DoneCallback done_callback_;
76 base::WeakPtrFactory<FakeDesktopMediaPicker> weak_factory_;
78 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPicker);
81 class FakeDesktopMediaPickerFactory :
82 public DesktopCaptureChooseDesktopMediaFunction::PickerFactory {
84 FakeDesktopMediaPickerFactory() {}
85 ~FakeDesktopMediaPickerFactory() override {}
87 void SetTestFlags(TestFlags* test_flags, int tests_count) {
88 test_flags_ = test_flags;
89 tests_count_ = tests_count;
93 // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface.
94 scoped_ptr<DesktopMediaList> CreateModel(bool show_screens,
95 bool show_windows) override {
96 EXPECT_LE(current_test_, tests_count_);
97 if (current_test_ >= tests_count_)
98 return scoped_ptr<DesktopMediaList>();
99 EXPECT_EQ(test_flags_[current_test_].expect_screens, show_screens);
100 EXPECT_EQ(test_flags_[current_test_].expect_windows, show_windows);
101 return scoped_ptr<DesktopMediaList>(new FakeDesktopMediaList());
104 scoped_ptr<DesktopMediaPicker> CreatePicker() override {
105 EXPECT_LE(current_test_, tests_count_);
106 if (current_test_ >= tests_count_)
107 return scoped_ptr<DesktopMediaPicker>();
109 return scoped_ptr<DesktopMediaPicker>(
110 new FakeDesktopMediaPicker(test_flags_ + current_test_ - 1));
114 TestFlags* test_flags_;
118 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPickerFactory);
121 class DesktopCaptureApiTest : public ExtensionApiTest {
123 DesktopCaptureApiTest() {
124 DesktopCaptureChooseDesktopMediaFunction::
125 SetPickerFactoryForTests(&picker_factory_);
127 ~DesktopCaptureApiTest() override {
128 DesktopCaptureChooseDesktopMediaFunction::
129 SetPickerFactoryForTests(NULL);
133 GURL GetURLForPath(const std::string& host, const std::string& path) {
134 std::string port = base::IntToString(embedded_test_server()->port());
135 GURL::Replacements replacements;
136 replacements.SetHostStr(host);
137 replacements.SetPortStr(port);
138 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements);
141 FakeDesktopMediaPickerFactory picker_factory_;
146 // Flaky on Windows: http://crbug.com/301887
148 #define MAYBE_ChooseDesktopMedia DISABLED_ChooseDesktopMedia
150 #define MAYBE_ChooseDesktopMedia ChooseDesktopMedia
152 IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, MAYBE_ChooseDesktopMedia) {
153 // Each element in the following array corresponds to one test in
154 // chrome/test/data/extensions/api_test/desktop_capture/test.js .
155 TestFlags test_flags[] = {
156 // pickerUiCanceled()
158 content::DesktopMediaID() },
161 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) },
164 content::DesktopMediaID() },
167 content::DesktopMediaID() },
168 // chooseMediaAndGetStream()
170 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
171 webrtc::kFullDesktopScreenId) },
172 // chooseMediaAndTryGetStreamWithInvalidId()
174 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
175 webrtc::kFullDesktopScreenId) },
178 content::DesktopMediaID(), true },
180 picker_factory_.SetTestFlags(test_flags, arraysize(test_flags));
181 ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_;
184 // Test is flaky http://crbug.com/301887.
185 IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, DISABLED_Delegation) {
186 // Initialize test server.
187 base::FilePath test_data;
188 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
189 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII(
190 "extensions/api_test/desktop_capture_delegate"));
191 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
192 host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
195 base::FilePath extension_path =
196 test_data_dir_.AppendASCII("desktop_capture_delegate");
197 const Extension* extension = LoadExtensionWithFlags(
198 extension_path, ExtensionBrowserTest::kFlagNone);
199 ASSERT_TRUE(extension);
201 ui_test_utils::NavigateToURL(
202 browser(), GetURLForPath("example.com", "/example.com.html"));
204 TestFlags test_flags[] = {
206 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) },
208 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) },
210 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0), true },
212 picker_factory_.SetTestFlags(test_flags, arraysize(test_flags));
216 content::WebContents* web_contents =
217 browser()->tab_strip_model()->GetActiveWebContents();
219 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
220 web_contents, "getStream()", &result));
223 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
224 web_contents, "getStreamWithInvalidId()", &result));
227 // Verify that the picker is closed once the tab is closed.
228 content::WebContentsDestroyedWatcher destroyed_watcher(web_contents);
229 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
230 web_contents, "openPickerDialogAndReturn()", &result));
232 EXPECT_TRUE(test_flags[2].picker_created);
233 EXPECT_FALSE(test_flags[2].picker_deleted);
235 web_contents->Close();
236 destroyed_watcher.Wait();
237 EXPECT_TRUE(test_flags[2].picker_deleted);
240 } // namespace extensions