#include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h"
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/user_metrics.h"
#include "base/ranges/algorithm.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/media/webrtc/desktop_capture_devices_util.h"
#include "chrome/browser/media/webrtc/desktop_media_list.h"
#include "chrome/browser/media/webrtc/desktop_media_picker_controller.h"
#include "chrome/browser/media/webrtc/desktop_media_picker_manager.h"
#include "chrome/browser/media/webrtc/desktop_media_picker_utils.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/extensions/extensions_container.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h"
#include "chrome/browser/ui/views/desktop_capture/screen_capture_permission_checker.h"
#include "chrome/browser/ui/views/desktop_capture/share_this_tab_dialog_views.h"
#include "chrome/browser/ui/views/extensions/security_dialog_tracker.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/strings/grit/components_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/media_stream_request.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 "content/public/browser/web_contents_delegate.h"
#include "media/base/media_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/style/typography.h"
#include "ui/views/widget/widget.h"
#if defined(USE_AURA)
#include "ui/aura/window_tree_host.h"
#endif
DesktopMediaID;
RenderFrameHost;
WebContents;
WebContentsMediaCaptureId;
RequestSource;
enum class DesktopMediaPickerDialogView::DialogType : int { … };
namespace {
DialogType;
enum class SelectedTabDiscardStatus { … };
#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_AURA)
DesktopMediaID::Id AcceleratedWidgetToDesktopMediaId(
gfx::AcceleratedWidget accelerated_widget) { … }
#endif
BASE_FEATURE(…);
enum class GDMResult { … };
void RecordUma(GDMResult result, base::TimeTicks dialog_open_time) { … }
enum class PermissionInteraction { … };
void RecordUmaCancellation(DialogType dialog_type,
base::TimeTicks dialog_open_time) { … }
void RecordUmaSelection(DialogType dialog_type,
content::GlobalRenderFrameHostId capturer_global_id,
const DesktopMediaID& selected_media,
DesktopMediaList::Type source_type,
base::TimeTicks dialog_open_time) { … }
#if BUILDFLAG(IS_MAC)
void RecordUma(PermissionInteraction permission_interaction) {
base::UmaHistogramEnumeration(
"Media.Ui.GetDisplayMedia.PermissionInteractionMac",
permission_interaction);
}
void RecordPermissionButtonOpenedAction(DesktopMediaList::Type type) {
switch (type) {
case DesktopMediaList::Type::kScreen:
RecordAction(base::UserMetricsAction(
"GetDisplayMedia.PermissionPane.Screen.Opened"));
return;
case DesktopMediaList::Type::kWindow:
RecordAction(base::UserMetricsAction(
"GetDisplayMedia.PermissionPane.Window.Opened"));
return;
case DesktopMediaList::Type::kWebContents:
case DesktopMediaList::Type::kCurrentTab:
case DesktopMediaList::Type::kNone:
break;
}
NOTREACHED();
}
#endif
std::u16string GetLabelForReselectButton(DesktopMediaList::Type type) { … }
bool AreEquivalentTypesForAudioCheckbox(DesktopMediaList::Type lhs,
DesktopMediaList::Type rhs) { … }
std::unique_ptr<views::View> CreatePolicyRestrictedView() { … }
bool ShouldSelectTab(DesktopMediaList::Type type,
blink::mojom::PreferredDisplaySurface display_surface) { … }
std::unique_ptr<views::ScrollView> CreateScrollView(bool audio_requested) { … }
}
BASE_FEATURE(…);
bool DesktopMediaPickerDialogView::AudioSupported(DesktopMediaList::Type type) { … }
DesktopMediaPickerDialogView::DisplaySurfaceCategory::DisplaySurfaceCategory(
DesktopMediaList::Type type,
std::unique_ptr<DesktopMediaListController> controller,
bool audio_offered,
bool audio_checked,
bool supports_reselect_button)
: … { … }
DesktopMediaPickerDialogView::DisplaySurfaceCategory::DisplaySurfaceCategory(
DesktopMediaPickerDialogView::DisplaySurfaceCategory&& other)
: … { … }
DesktopMediaPickerDialogView::DisplaySurfaceCategory::
~DisplaySurfaceCategory() = default;
DesktopMediaPickerDialogView::DesktopMediaPickerDialogView(
const DesktopMediaPicker::Params& params,
DesktopMediaPickerViews* parent,
std::vector<std::unique_ptr<DesktopMediaList>> source_lists)
: … { … }
DesktopMediaPickerDialogView::~DesktopMediaPickerDialogView() { … }
void DesktopMediaPickerDialogView::RecordUmaDismissal() const { … }
void DesktopMediaPickerDialogView::TabSelectedAt(int index) { … }
void DesktopMediaPickerDialogView::ConfigureUIForNewPane(int index) { … }
void DesktopMediaPickerDialogView::StoreAudioCheckboxState() { … }
void DesktopMediaPickerDialogView::RemoveCurrentPaneUI() { … }
void DesktopMediaPickerDialogView::MaybeCreateReselectButtonForPane(
const DisplaySurfaceCategory& category) { … }
std::u16string DesktopMediaPickerDialogView::GetLabelForAudioToggle(
const DisplaySurfaceCategory& category) const { … }
std::unique_ptr<views::View> DesktopMediaPickerDialogView::SetupPane(
DesktopMediaList::Type type,
std::unique_ptr<DesktopMediaListController> controller,
bool audio_offered,
bool audio_checked,
bool supports_reselect_button,
std::unique_ptr<views::View> content_view) { … }
int DesktopMediaPickerDialogView::GetSelectedTabIndex() const { … }
const DesktopMediaListController*
DesktopMediaPickerDialogView::GetSelectedController() const { … }
DesktopMediaListController*
DesktopMediaPickerDialogView::GetSelectedController() { … }
DesktopMediaList::Type DesktopMediaPickerDialogView::GetSelectedSourceListType()
const { … }
bool DesktopMediaPickerDialogView::IsAudioSharingApprovedByUser() const { … }
void DesktopMediaPickerDialogView::RecordSourceCountsUma() { … }
void DesktopMediaPickerDialogView::RecordTabDiscardedStatusUma(
const DesktopMediaID& source) { … }
std::optional<int> DesktopMediaPickerDialogView::CountSourcesOfType(
DesktopMediaList::Type type) { … }
void DesktopMediaPickerDialogView::DetachParent() { … }
gfx::Size DesktopMediaPickerDialogView::CalculatePreferredSize(
const views::SizeBounds& ) const { … }
std::u16string DesktopMediaPickerDialogView::GetWindowTitle() const { … }
bool DesktopMediaPickerDialogView::IsDialogButtonEnabled(
ui::mojom::DialogButton button) const { … }
views::View* DesktopMediaPickerDialogView::GetInitiallyFocusedView() { … }
bool DesktopMediaPickerDialogView::Accept() { … }
bool DesktopMediaPickerDialogView::Cancel() { … }
bool DesktopMediaPickerDialogView::ShouldShowCloseButton() const { … }
void DesktopMediaPickerDialogView::OnWidgetInitialized() { … }
void DesktopMediaPickerDialogView::OnSelectionChanged() { … }
void DesktopMediaPickerDialogView::AcceptSource() { … }
void DesktopMediaPickerDialogView::AcceptSpecificSource(
const DesktopMediaID& source) { … }
void DesktopMediaPickerDialogView::Reject() { … }
void DesktopMediaPickerDialogView::OnSourceListLayoutChanged() { … }
void DesktopMediaPickerDialogView::OnDelegatedSourceListDismissed() { … }
void DesktopMediaPickerDialogView::OnCanReselectChanged(
const DesktopMediaListController* controller) { … }
#if BUILDFLAG(IS_MAC)
void DesktopMediaPickerDialogView::OnPermissionUpdate(bool has_permission) {
CHECK(screen_capture_permission_checker_);
if (!initial_permission_state_.has_value()) {
initial_permission_state_ = has_permission;
}
if (has_permission) {
screen_capture_permission_checker_->Stop();
}
for (auto& category : categories_) {
category.pane->OnScreenCapturePermissionUpdate(has_permission);
}
}
void DesktopMediaPickerDialogView::RecordPermissionInteractionUma() const {
if (initial_permission_state_.value_or(true)) {
return;
}
bool permission_button_was_clicked = false;
for (auto& category : categories_) {
if (category.pane->WasPermissionButtonClicked()) {
permission_button_was_clicked = true;
break;
}
}
const PermissionInteraction permission_interaction =
permission_button_was_clicked ? PermissionInteraction::kClicked
: permission_pane_was_shown_ ? PermissionInteraction::kShown
: PermissionInteraction::kNotShown;
RecordUma(permission_interaction);
}
#endif
BEGIN_METADATA(…)
DesktopMediaPickerViews::DesktopMediaPickerViews() : … { … }
DesktopMediaPickerViews::~DesktopMediaPickerViews() { … }
void DesktopMediaPickerViews::Show(
const DesktopMediaPicker::Params& params,
std::vector<std::unique_ptr<DesktopMediaList>> source_lists,
DoneCallback done_callback) { … }
void DesktopMediaPickerViews::NotifyDialogResult(const DesktopMediaID& source) { … }
std::unique_ptr<DesktopMediaPicker> DesktopMediaPicker::Create(
const content::MediaStreamRequest* request) { … }