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/strings/string_number_conversions.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/media/fake_desktop_media_list.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/test/browser_test_utils.h"
19 #include "net/dns/mock_host_resolver.h"
20 #include "net/test/embedded_test_server/embedded_test_server.h"
21 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
23 namespace extensions
{
30 content::DesktopMediaID selected_source
;
33 // Following flags are set by FakeDesktopMediaPicker when it's created and
39 class FakeDesktopMediaPicker
: public DesktopMediaPicker
{
41 explicit FakeDesktopMediaPicker(TestFlags
* expectation
)
42 : expectation_(expectation
),
44 expectation_
->picker_created
= true;
46 ~FakeDesktopMediaPicker() override
{ expectation_
->picker_deleted
= true; }
48 // DesktopMediaPicker interface.
49 void Show(content::WebContents
* web_contents
,
50 gfx::NativeWindow context
,
51 gfx::NativeWindow parent
,
52 const base::string16
& app_name
,
53 const base::string16
& target_name
,
54 scoped_ptr
<DesktopMediaList
> model
,
55 const DoneCallback
& done_callback
) override
{
56 if (!expectation_
->cancelled
) {
57 // Post a task to call the callback asynchronously.
58 base::ThreadTaskRunnerHandle::Get()->PostTask(
60 base::Bind(&FakeDesktopMediaPicker::CallCallback
,
61 weak_factory_
.GetWeakPtr(), done_callback
));
63 // If we expect the dialog to be cancelled then store the callback to
64 // retain reference to the callback handler.
65 done_callback_
= done_callback
;
70 void CallCallback(DoneCallback done_callback
) {
71 done_callback
.Run(expectation_
->selected_source
);
74 TestFlags
* expectation_
;
75 DoneCallback done_callback_
;
77 base::WeakPtrFactory
<FakeDesktopMediaPicker
> weak_factory_
;
79 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPicker
);
82 class FakeDesktopMediaPickerFactory
:
83 public DesktopCaptureChooseDesktopMediaFunction::PickerFactory
{
85 FakeDesktopMediaPickerFactory() {}
86 ~FakeDesktopMediaPickerFactory() override
{}
88 void SetTestFlags(TestFlags
* test_flags
, int tests_count
) {
89 test_flags_
= test_flags
;
90 tests_count_
= tests_count
;
94 // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface.
95 scoped_ptr
<DesktopMediaList
> CreateModel(bool show_screens
,
96 bool show_windows
) override
{
97 EXPECT_LE(current_test_
, tests_count_
);
98 if (current_test_
>= tests_count_
)
99 return scoped_ptr
<DesktopMediaList
>();
100 EXPECT_EQ(test_flags_
[current_test_
].expect_screens
, show_screens
);
101 EXPECT_EQ(test_flags_
[current_test_
].expect_windows
, show_windows
);
102 return scoped_ptr
<DesktopMediaList
>(new FakeDesktopMediaList());
105 scoped_ptr
<DesktopMediaPicker
> CreatePicker() override
{
106 EXPECT_LE(current_test_
, tests_count_
);
107 if (current_test_
>= tests_count_
)
108 return scoped_ptr
<DesktopMediaPicker
>();
110 return scoped_ptr
<DesktopMediaPicker
>(
111 new FakeDesktopMediaPicker(test_flags_
+ current_test_
- 1));
115 TestFlags
* test_flags_
;
119 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPickerFactory
);
122 class DesktopCaptureApiTest
: public ExtensionApiTest
{
124 DesktopCaptureApiTest() {
125 DesktopCaptureChooseDesktopMediaFunction::
126 SetPickerFactoryForTests(&picker_factory_
);
128 ~DesktopCaptureApiTest() override
{
129 DesktopCaptureChooseDesktopMediaFunction::
130 SetPickerFactoryForTests(NULL
);
134 GURL
GetURLForPath(const std::string
& host
, const std::string
& path
) {
135 std::string port
= base::UintToString(embedded_test_server()->port());
136 GURL::Replacements replacements
;
137 replacements
.SetHostStr(host
);
138 replacements
.SetPortStr(port
);
139 return embedded_test_server()->GetURL(path
).ReplaceComponents(replacements
);
142 FakeDesktopMediaPickerFactory picker_factory_
;
147 // Flaky on Windows: http://crbug.com/301887
149 #define MAYBE_ChooseDesktopMedia DISABLED_ChooseDesktopMedia
151 #define MAYBE_ChooseDesktopMedia ChooseDesktopMedia
153 IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest
, MAYBE_ChooseDesktopMedia
) {
154 // Each element in the following array corresponds to one test in
155 // chrome/test/data/extensions/api_test/desktop_capture/test.js .
156 TestFlags test_flags
[] = {
157 // pickerUiCanceled()
159 content::DesktopMediaID() },
162 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
163 content::DesktopMediaID::kNullId
) },
166 content::DesktopMediaID() },
169 content::DesktopMediaID() },
170 // chooseMediaAndGetStream()
172 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
173 webrtc::kFullDesktopScreenId
) },
174 // chooseMediaAndTryGetStreamWithInvalidId()
176 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
177 webrtc::kFullDesktopScreenId
) },
180 content::DesktopMediaID(), true },
182 picker_factory_
.SetTestFlags(test_flags
, arraysize(test_flags
));
183 ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_
;
186 // Test is flaky http://crbug.com/301887.
187 IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest
, DISABLED_Delegation
) {
188 // Initialize test server.
189 base::FilePath test_data
;
190 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_data
));
191 embedded_test_server()->ServeFilesFromDirectory(test_data
.AppendASCII(
192 "extensions/api_test/desktop_capture_delegate"));
193 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
194 host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
197 base::FilePath extension_path
=
198 test_data_dir_
.AppendASCII("desktop_capture_delegate");
199 const Extension
* extension
= LoadExtensionWithFlags(
200 extension_path
, ExtensionBrowserTest::kFlagNone
);
201 ASSERT_TRUE(extension
);
203 ui_test_utils::NavigateToURL(
204 browser(), GetURLForPath("example.com", "/example.com.html"));
206 TestFlags test_flags
[] = {
208 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
209 content::DesktopMediaID::kNullId
) },
211 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
212 content::DesktopMediaID::kNullId
) },
214 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN
,
215 content::DesktopMediaID::kNullId
), true },
217 picker_factory_
.SetTestFlags(test_flags
, arraysize(test_flags
));
221 content::WebContents
* web_contents
=
222 browser()->tab_strip_model()->GetActiveWebContents();
224 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
225 web_contents
, "getStream()", &result
));
228 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
229 web_contents
, "getStreamWithInvalidId()", &result
));
232 // Verify that the picker is closed once the tab is closed.
233 content::WebContentsDestroyedWatcher
destroyed_watcher(web_contents
);
234 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
235 web_contents
, "openPickerDialogAndReturn()", &result
));
237 EXPECT_TRUE(test_flags
[2].picker_created
);
238 EXPECT_FALSE(test_flags
[2].picker_deleted
);
240 web_contents
->Close();
241 destroyed_watcher
.Wait();
242 EXPECT_TRUE(test_flags
[2].picker_deleted
);
245 } // namespace extensions