Commit ca44daf6 authored by Jazz Xu's avatar Jazz Xu Committed by Commit Bot

[Media Controls] Touchless media controls UI updates

This CL implements UI updates include
1. Hide volume slider immediately when showing mid
overlay (and vice versa), and
2. Set display to none after hide bottom progress bar UI
to give captions space to show.

Bug: 928443
Change-Id: I73db74c3047056424784804ae7f5ea942bcde22a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1610993Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Commit-Queue: Jazz Xu <jazzhsu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661026}
parent f0f53fff
......@@ -6,7 +6,6 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.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_impl.h"
......@@ -21,61 +20,6 @@ const char kTransparentClassName[] = "transparent";
} // anonymous namespace
// Listens for the 'transitionend' event.
class MediaControlPanelElement::TransitionEventListener final
: public NativeEventListener {
public:
using Callback = base::RepeatingCallback<void()>;
// |element| is the element to listen for the 'transitionend' event on.
// |callback| is the callback to call when the event is handled.
explicit TransitionEventListener(Element* element, Callback callback)
: callback_(callback), element_(element) {
DCHECK(callback_);
DCHECK(element_);
}
void Attach() {
DCHECK(!attached_);
attached_ = true;
element_->addEventListener(event_type_names::kTransitionend, this, false);
}
void Detach() {
DCHECK(attached_);
attached_ = false;
element_->removeEventListener(event_type_names::kTransitionend, this,
false);
}
bool IsAttached() const { return attached_; }
void Invoke(ExecutionContext* context, Event* event) override {
if (event->target() != element_)
return;
if (event->type() == event_type_names::kTransitionend) {
callback_.Run();
return;
}
NOTREACHED();
}
void Trace(blink::Visitor* visitor) override {
NativeEventListener::Trace(visitor);
visitor->Trace(element_);
}
private:
bool attached_ = false;
Callback callback_;
Member<Element> element_;
};
MediaControlPanelElement::MediaControlPanelElement(
MediaControlsImpl& media_controls)
: MediaControlDivElement(media_controls), event_listener_(nullptr) {
......@@ -148,10 +92,10 @@ bool MediaControlPanelElement::EventListenerIsAttachedForTest() const {
void MediaControlPanelElement::EnsureTransitionEventListener() {
// Create the event listener if it doesn't exist.
if (!event_listener_) {
event_listener_ =
MakeGarbageCollected<MediaControlPanelElement::TransitionEventListener>(
this, WTF::BindRepeating(
&MediaControlPanelElement::HandleTransitionEndEvent,
event_listener_ = MakeGarbageCollected<
MediaControlsSharedHelpers::TransitionEventListener>(
this,
WTF::BindRepeating(&MediaControlPanelElement::HandleTransitionEndEvent,
WrapWeakPersistent(this)));
}
......
......@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_PANEL_ELEMENT_H_
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace blink {
......@@ -40,8 +41,6 @@ class MODULES_EXPORT MediaControlPanelElement final
bool EventListenerIsAttachedForTest() const;
private:
class TransitionEventListener;
void EnsureTransitionEventListener();
void DetachTransitionEventListener();
......@@ -55,7 +54,7 @@ class MODULES_EXPORT MediaControlPanelElement final
bool opaque_ = true;
bool keep_displayed_for_accessibility_ = false;
Member<TransitionEventListener> event_listener_;
Member<MediaControlsSharedHelpers::TransitionEventListener> event_listener_;
};
} // namespace blink
......
......@@ -6,6 +6,7 @@
#include <cmath>
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
......@@ -21,6 +22,54 @@ const double kCurrentTimeBufferedDelta = 1.0;
namespace blink {
// |element| is the element to listen for the 'transitionend' event on.
// |callback| is the callback to call when the event is handled.
MediaControlsSharedHelpers::TransitionEventListener::TransitionEventListener(
Element* element,
Callback callback)
: callback_(callback), element_(element) {
DCHECK(callback_);
DCHECK(element_);
}
void MediaControlsSharedHelpers::TransitionEventListener::Attach() {
DCHECK(!attached_);
attached_ = true;
element_->addEventListener(event_type_names::kTransitionend, this, false);
}
void MediaControlsSharedHelpers::TransitionEventListener::Detach() {
DCHECK(attached_);
attached_ = false;
element_->removeEventListener(event_type_names::kTransitionend, this, false);
}
bool MediaControlsSharedHelpers::TransitionEventListener::IsAttached() const {
return attached_;
}
void MediaControlsSharedHelpers::TransitionEventListener::Invoke(
ExecutionContext* context,
Event* event) {
if (event->target() != element_)
return;
if (event->type() == event_type_names::kTransitionend) {
callback_.Run();
return;
}
NOTREACHED();
}
void MediaControlsSharedHelpers::TransitionEventListener::Trace(
blink::Visitor* visitor) {
NativeEventListener::Trace(visitor);
visitor->Trace(element_);
}
base::Optional<unsigned>
MediaControlsSharedHelpers::GetCurrentBufferedTimeRange(
HTMLMediaElement& media_element) {
......
......@@ -5,18 +5,38 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_MEDIA_CONTROLS_SHARED_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_MEDIA_CONTROLS_SHARED_HELPER_H_
#include "base/callback.h"
#include "base/optional.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class HTMLMediaElement;
class Element;
class MediaControlsSharedHelpers final {
STATIC_ONLY(MediaControlsSharedHelpers);
public:
class TransitionEventListener final : public NativeEventListener {
public:
using Callback = base::RepeatingCallback<void()>;
explicit TransitionEventListener(Element* element, Callback callback);
void Attach();
void Detach();
bool IsAttached() const;
void Invoke(ExecutionContext* context, Event* event) override;
void Trace(blink::Visitor* visitor) override;
private:
bool attached_ = false;
Callback callback_;
Member<Element> element_;
};
static base::Optional<unsigned> GetCurrentBufferedTimeRange(
HTMLMediaElement& media_element);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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() {
......
......@@ -27,7 +27,7 @@ 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 {}
......
......@@ -192,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;
......@@ -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);
}
......
......@@ -24,6 +24,7 @@
#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"
......@@ -146,7 +147,16 @@ 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; }
......@@ -480,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);
......@@ -506,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));
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment