chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc

/*
 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"

#include "base/auto_reset.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/user_metrics_action.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/events/gesture_event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/html/media/html_audio_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/core/html/track/text_track.h"
#include "third_party/blink/renderer/core/html/track/text_track_container.h"
#include "third_party/blink/renderer/core/html/track/text_track_list.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_button_panel_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_consts.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_enclosure_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_panel_enclosure_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_volume_control_container_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h"
#include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
#include "ui/gfx/geometry/size.h"

namespace blink {

namespace {

// (2px left border + 6px left padding + 56px button + 6px right padding + 2px
// right border) = 72px.
constexpr int kMinWidthForOverlayPlayButton =;

constexpr int kMinScrubbingMessageWidth =;

const char* const kStateCSSClasses[8] =;

// The padding in pixels inside the button panel.
constexpr int kAudioButtonPadding =;
constexpr int kVideoButtonPadding =;

const char kShowDefaultPosterCSSClass[] =;
const char kActAsAudioControlsCSSClass[] =;
const char kScrubbingMessageCSSClass[] =;
const char kTestModeCSSClass[] =;

// The delay between two taps to be recognized as a double tap gesture.
constexpr base::TimeDelta kDoubleTapDelay =;

// The time user have to hover on mute button to show volume slider.
// If this value is changed, you need to change the corresponding value in
// media_controls_impl_test.cc
constexpr base::TimeDelta kTimeToShowVolumeSlider =;
constexpr base::TimeDelta kTimeToShowVolumeSliderTest =;

// The number of seconds to jump when double tapping.
constexpr int kNumberOfSecondsToJump =;

void MaybeParserAppendChild(Element* parent, Element* child) {}

bool ShouldShowPlaybackSpeedButton(HTMLMediaElement& media_element) {}

bool ShouldShowPictureInPictureButton(HTMLMediaElement& media_element) {}

bool ShouldShowCastButton(HTMLMediaElement& media_element) {}

bool ShouldShowCastOverlayButton(HTMLMediaElement& media_element) {}

bool PreferHiddenVolumeControls(const Document& document) {}

// If you change this value, then also update the corresponding value in
// web_tests/media/media-controls.js.
constexpr base::TimeDelta kTimeWithoutMouseMovementBeforeHidingMediaControls =;

base::TimeDelta GetTimeWithoutMouseMovementBeforeHidingMediaControls() {}

}  // namespace

class MediaControlsImpl::BatchedControlUpdate {};

// Count of number open batches for controls visibility.
int MediaControlsImpl::BatchedControlUpdate::batch_depth_ =;

class MediaControlsImpl::MediaControlsResizeObserverDelegate final
    : public ResizeObserver::Delegate {};

// Observes changes to the HTMLMediaElement attributes that affect controls.
class MediaControlsImpl::MediaElementMutationCallback
    : public MutationObserver::Delegate {};

bool MediaControlsImpl::IsTouchEvent(Event* event) {}

MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& media_element)
    :{}

MediaControlsImpl* MediaControlsImpl::Create(HTMLMediaElement& media_element,
                                             ShadowRoot& shadow_root) {}

// The media controls DOM structure looks like:
//
// MediaControlsImpl
//     (-webkit-media-controls)
// +-MediaControlLoadingPanelElement
// |    (-internal-media-controls-loading-panel)
// +-MediaControlOverlayEnclosureElement
// |    (-webkit-media-controls-overlay-enclosure)
// | \-MediaControlCastButtonElement
// |     (-internal-media-controls-overlay-cast-button)
// \-MediaControlPanelEnclosureElement
//   |    (-webkit-media-controls-enclosure)
//   \-MediaControlPanelElement
//     |    (-webkit-media-controls-panel)
//     +-MediaControlScrubbingMessageElement
//     |  (-internal-media-controls-scrubbing-message)
//     |  {if is video element}
//     +-MediaControlOverlayPlayButtonElement
//     |  (-webkit-media-controls-overlay-play-button)
//     |  {if mediaControlsOverlayPlayButtonEnabled}
//     +-MediaControlButtonPanelElement
//     |  |  (-internal-media-controls-button-panel)
//     |  |  <video> only, otherwise children are directly attached to parent
//     |  +-MediaControlPlayButtonElement
//     |  |    (-webkit-media-controls-play-button)
//     |  |    {if !mediaControlsOverlayPlayButtonEnabled}
//     |  +-MediaControlCurrentTimeDisplayElement
//     |  |    (-webkit-media-controls-current-time-display)
//     |  +-MediaControlRemainingTimeDisplayElement
//     |  |    (-webkit-media-controls-time-remaining-display)
//     |  |    {if !IsLivePlayback}
//     |  +-HTMLDivElement
//     |  |    (-internal-media-controls-button-spacer)
//     |  |    {if is video element}
//     |  +-MediaControlVolumeControlContainerElement
//     |  |  |  (-webkit-media-controls-volume-control-container)
//     |  |  +-HTMLDivElement
//     |  |  |    (-webkit-media-controls-volume-control-hover-background)
//     |  |  +-MediaControlMuteButtonElement
//     |  |  |    (-webkit-media-controls-mute-button)
//     |  |  +-MediaControlVolumeSliderElement
//     |  |       (-webkit-media-controls-volume-slider)
//     |  +-MediaControlPictureInPictureButtonElement
//     |  |    (-webkit-media-controls-picture-in-picture-button)
//     |  +-MediaControlFullscreenButtonElement
//     |  |    (-webkit-media-controls-fullscreen-button)
//     \-MediaControlTimelineElement
//          (-webkit-media-controls-timeline)
//          {if !IsLivePlayback}
// +-MediaControlTextTrackListElement
// |    (-internal-media-controls-text-track-list)
// | {for each renderable text track}
//  \-MediaControlTextTrackListItem
//  |   (-internal-media-controls-text-track-list-item)
//  +-MediaControlTextTrackListItemInput
//  |    (-internal-media-controls-text-track-list-item-input)
//  +-MediaControlTextTrackListItemCaptions
//  |    (-internal-media-controls-text-track-list-kind-captions)
//  +-MediaControlTextTrackListItemSubtitles
//       (-internal-media-controls-text-track-list-kind-subtitles)
// +-MediaControlDisplayCutoutFullscreenElement
//       (-internal-media-controls-display-cutout-fullscreen-button)
void MediaControlsImpl::InitializeControls() {}

void MediaControlsImpl::PopulatePanel() {}

void MediaControlsImpl::AttachHoverBackground(Element* element) {}

Node::InsertionNotificationRequest MediaControlsImpl::InsertedInto(
    ContainerNode& root) {}

void MediaControlsImpl::UpdateCSSClassFromState() {}

void MediaControlsImpl::SetClass(const String& class_name,
                                 bool should_have_class) {}

MediaControlsImpl::ControlsState MediaControlsImpl::State() const {}

void MediaControlsImpl::RemovedFrom(ContainerNode& insertion_point) {}

void MediaControlsImpl::Reset() {}

void MediaControlsImpl::UpdateTimeIndicators(bool suppress_aria) {}

void MediaControlsImpl::OnControlsListUpdated() {}

LayoutObject* MediaControlsImpl::PanelLayoutObject() {}

LayoutObject* MediaControlsImpl::TimelineLayoutObject() {}

LayoutObject* MediaControlsImpl::ButtonPanelLayoutObject() {}

LayoutObject* MediaControlsImpl::ContainerLayoutObject() {}

void MediaControlsImpl::SetTestMode(bool enable) {}

void MediaControlsImpl::MaybeShow() {}

void MediaControlsImpl::Hide() {}

bool MediaControlsImpl::IsVisible() const {}

void MediaControlsImpl::MaybeShowOverlayPlayButton() {}

void MediaControlsImpl::MakeOpaque() {}

void MediaControlsImpl::MakeOpaqueFromPointerEvent() {}

void MediaControlsImpl::MakeTransparent() {}

bool MediaControlsImpl::ShouldHideMediaControls(unsigned behavior_flags) const {}

bool MediaControlsImpl::AreVideoControlsHovered() const {}

void MediaControlsImpl::UpdatePlayState() {}

HTMLDivElement* MediaControlsImpl::PanelElement() {}

HTMLDivElement* MediaControlsImpl::ButtonPanelElement() {}

void MediaControlsImpl::BeginScrubbing(bool is_touch_event) {}

void MediaControlsImpl::EndScrubbing() {}

void MediaControlsImpl::UpdateCurrentTimeDisplay() {}

void MediaControlsImpl::ToggleTextTrackList() {}

bool MediaControlsImpl::TextTrackListIsWanted() {}

void MediaControlsImpl::TogglePlaybackSpeedList() {}

bool MediaControlsImpl::PlaybackSpeedListIsWanted() {}

MediaControlsTextTrackManager& MediaControlsImpl::GetTextTrackManager() {}

void MediaControlsImpl::RefreshCastButtonVisibility() {}

void MediaControlsImpl::RefreshCastButtonVisibilityWithoutUpdate() {}

void MediaControlsImpl::ShowOverlayCastButtonIfNeeded() {}

void MediaControlsImpl::EnterFullscreen() {}

void MediaControlsImpl::ExitFullscreen() {}

bool MediaControlsImpl::IsFullscreenEnabled() const {}

void MediaControlsImpl::RemotePlaybackStateChanged() {}

void MediaControlsImpl::UpdateOverflowMenuWanted() const {}

// This method is responsible for adding css class to overflow menu list
// items to achieve the animation that items appears one after another when
// open the overflow menu.
void MediaControlsImpl::UpdateOverflowMenuItemCSSClass() const {}

void MediaControlsImpl::UpdateScrubbingMessageFits() const {}

void MediaControlsImpl::UpdateSizingCSSClass() {}

void MediaControlsImpl::MaybeToggleControlsFromTap() {}

void MediaControlsImpl::OnAccessibleFocus() {}

void MediaControlsImpl::OnAccessibleBlur() {}

void MediaControlsImpl::DefaultEventHandler(Event& event) {}

void MediaControlsImpl::HandlePointerEvent(Event* event) {}

void MediaControlsImpl::HandleClickEvent(Event* event) {}

void MediaControlsImpl::HandleTouchEvent(Event* event) {}

void MediaControlsImpl::EnsureAnimatedArrowContainer() {}

void MediaControlsImpl::MaybeJump(int seconds) {}

bool MediaControlsImpl::IsOnLeftSide(Event* event) {}

void MediaControlsImpl::TapTimerFired(TimerBase*) {}

void MediaControlsImpl::HideMediaControlsTimerFired(TimerBase*) {}

void MediaControlsImpl::StartHideMediaControlsIfNecessary() {}

void MediaControlsImpl::StartHideMediaControlsTimer() {}

void MediaControlsImpl::StopHideMediaControlsTimer() {}

void MediaControlsImpl::ResetHideMediaControlsTimer() {}

void MediaControlsImpl::HideCursor() {}

void MediaControlsImpl::ShowCursor() {}

bool MediaControlsImpl::ContainsRelatedTarget(Event* event) {}

void MediaControlsImpl::OnVolumeChange() {}

void MediaControlsImpl::OnFocusIn() {}

void MediaControlsImpl::OnTimeUpdate() {}

void MediaControlsImpl::OnDurationChange() {}

void MediaControlsImpl::OnPlay() {}

void MediaControlsImpl::OnPlaying() {}

void MediaControlsImpl::OnPause() {}

void MediaControlsImpl::OnSeeking() {}

void MediaControlsImpl::OnSeeked() {}

void MediaControlsImpl::OnTextTracksAddedOrRemoved() {}

void MediaControlsImpl::OnTextTracksChanged() {}

void MediaControlsImpl::OnError() {}

void MediaControlsImpl::OnLoadedMetadata() {}

void MediaControlsImpl::OnEnteredFullscreen() {}

void MediaControlsImpl::OnExitedFullscreen() {}

void MediaControlsImpl::OnPictureInPictureChanged() {}

void MediaControlsImpl::OnPanelKeypress() {}

void MediaControlsImpl::NotifyElementSizeChanged(DOMRectReadOnly* new_size) {}

void MediaControlsImpl::ElementSizeChangedTimerFired(TimerBase*) {}

void MediaControlsImpl::OnLoadingProgress() {}

void MediaControlsImpl::ComputeWhichControlsFit() {}

void MediaControlsImpl::MaybeRecordElementsDisplayed() const {}

const MediaControlCurrentTimeDisplayElement&
MediaControlsImpl::CurrentTimeDisplay() const {}

const MediaControlRemainingTimeDisplayElement&
MediaControlsImpl::RemainingTimeDisplay() const {}

MediaControlToggleClosedCaptionsButtonElement&
MediaControlsImpl::ToggleClosedCaptions() {}

bool MediaControlsImpl::ShouldActAsAudioControls() const {}

void MediaControlsImpl::StartActingAsAudioControls() {}

void MediaControlsImpl::StopActingAsAudioControls() {}

void MediaControlsImpl::UpdateActingAsAudioControls() {}

bool MediaControlsImpl::ShouldShowAudioControls() const {}

bool MediaControlsImpl::ShouldShowVideoControls() const {}

bool MediaControlsImpl::IsLivePlayback() const {}

void MediaControlsImpl::NetworkStateChanged() {}

void MediaControlsImpl::OpenOverflowMenu() {}

void MediaControlsImpl::CloseOverflowMenu() {}

bool MediaControlsImpl::OverflowMenuIsWanted() {}

bool MediaControlsImpl::OverflowMenuVisible() {}

void MediaControlsImpl::ToggleOverflowMenu() {}

void MediaControlsImpl::HidePopupMenu() {}

void MediaControlsImpl::VolumeSliderWantedTimerFired(TimerBase*) {}

void MediaControlsImpl::OpenVolumeSliderIfNecessary() {}

void MediaControlsImpl::CloseVolumeSliderIfNecessary() {}

bool MediaControlsImpl::ShouldOpenVolumeSlider() const {}

bool MediaControlsImpl::ShouldCloseVolumeSlider() const {}

const MediaControlOverflowMenuButtonElement& MediaControlsImpl::OverflowButton()
    const {}

MediaControlOverflowMenuButtonElement& MediaControlsImpl::OverflowButton() {}

void MediaControlsImpl::OnWaiting() {}

void MediaControlsImpl::OnLoadedData() {}

HTMLVideoElement& MediaControlsImpl::VideoElement() {}

void MediaControlsImpl::Trace(Visitor* visitor) const {}

}  // namespace blink