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