chromium/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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;

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class SelectedTabDiscardStatus {};

#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_AURA)
DesktopMediaID::Id AcceleratedWidgetToDesktopMediaId(
    gfx::AcceleratedWidget accelerated_widget) {}
#endif

BASE_FEATURE();

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class GDMResult {};

void RecordUma(GDMResult result, base::TimeTicks dialog_open_time) {}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class PermissionInteraction {};

void RecordUmaCancellation(DialogType dialog_type,
                           base::TimeTicks dialog_open_time) {}

// Convenience function for recording UMA.
// |source_type| is there to help us distinguish the current tab being
// selected explicitly, from it being selected from the list of all tabs.
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  // BUILDFLAG(IS_MAC)

std::u16string GetLabelForReselectButton(DesktopMediaList::Type type) {}

bool AreEquivalentTypesForAudioCheckbox(DesktopMediaList::Type lhs,
                                        DesktopMediaList::Type rhs) {}

// Helper to generate the view containing the enterprise icon and a message that
// the picker choices may have been restricted.
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) {}

}  // namespace

// Enable an updated dialog UI for the getDisplayMedia picker dialog under the
// preferCurrentTab constraint.
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& /*available_size*/) 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) {
    // Avoid needless polling.
    // (A user who revokes permission while the media-picker is visible,
    // likely knows what they are doing, and can recover by themselves.)
    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) {}

// static
std::unique_ptr<DesktopMediaPicker> DesktopMediaPicker::Create(
    const content::MediaStreamRequest* request) {}