diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/media_controls/touchless')
17 files changed, 329 insertions, 59 deletions
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc index 4542382a807..d70899258eb 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc @@ -4,8 +4,10 @@ #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" +#include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -25,6 +27,14 @@ MediaControlsTouchlessBottomContainerElement:: ParserAppendChild(time_display_element_); ParserAppendChild(timeline_element_); + + event_listener_ = + MakeGarbageCollected<MediaControlsSharedHelpers::TransitionEventListener>( + this, + WTF::BindRepeating(&MediaControlsTouchlessBottomContainerElement:: + HandleTransitionEndEvent, + WrapWeakPersistent(this))); + event_listener_->Attach(); } LayoutObject* @@ -37,10 +47,30 @@ MediaControlsTouchlessBottomContainerElement::TimeDisplayLayoutObject() { return time_display_element_->GetLayoutObject(); } +void MediaControlsTouchlessBottomContainerElement::MakeOpaque( + bool should_hide) { + SetDisplayed(true); + MediaElement().MediaControlsDidBecomeVisible(); + MediaControlsTouchlessElement::MakeOpaque(should_hide); +} + +void MediaControlsTouchlessBottomContainerElement::HandleTransitionEndEvent() { + SetDisplayed(false); +} + +void MediaControlsTouchlessBottomContainerElement::SetDisplayed( + bool displayed) { + if (displayed) + RemoveInlineStyleProperty(CSSPropertyID::kDisplay); + else + SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone); +} + void MediaControlsTouchlessBottomContainerElement::Trace( blink::Visitor* visitor) { visitor->Trace(timeline_element_); visitor->Trace(time_display_element_); + visitor->Trace(event_listener_); MediaControlsTouchlessElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h index 34d04de3191..e23acc51a24 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ +#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" namespace blink { @@ -20,11 +21,17 @@ class MediaControlsTouchlessBottomContainerElement MediaControlsTouchlessBottomContainerElement(MediaControlsTouchlessImpl&); LayoutObject* TimelineLayoutObject(); LayoutObject* TimeDisplayLayoutObject(); + + void MakeOpaque(bool); void Trace(blink::Visitor*) override; private: + void HandleTransitionEndEvent(); + void SetDisplayed(bool); + Member<MediaControlsTouchlessTimelineElement> timeline_element_; Member<MediaControlsTouchlessTimeDisplayElement> time_display_element_; + Member<MediaControlsSharedHelpers::TransitionEventListener> event_listener_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc index cbbac960438..4c2c2137a2d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc @@ -17,6 +17,7 @@ namespace { constexpr WTF::TimeDelta kTimeToHideControl = TimeDelta::FromMilliseconds(3000); const char kTransparentCSSClass[] = "transparent"; +const char kTransparentImmediateCSSClass[] = "transparent-immediate"; } // namespace @@ -34,7 +35,7 @@ HTMLMediaElement& MediaControlsTouchlessElement::MediaElement() const { void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) { EnsureHideControlTimer(); - classList().Remove(kTransparentCSSClass); + removeAttribute("class"); if (hide_control_timer_->IsActive()) StopHideControlTimer(); @@ -43,8 +44,9 @@ void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) { StartHideControlTimer(); } -void MediaControlsTouchlessElement::MakeTransparent() { - classList().Add(kTransparentCSSClass); +void MediaControlsTouchlessElement::MakeTransparent(bool hide_immediate) { + classList().Add(hide_immediate ? kTransparentImmediateCSSClass + : kTransparentCSSClass); } void MediaControlsTouchlessElement::EnsureHideControlTimer() { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h index b43c44d21db..f5463bbf466 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h @@ -27,12 +27,13 @@ class MediaControlsTouchlessElement void Trace(blink::Visitor* visitor) override; void MakeOpaque(bool /** True if control should hide after timer fired */); - void MakeTransparent(); + void MakeTransparent(bool = false /** True if hide immediately */); // Non-touch media event listener observer implementation. void OnFocusIn() override {} void OnTimeUpdate() override {} void OnDurationChange() override {} + void OnSeeking() override {} void OnLoadingProgress() override {} void OnPlay() override {} void OnPause() override {} diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc index 5e008b0b004..7ac1f447124 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc @@ -8,6 +8,8 @@ #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" +#include "third_party/blink/renderer/platform/text/platform_locale.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -39,6 +41,14 @@ MediaControlsTouchlessOverlayElement::MediaControlsTouchlessOverlayElement( ParserAppendChild(play_button); ParserAppendChild(seek_forward_button); ParserAppendChild(volume_down_button); + + StringBuilder aria_label; + aria_label.Append( + GetLocale().QueryString(WebLocalizedString::kAXMediaTouchLessSeekAction)); + aria_label.Append(" "); + aria_label.Append(GetLocale().QueryString( + WebLocalizedString::kAXMediaTouchLessVolumeAction)); + setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString()); } void MediaControlsTouchlessOverlayElement::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc index 261f52bb2d8..5c6db6bfa01 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" +#include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -27,6 +28,11 @@ void MediaControlsTouchlessTimeDisplayElement::OnTimeUpdate() { UpdateTimeDisplay(); } +void MediaControlsTouchlessTimeDisplayElement::OnSeeking() { + current_time_ = MediaElement().currentTime(); + UpdateTimeDisplay(); +} + void MediaControlsTouchlessTimeDisplayElement::OnDurationChange() { duration_ = MediaElement().duration(); UpdateTimeDisplay(); @@ -42,6 +48,16 @@ void MediaControlsTouchlessTimeDisplayElement::UpdateTimeDisplay() { builder.Append(" / "); builder.Append(MediaControlsSharedHelpers::FormatTime(duration_)); setInnerText(builder.ToAtomicString(), ASSERT_NO_EXCEPTION); + + StringBuilder aria_label; + aria_label.Append(GetLocale().QueryString( + WebLocalizedString::kAXMediaCurrentTimeDisplay, + MediaControlsSharedHelpers::FormatTime(current_time_))); + aria_label.Append(" "); + aria_label.Append(GetLocale().QueryString( + WebLocalizedString::kAXMediaTimeRemainingDisplay, + MediaControlsSharedHelpers::FormatTime(duration_))); + setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h index 6a8455a559e..0134b091c4c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h @@ -18,6 +18,7 @@ class MediaControlsTouchlessTimeDisplayElement // MediaControlsTouchlessMediaEventListenerObserver overrides void OnTimeUpdate() override; + void OnSeeking() override; void OnDurationChange() override; void Trace(blink::Visitor* visitor) override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc index 57bd4a639c8..413ae227057 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc @@ -34,6 +34,11 @@ void MediaControlsTouchlessTimelineElement::OnTimeUpdate() { UpdateBars(); } +void MediaControlsTouchlessTimelineElement::OnSeeking() { + current_time_ = MediaElement().currentTime(); + UpdateBars(); +} + void MediaControlsTouchlessTimelineElement::OnDurationChange() { duration_ = MediaElement().duration(); UpdateBars(); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h index b1416ce9ae2..c8a17e7ac55 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h @@ -17,6 +17,7 @@ class MediaControlsTouchlessTimelineElement // MediaControlsTouchlessMediaEventListenerObserver overrides void OnTimeUpdate() override; + void OnSeeking() override; void OnDurationChange() override; void OnLoadingProgress() override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc index 7a2c2a8c129..fd6b6b7719a 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.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_shared_helper.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h" @@ -77,24 +78,24 @@ MediaControlsTouchlessImpl* MediaControlsTouchlessImpl::Create( ShadowRoot& shadow_root) { MediaControlsTouchlessImpl* controls = MakeGarbageCollected<MediaControlsTouchlessImpl>(media_element); - controls->overlay_ = - MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls); controls->bottom_container_ = MakeGarbageCollected<MediaControlsTouchlessBottomContainerElement>( *controls); + controls->overlay_ = + MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls); controls->volume_container_ = MakeGarbageCollected<MediaControlsTouchlessVolumeContainerElement>( *controls); - controls->ParserAppendChild(controls->overlay_); controls->ParserAppendChild(controls->bottom_container_); + controls->ParserAppendChild(controls->overlay_); controls->ParserAppendChild(controls->volume_container_); // Controls start hidden. - controls->overlay_->MakeTransparent(); - controls->volume_container_->MakeTransparent(); if (!media_element.paused()) controls->bottom_container_->MakeTransparent(); + controls->overlay_->MakeTransparent(); + controls->volume_container_->MakeTransparent(); if (RuntimeEnabledFeatures::VideoFullscreenOrientationLockEnabled() && media_element.IsHTMLVideoElement()) { @@ -166,8 +167,8 @@ MediaControlsTouchlessImpl::MediaEventListener() const { void MediaControlsTouchlessImpl::OnFocusIn() { if (MediaElement().ShouldShowControls()) { - overlay_->MakeOpaque(true); bottom_container_->MakeOpaque(!MediaElement().paused()); + overlay_->MakeOpaque(true); } } @@ -191,7 +192,7 @@ void MediaControlsTouchlessImpl::OnKeyDown(KeyboardEvent* event) { bool handled = true; switch (event->keyCode()) { case VKEY_RETURN: - volume_container_->MakeTransparent(); + volume_container_->MakeTransparent(true); overlay_->MakeOpaque(true); MediaElement().TogglePlayState(); break; @@ -270,9 +271,8 @@ void MediaControlsTouchlessImpl::ShowContextMenu() { WTF::Vector<mojom::blink::MenuItem> menu_items; - // TODO(jazzhsu, https://crbug.com/942577): Populate fullscreen list entry - // properly. - menu_items.push_back(mojom::blink::MenuItem::FULLSCREEN); + if (MediaControlsSharedHelpers::ShouldShowFullscreenButton(MediaElement())) + menu_items.push_back(mojom::blink::MenuItem::FULLSCREEN); if (MediaElement().HasAudio()) menu_items.push_back(mojom::blink::MenuItem::MUTE); @@ -402,14 +402,14 @@ WebScreenOrientationType MediaControlsTouchlessImpl::GetOrientation() { void MediaControlsTouchlessImpl::HandleTopButtonPress() { MaybeChangeVolume(kVolumeToChangeForTouchless); volume_container_->UpdateVolume(); - overlay_->MakeTransparent(); + overlay_->MakeTransparent(true); volume_container_->MakeOpaque(true); } void MediaControlsTouchlessImpl::HandleBottomButtonPress() { MaybeChangeVolume(kVolumeToChangeForTouchless * -1); volume_container_->UpdateVolume(); - overlay_->MakeTransparent(); + overlay_->MakeTransparent(true); volume_container_->MakeOpaque(true); } @@ -448,9 +448,13 @@ void MediaControlsTouchlessImpl::Trace(blink::Visitor* visitor) { HTMLDivElement::Trace(visitor); } -void MediaControlsTouchlessImpl::OnMediaMenuResultForTest( - mojom::blink::MenuResponsePtr response) { - OnMediaMenuResult(std::move(response)); +void MediaControlsTouchlessImpl::SetMediaControlsMenuHostForTesting( + mojom::blink::MediaControlsMenuHostPtr menu_host) { + media_controls_host_ = std::move(menu_host); +} + +void MediaControlsTouchlessImpl::MenuHostFlushForTesting() { + media_controls_host_.FlushForTesting(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h index 14fc333e7fa..b3d86bd5102 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h @@ -56,6 +56,7 @@ class MODULES_EXPORT MediaControlsTouchlessImpl final void OnFocusIn() override; void OnTimeUpdate() override {} void OnDurationChange() override {} + void OnSeeking() override {} void OnLoadingProgress() override {} void OnPlay() override; void OnPause() override; @@ -70,7 +71,9 @@ class MODULES_EXPORT MediaControlsTouchlessImpl final MediaControlsTouchlessMediaEventListener& MediaEventListener() const; // Test functions - void OnMediaMenuResultForTest(mojom::blink::MenuResponsePtr); + void SetMediaControlsMenuHostForTesting( + mojom::blink::MediaControlsMenuHostPtr); + void MenuHostFlushForTesting(); void Trace(blink::Visitor*) override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc index 9215321dace..01576a0d722 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc @@ -8,21 +8,26 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/settings.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/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_media_test_helper.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_list.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/touchless/test_media_controls_menu_host.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -31,14 +36,27 @@ namespace blink { namespace { +const char kTextTracksOffString[] = "Off"; + +class LocalePlatformSupport : public TestingPlatformSupport { + public: + WebString QueryLocalizedString(WebLocalizedString::Name name) override { + if (name == WebLocalizedString::kTextTracksOff) + return kTextTracksOffString; + return TestingPlatformSupport::QueryLocalizedString(name); + } +}; + class MockWebMediaPlayerForTouchlessImpl : public EmptyWebMediaPlayer { public: WebTimeRanges Seekable() const override { return seekable_; } bool HasVideo() const override { return true; } + bool HasAudio() const override { return has_audio_; } WebTimeRanges Buffered() const override { return buffered_; } WebTimeRanges buffered_; WebTimeRanges seekable_; + bool has_audio_ = false; }; class MockChromeClientForTouchlessImpl : public EmptyChromeClient { @@ -52,6 +70,14 @@ class MockChromeClientForTouchlessImpl : public EmptyChromeClient { return screen_info; } + void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) final { + Fullscreen::DidEnterFullscreen(*frame.GetDocument()); + } + + void ExitFullscreen(LocalFrame& frame) final { + Fullscreen::DidExitFullscreen(*frame.GetDocument()); + } + void SetOrientation(WebScreenOrientationType orientation_type) { orientation_ = orientation_type; } @@ -66,6 +92,7 @@ class MediaControlsTouchlessImplTest : public PageTestBase { void InitializePage() { Page::PageClients clients; + FillWithEmptyClients(clients); chrome_client_ = MakeGarbageCollected<MockChromeClientForTouchlessImpl>(); clients.chrome_client = chrome_client_; @@ -78,6 +105,11 @@ class MediaControlsTouchlessImplTest : public PageTestBase { ToHTMLVideoElement(*GetDocument().QuerySelector("video")); media_controls_ = static_cast<MediaControlsTouchlessImpl*>(video.GetMediaControls()); + + test_media_controls_host_ = std::make_unique<TestMediaControlsMenuHost>(); + + media_controls_->SetMediaControlsMenuHostForTesting( + test_media_controls_host_->CreateMediaControlsMenuHostPtr()); } MediaControlsTouchlessImpl& MediaControls() { return *media_controls_; } @@ -88,6 +120,10 @@ class MediaControlsTouchlessImplTest : public PageTestBase { MediaElement().GetWebMediaPlayer()); } + TestMenuHostArgList& GetMenuHostArgList() { + return test_media_controls_host_->GetMenuHostArgList(); + } + void SimulateKeydownEvent(Element& element, int key_code) { KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create(); keyboard_event_init->setKeyCode(key_code); @@ -111,9 +147,20 @@ class MediaControlsTouchlessImplTest : public PageTestBase { } bool IsControlsVisible(Element* element) { - return !element->classList().contains("transparent"); + return !element->classList().contains("transparent") && + !element->classList().contains("transparent-immediate"); } + bool IsElementDisplayed(Element* element) { + if (!element->InlineStyle()) + return true; + + return element->InlineStyle()->GetPropertyValue(CSSPropertyID::kDisplay) != + "none"; + } + + void SetHasAudio(bool has_audio) { WebMediaPlayer()->has_audio_ = has_audio; } + Element* GetControlByShadowPseudoId(const char* shadow_pseudo_id) { for (Element& element : ElementTraversal::DescendantsOf(MediaControls())) { if (element.ShadowPseudoId() == shadow_pseudo_id) @@ -126,12 +173,15 @@ class MediaControlsTouchlessImplTest : public PageTestBase { chrome_client_->SetOrientation(orientation_type); } - void SimulateClickOnMenuItem(mojom::blink::MenuItem menu_item, - int track_index) { - mojom::blink::MenuResponsePtr response(mojom::blink::MenuResponse::New()); - response->clicked = menu_item; - response->track_index = track_index; - media_controls_->OnMediaMenuResultForTest(std::move(response)); + void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index = -1) { + test_media_controls_host_->SetMenuResponse(menu_item, track_index); + } + + void SetMenuResponseAndShowMenu(mojom::blink::MenuItem menu_item, + int track_index = -1) { + SetMenuResponse(menu_item, track_index); + MediaControls().ShowContextMenu(); + MediaControls().MenuHostFlushForTesting(); } void CheckControlKeys(int seek_forward_key, @@ -161,6 +211,7 @@ class MediaControlsTouchlessImplTest : public PageTestBase { private: Persistent<MediaControlsTouchlessImpl> media_controls_; Persistent<MockChromeClientForTouchlessImpl> chrome_client_; + std::unique_ptr<TestMediaControlsMenuHost> test_media_controls_host_; }; class MediaControlsTouchlessImplTestWithMockScheduler @@ -283,6 +334,14 @@ TEST_F(MediaControlsTouchlessImplTest, ProgressBar) { EXPECT_DOUBLE_EQ(buffered / duration, loaded_bar_width / timeline_width); EXPECT_DOUBLE_EQ(current_time / buffered, progress_bar_width / loaded_bar_width); + + // Seek event should trigger a UI update as well. + SetBufferedRange(0); + MediaElement().setCurrentTime(0); + MediaElement().DispatchEvent(*Event::Create(event_type_names::kSeeking)); + + EXPECT_DOUBLE_EQ(progress_bar->getBoundingClientRect()->width(), 0); + EXPECT_DOUBLE_EQ(loaded_bar->getBoundingClientRect()->width(), 0); } TEST_F(MediaControlsTouchlessImplTest, TimeDisplay) { @@ -325,47 +384,70 @@ TEST_F(MediaControlsTouchlessImplTest, VolumeDisplayTest) { volume_bar_height / volume_bar_background_height, error); } -/** (jazzhsu@) TODO: Add mojom binding test and fix the following test. -TEST_F(MediaControlsTouchlessImplTest, ContextMenuTest) { - // Fullscreen buttom test. - EXPECT_FALSE(MediaElement().IsFullscreen()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1); +TEST_F(MediaControlsTouchlessImplTest, ContextMenuMojomTest) { + ScopedTestingPlatformSupport<LocalePlatformSupport> support; + + MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); + std::unique_ptr<UserGestureIndicator> user_gesture_scope = + LocalFrame::NotifyUserActivation(GetDocument().GetFrame(), + UserGestureToken::kNewGesture); test::RunPendingTasks(); + + KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create(); + keyboard_event_init->setKey("SoftRight"); + Event* keyboard_event = + MakeGarbageCollected<KeyboardEvent>("keydown", keyboard_event_init); + + // Test fullscreen function. + SetMenuResponse(mojom::blink::MenuItem::FULLSCREEN); + MediaElement().DispatchEvent(*keyboard_event); + MediaControls().MenuHostFlushForTesting(); + test::RunPendingTasks(); + + TestMenuHostArgList& arg_list = GetMenuHostArgList(); + EXPECT_EQ((int)arg_list.menu_items.size(), 2); + EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::FULLSCREEN); + EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::DOWNLOAD); + EXPECT_FALSE(arg_list.video_state->is_fullscreen); EXPECT_TRUE(MediaElement().IsFullscreen()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::FULLSCREEN); test::RunPendingTasks(); + + EXPECT_TRUE(arg_list.video_state->is_fullscreen); EXPECT_FALSE(MediaElement().IsFullscreen()); - // Mute buttom test. - EXPECT_FALSE(MediaElement().muted()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1); + // Disable download and fullscreen, and show mute option. + MediaElement().ControlsListInternal()->Add("nofullscreen"); + MediaElement().GetDocument().GetSettings()->SetHideDownloadUI(true); + SetHasAudio(true); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); + + EXPECT_EQ((int)arg_list.menu_items.size(), 1); + EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::MUTE); + EXPECT_FALSE(arg_list.video_state->is_muted); EXPECT_TRUE(MediaElement().muted()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); + + EXPECT_TRUE(arg_list.video_state->is_muted); EXPECT_FALSE(MediaElement().muted()); - // Text track test. - TextTrack* track1 = MediaElement().addTextTrack("subtitle", "english", - "en", NASSERT_NO_EXCEPTION); - TextTrack* track2 = MediaElement().addTextTrack("subtitle", "english2", - "en", ASSERT_NO_EXCEPTION); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword()); - - // Select first track. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 0); - EXPECT_EQ(track1->mode(), TextTrack::ShowingKeyword()); - - // Select second track. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 1); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_EQ(track2->mode(), TextTrack::ShowingKeyword()); - - // Turn all tracks off. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, -1); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword()); + // Disable mute option and show text track option. + SetHasAudio(false); + TextTrack* track = MediaElement().addTextTrack("subtitles", "english", "en", + ASSERT_NO_EXCEPTION); + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, 0); + + EXPECT_EQ((int)arg_list.menu_items.size(), 1); + EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::CAPTIONS); + EXPECT_EQ(arg_list.text_tracks[1]->label, "english"); + EXPECT_EQ(track->mode(), TextTrack::ShowingKeyword()); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, -1); + EXPECT_NE(track->mode(), TextTrack::ShowingKeyword()); } -*/ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, MidOverlayHideTimerTest) { @@ -408,6 +490,7 @@ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, // Bottom container starts opaque since video is paused. EXPECT_TRUE(IsControlsVisible(bottom_container)); + EXPECT_TRUE(IsElementDisplayed(bottom_container)); MediaElement().Play(); platform()->RunForPeriodSeconds(3); @@ -434,6 +517,11 @@ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, platform()->RunForPeriodSeconds(3); EXPECT_FALSE(IsControlsVisible(bottom_container)); + // Display should be none after hide transition ends. + bottom_container->DispatchEvent( + *Event::Create(event_type_names::kTransitionend)); + EXPECT_FALSE(IsElementDisplayed(bottom_container)); + // Bottom container should show after pressing right/left arrow. SimulateKeydownEvent(MediaElement(), VK_RIGHT); EXPECT_TRUE(IsControlsVisible(bottom_container)); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc index 315164554be..17fc5f17796 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc @@ -35,6 +35,7 @@ void MediaControlsTouchlessMediaEventListener::Attach() { media_element_->addEventListener(event_type_names::kTimeupdate, this, false); media_element_->addEventListener(event_type_names::kDurationchange, this, false); + media_element_->addEventListener(event_type_names::kSeeking, this, false); media_element_->addEventListener(event_type_names::kProgress, this, false); media_element_->addEventListener(event_type_names::kPlay, this, false); @@ -76,6 +77,11 @@ void MediaControlsTouchlessMediaEventListener::Invoke( observer->OnDurationChange(); return; } + if (event->type() == event_type_names::kSeeking) { + for (auto& observer : observers_) + observer->OnSeeking(); + return; + } if (event->type() == event_type_names::kProgress) { for (auto& observer : observers_) observer->OnLoadingProgress(); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h index 1c297a9e47c..cf07510f775 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h @@ -17,6 +17,7 @@ class MediaControlsTouchlessMediaEventListenerObserver virtual void OnFocusIn() = 0; virtual void OnTimeUpdate() = 0; virtual void OnDurationChange() = 0; + virtual void OnSeeking() = 0; virtual void OnLoadingProgress() = 0; virtual void OnPlay() = 0; virtual void OnPause() = 0; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css index 1ef89f2a909..98516f3aa39 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css @@ -40,6 +40,10 @@ video::-internal-media-controls-touchless-overlay.transparent { transition: opacity .5s; } +video::-internal-media-controls-touchless-overlay.transparent-immediate { + opacity: 0; +} + video::-internal-media-controls-touchless-volume-up-button { width: 30px; height: 30px; @@ -175,6 +179,10 @@ video::-internal-media-controls-touchless-volume-container.transparent { transition: opacity .5s; } +video::-internal-media-controls-touchless-volume-container.transparent-immediate { + opacity: 0; +} + video::-internal-media-controls-touchless-volume-bar-background { width: 4px; margin-left: 20px; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc new file mode 100644 index 00000000000..d8780771ab3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc @@ -0,0 +1,47 @@ +// Copyright 2019 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/touchless/test_media_controls_menu_host.h" + +namespace blink { + +mojom::blink::MediaControlsMenuHostPtr +TestMediaControlsMenuHost::CreateMediaControlsMenuHostPtr() { + mojom::blink::MediaControlsMenuHostPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + return ptr; +} + +void TestMediaControlsMenuHost::ShowMediaMenu( + const WTF::Vector<mojom::MenuItem>& menu_items, + mojom::blink::VideoStatePtr video_state, + base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> text_tracks, + ShowMediaMenuCallback callback) { + arg_list_.menu_items = WTF::Vector<mojom::MenuItem>(menu_items); + + arg_list_.video_state = mojom::blink::VideoState::New(); + arg_list_.video_state->is_fullscreen = video_state->is_fullscreen; + arg_list_.video_state->is_muted = video_state->is_muted; + + arg_list_.text_tracks = WTF::Vector<mojom::blink::TextTrackMetadataPtr>( + std::move(text_tracks.value())); + + std::move(callback).Run(std::move(response_)); +} + +TestMenuHostArgList& TestMediaControlsMenuHost::GetMenuHostArgList() { + return arg_list_; +} + +void TestMediaControlsMenuHost::SetMenuResponse( + mojom::blink::MenuItem menu_item, + int track_index) { + if (response_.is_null()) + response_ = mojom::blink::MenuResponse::New(); + + response_->clicked = menu_item; + response_->track_index = track_index; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h new file mode 100644 index 00000000000..4378945032f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h @@ -0,0 +1,40 @@ +// Copyright 2019 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ + +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" + +namespace blink { + +struct TestMenuHostArgList { + WTF::Vector<mojom::MenuItem> menu_items; + mojom::blink::VideoStatePtr video_state; + WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks; +}; + +class TestMediaControlsMenuHost : public mojom::blink::MediaControlsMenuHost { + public: + mojom::blink::MediaControlsMenuHostPtr CreateMediaControlsMenuHostPtr(); + void ShowMediaMenu( + const WTF::Vector<mojom::MenuItem>& menu_items, + mojom::blink::VideoStatePtr video_state, + base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> + text_tracks, + ShowMediaMenuCallback callback) override; + + TestMenuHostArgList& GetMenuHostArgList(); + void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index); + + private: + mojo::Binding<mojom::blink::MediaControlsMenuHost> binding_{this}; + TestMenuHostArgList arg_list_; + mojom::blink::MenuResponsePtr response_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ |