#include "chrome/browser/ui/views/overlay/video_overlay_window_views.h"
#include <memory>
#include <string>
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/views/overlay/back_to_tab_button.h"
#include "chrome/browser/ui/views/overlay/back_to_tab_label_button.h"
#include "chrome/browser/ui/views/overlay/close_image_button.h"
#include "chrome/browser/ui/views/overlay/hang_up_button.h"
#include "chrome/browser/ui/views/overlay/minimize_button.h"
#include "chrome/browser/ui/views/overlay/playback_image_button.h"
#include "chrome/browser/ui/views/overlay/resize_handle_button.h"
#include "chrome/browser/ui/views/overlay/simple_overlay_window_image_button.h"
#include "chrome/browser/ui/views/overlay/skip_ad_label_button.h"
#include "chrome/browser/ui/views/overlay/toggle_camera_button.h"
#include "chrome/browser/ui/views/overlay/toggle_microphone_button.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/ui/base/chromeos_ui_constants.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/picture_in_picture_window_controller.h"
#include "content/public/browser/web_contents.h"
#include "media/base/media_switches.h"
#include "media/base/video_util.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/resize_utils.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/non_client_view.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/rounded_corner_utils.h"
#include "ash/public/cpp/window_properties.h"
#include "chromeos/ui/base/app_types.h"
#include "chromeos/ui/base/window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "chrome/browser/shell_integration_win.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/win/tsf_input_scope.h"
#include "ui/base/win/shell.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "ui/aura/window_tree_host.h"
#include "ui/platform_window/extensions/wayland_extension.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_lacros.h"
#endif
namespace {
constexpr gfx::Size kMinWindowSize(260, 146);
constexpr int kOverlayBorderThickness = …;
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
constexpr double kResizeHandleOpacity = 0.38;
#endif
constexpr gfx::Size kPrimaryControlSize(52, 52);
constexpr int kPrimaryControlBottomMargin = …;
constexpr gfx::Size kSecondaryControlSize(36, 36);
constexpr int kSecondaryControlBottomMargin = …;
constexpr int kControlMargin = …;
constexpr gfx::Size kOverlayViewPadding(64, 46);
VideoOverlayWindowViews::WindowQuadrant GetCurrentWindowQuadrant(
const gfx::Rect window_bounds,
content::PictureInPictureWindowController* controller) { … }
template <typename T>
T* AddChildView(std::vector<std::unique_ptr<views::View>>* views,
std::unique_ptr<T> child) { … }
class WindowBackgroundView : public views::View { … };
BEGIN_METADATA(…)
class ControlsBackgroundView : public views::View { … };
BEGIN_METADATA(…)
}
class OverlayWindowFrameView : public views::NonClientFrameView { … };
BEGIN_METADATA(…)
class OverlayWindowWidgetDelegate : public views::WidgetDelegate { … };
std::unique_ptr<VideoOverlayWindowViews> VideoOverlayWindowViews::Create(
content::VideoPictureInPictureWindowController* controller) { … }
std::unique_ptr<content::VideoOverlayWindow>
content::VideoOverlayWindow::Create(
content::VideoPictureInPictureWindowController* controller) { … }
VideoOverlayWindowViews::VideoOverlayWindowViews(
content::VideoPictureInPictureWindowController* controller)
: … { … }
VideoOverlayWindowViews::~VideoOverlayWindowViews() { … }
gfx::Size& VideoOverlayWindowViews::GetNaturalSize() { … }
gfx::Rect VideoOverlayWindowViews::CalculateAndUpdateWindowBounds() { … }
void VideoOverlayWindowViews::OnNativeFocus() { … }
void VideoOverlayWindowViews::OnNativeBlur() { … }
gfx::Size VideoOverlayWindowViews::GetMinimumSize() const { … }
gfx::Size VideoOverlayWindowViews::GetMaximumSize() const { … }
void VideoOverlayWindowViews::OnNativeWidgetMove() { … }
void VideoOverlayWindowViews::OnNativeWidgetSizeChanged(
const gfx::Size& new_size) { … }
void VideoOverlayWindowViews::OnKeyEvent(ui::KeyEvent* event) { … }
void VideoOverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) { … }
bool VideoOverlayWindowViews::OnGestureEventHandledOrIgnored(
ui::GestureEvent* event) { … }
void VideoOverlayWindowViews::ReEnableControlsAfterMove() { … }
void VideoOverlayWindowViews::ForceControlsVisibleForTesting(bool visible) { … }
bool VideoOverlayWindowViews::AreControlsVisible() const { … }
void VideoOverlayWindowViews::UpdateControlsVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::UpdateControlsBounds() { … }
bool VideoOverlayWindowViews::IsLayoutPendingForTesting() const { … }
void VideoOverlayWindowViews::OnDisplayMetricsChanged(
const display::Display& display,
uint32_t changed_metrics) { … }
void VideoOverlayWindowViews::OnViewVisibilityChanged(
views::View* observed_view,
views::View* starting_view) { … }
void VideoOverlayWindowViews::OnAutoPipSettingOverlayViewHidden() { … }
gfx::Rect VideoOverlayWindowViews::GetWorkAreaForWindow() const { … }
void VideoOverlayWindowViews::UpdateMaxSize(const gfx::Rect& work_area) { … }
bool VideoOverlayWindowViews::ControlsHitTestContainsPoint(
const gfx::Point& point) { … }
content::PictureInPictureWindowController*
VideoOverlayWindowViews::GetController() const { … }
views::View* VideoOverlayWindowViews::GetWindowBackgroundView() const { … }
views::View* VideoOverlayWindowViews::GetControlsContainerView() const { … }
void VideoOverlayWindowViews::SetUpViews() { … }
void VideoOverlayWindowViews::OnRootViewReady() { … }
void VideoOverlayWindowViews::UpdateLayerBoundsWithLetterboxing(
gfx::Size window_size) { … }
void VideoOverlayWindowViews::OnUpdateControlsBounds() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void VideoOverlayWindowViews::UpdateResizeHandleBounds(
WindowQuadrant quadrant) {
resize_handle_view_->SetPosition(GetBounds().size(), quadrant);
GetNativeWindow()->SetProperty(
ash::kWindowPipResizeHandleBoundsKey,
new gfx::Rect(GetResizeHandleControlsBounds()));
}
#endif
bool VideoOverlayWindowViews::IsActive() const { … }
void VideoOverlayWindowViews::Close() { … }
void VideoOverlayWindowViews::ShowInactive() { … }
void VideoOverlayWindowViews::Hide() { … }
bool VideoOverlayWindowViews::IsVisible() const { … }
gfx::Rect VideoOverlayWindowViews::GetBounds() { … }
void VideoOverlayWindowViews::UpdateNaturalSize(const gfx::Size& natural_size) { … }
void VideoOverlayWindowViews::SetPlaybackState(PlaybackState playback_state) { … }
void VideoOverlayWindowViews::SetPlayPauseButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetSkipAdButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetPreviousSlideButtonVisibility(
bool is_visible) { … }
void VideoOverlayWindowViews::SetNextSlideButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetNextTrackButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetPreviousTrackButtonVisibility(
bool is_visible) { … }
void VideoOverlayWindowViews::SetMicrophoneMuted(bool muted) { … }
void VideoOverlayWindowViews::SetCameraState(bool turned_on) { … }
void VideoOverlayWindowViews::SetToggleMicrophoneButtonVisibility(
bool is_visible) { … }
void VideoOverlayWindowViews::SetToggleCameraButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetHangUpButtonVisibility(bool is_visible) { … }
void VideoOverlayWindowViews::SetSurfaceId(const viz::SurfaceId& surface_id) { … }
void VideoOverlayWindowViews::OnNativeWidgetDestroying() { … }
void VideoOverlayWindowViews::OnNativeWidgetDestroyed() { … }
void VideoOverlayWindowViews::OnNativeWidgetAddedToCompositor() { … }
void VideoOverlayWindowViews::OnNativeWidgetRemovingFromCompositor() { … }
void VideoOverlayWindowViews::OnGestureEvent(ui::GestureEvent* event) { … }
gfx::Rect VideoOverlayWindowViews::GetBackToTabControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetSkipAdControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetCloseControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetMinimizeControlsBounds() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
gfx::Rect VideoOverlayWindowViews::GetResizeHandleControlsBounds() {
return resize_handle_view_->GetMirroredBounds();
}
#endif
gfx::Rect VideoOverlayWindowViews::GetPlayPauseControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetNextTrackControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetPreviousTrackControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetToggleMicrophoneButtonBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetToggleCameraButtonBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetHangUpButtonBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetPreviousSlideControlsBounds() { … }
gfx::Rect VideoOverlayWindowViews::GetNextSlideControlsBounds() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
int VideoOverlayWindowViews::GetResizeHTComponent() const {
return resize_handle_view_->GetHTComponent();
}
#endif
void VideoOverlayWindowViews::TogglePlayPause() { … }
void VideoOverlayWindowViews::CloseAndPauseIfAvailable() { … }
PlaybackImageButton*
VideoOverlayWindowViews::play_pause_controls_view_for_testing() const { … }
SimpleOverlayWindowImageButton*
VideoOverlayWindowViews::next_track_controls_view_for_testing() const { … }
SimpleOverlayWindowImageButton*
VideoOverlayWindowViews::previous_track_controls_view_for_testing() const { … }
SkipAdLabelButton* VideoOverlayWindowViews::skip_ad_controls_view_for_testing()
const { … }
ToggleMicrophoneButton*
VideoOverlayWindowViews::toggle_microphone_button_for_testing() const { … }
ToggleCameraButton* VideoOverlayWindowViews::toggle_camera_button_for_testing()
const { … }
HangUpButton* VideoOverlayWindowViews::hang_up_button_for_testing() const { … }
SimpleOverlayWindowImageButton*
VideoOverlayWindowViews::next_slide_controls_view_for_testing() const { … }
SimpleOverlayWindowImageButton*
VideoOverlayWindowViews::previous_slide_controls_view_for_testing() const { … }
CloseImageButton* VideoOverlayWindowViews::close_button_for_testing() const { … }
OverlayWindowMinimizeButton*
VideoOverlayWindowViews::minimize_button_for_testing() const { … }
OverlayWindowBackToTabButton*
VideoOverlayWindowViews::back_to_tab_button_for_testing() const { … }
gfx::Point VideoOverlayWindowViews::close_image_position_for_testing() const { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
gfx::Point VideoOverlayWindowViews::resize_handle_position_for_testing() const {
return resize_handle_view_->origin();
}
#endif
VideoOverlayWindowViews::PlaybackState
VideoOverlayWindowViews::playback_state_for_testing() const { … }
ui::Layer* VideoOverlayWindowViews::video_layer_for_testing() const { … }
const viz::FrameSinkId* VideoOverlayWindowViews::GetCurrentFrameSinkId() const { … }
void VideoOverlayWindowViews::MaybeUnregisterFrameSinkHierarchy() { … }
bool VideoOverlayWindowViews::IsOverlayViewShown() const { … }
void VideoOverlayWindowViews::RemoveOverlayViewIfExists() { … }