Chromium Code Reviews| Index: third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp |
| diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp |
| index 2e0c50d9968e11f12b3f089532a18a3617cc402f..30cb25f3e454338521729505c0ea19c0fca2fc31 100644 |
| --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp |
| +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp |
| @@ -4,12 +4,19 @@ |
| #include "modules/media_controls/elements/MediaControlCastButtonElement.h" |
| +#include "bindings/core/v8/ScriptState.h" |
| +#include "bindings/core/v8/ToV8.h" |
| #include "core/InputTypeNames.h" |
| #include "core/dom/ClientRect.h" |
| #include "core/events/Event.h" |
| +#include "core/frame/Settings.h" |
| #include "core/html/HTMLMediaElement.h" |
| +#include "core/html/media/HTMLMediaElementControlsList.h" |
| #include "modules/media_controls/MediaControlsImpl.h" |
| #include "modules/media_controls/elements/MediaControlElementsHelper.h" |
| +#include "modules/remoteplayback/HTMLMediaElementRemotePlayback.h" |
| +#include "modules/remoteplayback/RemotePlayback.h" |
| +#include "platform/wtf/Functional.h" |
| #include "public/platform/Platform.h" |
| namespace blink { |
| @@ -28,11 +35,37 @@ Element* ElementFromCenter(Element& element) { |
| } // anonymous namespace |
| +MediaControlCastButtonElement::RemotePlaybackEventListener:: |
| + RemotePlaybackEventListener(MediaControlCastButtonElement* cast_button) |
| + : EventListener(kCPPEventListenerType), cast_button_(cast_button) {} |
| + |
| +bool MediaControlCastButtonElement::RemotePlaybackEventListener::operator==( |
| + const EventListener& other) const { |
| + return this == &other; |
| +} |
| + |
| +void MediaControlCastButtonElement::RemotePlaybackEventListener::handleEvent( |
| + ExecutionContext* execution_context, |
| + Event* event) { |
| + DCHECK(event->type() == EventTypeNames::connect || |
| + event->type() == EventTypeNames::connecting || |
| + event->type() == EventTypeNames::disconnect); |
| + cast_button_->UpdateDisplayType(); |
| +} |
| + |
| +DEFINE_TRACE(MediaControlCastButtonElement::RemotePlaybackEventListener) { |
| + EventListener::Trace(visitor); |
| + visitor->Trace(cast_button_); |
| +} |
| + |
| MediaControlCastButtonElement::MediaControlCastButtonElement( |
| MediaControlsImpl& media_controls, |
| bool is_overlay_button) |
| : MediaControlInputElement(media_controls, kMediaCastOnButton), |
| - is_overlay_button_(is_overlay_button) { |
| + is_overlay_button_(is_overlay_button), |
| + remote_playback_(HTMLMediaElementRemotePlayback::remote( |
| + media_controls.MediaElement())), |
| + remote_playback_event_listener_(new RemotePlaybackEventListener(this)) { |
| EnsureUserAgentShadowRoot(); |
| SetShadowPseudoId(is_overlay_button |
| ? "-internal-media-controls-overlay-cast-button" |
| @@ -41,41 +74,14 @@ MediaControlCastButtonElement::MediaControlCastButtonElement( |
| if (is_overlay_button_) |
| RecordMetrics(CastOverlayMetrics::kCreated); |
| - SetIsPlayingRemotely(false); |
| -} |
| - |
| -void MediaControlCastButtonElement::TryShowOverlay() { |
| - DCHECK(is_overlay_button_); |
| - SetIsWanted(true); |
| - if (ElementFromCenter(*this) != &MediaElement()) { |
| - SetIsWanted(false); |
| - return; |
| - } |
| - |
| - DCHECK(IsWanted()); |
| - if (!show_use_counted_) { |
| - show_use_counted_ = true; |
| - RecordMetrics(CastOverlayMetrics::kShown); |
| - } |
| -} |
| - |
| -void MediaControlCastButtonElement::SetIsPlayingRemotely( |
| - bool is_playing_remotely) { |
| - if (is_playing_remotely) { |
| - if (is_overlay_button_) { |
| - SetDisplayType(kMediaOverlayCastOnButton); |
| - } else { |
| - SetDisplayType(kMediaCastOnButton); |
| - } |
| - } else { |
| - if (is_overlay_button_) { |
| - SetDisplayType(kMediaOverlayCastOffButton); |
| - } else { |
| - SetDisplayType(kMediaCastOffButton); |
| - } |
| - } |
| - UpdateOverflowString(); |
| + remote_playback_->addEventListener(EventTypeNames::connect, |
| + remote_playback_event_listener_); |
| + remote_playback_->addEventListener(EventTypeNames::connecting, |
| + remote_playback_event_listener_); |
| + remote_playback_->addEventListener(EventTypeNames::disconnect, |
| + remote_playback_event_listener_); |
| + UpdateDisplayType(); |
|
mlamouri (slow - plz ping)
2017/04/18 13:02:40
I think you should stop listening to those when th
whywhat
2017/04/19 02:27:56
Okay. Seems like availability callbacks should be
whywhat
2017/04/24 14:16:38
RE: tests - I'd have to add them in RemotePlayback
|
| } |
| bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() { |
| @@ -84,7 +90,7 @@ bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() { |
| WebLocalizedString::Name |
| MediaControlCastButtonElement::GetOverflowStringName() { |
| - if (MediaElement().IsPlayingRemotely()) |
| + if (IsPlayingRemotely()) |
| return WebLocalizedString::kOverflowMenuStopCast; |
| return WebLocalizedString::kOverflowMenuCast; |
| } |
| @@ -98,24 +104,107 @@ void MediaControlCastButtonElement::DefaultEventHandler(Event* event) { |
| if (is_overlay_button_) { |
| Platform::Current()->RecordAction( |
| UserMetricsAction("Media.Controls.CastOverlay")); |
| + |
| + if (!click_use_counted_) { |
| + click_use_counted_ = true; |
| + RecordMetrics(CastOverlayMetrics::kClicked); |
| + } |
| } else { |
| Platform::Current()->RecordAction( |
| UserMetricsAction("Media.Controls.Cast")); |
| } |
| - if (is_overlay_button_ && !click_use_counted_) { |
| - click_use_counted_ = true; |
| - RecordMetrics(CastOverlayMetrics::kClicked); |
| - } |
| - if (MediaElement().IsPlayingRemotely()) { |
| - MediaElement().RequestRemotePlaybackControl(); |
| - } else { |
| - MediaElement().RequestRemotePlayback(); |
| - } |
| + remote_playback_->PromptInternal(); |
| } |
| MediaControlInputElement::DefaultEventHandler(event); |
| } |
| +void MediaControlCastButtonElement::UpdateDisplayType() { |
| + if (IsPlayingRemotely()) { |
| + if (is_overlay_button_) |
| + SetDisplayType(kMediaOverlayCastOnButton); |
| + else |
| + SetDisplayType(kMediaCastOnButton); |
| + } else { |
| + if (is_overlay_button_) |
| + SetDisplayType(kMediaOverlayCastOffButton); |
| + else |
| + SetDisplayType(kMediaCastOffButton); |
| + } |
| + UpdateOverflowString(); |
| +} |
| + |
| +void MediaControlCastButtonElement::SetIsWanted(bool wanted) { |
| + if (wanted == is_wanted_by_controls_) |
| + return; |
| + |
| + is_wanted_by_controls_ = wanted; |
| + UpdateVisibility(); |
| +} |
| + |
| +void MediaControlCastButtonElement::UpdateVisibility() { |
| + if (!ShouldShow()) { |
| + DCHECK_NE(-1, availability_callback_id_); |
| + remote_playback_->CancelWatchAvailabilityInternal( |
| + availability_callback_id_); |
| + MediaControlElement::SetIsWanted(false); |
| + return; |
| + } |
| + |
| + // TODO(avayvod): DO NOT SUBMIT, set watch availability callback. |
| + availability_callback_id_ = remote_playback_->WatchAvailabilityInternal( |
| + WTF::Bind(&MediaControlCastButtonElement::UpdateVisibility, |
| + WrapPersistent(this))); |
| + MediaControlElement::SetIsWanted(remote_playback_->RemotePlaybackAvailable()); |
| + if (IsWanted() && is_overlay_button_ && !show_use_counted_) { |
| + show_use_counted_ = true; |
| + RecordMetrics(CastOverlayMetrics::kShown); |
| + } |
| +} |
| + |
| +bool MediaControlCastButtonElement::ShouldShow() { |
| + if (!is_wanted_by_controls_) |
| + return false; |
| + |
| + if (MediaElement().FastHasAttribute(HTMLNames::disableremoteplaybackAttr)) |
| + return false; |
| + |
| + // Explicitly do not show cast button when the MediaControlsEnabled setting is |
| + // false to make sure the overlay does not appear. |
| + Document& document = MediaElement().GetDocument(); |
| + if (document.GetSettings() && |
| + !document.GetSettings()->GetMediaControlsEnabled()) { |
| + return false; |
| + } |
| + |
| + // The page disabled the button via the attribute. |
| + if (MediaElement().ControlsListInternal()->ShouldHideRemotePlayback()) { |
| + UseCounter::Count( |
| + document, UseCounter::kHTMLMediaElementControlsListNoRemotePlayback); |
| + return false; |
| + } |
| + |
| + if (is_overlay_button_) { |
| + // The reason for the autoplay test is that some pages (e.g. vimeo.com) have |
| + // an autoplay background video, which doesn't autoplay on Chrome for |
| + // Android (we prevent it) so starts paused. In such cases we don't want to |
| + // automatically show the cast button, since it looks strange and is |
| + // unlikely to correspond with anything the user wants to do. If a user |
| + // does want to cast a paused autoplay video then they can still do so by |
| + // touching or clicking on the video, which will cause the cast button to |
| + // appear. |
| + if (MediaElement().Autoplay() || !MediaElement().paused()) |
| + return false; |
| + |
| + // Don't show the overlay button if it would cover something on top of the |
| + // media element. |
| + // TODO(avayvod): DO NOT SUBMIT, should show the button to do the hit test? |
| + if (ElementFromCenter(*this) != &MediaElement()) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| bool MediaControlCastButtonElement::KeepEventInNode(Event* event) { |
| return MediaControlElementsHelper::IsUserInteractionEvent(event); |
| } |
| @@ -128,4 +217,16 @@ void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) { |
| overlay_histogram.Count(static_cast<int>(metric)); |
| } |
| +bool MediaControlCastButtonElement::IsPlayingRemotely() const { |
| + // TODO(avayvod): DO NOT SUBMIT, find a way to use a named constant shared |
| + // with RemotePlayback.h. |
| + return remote_playback_->state() != "disconnected"; |
|
mlamouri (slow - plz ping)
2017/04/18 13:02:40
Can't use add `constexpr` to the header? Or even h
whywhat
2017/04/19 02:27:57
With GetState() I don't really need ...ForBindings
mlamouri (slow - plz ping)
2017/04/19 16:35:36
I was suggesting to have stateForBindings() instea
|
| +} |
| + |
| +DEFINE_TRACE(MediaControlCastButtonElement) { |
| + MediaControlInputElement::Trace(visitor); |
| + visitor->Trace(remote_playback_); |
| + visitor->Trace(remote_playback_event_listener_); |
| +} |
| + |
| } // namespace blink |