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

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

Issue 2415723002: [Blink, RemotePlayback] watchAvailability() implementation. (Closed)
Patch Set: Addressing comments Created 4 years, 2 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 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 "core/HTMLNames.h" 9 #include "core/HTMLNames.h"
9 #include "core/dom/DOMException.h" 10 #include "core/dom/DOMException.h"
10 #include "core/dom/Document.h" 11 #include "core/dom/Document.h"
12 #include "core/dom/ExecutionContextTask.h"
11 #include "core/events/Event.h" 13 #include "core/events/Event.h"
12 #include "core/html/HTMLMediaElement.h" 14 #include "core/html/HTMLMediaElement.h"
13 #include "modules/EventTargetModules.h" 15 #include "modules/EventTargetModules.h"
14 #include "modules/remoteplayback/RemotePlaybackAvailability.h"
15 #include "platform/UserGestureIndicator.h" 16 #include "platform/UserGestureIndicator.h"
16 17
17 namespace blink { 18 namespace blink {
18 19
19 namespace { 20 namespace {
20 21
21 const AtomicString& remotePlaybackStateToString(WebRemotePlaybackState state) { 22 const AtomicString& remotePlaybackStateToString(WebRemotePlaybackState state) {
22 DEFINE_STATIC_LOCAL(const AtomicString, connectingValue, ("connecting")); 23 DEFINE_STATIC_LOCAL(const AtomicString, connectingValue, ("connecting"));
23 DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected")); 24 DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected"));
24 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected")); 25 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected"));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 m_mediaElement(&element) {} 58 m_mediaElement(&element) {}
58 59
59 const AtomicString& RemotePlayback::interfaceName() const { 60 const AtomicString& RemotePlayback::interfaceName() const {
60 return EventTargetNames::RemotePlayback; 61 return EventTargetNames::RemotePlayback;
61 } 62 }
62 63
63 ExecutionContext* RemotePlayback::getExecutionContext() const { 64 ExecutionContext* RemotePlayback::getExecutionContext() const {
64 return &m_mediaElement->document(); 65 return &m_mediaElement->document();
65 } 66 }
66 67
67 ScriptPromise RemotePlayback::getAvailability(ScriptState* scriptState) { 68 ScriptPromise RemotePlayback::watchAvailability(
69 ScriptState* scriptState,
70 RemotePlaybackAvailabilityCallback* callback) {
68 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 71 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
69 ScriptPromise promise = resolver->promise(); 72 ScriptPromise promise = resolver->promise();
70 73
74 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
75 resolver->reject(DOMException::create(
76 InvalidStateError, "disableRemotePlayback attribute is present."));
77 return promise;
78 }
79
80 // TODO(avayvod): implement steps 4 and 5 of the algorithm.
81 // https://crbug.com/655233
82 int id;
83 do {
84 id = getExecutionContext()->circularSequentialID();
85 } while (!m_availabilityCallbacks.add(id, callback).isNewEntry);
86
87 if (!m_scriptState)
88 m_scriptState = scriptState;
89
90 // Report the current availability via the callback.
91 getExecutionContext()->postTask(
92 BLINK_FROM_HERE,
93 createSameThreadTask(&RemotePlayback::notifyInitialAvailability,
94 wrapPersistent(this), id),
haraken 2016/10/15 01:52:45 Would you help me understand why you need to post
mlamouri (slow - plz ping) 2016/10/15 18:14:00 I'm not avayvod@ but I think this is because the s
whywhat 2016/10/16 03:41:40 There's also an issue of calling the callback befo
95 "watchAvailabilityCallback");
96
71 // TODO(avayvod): Currently the availability is tracked for each media element 97 // TODO(avayvod): Currently the availability is tracked for each media element
72 // as soon as it's created, we probably want to limit that to when the 98 // as soon as it's created, we probably want to limit that to when the
73 // page/element is visible (see https://crbug.com/597281) and has default 99 // page/element is visible (see https://crbug.com/597281) and has default
74 // controls. If there are no default controls, we should also start tracking 100 // controls. If there are no default controls, we should also start tracking
75 // availability on demand meaning the Promise returned by getAvailability() 101 // availability on demand meaning the Promise returned by watchAvailability()
76 // will be resolved asynchronously. 102 // will be resolved asynchronously.
77 RemotePlaybackAvailability* availability = 103 resolver->resolve(id);
78 RemotePlaybackAvailability::take(resolver, m_availability); 104 return promise;
79 m_availabilityObjects.append(availability); 105 }
80 resolver->resolve(availability); 106
107 ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* scriptState,
108 int id) {
109 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
110 ScriptPromise promise = resolver->promise();
111
112 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
113 resolver->reject(DOMException::create(
114 InvalidStateError, "disableRemotePlayback attribute is present."));
115 return promise;
116 }
117
118 auto iter = m_availabilityCallbacks.find(id);
119 if (iter == m_availabilityCallbacks.end()) {
120 resolver->reject(DOMException::create(
121 NotFoundError, "A callback with the given id is not found."));
mlamouri (slow - plz ping) 2016/10/15 18:14:00 s/is not found/was not found/ ?
122 return promise;
123 }
124
125 m_availabilityCallbacks.remove(iter);
126
127 resolver->resolve();
128 return promise;
129 }
130
131 ScriptPromise RemotePlayback::cancelWatchAvailability(
132 ScriptState* scriptState) {
133 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
134 ScriptPromise promise = resolver->promise();
135
136 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
mlamouri (slow - plz ping) 2016/10/15 18:14:00 Here and above, there is an issue where we don't c
whywhat 2016/10/16 03:41:40 Right, thanks for filing the spec bug. Cancelling
137 resolver->reject(DOMException::create(
138 InvalidStateError, "disableRemotePlayback attribute is present."));
139 return promise;
140 }
141
142 m_availabilityCallbacks.clear();
143
144 resolver->resolve();
81 return promise; 145 return promise;
82 } 146 }
83 147
84 ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) { 148 ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) {
85 // TODO(avayvod): implement steps 4, 5, 8, 9 of the algorithm. 149 // TODO(avayvod): implement steps 5, 8, 9 of the algorithm.
86 // https://crbug.com/647441 150 // https://crbug.com/647441
87 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 151 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
88 ScriptPromise promise = resolver->promise(); 152 ScriptPromise promise = resolver->promise();
89 153
90 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { 154 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
91 resolver->reject(DOMException::create( 155 resolver->reject(DOMException::create(
92 InvalidStateError, "disableRemotePlayback attribute is present.")); 156 InvalidStateError, "disableRemotePlayback attribute is present."));
93 return promise; 157 return promise;
94 } 158 }
95 159
(...skipping 23 matching lines...) Expand all
119 } 183 }
120 184
121 return promise; 185 return promise;
122 } 186 }
123 187
124 String RemotePlayback::state() const { 188 String RemotePlayback::state() const {
125 return remotePlaybackStateToString(m_state); 189 return remotePlaybackStateToString(m_state);
126 } 190 }
127 191
128 bool RemotePlayback::hasPendingActivity() const { 192 bool RemotePlayback::hasPendingActivity() const {
129 return hasEventListeners() || !m_availabilityObjects.isEmpty() || 193 return hasEventListeners() || !m_availabilityCallbacks.isEmpty() ||
130 m_promptPromiseResolver; 194 m_promptPromiseResolver;
131 } 195 }
132 196
197 void RemotePlayback::notifyInitialAvailability(int callbackId) {
198 // May not find the callback if the website cancels it fast enough.
199 auto iter = m_availabilityCallbacks.find(callbackId);
200 if (iter == m_availabilityCallbacks.end())
201 return;
202
203 iter->value->call(m_scriptState.get(), this, m_availability);
204 }
205
133 void RemotePlayback::stateChanged(WebRemotePlaybackState state) { 206 void RemotePlayback::stateChanged(WebRemotePlaybackState state) {
134 // We may get a "disconnected" state change while in the "disconnected" 207 // We may get a "disconnected" state change while in the "disconnected"
135 // state if initiated connection fails. So cleanup the promise resolvers 208 // state if initiated connection fails. So cleanup the promise resolvers
136 // before checking if anything changed. 209 // before checking if anything changed.
137 // TODO(avayvod): cleanup this logic when we implementing the "connecting" 210 // TODO(avayvod): cleanup this logic when we implementing the "connecting"
138 // state. 211 // state.
139 if (m_promptPromiseResolver) { 212 if (m_promptPromiseResolver) {
140 if (state != WebRemotePlaybackState::Disconnected) 213 if (state != WebRemotePlaybackState::Disconnected)
141 m_promptPromiseResolver->resolve(); 214 m_promptPromiseResolver->resolve();
142 else 215 else
(...skipping 17 matching lines...) Expand all
160 dispatchEvent(Event::create(EventTypeNames::disconnect)); 233 dispatchEvent(Event::create(EventTypeNames::disconnect));
161 break; 234 break;
162 } 235 }
163 } 236 }
164 237
165 void RemotePlayback::availabilityChanged(bool available) { 238 void RemotePlayback::availabilityChanged(bool available) {
166 if (m_availability == available) 239 if (m_availability == available)
167 return; 240 return;
168 241
169 m_availability = available; 242 m_availability = available;
170 for (auto& availabilityObject : m_availabilityObjects) 243 for (auto& callback : m_availabilityCallbacks.values())
171 availabilityObject->availabilityChanged(available); 244 callback->call(m_scriptState.get(), this, m_availability);
172 } 245 }
173 246
174 void RemotePlayback::promptCancelled() { 247 void RemotePlayback::promptCancelled() {
175 if (!m_promptPromiseResolver) 248 if (!m_promptPromiseResolver)
176 return; 249 return;
177 250
178 m_promptPromiseResolver->reject( 251 m_promptPromiseResolver->reject(
179 DOMException::create(NotAllowedError, "The prompt was dismissed.")); 252 DOMException::create(NotAllowedError, "The prompt was dismissed."));
180 m_promptPromiseResolver = nullptr; 253 m_promptPromiseResolver = nullptr;
181 } 254 }
182 255
183 DEFINE_TRACE(RemotePlayback) { 256 DEFINE_TRACE(RemotePlayback) {
184 visitor->trace(m_availabilityObjects); 257 visitor->trace(m_availabilityCallbacks);
185 visitor->trace(m_promptPromiseResolver); 258 visitor->trace(m_promptPromiseResolver);
186 visitor->trace(m_mediaElement); 259 visitor->trace(m_mediaElement);
187 EventTargetWithInlineData::trace(visitor); 260 EventTargetWithInlineData::trace(visitor);
188 } 261 }
189 262
190 } // namespace blink 263 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698