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

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

#include <limits>
#include <memory>

#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/common/widget/screen_info.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/mojom/widget/screen_orientation.mojom-blink.h"
#include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_parser.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/text.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/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.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_current_time_display_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_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_play_button_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_timeline_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h"
#include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/web_test_support.h"

// The MediaTimelineWidths histogram suffix expected to be encountered in these
// tests.
#define TIMELINE_W "256_511"

namespace blink {

namespace {

class FakeChromeClient : public EmptyChromeClient {
 public:
  FakeChromeClient()
      : screen_info_({.orientation_type =
                          mojom::blink::ScreenOrientation::kLandscapePrimary}) {
  }

  // ChromeClient overrides.
  const ScreenInfo& GetScreenInfo(LocalFrame&) const override {
    return screen_info_;
  }

 private:
  const ScreenInfo screen_info_;
};

class MockWebMediaPlayerForImpl : public EmptyWebMediaPlayer {
 public:
  // WebMediaPlayer overrides:
  WebTimeRanges Seekable() const override { return seekable_; }
  bool HasVideo() const override { return true; }
  bool HasAudio() const override { return has_audio_; }
  SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
    return SurfaceLayerMode::kAlways;
  }

  bool has_audio_ = false;
  WebTimeRanges seekable_;
};

class MockLayoutObject : public LayoutObject {
 public:
  MockLayoutObject(Node* node) : LayoutObject(node) {}

  const char* GetName() const override { return "MockLayoutObject"; }
  void UpdateLayout() override {}
  FloatRect LocalBoundingBoxRectForAccessibility() const override {
    return FloatRect();
  }
};

class StubLocalFrameClientForImpl : public EmptyLocalFrameClient {
 public:
  std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
      HTMLMediaElement&,
      const WebMediaPlayerSource&,
      WebMediaPlayerClient*) override {
    return std::make_unique<MockWebMediaPlayerForImpl>();
  }

  WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
      HTMLMediaElement& element) override {
    return &RemotePlayback::From(element);
  }
};

Element* GetElementByShadowPseudoId(Node& root_node,
                                    const char* shadow_pseudo_id) {
  for (Element& element : ElementTraversal::DescendantsOf(root_node)) {
    if (element.ShadowPseudoId() == shadow_pseudo_id)
      return &element;
  }
  return nullptr;
}

bool IsElementVisible(Element& element) {
  const CSSPropertyValueSet* inline_style = element.InlineStyle();

  if (!inline_style)
    return element.getAttribute("class") != "transparent";

  if (inline_style->GetPropertyValue(CSSPropertyID::kDisplay) == "none")
    return false;

  if (inline_style->HasProperty(CSSPropertyID::kOpacity) &&
      inline_style->GetPropertyValue(CSSPropertyID::kOpacity).ToDouble() ==
          0.0) {
    return false;
  }

  if (inline_style->GetPropertyValue(CSSPropertyID::kVisibility) == "hidden")
    return false;

  if (Element* parent = element.parentElement())
    return IsElementVisible(*parent);

  return true;
}

void SimulateTransitionEnd(Element& element) {
  element.DispatchEvent(*Event::Create(event_type_names::kTransitionend));
}

// This must match MediaControlDownloadButtonElement::DownloadActionMetrics.
enum DownloadActionMetrics {
  kShown = 0,
  kClicked,
  kCount  // Keep last.
};

}  // namespace

class MediaControlsImplTest : public PageTestBase,
                              private ScopedMediaCastOverlayButtonForTest {
 public:
  MediaControlsImplTest() : ScopedMediaCastOverlayButtonForTest(true) {}

 protected:
  void SetUp() override {
    InitializePage();
  }

  void InitializePage() {
    Page::PageClients clients;
    FillWithEmptyClients(clients);
    clients.chrome_client = MakeGarbageCollected<FakeChromeClient>();
    SetupPageWithClients(&clients,
                         MakeGarbageCollected<StubLocalFrameClientForImpl>());

    GetDocument().write("<video controls>");
    auto& video = To<HTMLVideoElement>(*GetDocument().QuerySelector("video"));
    media_controls_ = static_cast<MediaControlsImpl*>(video.GetMediaControls());

    // Scripts are disabled by default which forces controls to be on.
    GetFrame().GetSettings()->SetScriptEnabled(true);
  }

  void SimulateRouteAvailable() {
    RemotePlayback::From(media_controls_->MediaElement())
        .AvailabilityChangedForTesting(/* screen_is_available */ true);
  }

  void EnsureSizing() {
    // Fire the size-change callback to ensure that the controls have
    // been properly notified of the video size.
    media_controls_->NotifyElementSizeChanged(
        media_controls_->MediaElement().getBoundingClientRect());
  }

  void SimulateHideMediaControlsTimerFired() {
    media_controls_->HideMediaControlsTimerFired(nullptr);
  }

  void SimulateLoadedMetadata() { media_controls_->OnLoadedMetadata(); }

  void SimulateOnSeeking() { media_controls_->OnSeeking(); }
  void SimulateOnSeeked() { media_controls_->OnSeeked(); }

  MediaControlsImpl& MediaControls() { return *media_controls_; }
  MediaControlVolumeSliderElement* VolumeSliderElement() const {
    return media_controls_->volume_slider_;
  }
  MediaControlTimelineElement* TimelineElement() const {
    return media_controls_->timeline_;
  }
  Element* TimelineTrackElement() const {
    if (!TimelineElement())
      return nullptr;
    return &TimelineElement()->GetTrackElement();
  }
  MediaControlCurrentTimeDisplayElement* GetCurrentTimeDisplayElement() const {
    return media_controls_->current_time_display_;
  }
  MediaControlRemainingTimeDisplayElement* GetRemainingTimeDisplayElement()
      const {
    return media_controls_->duration_display_;
  }
  MediaControlMuteButtonElement* MuteButtonElement() const {
    return media_controls_->mute_button_;
  }
  MediaControlCastButtonElement* CastButtonElement() const {
    return media_controls_->cast_button_;
  }
  MediaControlDownloadButtonElement* DownloadButtonElement() const {
    return media_controls_->download_button_;
  }
  MediaControlPlayButtonElement* PlayButtonElement() const {
    return media_controls_->play_button_;
  }
  MediaControlOverflowMenuButtonElement* OverflowMenuButtonElement() const {
    return media_controls_->overflow_menu_;
  }
  MediaControlOverflowMenuListElement* OverflowMenuListElement() const {
    return media_controls_->overflow_list_;
  }

  MockWebMediaPlayerForImpl* WebMediaPlayer() {
    return static_cast<MockWebMediaPlayerForImpl*>(
        MediaControls().MediaElement().GetWebMediaPlayer());
  }

  HistogramTester& GetHistogramTester() { return histogram_tester_; }

  void LoadMediaWithDuration(double duration) {
    MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
    test::RunPendingTasks();
    WebTimeRange time_range(0.0, duration);
    WebMediaPlayer()->seekable_.Assign(&time_range, 1);
    MediaControls().MediaElement().DurationChanged(duration,
                                                   false /* requestSeek */);
    SimulateLoadedMetadata();
  }

  void SetHasAudio(bool has_audio) { WebMediaPlayer()->has_audio_ = has_audio; }

  void ClickOverflowButton() {
    MediaControls()
        .download_button_->OverflowElementForTests()
        ->DispatchSimulatedClick(nullptr);
  }

  void SetReady() {
    MediaControls().MediaElement().SetReadyState(
        HTMLMediaElement::kHaveEnoughData);
  }

  void MouseDownAt(gfx::PointF pos);
  void MouseMoveTo(gfx::PointF pos);
  void MouseUpAt(gfx::PointF pos);

  void GestureTapAt(gfx::PointF pos);
  void GestureDoubleTapAt(gfx::PointF pos);

  bool HasAvailabilityCallbacks(RemotePlayback& remote_playback) {
    return !remote_playback.availability_callbacks_.IsEmpty();
  }

  const String GetDisplayedTime(MediaControlTimeDisplayElement* display) {
    return To<Text>(display->firstChild())->data();
  }

  bool IsOverflowElementVisible(MediaControlInputElement& element) {
    MediaControlInputElement* overflow_element =
        element.OverflowElementForTests();
    if (!overflow_element)
      return false;

    Element* overflow_parent_label = overflow_element->parentElement();
    if (!overflow_parent_label)
      return false;

    const CSSPropertyValueSet* inline_style =
        overflow_parent_label->InlineStyle();
    if (inline_style->GetPropertyValue(CSSPropertyID::kDisplay) == "none")
      return false;

    return true;
  }

 private:
  Persistent<MediaControlsImpl> media_controls_;
  HistogramTester histogram_tester_;
};

void MediaControlsImplTest::MouseDownAt(gfx::PointF pos) {
  WebMouseEvent mouse_down_event(WebInputEvent::Type::kMouseDown,
                                 pos /* client pos */, pos /* screen pos */,
                                 WebPointerProperties::Button::kLeft, 1,
                                 WebInputEvent::Modifiers::kLeftButtonDown,
                                 WebInputEvent::GetStaticTimeStampForTests());
  mouse_down_event.SetFrameScale(1);
  GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
      mouse_down_event);
}

void MediaControlsImplTest::MouseMoveTo(gfx::PointF pos) {
  WebMouseEvent mouse_move_event(WebInputEvent::Type::kMouseMove,
                                 pos /* client pos */, pos /* screen pos */,
                                 WebPointerProperties::Button::kLeft, 1,
                                 WebInputEvent::Modifiers::kLeftButtonDown,
                                 WebInputEvent::GetStaticTimeStampForTests());
  mouse_move_event.SetFrameScale(1);
  GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
      mouse_move_event, {}, {});
}

void MediaControlsImplTest::MouseUpAt(gfx::PointF pos) {
  WebMouseEvent mouse_up_event(
      WebMouseEvent::Type::kMouseUp, pos /* client pos */, pos /* screen pos */,
      WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
      WebInputEvent::GetStaticTimeStampForTests());
  mouse_up_event.SetFrameScale(1);
  GetDocument().GetFrame()->GetEventHandler().HandleMouseReleaseEvent(
      mouse_up_event);
}

void MediaControlsImplTest::GestureTapAt(gfx::PointF pos) {
  WebGestureEvent gesture_tap_event(
      WebInputEvent::Type::kGestureTap, WebInputEvent::kNoModifiers,
      WebInputEvent::GetStaticTimeStampForTests());

  // Adjust |pos| by current frame scale.
  float frame_scale = GetDocument().GetFrame()->PageZoomFactor();
  gesture_tap_event.SetFrameScale(frame_scale);
  pos.Scale(frame_scale);
  gesture_tap_event.SetPositionInWidget(pos);

  // Fire the event.
  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(
      gesture_tap_event);
}

void MediaControlsImplTest::GestureDoubleTapAt(gfx::PointF pos) {
  GestureTapAt(pos);
  GestureTapAt(pos);
}

TEST_F(MediaControlsImplTest, HideAndShow) {
  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  ASSERT_TRUE(IsElementVisible(*panel));
  MediaControls().Hide();
  ASSERT_FALSE(IsElementVisible(*panel));
  MediaControls().MaybeShow();
  ASSERT_TRUE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTest, Reset) {
  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  ASSERT_TRUE(IsElementVisible(*panel));
  MediaControls().Reset();
  ASSERT_TRUE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTest, HideAndReset) {
  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  ASSERT_TRUE(IsElementVisible(*panel));
  MediaControls().Hide();
  ASSERT_FALSE(IsElementVisible(*panel));
  MediaControls().Reset();
  ASSERT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTest, ResetDoesNotTriggerInitialLayout) {
  Document& document = this->GetDocument();
  int old_element_count = document.GetStyleEngine().StyleForElementCount();
  // Also assert that there are no layouts yet.
  ASSERT_EQ(0, old_element_count);
  MediaControls().Reset();
  int new_element_count = document.GetStyleEngine().StyleForElementCount();
  ASSERT_EQ(old_element_count, new_element_count);
}

TEST_F(MediaControlsImplTest, CastButtonRequiresRoute) {
  EnsureSizing();

  MediaControlCastButtonElement* cast_button = CastButtonElement();
  ASSERT_NE(nullptr, cast_button);

  ASSERT_FALSE(IsOverflowElementVisible(*cast_button));

  SimulateRouteAvailable();
  ASSERT_TRUE(IsOverflowElementVisible(*cast_button));
}

TEST_F(MediaControlsImplTest, CastButtonDisableRemotePlaybackAttr) {
  EnsureSizing();

  MediaControlCastButtonElement* cast_button = CastButtonElement();
  ASSERT_NE(nullptr, cast_button);

  ASSERT_FALSE(IsOverflowElementVisible(*cast_button));
  SimulateRouteAvailable();
  ASSERT_TRUE(IsOverflowElementVisible(*cast_button));

  MediaControls().MediaElement().SetBooleanAttribute(
      html_names::kDisableremoteplaybackAttr, true);
  test::RunPendingTasks();
  ASSERT_FALSE(IsOverflowElementVisible(*cast_button));

  MediaControls().MediaElement().SetBooleanAttribute(
      html_names::kDisableremoteplaybackAttr, false);
  test::RunPendingTasks();
  ASSERT_TRUE(IsOverflowElementVisible(*cast_button));
}

TEST_F(MediaControlsImplTest, CastOverlayDefault) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  SimulateRouteAvailable();
  ASSERT_TRUE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, CastOverlayDisabled) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  ScopedMediaCastOverlayButtonForTest media_cast_overlay_button(false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  SimulateRouteAvailable();
  ASSERT_FALSE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, CastOverlayDisableRemotePlaybackAttr) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  ASSERT_FALSE(IsElementVisible(*cast_overlay_button));
  SimulateRouteAvailable();
  ASSERT_TRUE(IsElementVisible(*cast_overlay_button));

  MediaControls().MediaElement().SetBooleanAttribute(
      html_names::kDisableremoteplaybackAttr, true);
  test::RunPendingTasks();
  ASSERT_FALSE(IsElementVisible(*cast_overlay_button));

  MediaControls().MediaElement().SetBooleanAttribute(
      html_names::kDisableremoteplaybackAttr, false);
  test::RunPendingTasks();
  ASSERT_TRUE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, CastOverlayMediaControlsDisabled) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));
  SimulateRouteAvailable();
  EXPECT_TRUE(IsElementVisible(*cast_overlay_button));

  GetDocument().GetSettings()->SetMediaControlsEnabled(false);
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));

  GetDocument().GetSettings()->SetMediaControlsEnabled(true);
  EXPECT_TRUE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, CastOverlayDisabledMediaControlsDisabled) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  ScopedMediaCastOverlayButtonForTest media_cast_overlay_button(false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));
  SimulateRouteAvailable();
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));

  GetDocument().GetSettings()->SetMediaControlsEnabled(false);
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));

  GetDocument().GetSettings()->SetMediaControlsEnabled(true);
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, KeepControlsVisibleIfOverflowListVisible) {
  Element* overflow_list = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overflow-menu-list");
  ASSERT_NE(nullptr, overflow_list);

  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();
  test::RunPendingTasks();

  MediaControls().MaybeShow();
  MediaControls().ToggleOverflowMenu();
  EXPECT_TRUE(IsElementVisible(*overflow_list));

  SimulateHideMediaControlsTimerFired();
  EXPECT_TRUE(IsElementVisible(*overflow_list));
  EXPECT_TRUE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTest, DownloadButtonDisplayed) {
  EnsureSizing();

  MediaControlDownloadButtonElement* download_button = DownloadButtonElement();
  ASSERT_NE(nullptr, download_button);

  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
  test::RunPendingTasks();
  SimulateLoadedMetadata();

  // Download button should normally be displayed.
  EXPECT_TRUE(IsOverflowElementVisible(*download_button));
}

TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedEmptyUrl) {
  EnsureSizing();

  MediaControlDownloadButtonElement* download_button = DownloadButtonElement();
  ASSERT_NE(nullptr, download_button);

  // Download button should not be displayed when URL is empty.
  MediaControls().MediaElement().SetSrc("");
  test::RunPendingTasks();
  SimulateLoadedMetadata();
  EXPECT_FALSE(IsOverflowElementVisible(*download_button));
}

TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedInfiniteDuration) {
  EnsureSizing();

  MediaControlDownloadButtonElement* download_button = DownloadButtonElement();
  ASSERT_NE(nullptr, download_button);

  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
  test::RunPendingTasks();

  // Download button should not be displayed when duration is infinite.
  MediaControls().MediaElement().DurationChanged(
      std::numeric_limits<double>::infinity(), false /* requestSeek */);
  SimulateLoadedMetadata();
  EXPECT_FALSE(IsOverflowElementVisible(*download_button));

  // Download button should be shown if the duration changes back to finite.
  MediaControls().MediaElement().DurationChanged(20.0f,
                                                 false /* requestSeek */);
  SimulateLoadedMetadata();
  EXPECT_TRUE(IsOverflowElementVisible(*download_button));
}

TEST_F(MediaControlsImplTest, DownloadButtonNotDisplayedHLS) {
  EnsureSizing();

  MediaControlDownloadButtonElement* download_button = DownloadButtonElement();
  ASSERT_NE(nullptr, download_button);

  // Download button should not be displayed for HLS streams.
  MediaControls().MediaElement().SetSrc("https://example.com/foo.m3u8");
  test::RunPendingTasks();
  SimulateLoadedMetadata();
  EXPECT_FALSE(IsOverflowElementVisible(*download_button));
}

TEST_F(MediaControlsImplTest, TimelineSeekToRoundedEnd) {
  EnsureSizing();

  // Tests the case where the real length of the video, |exact_duration|, gets
  // rounded up slightly to |rounded_up_duration| when setting the timeline's
  // |max| attribute (crbug.com/695065).
  double exact_duration = 596.586667;
  double rounded_up_duration = 596.586667;
  LoadMediaWithDuration(exact_duration);

  // Simulate a click slightly past the end of the track of the timeline's
  // underlying <input type="range">. This would set the |value| to the |max|
  // attribute, which can be slightly rounded relative to the duration.
  MediaControlTimelineElement* timeline = TimelineElement();
  timeline->setValueAsNumber(rounded_up_duration, ASSERT_NO_EXCEPTION);
  ASSERT_EQ(rounded_up_duration, timeline->valueAsNumber());
  EXPECT_EQ(0.0, MediaControls().MediaElement().currentTime());
  timeline->DispatchInputEvent();
  EXPECT_EQ(exact_duration, MediaControls().MediaElement().currentTime());
}

TEST_F(MediaControlsImplTest, TimelineImmediatelyUpdatesCurrentTime) {
  EnsureSizing();

  MediaControlCurrentTimeDisplayElement* current_time_display =
      GetCurrentTimeDisplayElement();
  double duration = 600;
  LoadMediaWithDuration(duration);

  // Simulate seeking the underlying range to 50%. Current time display should
  // update synchronously (rather than waiting for media to finish seeking).
  TimelineElement()->setValueAsNumber(duration / 2, ASSERT_NO_EXCEPTION);
  TimelineElement()->DispatchInputEvent();
  EXPECT_EQ(duration / 2, current_time_display->CurrentValue());
}

TEST_F(MediaControlsImplTest, TimeIndicatorsUpdatedOnSeeking) {
  EnsureSizing();

  MediaControlCurrentTimeDisplayElement* current_time_display =
      GetCurrentTimeDisplayElement();
  MediaControlTimelineElement* timeline = TimelineElement();
  double duration = 1000;
  LoadMediaWithDuration(duration);

  EXPECT_EQ(0, current_time_display->CurrentValue());
  EXPECT_EQ(0, timeline->valueAsNumber());

  MediaControls().MediaElement().setCurrentTime(duration / 4);

  // Time indicators are not yet updated.
  EXPECT_EQ(0, current_time_display->CurrentValue());
  EXPECT_EQ(0, timeline->valueAsNumber());

  SimulateOnSeeking();

  // The time indicators should be updated immediately when the 'seeking' event
  // is fired.
  EXPECT_EQ(duration / 4, current_time_display->CurrentValue());
  EXPECT_EQ(duration / 4, timeline->valueAsNumber());
}

TEST_F(MediaControlsImplTest, TimeIsCorrectlyFormatted) {
  struct {
    double time;
    String expected_result;
  } tests[] = {
      {-3661, "-1:01:01"},   {-1, "-0:01"},     {0, "0:00"},
      {1, "0:01"},           {15, "0:15"},      {125, "2:05"},
      {615, "10:15"},        {3666, "1:01:06"}, {75123, "20:52:03"},
      {360600, "100:10:00"},
  };

  double duration = 360600;  // Long enough to check each of the tests.
  LoadMediaWithDuration(duration);
  EnsureSizing();
  test::RunPendingTasks();

  MediaControlCurrentTimeDisplayElement* current_display =
      GetCurrentTimeDisplayElement();
  MediaControlRemainingTimeDisplayElement* duration_display =
      GetRemainingTimeDisplayElement();

  // The value and format of the duration display should be correct.
  EXPECT_EQ(360600, duration_display->CurrentValue());
  EXPECT_EQ("/ 100:10:00", GetDisplayedTime(duration_display));

  for (const auto& testcase : tests) {
    current_display->SetCurrentValue(testcase.time);

    // Current value should be updated.
    EXPECT_EQ(testcase.time, current_display->CurrentValue());

    // Display text should be updated and correctly formatted.
    EXPECT_EQ(testcase.expected_result, GetDisplayedTime(current_display));
  }
}

namespace {

class MediaControlsImplTestWithMockScheduler : public MediaControlsImplTest {
 public:
  MediaControlsImplTestWithMockScheduler() { EnablePlatform(); }

 protected:
  void SetUp() override {
    // DocumentParserTiming has DCHECKS to make sure time > 0.0.
    platform()->AdvanceClockSeconds(1);
    platform()->SetAutoAdvanceNowToPendingTasks(false);

    MediaControlsImplTest::SetUp();
  }

  void TearDown() override {
    platform()->SetAutoAdvanceNowToPendingTasks(true);
  }

  void ToggleOverflowMenu() {
    MediaControls().ToggleOverflowMenu();
    platform()->RunUntilIdle();
  }

  bool IsCursorHidden() {
    const CSSPropertyValueSet* style = MediaControls().InlineStyle();
    if (!style)
      return false;
    return style->GetPropertyValue(CSSPropertyID::kCursor) == "none";
  }
};

}  // namespace

TEST_F(MediaControlsImplTestWithMockScheduler, SeekingShowsControls) {
  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  // Hide the controls to start.
  MediaControls().Hide();
  EXPECT_FALSE(IsElementVisible(*panel));

  // Seeking should cause the controls to become visible.
  SimulateOnSeeking();
  EXPECT_TRUE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       SeekingDoesNotShowControlsWhenNoControlsAttr) {
  Element* panel = GetElementByShadowPseudoId(MediaControls(),
                                              "-webkit-media-controls-panel");
  ASSERT_NE(nullptr, panel);

  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  // Hide the controls to start.
  MediaControls().Hide();
  EXPECT_FALSE(IsElementVisible(*panel));

  // Seeking should not cause the controls to become visible because the
  // controls attribute is not set.
  SimulateOnSeeking();
  EXPECT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       ControlsRemainVisibleDuringKeyboardInteraction) {
  EnsureSizing();

  Element* panel = MediaControls().PanelElement();

  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  // Controls start out visible.
  EXPECT_TRUE(IsElementVisible(*panel));

  // Tabbing between controls prevents controls from hiding.
  platform()->RunForPeriodSeconds(2);
  MuteButtonElement()->DispatchEvent(*Event::CreateBubble("focusin"));
  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  // Seeking on the timeline or volume bar prevents controls from hiding.
  TimelineElement()->DispatchEvent(*Event::CreateBubble("input"));
  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  // Pressing a key prevents controls from hiding.
  MuteButtonElement()->DispatchEvent(*Event::CreateBubble("keypress"));
  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  // Once user interaction stops, controls can hide.
  platform()->RunForPeriodSeconds(2);
  SimulateTransitionEnd(*panel);
  EXPECT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       ControlsHideAfterFocusedAndMouseMovement) {
  EnsureSizing();

  Element* panel = MediaControls().PanelElement();
  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  // Controls start out visible
  EXPECT_TRUE(IsElementVisible(*panel));
  platform()->RunForPeriodSeconds(1);

  // Mouse move while focused
  MediaControls().DispatchEvent(*Event::Create("focusin"));
  MediaControls().MediaElement().SetFocused(true,
                                            mojom::blink::FocusType::kNone);
  MediaControls().DispatchEvent(*Event::Create("pointermove"));

  // Controls should remain visible
  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  // Controls should hide after being inactive for 4 seconds.
  platform()->RunForPeriodSeconds(2);
  EXPECT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       ControlsHideAfterFocusedAndMouseMoveout) {
  EnsureSizing();

  Element* panel = MediaControls().PanelElement();
  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  // Controls start out visible
  EXPECT_TRUE(IsElementVisible(*panel));
  platform()->RunForPeriodSeconds(1);

  // Mouse move out while focused, controls should hide
  MediaControls().DispatchEvent(*Event::Create("focusin"));
  MediaControls().MediaElement().SetFocused(true,
                                            mojom::blink::FocusType::kNone);
  MediaControls().DispatchEvent(*Event::Create("pointerout"));
  EXPECT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTestWithMockScheduler, CursorHidesWhenControlsHide) {
  EnsureSizing();

  MediaControls().MediaElement().SetSrc("http://example.com");

  // Cursor is not initially hidden.
  EXPECT_FALSE(IsCursorHidden());

  MediaControls().MediaElement().Play();

  // Tabbing into the controls shows the controls and therefore the cursor.
  MediaControls().DispatchEvent(*Event::Create("focusin"));
  EXPECT_FALSE(IsCursorHidden());

  // Once the controls hide, the cursor is hidden.
  platform()->RunForPeriodSeconds(4);
  EXPECT_TRUE(IsCursorHidden());

  // If the mouse moves, the controls are shown and the cursor is no longer
  // hidden.
  MediaControls().DispatchEvent(*Event::Create("pointermove"));
  EXPECT_FALSE(IsCursorHidden());

  // Once the controls hide again, the cursor is hidden again.
  platform()->RunForPeriodSeconds(4);
  EXPECT_TRUE(IsCursorHidden());
}

TEST_F(MediaControlsImplTestWithMockScheduler, AccessibleFocusShowsControls) {
  EnsureSizing();

  Element* panel = MediaControls().PanelElement();

  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();

  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  MediaControls().OnAccessibleFocus();
  platform()->RunForPeriodSeconds(2);
  EXPECT_TRUE(IsElementVisible(*panel));

  platform()->RunForPeriodSeconds(2);
  SimulateHideMediaControlsTimerFired();
  EXPECT_TRUE(IsElementVisible(*panel));

  MediaControls().OnAccessibleBlur();
  platform()->RunForPeriodSeconds(4);
  SimulateHideMediaControlsTimerFired();
  EXPECT_FALSE(IsElementVisible(*panel));
}

TEST_F(MediaControlsImplTest,
       RemovingFromDocumentRemovesListenersAndCallbacks) {
  auto page_holder = std::make_unique<DummyPageHolder>();

  auto* element =
      MakeGarbageCollected<HTMLVideoElement>(page_holder->GetDocument());
  page_holder->GetDocument().body()->AppendChild(element);

  RemotePlayback& remote_playback = RemotePlayback::From(*element);

  EXPECT_TRUE(remote_playback.HasEventListeners());
  EXPECT_TRUE(HasAvailabilityCallbacks(remote_playback));

  WeakPersistent<HTMLMediaElement> weak_persistent_video = element;
  {
    Persistent<HTMLMediaElement> persistent_video = element;
    page_holder->GetDocument().body()->setInnerHTML("");

    // When removed from the document, the event listeners should have been
    // dropped.
    EXPECT_FALSE(remote_playback.HasEventListeners());
    EXPECT_FALSE(HasAvailabilityCallbacks(remote_playback));
  }

  test::RunPendingTasks();

  ThreadState::Current()->CollectAllGarbageForTesting();

  // It has been GC'd.
  EXPECT_EQ(nullptr, weak_persistent_video);
}

TEST_F(MediaControlsImplTest,
       RemovingFromDocumentWhenResettingSrcAllowsReclamation) {
  // Regression test: https://crbug.com/918064
  //
  // Test ensures that unified heap garbage collections are able to collect
  // detached HTMLVideoElements. The tricky part is that ResizeObserver's are
  // treated as roots as long as they have observations which prevent the video
  // element from being collected.

  auto page_holder = std::make_unique<DummyPageHolder>();
  page_holder->GetDocument().write("<video controls>");
  page_holder->GetDocument().Parser()->Finish();

  auto& video =
      To<HTMLVideoElement>(*page_holder->GetDocument().QuerySelector("video"));
  WeakPersistent<HTMLMediaElement> weak_persistent_video = &video;
  video.remove();

  test::RunPendingTasks();

  ThreadState::Current()->CollectAllGarbageForTesting();
  EXPECT_EQ(nullptr, weak_persistent_video);
}

TEST_F(MediaControlsImplTest,
       ReInsertingInDocumentRestoresListenersAndCallbacks) {
  auto page_holder = std::make_unique<DummyPageHolder>();

  auto* element =
      MakeGarbageCollected<HTMLVideoElement>(page_holder->GetDocument());
  page_holder->GetDocument().body()->AppendChild(element);

  RemotePlayback& remote_playback = RemotePlayback::From(*element);

  // This should be a no-op. We keep a reference on the media element to avoid
  // an unexpected GC.
  {
    Persistent<HTMLMediaElement> video_holder = element;
    page_holder->GetDocument().body()->RemoveChild(element);
    page_holder->GetDocument().body()->AppendChild(video_holder.Get());
    EXPECT_TRUE(remote_playback.HasEventListeners());
    EXPECT_TRUE(HasAvailabilityCallbacks(remote_playback));
  }
}

TEST_F(MediaControlsImplTest, InitialInfinityDurationHidesDurationField) {
  EnsureSizing();

  LoadMediaWithDuration(std::numeric_limits<double>::infinity());

  MediaControlRemainingTimeDisplayElement* duration_display =
      GetRemainingTimeDisplayElement();

  EXPECT_FALSE(duration_display->IsWanted());
  EXPECT_EQ(std::numeric_limits<double>::infinity(),
            duration_display->CurrentValue());
}

TEST_F(MediaControlsImplTest, InfinityDurationChangeHidesDurationField) {
  EnsureSizing();

  LoadMediaWithDuration(42);

  MediaControlRemainingTimeDisplayElement* duration_display =
      GetRemainingTimeDisplayElement();

  EXPECT_TRUE(duration_display->IsWanted());
  EXPECT_EQ(42, duration_display->CurrentValue());

  MediaControls().MediaElement().DurationChanged(
      std::numeric_limits<double>::infinity(), false /* request_seek */);
  test::RunPendingTasks();

  EXPECT_FALSE(duration_display->IsWanted());
  EXPECT_EQ(std::numeric_limits<double>::infinity(),
            duration_display->CurrentValue());
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       ShowVolumeSliderAfterHoverTimerFired) {
  const double kTimeToShowVolumeSlider = 0.2;

  EnsureSizing();
  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
  platform()->RunForPeriodSeconds(1);
  SetHasAudio(true);
  SimulateLoadedMetadata();

  WebTestSupport::SetIsRunningWebTest(false);

  Element* volume_slider = VolumeSliderElement();
  Element* mute_btn = MuteButtonElement();

  ASSERT_NE(nullptr, volume_slider);
  ASSERT_NE(nullptr, mute_btn);

  EXPECT_TRUE(IsElementVisible(*mute_btn));
  EXPECT_TRUE(volume_slider->classList().contains("closed"));

  DOMRect* mute_btn_rect = mute_btn->getBoundingClientRect();
  gfx::PointF mute_btn_center(
      mute_btn_rect->left() + mute_btn_rect->width() / 2,
      mute_btn_rect->top() + mute_btn_rect->height() / 2);
  gfx::PointF edge(0, 0);

  // Hover on mute button and stay
  MouseMoveTo(mute_btn_center);
  platform()->RunForPeriodSeconds(kTimeToShowVolumeSlider - 0.001);
  EXPECT_TRUE(volume_slider->classList().contains("closed"));

  platform()->RunForPeriodSeconds(0.002);
  EXPECT_FALSE(volume_slider->classList().contains("closed"));

  MouseMoveTo(edge);
  EXPECT_TRUE(volume_slider->classList().contains("closed"));

  // Hover on mute button and move away before timer fired
  MouseMoveTo(mute_btn_center);
  platform()->RunForPeriodSeconds(kTimeToShowVolumeSlider - 0.001);
  EXPECT_TRUE(volume_slider->classList().contains("closed"));

  MouseMoveTo(edge);
  EXPECT_TRUE(volume_slider->classList().contains("closed"));
}

TEST_F(MediaControlsImplTestWithMockScheduler,
       VolumeSliderBehaviorWhenFocused) {
  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
  platform()->RunForPeriodSeconds(1);
  SetHasAudio(true);

  WebTestSupport::SetIsRunningWebTest(false);

  Element* volume_slider = VolumeSliderElement();

  ASSERT_NE(nullptr, volume_slider);

  // Volume slider starts out hidden
  EXPECT_TRUE(volume_slider->classList().contains("closed"));

  // Tab focus should open volume slider immediately.
  volume_slider->SetFocused(true, mojom::blink::FocusType::kNone);
  volume_slider->DispatchEvent(*Event::Create("focus"));
  EXPECT_FALSE(volume_slider->classList().contains("closed"));

  // Unhover slider while focused should not close slider.
  volume_slider->DispatchEvent(*Event::Create("mouseout"));
  EXPECT_FALSE(volume_slider->classList().contains("closed"));
}

TEST_F(MediaControlsImplTest, CastOverlayDefaultHidesOnTimer) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  SimulateRouteAvailable();
  EXPECT_TRUE(IsElementVisible(*cast_overlay_button));

  // Starts playback because overlay never hides if paused.
  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();
  test::RunPendingTasks();

  SimulateHideMediaControlsTimerFired();
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));
}

TEST_F(MediaControlsImplTest, CastOverlayShowsOnSomeEvents) {
  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
                                                     false);

  Element* cast_overlay_button = GetElementByShadowPseudoId(
      MediaControls(), "-internal-media-controls-overlay-cast-button");
  ASSERT_NE(nullptr, cast_overlay_button);

  Element* overlay_enclosure = GetElementByShadowPseudoId(
      MediaControls(), "-webkit-media-controls-overlay-enclosure");
  ASSERT_NE(nullptr, overlay_enclosure);

  SimulateRouteAvailable();
  EXPECT_TRUE(IsElementVisible(*cast_overlay_button));

  // Starts playback because overlay never hides if paused.
  MediaControls().MediaElement().SetSrc("http://example.com");
  MediaControls().MediaElement().Play();
  test::RunPendingTasks();

  SimulateRouteAvailable();
  SimulateHideMediaControlsTimerFired();
  EXPECT_FALSE(IsElementVisible(*cast_overlay_button));

  for (auto* const event_name :
       {"gesturetap", "click", "pointerover", "pointermove"}) {
    overlay_enclosure->DispatchEvent(*Event::Create(event_name));
    EXPECT_TRUE(IsElementVisible(*cast_overlay_button));

    SimulateHideMediaControlsTimerFired();
    EXPECT_FALSE(IsElementVisible(*cast_overlay_button));
  }
}

TEST_F(MediaControlsImplTest, isConnected) {
  EXPECT_TRUE(MediaControls().isConnected());
  MediaControls().MediaElement().remove();
  EXPECT_FALSE(MediaControls().isConnected());
}

TEST_F(MediaControlsImplTest, ControlsShouldUseSafeAreaInsets) {
  UpdateAllLifecyclePhasesForTest();
  {
    const ComputedStyle* style = MediaControls().GetComputedStyle();
    EXPECT_EQ(0.0, style->MarginTop().Pixels());
    EXPECT_EQ(0.0, style->MarginLeft().Pixels());
    EXPECT_EQ(0.0, style->MarginBottom().Pixels());
    EXPECT_EQ(0.0, style->MarginRight().Pixels());
  }

  GetStyleEngine().EnsureEnvironmentVariables().SetVariable(
      "safe-area-inset-top", "1px");
  GetStyleEngine().EnsureEnvironmentVariables().SetVariable(
      "safe-area-inset-left", "2px");
  GetStyleEngine().EnsureEnvironmentVariables().SetVariable(
      "safe-area-inset-bottom", "3px");
  GetStyleEngine().EnsureEnvironmentVariables().SetVariable(
      "safe-area-inset-right", "4px");

  EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
  UpdateAllLifecyclePhasesForTest();

  {
    const ComputedStyle* style = MediaControls().GetComputedStyle();
    EXPECT_EQ(1.0, style->MarginTop().Pixels());
    EXPECT_EQ(2.0, style->MarginLeft().Pixels());
    EXPECT_EQ(3.0, style->MarginBottom().Pixels());
    EXPECT_EQ(4.0, style->MarginRight().Pixels());
  }
}

TEST_F(MediaControlsImplTest, MediaControlsDisabledWithNoSource) {
  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kNoSource);

  EXPECT_TRUE(PlayButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_TRUE(
      OverflowMenuButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_TRUE(TimelineElement()->FastHasAttribute(html_names::kDisabledAttr));

  MediaControls().MediaElement().setAttribute(html_names::kPreloadAttr, "none");
  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
  test::RunPendingTasks();
  SimulateLoadedMetadata();

  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kNotLoaded);

  EXPECT_FALSE(
      PlayButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_FALSE(
      OverflowMenuButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_TRUE(TimelineElement()->FastHasAttribute(html_names::kDisabledAttr));

  MediaControls().MediaElement().removeAttribute(html_names::kPreloadAttr);
  SimulateLoadedMetadata();

  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kLoadingMetadataPaused);

  EXPECT_FALSE(
      PlayButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_FALSE(
      OverflowMenuButtonElement()->FastHasAttribute(html_names::kDisabledAttr));
  EXPECT_FALSE(TimelineElement()->FastHasAttribute(html_names::kDisabledAttr));
}

TEST_F(MediaControlsImplTest, DoubleTouchChangesTime) {
  double duration = 60;  // 1 minute.
  LoadMediaWithDuration(duration);
  EnsureSizing();
  MediaControls().MediaElement().setCurrentTime(30);
  test::RunPendingTasks();

  // We've set the video to the halfway mark.
  EXPECT_EQ(30, MediaControls().MediaElement().currentTime());

  DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
  ASSERT_LT(0, videoRect->width());
  gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
                           videoRect->top() + 5);
  gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
                            videoRect->top() + 5);

  // Double-tapping left of center should shift the time backwards by 10
  // seconds.
  GestureDoubleTapAt(leftOfCenter);
  test::RunPendingTasks();
  EXPECT_EQ(20, MediaControls().MediaElement().currentTime());

  // Double-tapping right of center should shift the time forwards by 10
  // seconds.
  GestureDoubleTapAt(rightOfCenter);
  test::RunPendingTasks();
  EXPECT_EQ(30, MediaControls().MediaElement().currentTime());
}

TEST_F(MediaControlsImplTest, DoubleTouchChangesTimeWhenZoomed) {
  double duration = 60;  // 1 minute.
  LoadMediaWithDuration(duration);
  EnsureSizing();
  MediaControls().MediaElement().setCurrentTime(30);
  test::RunPendingTasks();

  // We've set the video to the halfway mark.
  EXPECT_EQ(30, MediaControls().MediaElement().currentTime());

  DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
  ASSERT_LT(0, videoRect->width());
  gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
                           videoRect->top() + 10);
  gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
                            videoRect->top() + 10);

  // Add a zoom factor and ensure that it's properly handled.
  MediaControls().GetDocument().GetFrame()->SetPageZoomFactor(2);

  // Double-tapping left of center should shift the time backwards by 10
  // seconds.
  GestureDoubleTapAt(leftOfCenter);
  test::RunPendingTasks();
  EXPECT_EQ(20, MediaControls().MediaElement().currentTime());

  // Double-tapping right of center should shift the time forwards by 10
  // seconds.
  GestureDoubleTapAt(rightOfCenter);
  test::RunPendingTasks();
  EXPECT_EQ(30, MediaControls().MediaElement().currentTime());
}

}  // namespace blink
