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

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

Issue 2415723002: [Blink, RemotePlayback] watchAvailability() implementation. (Closed)
Patch Set: Cleanup after RemotePlaybackAvailability 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, connectedValue, ("connected")); 23 DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected"));
23 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected")); 24 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected"));
24 25
(...skipping 29 matching lines...) Expand all
54 m_mediaElement(&element) {} 55 m_mediaElement(&element) {}
55 56
56 const AtomicString& RemotePlayback::interfaceName() const { 57 const AtomicString& RemotePlayback::interfaceName() const {
57 return EventTargetNames::RemotePlayback; 58 return EventTargetNames::RemotePlayback;
58 } 59 }
59 60
60 ExecutionContext* RemotePlayback::getExecutionContext() const { 61 ExecutionContext* RemotePlayback::getExecutionContext() const {
61 return &m_mediaElement->document(); 62 return &m_mediaElement->document();
62 } 63 }
63 64
64 ScriptPromise RemotePlayback::getAvailability(ScriptState* scriptState) { 65 ScriptPromise RemotePlayback::watchAvailability(
66 ScriptState* scriptState,
67 RemotePlaybackAvailabilityCallback* callback) {
65 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 68 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
66 ScriptPromise promise = resolver->promise(); 69 ScriptPromise promise = resolver->promise();
67 70
71 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
72 resolver->reject(DOMException::create(
73 InvalidStateError, "disableRemotePlayback attribute is present."));
74 return promise;
75 }
76
77 // TODO(avayvod): implement steps 4 and 5 of the algorithm.
Zhiqiang Zhang (Slow) 2016/10/13 15:23:11 add a bug number?
whywhat 2016/10/14 19:58:19 Done.
78 int id;
79 do {
80 id = getExecutionContext()->circularSequentialID();
81 } while (!m_availabilityCallbacks.add(id, callback).isNewEntry);
bashi 2016/10/13 00:45:46 |callback| only has a weak reference to v8::Functi
whywhat 2016/10/14 19:58:19 I think I need more info... Should I add Prologue
bashi 2016/10/17 00:11:05 Maybe either is fine. As for removing, it depend
82
83 if (!m_scriptState)
84 m_scriptState = scriptState;
Zhiqiang Zhang (Slow) 2016/10/13 15:23:11 Is this the same scriptState every time? Maybe yes
whywhat 2016/10/14 19:58:19 That's something I'm not 100% sure about. Other pl
haraken 2016/10/15 01:52:45 m_scriptState must be equal to scriptState. You c
whywhat 2016/10/16 03:41:40 Do you mean I should remove the if and just always
haraken 2016/10/17 00:19:52 Yes. You can save the ScriptState in the construct
85
86 // Report the current availability via the callback.
87 getExecutionContext()->postTask(
88 BLINK_FROM_HERE,
89 createSameThreadTask(&RemotePlayback::notifyInitialAvailability,
90 wrapPersistent(this), id),
91 "watchAvailabilityCallback");
92
68 // TODO(avayvod): Currently the availability is tracked for each media element 93 // TODO(avayvod): Currently the availability is tracked for each media element
69 // as soon as it's created, we probably want to limit that to when the 94 // as soon as it's created, we probably want to limit that to when the
70 // page/element is visible (see https://crbug.com/597281) and has default 95 // page/element is visible (see https://crbug.com/597281) and has default
71 // controls. If there are no default controls, we should also start tracking 96 // controls. If there are no default controls, we should also start tracking
72 // availability on demand meaning the Promise returned by getAvailability() 97 // availability on demand meaning the Promise returned by watchAvailability()
73 // will be resolved asynchronously. 98 // will be resolved asynchronously.
74 RemotePlaybackAvailability* availability = 99 resolver->resolve(id);
75 RemotePlaybackAvailability::take(resolver, m_availability); 100 return promise;
76 m_availabilityObjects.append(availability); 101 }
77 resolver->resolve(availability); 102
103 ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* scriptState,
104 int id) {
105 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
106 ScriptPromise promise = resolver->promise();
107
108 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
109 resolver->reject(DOMException::create(
110 InvalidStateError, "disableRemotePlayback attribute is present."));
111 return promise;
112 }
113
114 auto iter = m_availabilityCallbacks.find(id);
115 if (iter == m_availabilityCallbacks.end()) {
116 resolver->reject(DOMException::create(
117 NotFoundError, "A callback with the given id is not found."));
118 return promise;
119 }
120
121 m_availabilityCallbacks.remove(iter);
122
123 resolver->resolve();
124 return promise;
125 }
126
127 ScriptPromise RemotePlayback::cancelWatchAvailability(
128 ScriptState* scriptState) {
129 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
130 ScriptPromise promise = resolver->promise();
131
132 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
133 resolver->reject(DOMException::create(
134 InvalidStateError, "disableRemotePlayback attribute is present."));
135 return promise;
136 }
137
138 m_availabilityCallbacks.clear();
139
140 resolver->resolve();
78 return promise; 141 return promise;
79 } 142 }
80 143
81 ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) { 144 ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) {
82 // TODO(avayvod): implement steps 4, 5, 8, 9 of the algorithm. 145 // TODO(avayvod): implement steps 5, 8, 9 of the algorithm.
83 // https://crbug.com/647441 146 // https://crbug.com/647441
84 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 147 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
85 ScriptPromise promise = resolver->promise(); 148 ScriptPromise promise = resolver->promise();
86 149
87 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { 150 if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
88 resolver->reject(DOMException::create( 151 resolver->reject(DOMException::create(
89 InvalidStateError, "disableRemotePlayback attribute is present.")); 152 InvalidStateError, "disableRemotePlayback attribute is present."));
90 return promise; 153 return promise;
91 } 154 }
92 155
(...skipping 23 matching lines...) Expand all
116 } 179 }
117 180
118 return promise; 181 return promise;
119 } 182 }
120 183
121 String RemotePlayback::state() const { 184 String RemotePlayback::state() const {
122 return remotePlaybackStateToString(m_state); 185 return remotePlaybackStateToString(m_state);
123 } 186 }
124 187
125 bool RemotePlayback::hasPendingActivity() const { 188 bool RemotePlayback::hasPendingActivity() const {
126 return hasEventListeners() || !m_availabilityObjects.isEmpty() || 189 return hasEventListeners() || !m_availabilityCallbacks.isEmpty() ||
127 m_promptPromiseResolver; 190 m_promptPromiseResolver;
128 } 191 }
129 192
193 void RemotePlayback::notifyInitialAvailability(int callbackId) {
194 // May not find the callback if the website cancels it fast enough.
195 auto iter = m_availabilityCallbacks.find(callbackId);
196 if (iter == m_availabilityCallbacks.end())
197 return;
198
199 iter->value->call(m_scriptState.get(), this, m_availability);
200 }
201
130 void RemotePlayback::stateChanged(WebRemotePlaybackState state) { 202 void RemotePlayback::stateChanged(WebRemotePlaybackState state) {
131 // We may get a "disconnected" state change while in the "disconnected" 203 // We may get a "disconnected" state change while in the "disconnected"
132 // state if initiated connection fails. So cleanup the promise resolvers 204 // state if initiated connection fails. So cleanup the promise resolvers
133 // before checking if anything changed. 205 // before checking if anything changed.
134 // TODO(avayvod): cleanup this logic when we implementing the "connecting" 206 // TODO(avayvod): cleanup this logic when we implementing the "connecting"
135 // state. 207 // state.
136 if (m_promptPromiseResolver) { 208 if (m_promptPromiseResolver) {
137 if (state != WebRemotePlaybackState::Disconnected) 209 if (state != WebRemotePlaybackState::Disconnected)
138 m_promptPromiseResolver->resolve(); 210 m_promptPromiseResolver->resolve();
139 else 211 else
140 m_promptPromiseResolver->reject(DOMException::create( 212 m_promptPromiseResolver->reject(DOMException::create(
141 AbortError, "Failed to connect to the remote device.")); 213 AbortError, "Failed to connect to the remote device."));
142 m_promptPromiseResolver = nullptr; 214 m_promptPromiseResolver = nullptr;
143 } 215 }
144 216
145 if (m_state == state) 217 if (m_state == state)
146 return; 218 return;
147 219
148 m_state = state; 220 m_state = state;
149 dispatchEvent(Event::create(EventTypeNames::statechange)); 221 dispatchEvent(Event::create(EventTypeNames::statechange));
150 } 222 }
151 223
152 void RemotePlayback::availabilityChanged(bool available) { 224 void RemotePlayback::availabilityChanged(bool available) {
153 if (m_availability == available) 225 if (m_availability == available)
154 return; 226 return;
155 227
156 m_availability = available; 228 m_availability = available;
157 for (auto& availabilityObject : m_availabilityObjects) 229 for (auto& callback : m_availabilityCallbacks.values())
158 availabilityObject->availabilityChanged(available); 230 callback->call(m_scriptState.get(), this, m_availability);
159 } 231 }
160 232
161 void RemotePlayback::promptCancelled() { 233 void RemotePlayback::promptCancelled() {
162 if (!m_promptPromiseResolver) 234 if (!m_promptPromiseResolver)
163 return; 235 return;
164 236
165 m_promptPromiseResolver->reject( 237 m_promptPromiseResolver->reject(
166 DOMException::create(NotAllowedError, "The prompt was dismissed.")); 238 DOMException::create(NotAllowedError, "The prompt was dismissed."));
167 m_promptPromiseResolver = nullptr; 239 m_promptPromiseResolver = nullptr;
168 } 240 }
169 241
170 DEFINE_TRACE(RemotePlayback) { 242 DEFINE_TRACE(RemotePlayback) {
171 visitor->trace(m_availabilityObjects); 243 visitor->trace(m_availabilityCallbacks);
172 visitor->trace(m_promptPromiseResolver); 244 visitor->trace(m_promptPromiseResolver);
173 visitor->trace(m_mediaElement); 245 visitor->trace(m_mediaElement);
174 EventTargetWithInlineData::trace(visitor); 246 EventTargetWithInlineData::trace(visitor);
175 } 247 }
176 248
177 } // namespace blink 249 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698