Home | History | Annotate | Download | only in desktop_capture
      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 
     22 namespace extensions {
     23 
     24 namespace {
     25 
     26 struct 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 
     38 class 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 
     83 class 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 
    124 class 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
    155 IN_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.
    188 IN_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