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. 4 5#include <queue> 6 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" 21 22namespace extensions { 23 24namespace { 25 26struct TestFlags { 27 bool expect_screens; 28 bool expect_windows; 29 content::DesktopMediaID selected_source; 30 bool cancelled; 31 32 // Following flags are set by FakeDesktopMediaPicker when it's created and 33 // deleted. 34 bool picker_created; 35 bool picker_deleted; 36}; 37 38class FakeDesktopMediaPicker : public DesktopMediaPicker { 39 public: 40 explicit FakeDesktopMediaPicker(TestFlags* expectation) 41 : expectation_(expectation), 42 weak_factory_(this) { 43 expectation_->picker_created = true; 44 } 45 virtual ~FakeDesktopMediaPicker() { 46 expectation_->picker_deleted = true; 47 } 48 49 // DesktopMediaPicker interface. 50 virtual void Show(content::WebContents* web_contents, 51 gfx::NativeWindow context, 52 gfx::NativeWindow parent, 53 const base::string16& app_name, 54 const base::string16& target_name, 55 scoped_ptr<DesktopMediaList> model, 56 const DoneCallback& done_callback) OVERRIDE { 57 if (!expectation_->cancelled) { 58 // Post a task to call the callback asynchronously. 59 base::ThreadTaskRunnerHandle::Get()->PostTask( 60 FROM_HERE, 61 base::Bind(&FakeDesktopMediaPicker::CallCallback, 62 weak_factory_.GetWeakPtr(), done_callback)); 63 } else { 64 // If we expect the dialog to be cancelled then store the callback to 65 // retain reference to the callback handler. 66 done_callback_ = done_callback; 67 } 68 } 69 70 private: 71 void CallCallback(DoneCallback done_callback) { 72 done_callback.Run(expectation_->selected_source); 73 } 74 75 TestFlags* expectation_; 76 DoneCallback done_callback_; 77 78 base::WeakPtrFactory<FakeDesktopMediaPicker> weak_factory_; 79 80 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPicker); 81}; 82 83class FakeDesktopMediaPickerFactory : 84 public DesktopCaptureChooseDesktopMediaFunction::PickerFactory { 85 public: 86 FakeDesktopMediaPickerFactory() {} 87 virtual ~FakeDesktopMediaPickerFactory() {} 88 89 void SetTestFlags(TestFlags* test_flags, int tests_count) { 90 test_flags_ = test_flags; 91 tests_count_ = tests_count; 92 current_test_ = 0; 93 } 94 95 // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface. 96 virtual scoped_ptr<DesktopMediaList> CreateModel( 97 bool show_screens, 98 bool show_windows) OVERRIDE { 99 EXPECT_LE(current_test_, tests_count_); 100 if (current_test_ >= tests_count_) 101 return scoped_ptr<DesktopMediaList>(); 102 EXPECT_EQ(test_flags_[current_test_].expect_screens, show_screens); 103 EXPECT_EQ(test_flags_[current_test_].expect_windows, show_windows); 104 return scoped_ptr<DesktopMediaList>(new FakeDesktopMediaList()); 105 } 106 107 virtual scoped_ptr<DesktopMediaPicker> CreatePicker() OVERRIDE { 108 EXPECT_LE(current_test_, tests_count_); 109 if (current_test_ >= tests_count_) 110 return scoped_ptr<DesktopMediaPicker>(); 111 ++current_test_; 112 return scoped_ptr<DesktopMediaPicker>( 113 new FakeDesktopMediaPicker(test_flags_ + current_test_ - 1)); 114 } 115 116 private: 117 TestFlags* test_flags_; 118 int tests_count_; 119 int current_test_; 120 121 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPickerFactory); 122}; 123 124class DesktopCaptureApiTest : public ExtensionApiTest { 125 public: 126 DesktopCaptureApiTest() { 127 DesktopCaptureChooseDesktopMediaFunction:: 128 SetPickerFactoryForTests(&picker_factory_); 129 } 130 virtual ~DesktopCaptureApiTest() { 131 DesktopCaptureChooseDesktopMediaFunction:: 132 SetPickerFactoryForTests(NULL); 133 } 134 135 protected: 136 GURL GetURLForPath(const std::string& host, const std::string& path) { 137 std::string port = base::IntToString(embedded_test_server()->port()); 138 GURL::Replacements replacements; 139 replacements.SetHostStr(host); 140 replacements.SetPortStr(port); 141 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements); 142 } 143 144 FakeDesktopMediaPickerFactory picker_factory_; 145}; 146 147} // namespace 148 149// Flaky on Windows: http://crbug.com/301887 150#if defined(OS_WIN) 151#define MAYBE_ChooseDesktopMedia DISABLED_ChooseDesktopMedia 152#else 153#define MAYBE_ChooseDesktopMedia ChooseDesktopMedia 154#endif 155IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, MAYBE_ChooseDesktopMedia) { 156 // Each element in the following array corresponds to one test in 157 // chrome/test/data/extensions/api_test/desktop_capture/test.js . 158 TestFlags test_flags[] = { 159 // pickerUiCanceled() 160 { true, true, 161 content::DesktopMediaID() }, 162 // chooseMedia() 163 { true, true, 164 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 165 // screensOnly() 166 { true, false, 167 content::DesktopMediaID() }, 168 // WindowsOnly() 169 { false, true, 170 content::DesktopMediaID() }, 171 // chooseMediaAndGetStream() 172 { true, true, 173 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 174 webrtc::kFullDesktopScreenId) }, 175 // chooseMediaAndTryGetStreamWithInvalidId() 176 { true, true, 177 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 178 webrtc::kFullDesktopScreenId) }, 179 // cancelDialog() 180 { true, true, 181 content::DesktopMediaID(), true }, 182 }; 183 picker_factory_.SetTestFlags(test_flags, arraysize(test_flags)); 184 ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_; 185} 186 187// Test is flaky http://crbug.com/301887. 188IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, DISABLED_Delegation) { 189 // Initialize test server. 190 base::FilePath test_data; 191 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); 192 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII( 193 "extensions/api_test/desktop_capture_delegate")); 194 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 195 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); 196 197 // Load extension. 198 base::FilePath extension_path = 199 test_data_dir_.AppendASCII("desktop_capture_delegate"); 200 const Extension* extension = LoadExtensionWithFlags( 201 extension_path, ExtensionBrowserTest::kFlagNone); 202 ASSERT_TRUE(extension); 203 204 ui_test_utils::NavigateToURL( 205 browser(), GetURLForPath("example.com", "/example.com.html")); 206 207 TestFlags test_flags[] = { 208 { true, true, 209 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 210 { true, true, 211 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 212 { true, true, 213 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0), true }, 214 }; 215 picker_factory_.SetTestFlags(test_flags, arraysize(test_flags)); 216 217 bool result; 218 219 content::WebContents* web_contents = 220 browser()->tab_strip_model()->GetActiveWebContents(); 221 222 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 223 web_contents, "getStream()", &result)); 224 EXPECT_TRUE(result); 225 226 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 227 web_contents, "getStreamWithInvalidId()", &result)); 228 EXPECT_TRUE(result); 229 230 // Verify that the picker is closed once the tab is closed. 231 content::WebContentsDestroyedWatcher destroyed_watcher(web_contents); 232 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 233 web_contents, "openPickerDialogAndReturn()", &result)); 234 EXPECT_TRUE(result); 235 EXPECT_TRUE(test_flags[2].picker_created); 236 EXPECT_FALSE(test_flags[2].picker_deleted); 237 238 web_contents->Close(); 239 destroyed_watcher.Wait(); 240 EXPECT_TRUE(test_flags[2].picker_deleted); 241} 242 243} // namespace extensions 244