Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: third_party/WebKit/Source/modules/media_controls/elements/MediaControlCastButtonElement.cpp

Issue 2782373002: Remove MediaControls methods needed for the Cast button (Closed)
Patch Set: Rebased Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/media_controls/elements/MediaControlCastButtonElement.h" 5 #include "modules/media_controls/elements/MediaControlCastButtonElement.h"
6 6
7 #include "bindings/core/v8/ScriptState.h"
8 #include "bindings/core/v8/ToV8.h"
7 #include "core/InputTypeNames.h" 9 #include "core/InputTypeNames.h"
8 #include "core/dom/ClientRect.h" 10 #include "core/dom/ClientRect.h"
9 #include "core/events/Event.h" 11 #include "core/events/Event.h"
12 #include "core/frame/Settings.h"
10 #include "core/html/HTMLMediaElement.h" 13 #include "core/html/HTMLMediaElement.h"
14 #include "core/html/media/HTMLMediaElementControlsList.h"
11 #include "modules/media_controls/MediaControlsImpl.h" 15 #include "modules/media_controls/MediaControlsImpl.h"
12 #include "modules/media_controls/elements/MediaControlElementsHelper.h" 16 #include "modules/media_controls/elements/MediaControlElementsHelper.h"
17 #include "modules/remoteplayback/HTMLMediaElementRemotePlayback.h"
18 #include "modules/remoteplayback/RemotePlayback.h"
19 #include "platform/wtf/Functional.h"
13 #include "public/platform/Platform.h" 20 #include "public/platform/Platform.h"
14 21
15 namespace blink { 22 namespace blink {
16 23
17 namespace { 24 namespace {
18 25
19 Element* ElementFromCenter(Element& element) { 26 Element* ElementFromCenter(Element& element) {
20 ClientRect* client_rect = element.getBoundingClientRect(); 27 ClientRect* client_rect = element.getBoundingClientRect();
21 int center_x = 28 int center_x =
22 static_cast<int>((client_rect->left() + client_rect->right()) / 2); 29 static_cast<int>((client_rect->left() + client_rect->right()) / 2);
23 int center_y = 30 int center_y =
24 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2); 31 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2);
25 32
26 return element.GetDocument().ElementFromPoint(center_x, center_y); 33 return element.GetDocument().ElementFromPoint(center_x, center_y);
27 } 34 }
28 35
29 } // anonymous namespace 36 } // anonymous namespace
30 37
38 MediaControlCastButtonElement::RemotePlaybackEventListener::
39 RemotePlaybackEventListener(MediaControlCastButtonElement* cast_button)
40 : EventListener(kCPPEventListenerType), cast_button_(cast_button) {}
41
42 bool MediaControlCastButtonElement::RemotePlaybackEventListener::operator==(
43 const EventListener& other) const {
44 return this == &other;
45 }
46
47 void MediaControlCastButtonElement::RemotePlaybackEventListener::handleEvent(
48 ExecutionContext* execution_context,
49 Event* event) {
50 DCHECK(event->type() == EventTypeNames::connect ||
51 event->type() == EventTypeNames::connecting ||
52 event->type() == EventTypeNames::disconnect);
53 cast_button_->UpdateDisplayType();
54 }
55
56 DEFINE_TRACE(MediaControlCastButtonElement::RemotePlaybackEventListener) {
57 EventListener::Trace(visitor);
58 visitor->Trace(cast_button_);
59 }
60
31 MediaControlCastButtonElement::MediaControlCastButtonElement( 61 MediaControlCastButtonElement::MediaControlCastButtonElement(
32 MediaControlsImpl& media_controls, 62 MediaControlsImpl& media_controls,
33 bool is_overlay_button) 63 bool is_overlay_button)
34 : MediaControlInputElement(media_controls, kMediaCastOnButton), 64 : MediaControlInputElement(media_controls, kMediaCastOnButton),
35 is_overlay_button_(is_overlay_button) { 65 is_overlay_button_(is_overlay_button),
66 remote_playback_(HTMLMediaElementRemotePlayback::remote(
67 media_controls.MediaElement())),
68 remote_playback_event_listener_(new RemotePlaybackEventListener(this)) {
36 EnsureUserAgentShadowRoot(); 69 EnsureUserAgentShadowRoot();
37 SetShadowPseudoId(is_overlay_button 70 SetShadowPseudoId(is_overlay_button
38 ? "-internal-media-controls-overlay-cast-button" 71 ? "-internal-media-controls-overlay-cast-button"
39 : "-internal-media-controls-cast-button"); 72 : "-internal-media-controls-cast-button");
40 setType(InputTypeNames::button); 73 setType(InputTypeNames::button);
41 74
42 if (is_overlay_button_) 75 if (is_overlay_button_)
43 RecordMetrics(CastOverlayMetrics::kCreated); 76 RecordMetrics(CastOverlayMetrics::kCreated);
44 SetIsPlayingRemotely(false);
45 }
46 77
47 void MediaControlCastButtonElement::TryShowOverlay() { 78 remote_playback_->addEventListener(EventTypeNames::connect,
48 DCHECK(is_overlay_button_); 79 remote_playback_event_listener_);
49 80 remote_playback_->addEventListener(EventTypeNames::connecting,
50 SetIsWanted(true); 81 remote_playback_event_listener_);
51 if (ElementFromCenter(*this) != &MediaElement()) { 82 remote_playback_->addEventListener(EventTypeNames::disconnect,
52 SetIsWanted(false); 83 remote_playback_event_listener_);
53 return; 84 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
54 }
55
56 DCHECK(IsWanted());
57 if (!show_use_counted_) {
58 show_use_counted_ = true;
59 RecordMetrics(CastOverlayMetrics::kShown);
60 }
61 }
62
63 void MediaControlCastButtonElement::SetIsPlayingRemotely(
64 bool is_playing_remotely) {
65 if (is_playing_remotely) {
66 if (is_overlay_button_) {
67 SetDisplayType(kMediaOverlayCastOnButton);
68 } else {
69 SetDisplayType(kMediaCastOnButton);
70 }
71 } else {
72 if (is_overlay_button_) {
73 SetDisplayType(kMediaOverlayCastOffButton);
74 } else {
75 SetDisplayType(kMediaCastOffButton);
76 }
77 }
78 UpdateOverflowString();
79 } 85 }
80 86
81 bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() { 87 bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() {
82 return true; 88 return true;
83 } 89 }
84 90
85 WebLocalizedString::Name 91 WebLocalizedString::Name
86 MediaControlCastButtonElement::GetOverflowStringName() { 92 MediaControlCastButtonElement::GetOverflowStringName() {
87 if (MediaElement().IsPlayingRemotely()) 93 if (IsPlayingRemotely())
88 return WebLocalizedString::kOverflowMenuStopCast; 94 return WebLocalizedString::kOverflowMenuStopCast;
89 return WebLocalizedString::kOverflowMenuCast; 95 return WebLocalizedString::kOverflowMenuCast;
90 } 96 }
91 97
92 bool MediaControlCastButtonElement::HasOverflowButton() { 98 bool MediaControlCastButtonElement::HasOverflowButton() {
93 return true; 99 return true;
94 } 100 }
95 101
96 void MediaControlCastButtonElement::DefaultEventHandler(Event* event) { 102 void MediaControlCastButtonElement::DefaultEventHandler(Event* event) {
97 if (event->type() == EventTypeNames::click) { 103 if (event->type() == EventTypeNames::click) {
98 if (is_overlay_button_) { 104 if (is_overlay_button_) {
99 Platform::Current()->RecordAction( 105 Platform::Current()->RecordAction(
100 UserMetricsAction("Media.Controls.CastOverlay")); 106 UserMetricsAction("Media.Controls.CastOverlay"));
107
108 if (!click_use_counted_) {
109 click_use_counted_ = true;
110 RecordMetrics(CastOverlayMetrics::kClicked);
111 }
101 } else { 112 } else {
102 Platform::Current()->RecordAction( 113 Platform::Current()->RecordAction(
103 UserMetricsAction("Media.Controls.Cast")); 114 UserMetricsAction("Media.Controls.Cast"));
104 } 115 }
105 116
106 if (is_overlay_button_ && !click_use_counted_) { 117 remote_playback_->PromptInternal();
107 click_use_counted_ = true;
108 RecordMetrics(CastOverlayMetrics::kClicked);
109 }
110 if (MediaElement().IsPlayingRemotely()) {
111 MediaElement().RequestRemotePlaybackControl();
112 } else {
113 MediaElement().RequestRemotePlayback();
114 }
115 } 118 }
116 MediaControlInputElement::DefaultEventHandler(event); 119 MediaControlInputElement::DefaultEventHandler(event);
117 } 120 }
118 121
122 void MediaControlCastButtonElement::UpdateDisplayType() {
123 if (IsPlayingRemotely()) {
124 if (is_overlay_button_)
125 SetDisplayType(kMediaOverlayCastOnButton);
126 else
127 SetDisplayType(kMediaCastOnButton);
128 } else {
129 if (is_overlay_button_)
130 SetDisplayType(kMediaOverlayCastOffButton);
131 else
132 SetDisplayType(kMediaCastOffButton);
133 }
134 UpdateOverflowString();
135 }
136
137 void MediaControlCastButtonElement::SetIsWanted(bool wanted) {
138 if (wanted == is_wanted_by_controls_)
139 return;
140
141 is_wanted_by_controls_ = wanted;
142 UpdateVisibility();
143 }
144
145 void MediaControlCastButtonElement::UpdateVisibility() {
146 if (!ShouldShow()) {
147 DCHECK_NE(-1, availability_callback_id_);
148 remote_playback_->CancelWatchAvailabilityInternal(
149 availability_callback_id_);
150 MediaControlElement::SetIsWanted(false);
151 return;
152 }
153
154 // TODO(avayvod): DO NOT SUBMIT, set watch availability callback.
155 availability_callback_id_ = remote_playback_->WatchAvailabilityInternal(
156 WTF::Bind(&MediaControlCastButtonElement::UpdateVisibility,
157 WrapPersistent(this)));
158 MediaControlElement::SetIsWanted(remote_playback_->RemotePlaybackAvailable());
159 if (IsWanted() && is_overlay_button_ && !show_use_counted_) {
160 show_use_counted_ = true;
161 RecordMetrics(CastOverlayMetrics::kShown);
162 }
163 }
164
165 bool MediaControlCastButtonElement::ShouldShow() {
166 if (!is_wanted_by_controls_)
167 return false;
168
169 if (MediaElement().FastHasAttribute(HTMLNames::disableremoteplaybackAttr))
170 return false;
171
172 // Explicitly do not show cast button when the MediaControlsEnabled setting is
173 // false to make sure the overlay does not appear.
174 Document& document = MediaElement().GetDocument();
175 if (document.GetSettings() &&
176 !document.GetSettings()->GetMediaControlsEnabled()) {
177 return false;
178 }
179
180 // The page disabled the button via the attribute.
181 if (MediaElement().ControlsListInternal()->ShouldHideRemotePlayback()) {
182 UseCounter::Count(
183 document, UseCounter::kHTMLMediaElementControlsListNoRemotePlayback);
184 return false;
185 }
186
187 if (is_overlay_button_) {
188 // The reason for the autoplay test is that some pages (e.g. vimeo.com) have
189 // an autoplay background video, which doesn't autoplay on Chrome for
190 // Android (we prevent it) so starts paused. In such cases we don't want to
191 // automatically show the cast button, since it looks strange and is
192 // unlikely to correspond with anything the user wants to do. If a user
193 // does want to cast a paused autoplay video then they can still do so by
194 // touching or clicking on the video, which will cause the cast button to
195 // appear.
196 if (MediaElement().Autoplay() || !MediaElement().paused())
197 return false;
198
199 // Don't show the overlay button if it would cover something on top of the
200 // media element.
201 // TODO(avayvod): DO NOT SUBMIT, should show the button to do the hit test?
202 if (ElementFromCenter(*this) != &MediaElement())
203 return false;
204 }
205 return true;
206 }
207
119 bool MediaControlCastButtonElement::KeepEventInNode(Event* event) { 208 bool MediaControlCastButtonElement::KeepEventInNode(Event* event) {
120 return MediaControlElementsHelper::IsUserInteractionEvent(event); 209 return MediaControlElementsHelper::IsUserInteractionEvent(event);
121 } 210 }
122 211
123 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) { 212 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) {
124 DCHECK(is_overlay_button_); 213 DCHECK(is_overlay_button_);
125 DEFINE_STATIC_LOCAL( 214 DEFINE_STATIC_LOCAL(
126 EnumerationHistogram, overlay_histogram, 215 EnumerationHistogram, overlay_histogram,
127 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount))); 216 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount)));
128 overlay_histogram.Count(static_cast<int>(metric)); 217 overlay_histogram.Count(static_cast<int>(metric));
129 } 218 }
130 219
220 bool MediaControlCastButtonElement::IsPlayingRemotely() const {
221 // TODO(avayvod): DO NOT SUBMIT, find a way to use a named constant shared
222 // with RemotePlayback.h.
223 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
224 }
225
226 DEFINE_TRACE(MediaControlCastButtonElement) {
227 MediaControlInputElement::Trace(visitor);
228 visitor->Trace(remote_playback_);
229 visitor->Trace(remote_playback_event_listener_);
230 }
231
131 } // namespace blink 232 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698