desktop_capture_apitest.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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/desktop_media_picker.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/screen_capturer.h" 21#include "third_party/webrtc/modules/desktop_capture/window_capturer.h" 22 23namespace extensions { 24 25namespace { 26 27class FakeDesktopMediaPicker : public DesktopMediaPicker { 28 public: 29 explicit FakeDesktopMediaPicker(const content::DesktopMediaID& source, 30 bool expect_cancelled) 31 : source_(source), 32 expect_cancelled_(expect_cancelled), 33 weak_factory_(this) { 34 } 35 virtual ~FakeDesktopMediaPicker() {} 36 37 // DesktopMediaPicker interface. 38 virtual void Show(gfx::NativeWindow context, 39 gfx::NativeWindow parent, 40 const string16& app_name, 41 scoped_ptr<DesktopMediaPickerModel> model, 42 const DoneCallback& done_callback) OVERRIDE { 43 if (!expect_cancelled_) { 44 // Post a task to call the callback asynchronously. 45 base::ThreadTaskRunnerHandle::Get()->PostTask( 46 FROM_HERE, 47 base::Bind(&FakeDesktopMediaPicker::CallCallback, 48 weak_factory_.GetWeakPtr(), done_callback)); 49 } else { 50 // If we expect the dialog to be canceled then store the callback to 51 // retain reference to the callback handler. 52 done_callback_ = done_callback; 53 } 54 } 55 56 private: 57 void CallCallback(DoneCallback done_callback) { 58 done_callback.Run(source_); 59 } 60 61 content::DesktopMediaID source_; 62 bool expect_cancelled_; 63 DoneCallback done_callback_; 64 65 base::WeakPtrFactory<FakeDesktopMediaPicker> weak_factory_; 66 67 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPicker); 68}; 69 70class FakeDesktopMediaPickerFactory : 71 public DesktopCaptureChooseDesktopMediaFunction::PickerFactory { 72 public: 73 struct Expectation { 74 bool screens; 75 bool windows; 76 content::DesktopMediaID selected_source; 77 bool cancelled; 78 }; 79 80 FakeDesktopMediaPickerFactory() {} 81 virtual ~FakeDesktopMediaPickerFactory() {} 82 83 void SetExpectations(const Expectation* expectation_array, int size) { 84 for (int i = 0; i < size; ++i) { 85 expectations_.push(expectation_array[i]); 86 } 87 } 88 89 // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface. 90 virtual scoped_ptr<DesktopMediaPickerModel> CreateModel( 91 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, 92 scoped_ptr<webrtc::WindowCapturer> window_capturer) OVERRIDE { 93 EXPECT_TRUE(!expectations_.empty()); 94 if (!expectations_.empty()) { 95 EXPECT_EQ(expectations_.front().screens, !!screen_capturer.get()); 96 EXPECT_EQ(expectations_.front().windows, !!window_capturer.get()); 97 } 98 return scoped_ptr<DesktopMediaPickerModel>( 99 new DesktopMediaPickerModelImpl(screen_capturer.Pass(), 100 window_capturer.Pass())); 101 } 102 virtual scoped_ptr<DesktopMediaPicker> CreatePicker() OVERRIDE { 103 content::DesktopMediaID next_source; 104 bool expect_cancelled = false; 105 if (!expectations_.empty()) { 106 next_source = expectations_.front().selected_source; 107 expect_cancelled = expectations_.front().cancelled; 108 expectations_.pop(); 109 } 110 return scoped_ptr<DesktopMediaPicker>( 111 new FakeDesktopMediaPicker(next_source, expect_cancelled)); 112 } 113 114 private: 115 std::queue<Expectation> expectations_; 116 117 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaPickerFactory); 118}; 119 120class DesktopCaptureApiTest : public ExtensionApiTest { 121 public: 122 DesktopCaptureApiTest() { 123 DesktopCaptureChooseDesktopMediaFunction:: 124 SetPickerFactoryForTests(&picker_factory_); 125 } 126 virtual ~DesktopCaptureApiTest() { 127 DesktopCaptureChooseDesktopMediaFunction:: 128 SetPickerFactoryForTests(NULL); 129 } 130 131 protected: 132 GURL GetURLForPath(const std::string& host, const std::string& path) { 133 std::string port = base::IntToString(embedded_test_server()->port()); 134 GURL::Replacements replacements; 135 replacements.SetHostStr(host); 136 replacements.SetPortStr(port); 137 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements); 138 } 139 140 FakeDesktopMediaPickerFactory picker_factory_; 141}; 142 143} // namespace 144 145// Flaky on Windows: http://crbug.com/301887 146#if defined(OS_WIN) 147#define MAYBE_ChooseDesktopMedia DISABLED_ChooseDesktopMedia 148#else 149#define MAYBE_ChooseDesktopMedia ChooseDesktopMedia 150#endif 151IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, MAYBE_ChooseDesktopMedia) { 152 // Each of the following expectations corresponds to one test in 153 // chrome/test/data/extensions/api_test/desktop_capture/test.js . 154 FakeDesktopMediaPickerFactory::Expectation picker_expectations[] = { 155 // pickerUiCanceled() 156 { true, true, 157 content::DesktopMediaID() }, 158 // chooseMedia() 159 { true, true, 160 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 161 // screensOnly() 162 { true, false, 163 content::DesktopMediaID() }, 164 // WindowsOnly() 165 { false, true, 166 content::DesktopMediaID() }, 167 // chooseMediaAndGetStream() 168 { true, true, 169 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 170 // chooseMediaAndTryGetStreamWithInvalidId() 171 { true, true, 172 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 173 // cancelDialog() 174 { true, true, 175 content::DesktopMediaID(), true }, 176 }; 177 picker_factory_.SetExpectations(picker_expectations, 178 arraysize(picker_expectations)); 179 ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_; 180} 181 182IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, Delegation) { 183 // Initialize test server. 184 base::FilePath test_data; 185 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); 186 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII( 187 "extensions/api_test/desktop_capture_delegate")); 188 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 189 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); 190 191 // Load extension. 192 base::FilePath extension_path = 193 test_data_dir_.AppendASCII("desktop_capture_delegate"); 194 const Extension* extension = LoadExtensionWithFlags( 195 extension_path, ExtensionBrowserTest::kFlagNone); 196 ASSERT_TRUE(extension); 197 198 ui_test_utils::NavigateToURL( 199 browser(), GetURLForPath("example.com", "/example.com.html")); 200 201 FakeDesktopMediaPickerFactory::Expectation picker_expectations[] = { 202 { true, true, 203 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 204 { true, true, 205 content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0) }, 206 }; 207 picker_factory_.SetExpectations(picker_expectations, 208 arraysize(picker_expectations)); 209 210 bool result; 211 212 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 213 browser()->tab_strip_model()->GetActiveWebContents(), 214 "getStream()", &result)); 215 EXPECT_TRUE(result); 216 217 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 218 browser()->tab_strip_model()->GetActiveWebContents(), 219 "getStreamWithInvalidId()", &result)); 220 EXPECT_TRUE(result); 221} 222 223} // namespace extensions 224