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

Side by Side Diff: third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp

Issue 2480003002: [RemotePlayback] Keep track of source compatibility and reject prompt() correspondingly (Closed)
Patch Set: Fixed failing tests Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/remoteplayback/RemotePlayback.h" 5 #include "modules/remoteplayback/RemotePlayback.h"
6 6
7 #include "bindings/core/v8/ScriptPromiseResolver.h" 7 #include "bindings/core/v8/ScriptPromiseResolver.h"
8 #include "bindings/modules/v8/RemotePlaybackAvailabilityCallback.h" 8 #include "bindings/modules/v8/RemotePlaybackAvailabilityCallback.h"
9 #include "core/HTMLNames.h" 9 #include "core/HTMLNames.h"
10 #include "core/dom/DOMException.h" 10 #include "core/dom/DOMException.h"
(...skipping 27 matching lines...) Expand all
38 } 38 }
39 39
40 } // anonymous namespace 40 } // anonymous namespace
41 41
42 // static 42 // static
43 RemotePlayback* RemotePlayback::create(ScriptState* scriptState, 43 RemotePlayback* RemotePlayback::create(ScriptState* scriptState,
44 HTMLMediaElement& element) { 44 HTMLMediaElement& element) {
45 DCHECK(element.document().frame()); 45 DCHECK(element.document().frame());
46 DCHECK(scriptState); 46 DCHECK(scriptState);
47 47
48 RemotePlayback* remotePlayback = new RemotePlayback(scriptState, element); 48 return new RemotePlayback(scriptState, element);
49 element.setRemotePlaybackClient(remotePlayback);
50
51 return remotePlayback;
52 } 49 }
53 50
54 RemotePlayback::RemotePlayback(ScriptState* scriptState, 51 RemotePlayback::RemotePlayback(ScriptState* scriptState,
55 HTMLMediaElement& element) 52 HTMLMediaElement& element)
56 : ActiveScriptWrappable(this), 53 : ActiveScriptWrappable(this),
57 m_scriptState(scriptState), 54 m_scriptState(scriptState),
58 m_state(element.isPlayingRemotely() 55 m_state(element.isPlayingRemotely()
59 ? WebRemotePlaybackState::Connected 56 ? WebRemotePlaybackState::Connected
60 : WebRemotePlaybackState::Disconnected), 57 : WebRemotePlaybackState::Disconnected),
61 m_availability(element.hasRemoteRoutes()), 58 m_routeAvailable(false),
59 m_sourceCompatible(false),
62 m_mediaElement(&element) {} 60 m_mediaElement(&element) {}
63 61
64 const AtomicString& RemotePlayback::interfaceName() const { 62 const AtomicString& RemotePlayback::interfaceName() const {
65 return EventTargetNames::RemotePlayback; 63 return EventTargetNames::RemotePlayback;
66 } 64 }
67 65
68 ExecutionContext* RemotePlayback::getExecutionContext() const { 66 ExecutionContext* RemotePlayback::getExecutionContext() const {
69 return &m_mediaElement->document(); 67 return &m_mediaElement->document();
70 } 68 }
71 69
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 "A prompt is already being shown for this media element.")); 166 "A prompt is already being shown for this media element."));
169 return promise; 167 return promise;
170 } 168 }
171 169
172 if (!UserGestureIndicator::utilizeUserGesture()) { 170 if (!UserGestureIndicator::utilizeUserGesture()) {
173 resolver->reject(DOMException::create( 171 resolver->reject(DOMException::create(
174 InvalidAccessError, "RemotePlayback::prompt() requires user gesture.")); 172 InvalidAccessError, "RemotePlayback::prompt() requires user gesture."));
175 return promise; 173 return promise;
176 } 174 }
177 175
176 // TODO(avayvod): don't do this check on low-end devices - merge with
177 // https://codereview.chromium.org/2475293003
178 if (!m_routeAvailable) {
179 resolver->reject(DOMException::create(NotFoundError,
180 "No remote playback devices found."));
181 return promise;
182 }
183
184 if (!m_sourceCompatible) {
185 resolver->reject(DOMException::create(
186 NotSupportedError,
187 "The currentSrc is not compatible with remote playback"));
188 return promise;
189 }
190
178 if (m_state == WebRemotePlaybackState::Disconnected) { 191 if (m_state == WebRemotePlaybackState::Disconnected) {
179 m_promptPromiseResolver = resolver; 192 m_promptPromiseResolver = resolver;
180 m_mediaElement->requestRemotePlayback(); 193 m_mediaElement->requestRemotePlayback();
181 } else { 194 } else {
182 m_promptPromiseResolver = resolver; 195 m_promptPromiseResolver = resolver;
183 m_mediaElement->requestRemotePlaybackControl(); 196 m_mediaElement->requestRemotePlaybackControl();
184 } 197 }
185 198
186 return promise; 199 return promise;
187 } 200 }
188 201
189 String RemotePlayback::state() const { 202 String RemotePlayback::state() const {
190 return remotePlaybackStateToString(m_state); 203 return remotePlaybackStateToString(m_state);
191 } 204 }
192 205
193 bool RemotePlayback::hasPendingActivity() const { 206 bool RemotePlayback::hasPendingActivity() const {
194 return hasEventListeners() || !m_availabilityCallbacks.isEmpty() || 207 return hasEventListeners() || !m_availabilityCallbacks.isEmpty() ||
195 m_promptPromiseResolver; 208 m_promptPromiseResolver;
196 } 209 }
197 210
198 void RemotePlayback::notifyInitialAvailability(int callbackId) { 211 void RemotePlayback::notifyInitialAvailability(int callbackId) {
199 // May not find the callback if the website cancels it fast enough. 212 // May not find the callback if the website cancels it fast enough.
200 auto iter = m_availabilityCallbacks.find(callbackId); 213 auto iter = m_availabilityCallbacks.find(callbackId);
201 if (iter == m_availabilityCallbacks.end()) 214 if (iter == m_availabilityCallbacks.end())
202 return; 215 return;
203 216
204 iter->value->call(this, m_availability); 217 iter->value->call(this, m_routeAvailable && m_sourceCompatible);
205 } 218 }
206 219
207 void RemotePlayback::stateChanged(WebRemotePlaybackState state) { 220 void RemotePlayback::stateChanged(WebRemotePlaybackState state) {
208 if (m_state == state) 221 if (m_state == state)
209 return; 222 return;
210 223
211 if (m_promptPromiseResolver) { 224 if (m_promptPromiseResolver) {
212 // Changing state to Disconnected from "disconnected" or "connecting" means 225 // Changing state to Disconnected from "disconnected" or "connecting" means
213 // that establishing connection with remote playback device failed. 226 // that establishing connection with remote playback device failed.
214 // Changing state to anything else means the state change intended by 227 // Changing state to anything else means the state change intended by
(...skipping 19 matching lines...) Expand all
234 break; 247 break;
235 case WebRemotePlaybackState::Connected: 248 case WebRemotePlaybackState::Connected:
236 dispatchEvent(Event::create(EventTypeNames::connect)); 249 dispatchEvent(Event::create(EventTypeNames::connect));
237 break; 250 break;
238 case WebRemotePlaybackState::Disconnected: 251 case WebRemotePlaybackState::Disconnected:
239 dispatchEvent(Event::create(EventTypeNames::disconnect)); 252 dispatchEvent(Event::create(EventTypeNames::disconnect));
240 break; 253 break;
241 } 254 }
242 } 255 }
243 256
244 void RemotePlayback::availabilityChanged(bool available) { 257 void RemotePlayback::availabilityChanged(bool isRouteAvailable,
245 if (m_availability == available) 258 bool isSourceCompatible) {
259 if (m_routeAvailable == isRouteAvailable &&
260 m_sourceCompatible == isSourceCompatible) {
261 return;
262 }
263
264 bool oldAvailability = m_routeAvailable && m_sourceCompatible;
265 m_routeAvailable = isRouteAvailable;
266 m_sourceCompatible = isSourceCompatible;
267
268 bool newAvailability = isRouteAvailable && isSourceCompatible;
269 if (newAvailability == oldAvailability)
246 return; 270 return;
247 271
248 m_availability = available;
249 for (auto& callback : m_availabilityCallbacks.values()) 272 for (auto& callback : m_availabilityCallbacks.values())
250 callback->call(this, m_availability); 273 callback->call(this, newAvailability);
251 } 274 }
252 275
253 void RemotePlayback::promptCancelled() { 276 void RemotePlayback::promptCancelled() {
254 if (!m_promptPromiseResolver) 277 if (!m_promptPromiseResolver)
255 return; 278 return;
256 279
257 m_promptPromiseResolver->reject( 280 m_promptPromiseResolver->reject(
258 DOMException::create(NotAllowedError, "The prompt was dismissed.")); 281 DOMException::create(NotAllowedError, "The prompt was dismissed."));
259 m_promptPromiseResolver = nullptr; 282 m_promptPromiseResolver = nullptr;
260 } 283 }
261 284
285 bool RemotePlayback::remotePlaybackAvailable() const {
286 return m_routeAvailable && m_sourceCompatible;
287 }
288
262 void RemotePlayback::remotePlaybackDisabled() { 289 void RemotePlayback::remotePlaybackDisabled() {
263 if (m_promptPromiseResolver) { 290 if (m_promptPromiseResolver) {
264 m_promptPromiseResolver->reject(DOMException::create( 291 m_promptPromiseResolver->reject(DOMException::create(
265 InvalidStateError, "disableRemotePlayback attribute is present.")); 292 InvalidStateError, "disableRemotePlayback attribute is present."));
266 m_promptPromiseResolver = nullptr; 293 m_promptPromiseResolver = nullptr;
267 } 294 }
268 295
269 m_availabilityCallbacks.clear(); 296 m_availabilityCallbacks.clear();
270 297
271 if (m_state != WebRemotePlaybackState::Disconnected) 298 if (m_state != WebRemotePlaybackState::Disconnected)
(...skipping 15 matching lines...) Expand all
287 } 314 }
288 315
289 DEFINE_TRACE_WRAPPERS(RemotePlayback) { 316 DEFINE_TRACE_WRAPPERS(RemotePlayback) {
290 for (auto callback : m_availabilityCallbacks.values()) { 317 for (auto callback : m_availabilityCallbacks.values()) {
291 visitor->traceWrappers(callback); 318 visitor->traceWrappers(callback);
292 } 319 }
293 EventTargetWithInlineData::traceWrappers(visitor); 320 EventTargetWithInlineData::traceWrappers(visitor);
294 } 321 }
295 322
296 } // namespace blink 323 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698