| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/media/webrtc/desktop_media_picker_controller.h" |
| |
| #include <memory> |
| #include <tuple> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/media/webrtc/desktop_media_list_ash.h" |
| #include "chrome/browser/media/webrtc/desktop_media_picker.h" |
| #include "chrome/browser/media/webrtc/desktop_media_picker_factory_impl.h" |
| #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" |
| #include "chrome/browser/media/webrtc/native_desktop_media_list.h" |
| #include "chrome/browser/media/webrtc/tab_desktop_media_list.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser_finder.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/grit/chromium_strings.h" |
| #include "content/public/browser/desktop_capture.h" |
| #include "content/public/browser/desktop_streams_registry.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "desktop_media_picker.h" |
| #include "extensions/common/manifest.h" |
| #include "extensions/common/switches.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| DesktopMediaPickerController::DesktopMediaPickerController( |
| DesktopMediaPickerFactory* picker_factory) |
| : picker_factory_(picker_factory |
| ? picker_factory |
| : DesktopMediaPickerFactoryImpl::GetInstance()) {} |
| |
| DesktopMediaPickerController::~DesktopMediaPickerController() = default; |
| |
| void DesktopMediaPickerController::Show( |
| const Params& params, |
| const std::vector<content::DesktopMediaID::Type>& sources, |
| DoneCallback done_callback) { |
| DCHECK(!base::Contains(sources, content::DesktopMediaID::TYPE_NONE)); |
| DCHECK(!done_callback_); |
| |
| done_callback_ = std::move(done_callback); |
| params_ = params; |
| |
| Observe(params.web_contents); |
| |
| // Keep same order as the input |sources| and avoid duplicates. |
| source_lists_ = picker_factory_->CreateMediaList(sources); |
| if (source_lists_.empty()) { |
| OnPickerDialogResults("At least one source type must be specified.", {}); |
| return; |
| } |
| |
| if (params.select_only_screen && sources.size() == 1 && |
| sources[0] == content::DesktopMediaID::TYPE_SCREEN) { |
| // Try to bypass the picker dialog if possible. |
| DCHECK(source_lists_.size() == 1); |
| auto* source_list = source_lists_[0].get(); |
| source_list->Update( |
| base::BindOnce(&DesktopMediaPickerController::OnInitialMediaListFound, |
| base::Unretained(this))); |
| } else { |
| ShowPickerDialog(); |
| } |
| } |
| |
| void DesktopMediaPickerController::WebContentsDestroyed() { |
| OnPickerDialogResults(std::string(), content::DesktopMediaID()); |
| |
| // This ensures that OnPickerDialogResults() won't be called again as a result |
| // of previously registered callbacks. |
| picker_.reset(); |
| source_lists_.clear(); |
| } |
| |
| void DesktopMediaPickerController::OnInitialMediaListFound() { |
| DCHECK(params_.select_only_screen); |
| DCHECK(source_lists_.size() == 1); |
| auto* source_list = source_lists_[0].get(); |
| if (source_list->GetSourceCount() == 1) { |
| OnPickerDialogResults({}, source_list->GetSource(0).id); |
| return; |
| } |
| |
| ShowPickerDialog(); |
| } |
| |
| void DesktopMediaPickerController::ShowPickerDialog() { |
| picker_ = picker_factory_->CreatePicker(); |
| if (!picker_) { |
| OnPickerDialogResults( |
| "Desktop Capture API is not yet implemented for this platform.", {}); |
| return; |
| } |
| |
| picker_->Show(params_, std::move(source_lists_), |
| base::Bind(&DesktopMediaPickerController::OnPickerDialogResults, |
| base::Unretained(this), std::string())); |
| } |
| |
| void DesktopMediaPickerController::OnPickerDialogResults( |
| const std::string& err, |
| content::DesktopMediaID source) { |
| DCHECK(done_callback_); |
| std::move(done_callback_).Run(err, source); |
| } |