| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_UI_VIEWS_OVERLAY_VIDEO_OVERLAY_WINDOW_VIEWS_H_ |
| #define CHROME_BROWSER_UI_VIEWS_OVERLAY_VIDEO_OVERLAY_WINDOW_VIEWS_H_ |
| |
| #include <optional> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/picture_in_picture/auto_pip_setting_overlay_view.h" |
| #include "chrome/browser/picture_in_picture/picture_in_picture_widget_fade_animator.h" |
| #include "chrome/browser/picture_in_picture/picture_in_picture_window.h" |
| #include "components/global_media_controls/public/views/media_progress_view.h" |
| #include "content/public/browser/overlay_window.h" |
| #include "content/public/browser/video_picture_in_picture_window_controller.h" |
| #include "ui/display/display.h" |
| #include "ui/display/display_observer.h" |
| #include "ui/gfx/geometry/size.h" |
| #include "ui/views/view_observer.h" |
| #include "ui/views/widget/widget.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| #include "chromeos/ui/frame/highlight_border_overlay.h" |
| #endif |
| |
| namespace views { |
| class ImageView; |
| class Label; |
| } // namespace views |
| |
| namespace viz { |
| class FrameSinkId; |
| } // namespace viz |
| |
| class BackToTabLabelButton; |
| class CloseImageButton; |
| class HangUpButton; |
| class OverlayControlsFadeAnimation; |
| class OverlayWindowBackToTabButton; |
| class OverlayWindowLiveCaptionButton; |
| class OverlayWindowLiveCaptionDialog; |
| class OverlayWindowMinimizeButton; |
| class PictureInPictureTucker; |
| class PlaybackImageButton; |
| class ResizeHandleButton; |
| class SimpleOverlayWindowImageButton; |
| class SkipAdLabelButton; |
| class ToggleMicrophoneButton; |
| class ToggleCameraButton; |
| |
| // The Chrome desktop implementation of VideoOverlayWindow. This will only be |
| // implemented in views, which will support all desktop platforms. |
| class VideoOverlayWindowViews : public content::VideoOverlayWindow, |
| public views::Widget, |
| public display::DisplayObserver, |
| public views::ViewObserver, |
| public PictureInPictureWindow, |
| public AutoPipSettingOverlayView::Delegate { |
| public: |
| using GetOverlayViewCb = |
| base::RepeatingCallback<std::unique_ptr<AutoPipSettingOverlayView>()>; |
| |
| static std::unique_ptr<VideoOverlayWindowViews> Create( |
| content::VideoPictureInPictureWindowController* controller); |
| |
| VideoOverlayWindowViews(const VideoOverlayWindowViews&) = delete; |
| VideoOverlayWindowViews& operator=(const VideoOverlayWindowViews&) = delete; |
| |
| ~VideoOverlayWindowViews() override; |
| |
| enum class WindowQuadrant { kBottomLeft, kBottomRight, kTopLeft, kTopRight }; |
| |
| // The amount of time to keep the controls hidden after a widget move. |
| static constexpr base::TimeDelta kControlHideDelayAfterMove = |
| base::Milliseconds(100); |
| |
| // The amount of time to display the title and top controls scrim. |
| static constexpr base::TimeDelta kTitleShowDuration = base::Seconds(5); |
| |
| // VideoOverlayWindow: |
| void Close() override; |
| void ShowInactive() override; |
| bool IsVisible() const override; |
| void Hide() override; |
| gfx::Rect GetBounds() override; |
| void UpdateNaturalSize(const gfx::Size& natural_size) override; |
| void SetPlaybackState(PlaybackState playback_state) override; |
| void SetPlayPauseButtonVisibility(bool is_visible) override; |
| void SetSkipAdButtonVisibility(bool is_visible) override; |
| void SetNextTrackButtonVisibility(bool is_visible) override; |
| void SetPreviousTrackButtonVisibility(bool is_visible) override; |
| void SetHidePictureInPictureButtonVisibility(bool is_visible) override {} |
| void SetMicrophoneMuted(bool muted) override; |
| void SetCameraState(bool turned_on) override; |
| void SetToggleMicrophoneButtonVisibility(bool is_visible) override; |
| void SetToggleCameraButtonVisibility(bool is_visible) override; |
| void SetHangUpButtonVisibility(bool is_visible) override; |
| void SetPreviousSlideButtonVisibility(bool is_visible) override; |
| void SetNextSlideButtonVisibility(bool is_visible) override; |
| void SetMediaPosition(const media_session::MediaPosition& position) override; |
| void SetSourceTitle(const std::u16string& source_title) override; |
| void SetFaviconImages( |
| const std::vector<media_session::MediaImage>& images) override; |
| void SetSurfaceId(const viz::SurfaceId& surface_id) override; |
| |
| // views::Widget: |
| bool IsActive() const override; |
| void OnNativeFocus() override; |
| void OnNativeBlur() override; |
| gfx::Size GetMinimumSize() const override; |
| gfx::Size GetMaximumSize() const override; |
| void OnNativeWidgetMove() override; |
| void OnNativeWidgetDestroying() override; |
| void OnNativeWidgetDestroyed() override; |
| void OnNativeWidgetAddedToCompositor() override; |
| void OnNativeWidgetRemovingFromCompositor() override; |
| void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override; |
| void OnKeyEvent(ui::KeyEvent* event) override; |
| void OnMouseEvent(ui::MouseEvent* event) override; |
| void OnGestureEvent(ui::GestureEvent* event) override; |
| |
| // display::DisplayObserver: |
| void OnDisplayMetricsChanged(const display::Display& display, |
| uint32_t changed_metrics) override; |
| |
| // views::ViewObserver: |
| void OnViewVisibilityChanged(views::View* observed_view, |
| views::View* starting_view, |
| bool visible) override; |
| |
| // PictureInPictureWindow: |
| void SetForcedTucking(bool tuck) override; |
| |
| // AutoPipSettingOverlayView::Delegate: |
| void OnAutoPipSettingOverlayViewHidden() override; |
| |
| bool ControlsHitTestContainsPoint(const gfx::Point& point); |
| #if BUILDFLAG(IS_CHROMEOS) |
| // Gets the proper hit test component when the hit point is on the resize |
| // handle in order to force a drag-to-resize. |
| int GetResizeHTComponent() const; |
| |
| gfx::Rect GetResizeHandleControlsBounds(); |
| |
| // Updates the bounds of |resize_handle_view_| based on what |quadrant| the |
| // PIP window is in. |
| void UpdateResizeHandleBounds(WindowQuadrant quadrant); |
| #endif |
| |
| // Called when the bounds of the controls should be updated. |
| void OnUpdateControlsBounds(); |
| |
| content::PictureInPictureWindowController* GetController() const; |
| views::View* GetWindowBackgroundView() const; |
| views::View* GetControlsContainerView() const; |
| views::View* GetTitleView() const; |
| views::View* GetControlsTopScrimView() const; |
| |
| gfx::Size& GetNaturalSize(); |
| |
| // Shows the controls on a gesture tap if they are not already shown. Returns |
| // true if the controls were shown. |
| bool ShowControlsForGestureIfNecessary(ui::GestureEvent* event); |
| |
| // Hides the live caption dialog on a gesture tap if it's shown and the tap is |
| // outside of the dialog. Returns true if the dialog was hidden. |
| bool HideLiveCaptionDialogForGestureIfNecessary(ui::GestureEvent* event); |
| |
| // Returns true if the controls (e.g. close button, play/pause button) are |
| // visible. |
| bool AreControlsVisible() const; |
| |
| // Updates the controls view::Views to reflect |is_visible|. If the window is |
| // currently in motion, the update is queued until the end of motion. If |
| // multiple updates are requested, only the last update will be applied. |
| // When `should_animate` is true, there will be fade animation to the new |
| // state. |
| void UpdateControlsVisibility(bool is_visible, bool should_animate = true); |
| |
| // Gets the bounds of the controls. |
| gfx::Rect GetBackToTabControlsBounds(); |
| gfx::Rect GetSkipAdControlsBounds(); |
| gfx::Rect GetCloseControlsBounds(); |
| gfx::Rect GetMinimizeControlsBounds(); |
| gfx::Rect GetPlayPauseControlsBounds(); |
| gfx::Rect GetReplay10SecondsButtonBounds(); |
| gfx::Rect GetForward10SecondsButtonBounds(); |
| gfx::Rect GetNextTrackControlsBounds(); |
| gfx::Rect GetPreviousTrackControlsBounds(); |
| gfx::Rect GetToggleMicrophoneButtonBounds(); |
| gfx::Rect GetToggleCameraButtonBounds(); |
| gfx::Rect GetHangUpButtonBounds(); |
| gfx::Rect GetProgressViewBounds(); |
| gfx::Rect GetLiveCaptionButtonBounds(); |
| gfx::Rect GetLiveCaptionDialogBounds(); |
| |
| PlaybackImageButton* play_pause_controls_view_for_testing() const; |
| SimpleOverlayWindowImageButton* replay_10_seconds_button_for_testing() const; |
| SimpleOverlayWindowImageButton* forward_10_seconds_button_for_testing() const; |
| SimpleOverlayWindowImageButton* next_track_controls_view_for_testing() const; |
| SimpleOverlayWindowImageButton* previous_track_controls_view_for_testing() |
| const; |
| SkipAdLabelButton* skip_ad_controls_view_for_testing() const; |
| ToggleMicrophoneButton* toggle_microphone_button_for_testing() const; |
| ToggleCameraButton* toggle_camera_button_for_testing() const; |
| HangUpButton* hang_up_button_for_testing() const; |
| global_media_controls::MediaProgressView* progress_view_for_testing() const; |
| views::Label* timestamp_for_testing() const; |
| views::Label* live_status_for_testing() const; |
| OverlayWindowLiveCaptionButton* live_caption_button_for_testing() const; |
| OverlayWindowLiveCaptionDialog* live_caption_dialog_for_testing() const; |
| views::ImageView* favicon_view_for_testing() const; |
| views::Label* origin_for_testing() const; |
| CloseImageButton* close_button_for_testing() const; |
| OverlayWindowMinimizeButton* minimize_button_for_testing() const; |
| OverlayWindowBackToTabButton* back_to_tab_button_for_testing() const; |
| gfx::Point close_image_position_for_testing() const; |
| gfx::Point resize_handle_position_for_testing() const; |
| PlaybackState playback_state_for_testing() const; |
| ui::Layer* video_layer_for_testing() const; |
| views::View* window_background_view_for_testing() const { |
| return window_background_view_; |
| } |
| views::View* title_view_for_testing() const; |
| views::View* controls_top_scrim_view_for_testing() const; |
| base::OneShotTimer& initial_title_hide_timer_for_testing(); |
| |
| void ForceControlsVisibleForTesting( |
| bool controls_visible, |
| std::optional<bool> title_and_scrim_visible = std::nullopt); |
| void StopForcingControlsVisibleForTesting(); |
| |
| void FireEnableControlsAfterMoveTimerForTesting(); |
| |
| void set_overlay_view_cb_for_testing(GetOverlayViewCb get_overlay_view_cb) { |
| get_overlay_view_cb_ = std::move(get_overlay_view_cb); |
| } |
| |
| AutoPipSettingOverlayView* get_overlay_view_for_testing() { |
| return overlay_view_; |
| } |
| |
| PictureInPictureWidgetFadeAnimator* get_fade_animator_for_testing() { |
| return fade_animator_.get(); |
| } |
| |
| // Determines whether a layout of the window controls has been scheduled but |
| // is not done yet. |
| bool IsLayoutPendingForTesting() const; |
| |
| void set_minimum_size_for_testing(const gfx::Size& min_size) { |
| min_size_ = min_size; |
| } |
| |
| void set_meets_user_interaction_for_testing(bool meets_user_interaction) { |
| meets_user_interaction_ = meets_user_interaction; |
| } |
| |
| void FinishTuckAnimationForTesting(); |
| |
| bool AreTitleAndScrimVisibleForTesting() const; |
| |
| protected: |
| explicit VideoOverlayWindowViews( |
| content::VideoPictureInPictureWindowController* controller); |
| |
| private: |
| friend class VideoPictureInPictureWindowControllerBrowserTest; |
| |
| // Return the work area for the nearest display the widget is on. |
| gfx::Rect GetWorkAreaForWindow() const; |
| |
| // Determine the intended bounds of |this|. This should be called when there |
| // is reason for the bounds to change, such as switching primary displays or |
| // playing a new video (i.e. different aspect ratio). |
| gfx::Rect CalculateAndUpdateWindowBounds(); |
| |
| // Set up the views::Views that will be shown on the window. |
| void SetUpViews(); |
| |
| // Finish initialization by performing the steps that require the root View. |
| void OnRootViewReady(); |
| |
| // Updates the bounds of the controls. |
| void UpdateControlsBounds(); |
| |
| // Update the max size of the widget based on |work_area| and window size. |
| void UpdateMaxSize(const gfx::Rect& work_area); |
| |
| // Update the bounds of the layers on the window. This may introduce |
| // letterboxing. |
| void UpdateLayerBoundsWithLetterboxing(gfx::Size window_size); |
| |
| // Toggles the play/pause control through the |controller_| and updates the |
| // |play_pause_controls_view_| toggled state to reflect the current playing |
| // state. |
| void TogglePlayPause(); |
| |
| void Replay10Seconds(); |
| |
| void Forward10Seconds(); |
| |
| // Closes this window and also pauses the underlying video if pausing is |
| // available. |
| void CloseAndPauseIfAvailable(); |
| |
| // Returns the current frame sink id for the surface displayed in the |
| // |video_view_|. If |video_view_| is not currently displaying a surface then |
| // returns nullptr. |
| const viz::FrameSinkId* GetCurrentFrameSinkId() const; |
| |
| // Unregisters the current frame sink id for the surface displayed in the |
| // |video_view_| from its parent frame sink if the frame sink hierarchy has |
| // been registered before. |
| void MaybeUnregisterFrameSinkHierarchy(); |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class OverlayWindowControl { |
| kBackToTab = 0, |
| kMuteDeprecated, |
| kSkipAd, |
| kClose, |
| kPlayPause, |
| kNextTrack, |
| kPreviousTrack, |
| kToggleMicrophone, |
| kToggleCamera, |
| kHangUp, |
| kPreviousSlide, |
| kNextSlide, |
| kMinimize, |
| kMaxValue = kMinimize |
| }; |
| void RecordButtonPressed(OverlayWindowControl); |
| void RecordTapGesture(OverlayWindowControl); |
| |
| // Re-enables controls after moving. Controls are hidden while the pip window |
| // is in motion. This will change the move status and set the control |
| // visibility to the last requested state. |
| void ReEnableControlsAfterMove(); |
| |
| // Returns true if and only if `overlay_view_` is currently shown. In |
| // practice, the is the allow / block UI for auto-pip. |
| bool IsOverlayViewShown() const; |
| |
| // Removes the `overlay_view_` if it exists. |
| void RemoveOverlayViewIfExists(); |
| |
| void OnProgressDragStateChanged(global_media_controls::DragState drag_state); |
| void ChangePlaybackStateForProgressDrag( |
| global_media_controls::PlaybackStateChangeForDragging |
| playback_state_change); |
| void SeekForProgressBarInteraction(double seek_progress); |
| void OnProgressViewUpdateCurrentTime(base::TimeDelta current_time); |
| |
| void UpdateTimestampLabel(base::TimeDelta current_time, |
| base::TimeDelta duration); |
| |
| void OnLiveCaptionButtonPressed(); |
| void SetLiveCaptionDialogVisibility(bool wanted_visibility); |
| |
| void OnFaviconReceived(const SkBitmap& image); |
| void UpdateFavicon(const gfx::ImageSkia& favicon); |
| |
| // Called when the timer to initially show the title view fires. |
| void OnInitialTitleTimerFired(); |
| |
| // Returns true if the title and top scrim are visible. |
| bool AreTitleAndScrimVisible() const; |
| |
| bool HasHighMediaEngagement(const url::Origin& origin) const; |
| |
| // Returns true if the current Picture-in-Picture window is trusted for media |
| // playback. |
| // |
| // A Picture-in-Picture window is trusted for media playback if all of the |
| // following conditions are met: |
| // * `MediaSession` exists |
| // * `MediaSession` routed frame exists |
| // * The `MediaSession` routed frame is the primary main frame |
| // * The origin URL has high media engagement or is a file |
| bool IsTrustedForMediaPlayback() const; |
| |
| // Updates the value of `meets_user_interaction_` if needed. |
| // |
| // `meets_user_interaction_` is only set to true after |
| // `initial_title_hide_timer_` fires and a desired `event` is triggered. If |
| // `event` fires while the `initial_title_hide_timer_` is running, the |
| // `meets_user_interaction_` update is done after the timer finishes. |
| void MaybeUpdateMeetsUserInteraction(const ui::Event& event); |
| |
| // Not owned; |controller_| owns |this|. |
| raw_ptr<content::VideoPictureInPictureWindowController> controller_; |
| |
| // Whether or not the play/pause button will be shown. |
| bool show_play_pause_button_ = false; |
| |
| // Temporary storage for child Views. Used during the time between |
| // construction and initialization, when the views::View pointer members must |
| // already be initialized, but there is no root view to add them to yet. |
| std::vector<std::unique_ptr<views::View>> view_holder_; |
| |
| // Whether or not the window has been shown before. This is used to determine |
| // sizing and placement. This is different from checking whether the window |
| // components has been initialized. |
| bool has_been_shown_ = false; |
| |
| // The upper and lower bounds of |current_size_|. These are determined by the |
| // size of the primary display work area when Picture-in-Picture is initiated. |
| // TODO(apacible): Update these bounds when the display the window is on |
| // changes. http://crbug.com/819673 |
| gfx::Size min_size_; |
| gfx::Size max_size_; |
| |
| // The natural size of the video to show. This is used to compute sizing and |
| // ensuring factors such as aspect ratio is maintained. |
| gfx::Size natural_size_; |
| |
| // Automatically hides the controls a few seconds after user tap gesture. |
| base::RetainingOneShotTimer hide_controls_timer_; |
| |
| // Automatically hides the title view a few seconds after the window is first |
| // shown. |
| base::OneShotTimer initial_title_hide_timer_; |
| |
| // Used to track movement of the window. The mouse movement and the window |
| // movement can cause the overlay to flicker, because mouse movement shows |
| // the overlay while the window movement hides the overlay. A timer is used |
| // to prevent the rapid changes between states. |
| base::RetainingOneShotTimer enable_controls_after_move_timer_; |
| bool is_moving_ = false; |
| |
| struct VisibilityStatus { |
| bool is_visible; |
| bool should_animate; |
| }; |
| std::optional<VisibilityStatus> queued_controls_visibility_status_; |
| |
| // Timer used to update controls bounds. |
| std::unique_ptr<base::OneShotTimer> update_controls_bounds_timer_; |
| |
| // If set, controls will always either be shown or hidden, instead of showing |
| // and hiding automatically. Only used for testing via |
| // ForceControlsVisibleForTesting(). |
| std::optional<bool> force_controls_visible_; |
| |
| // If set, title and scrim will always either be shown or hidden, instead of |
| // showing and hiding automatically. Only used for testing via |
| // ForceControlsVisibleForTesting(). |
| std::optional<bool> force_title_and_scrim_visible_; |
| |
| // Views to be shown. The views are first temporarily owned by view_holder_, |
| // then passed to this widget's ContentsView which takes ownership. |
| raw_ptr<views::View> window_background_view_ = nullptr; |
| raw_ptr<views::View> video_view_ = nullptr; |
| raw_ptr<views::View> controls_scrim_view_ = nullptr; |
| raw_ptr<views::View> controls_top_scrim_view_ = nullptr; |
| raw_ptr<views::View> controls_bottom_scrim_view_ = nullptr; |
| raw_ptr<views::View> controls_container_view_ = nullptr; |
| raw_ptr<views::View> playback_controls_container_view_ = nullptr; |
| raw_ptr<views::View> vc_controls_container_view_ = nullptr; |
| raw_ptr<views::ImageView> favicon_view_ = nullptr; |
| raw_ptr<views::Label> origin_ = nullptr; |
| raw_ptr<CloseImageButton> close_controls_view_ = nullptr; |
| raw_ptr<OverlayWindowMinimizeButton> minimize_button_ = nullptr; |
| raw_ptr<OverlayWindowBackToTabButton> back_to_tab_button_ = nullptr; |
| raw_ptr<BackToTabLabelButton> back_to_tab_label_button_ = nullptr; |
| raw_ptr<SimpleOverlayWindowImageButton> previous_track_controls_view_ = |
| nullptr; |
| raw_ptr<PlaybackImageButton> play_pause_controls_view_ = nullptr; |
| raw_ptr<SimpleOverlayWindowImageButton> replay_10_seconds_button_ = nullptr; |
| raw_ptr<SimpleOverlayWindowImageButton> forward_10_seconds_button_ = nullptr; |
| raw_ptr<SimpleOverlayWindowImageButton> next_track_controls_view_ = nullptr; |
| raw_ptr<SkipAdLabelButton> skip_ad_controls_view_ = nullptr; |
| raw_ptr<ResizeHandleButton> resize_handle_view_ = nullptr; |
| raw_ptr<ToggleMicrophoneButton> toggle_microphone_button_ = nullptr; |
| raw_ptr<ToggleCameraButton> toggle_camera_button_ = nullptr; |
| raw_ptr<HangUpButton> hang_up_button_ = nullptr; |
| raw_ptr<global_media_controls::MediaProgressView> progress_view_ = nullptr; |
| raw_ptr<views::Label> timestamp_ = nullptr; |
| raw_ptr<views::Label> live_status_ = nullptr; |
| raw_ptr<OverlayWindowLiveCaptionButton> live_caption_button_ = nullptr; |
| raw_ptr<OverlayWindowLiveCaptionDialog> live_caption_dialog_ = nullptr; |
| raw_ptr<AutoPipSettingOverlayView> overlay_view_ = nullptr; |
| raw_ptr<views::View> title_view_ = nullptr; |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| // Generates a nine patch layer painted with a highlight border for ChromeOS |
| // Ash. |
| std::unique_ptr<HighlightBorderOverlay> highlight_border_overlay_; |
| #endif |
| |
| // Current playback state on the video in Picture-in-Picture window. It is |
| // used to toggle play/pause/replay button. |
| PlaybackState playback_state_for_testing_ = kEndOfVideo; |
| |
| // True if the Media Session "skipad" action is handled by the website. |
| bool show_skip_ad_button_ = false; |
| |
| // True if the Media Session "nexttrack" action is handled by the website. |
| bool show_next_track_button_ = false; |
| |
| // True if the Media Session "previoustrack" action is handled by the website. |
| bool show_previous_track_button_ = false; |
| |
| // True if the Media Session "togglemicrophone" action is handled by the |
| // website. |
| bool show_toggle_microphone_button_ = false; |
| |
| // True if the Media Session "togglecamera" action is handled by the website. |
| bool show_toggle_camera_button_ = false; |
| |
| // True if the Media Session "hangup" action is handled by the website. |
| bool show_hang_up_button_ = false; |
| |
| // True if the Media Session "previousslide" action is handled by the website. |
| bool show_previous_slide_button_ = false; |
| |
| // True if the Media Session "nextslide" action is handled by the website. |
| bool show_next_slide_button_ = false; |
| |
| // Tracks whether or not the progress bar is currently being dragged by the |
| // user. Used to ensure that controls don't hide while dragging. |
| global_media_controls::DragState progress_view_drag_state_ = |
| global_media_controls::DragState::kDragEnded; |
| |
| // Tracks the current position of media playback. Used for seeking to the |
| // proper time when the user interacts with the progress bar. |
| media_session::MediaPosition position_; |
| |
| // True if the video in the picture-in-picture window is live. |
| bool is_live_ = false; |
| |
| // Whether or not the current frame sink for the surface displayed in the |
| // |video_view_| is registered as the child of the overlay window frame sink. |
| bool has_registered_frame_sink_hierarchy_ = false; |
| |
| // Used to tuck/untuck this widget into the side of the screen. |
| std::unique_ptr<PictureInPictureTucker> tucker_; |
| bool is_tucking_forced_ = false; |
| |
| // Used for when the controls change visibility. |
| std::unique_ptr<OverlayControlsFadeAnimation> fade_animation_; |
| |
| // Used for when the title changes visibility. The title and controls top |
| // scrim must be animated together. |
| std::unique_ptr<OverlayControlsFadeAnimation> |
| title_and_top_scrim_fade_animation_; |
| |
| // Callback to get / create an overlay view. This is a callback to let tests |
| // provide alternate implementations. |
| GetOverlayViewCb get_overlay_view_cb_; |
| |
| // Used to animate the Picture-in-Picture window creation. |
| std::unique_ptr<PictureInPictureWidgetFadeAnimator> fade_animator_; |
| |
| // Set to true when the user has interacted with the overlay window in an |
| // intentional manner. False otherwise. For example, hovering the cursor over |
| // the overlay window is not considered meeting user interaction. |
| bool meets_user_interaction_ = false; |
| |
| // Set to true if the user interacts with the window before the |
| // `initial_title_hide_timer_` fires. |
| bool user_interacted_before_timer_fired_ = false; |
| |
| base::WeakPtrFactory<VideoOverlayWindowViews> weak_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_UI_VIEWS_OVERLAY_VIDEO_OVERLAY_WINDOW_VIEWS_H_ |