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

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

Issue 2782373002: Remove MediaControls methods needed for the Cast button (Closed)
Patch Set: Fixed more tests Created 3 years, 7 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 "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 29 matching lines...) Expand all
40 } 40 }
41 41
42 void RunNotifyInitialAvailabilityTask(ExecutionContext* context, 42 void RunNotifyInitialAvailabilityTask(ExecutionContext* context,
43 std::unique_ptr<WTF::Closure> task) { 43 std::unique_ptr<WTF::Closure> task) {
44 probe::AsyncTask async_task(context, task.get()); 44 probe::AsyncTask async_task(context, task.get());
45 (*task)(); 45 (*task)();
46 } 46 }
47 47
48 } // anonymous namespace 48 } // anonymous namespace
49 49
50 RemotePlayback::AvailabilityCallback::AvailabilityCallback(
51 RemotePlaybackAvailabilityCallback* callback)
52 : bindings_cb_(this, callback) {}
53
54 RemotePlayback::AvailabilityCallback::AvailabilityCallback(
55 std::unique_ptr<WTF::Closure> callback)
56 : bindings_cb_(nullptr, nullptr), internal_cb_(std::move(callback)) {}
57
58 void RemotePlayback::AvailabilityCallback::Run(RemotePlayback* remote_playback,
59 bool new_availability) {
60 if (internal_cb_) {
61 DCHECK(!bindings_cb_);
62 (*internal_cb_.get())();
63 return;
64 }
65
66 bindings_cb_->call(remote_playback, new_availability);
67 }
68
69 DEFINE_TRACE_WRAPPERS(RemotePlayback::AvailabilityCallback) {
70 visitor->TraceWrappers(bindings_cb_);
71 }
72
50 // static 73 // static
51 RemotePlayback* RemotePlayback::Create(HTMLMediaElement& element) { 74 RemotePlayback* RemotePlayback::Create(HTMLMediaElement& element) {
52 return new RemotePlayback(element); 75 return new RemotePlayback(element);
53 } 76 }
54 77
55 RemotePlayback::RemotePlayback(HTMLMediaElement& element) 78 RemotePlayback::RemotePlayback(HTMLMediaElement& element)
56 : state_(element.IsPlayingRemotely() 79 : state_(element.IsPlayingRemotely()
57 ? WebRemotePlaybackState::kConnected 80 ? WebRemotePlaybackState::kConnected
58 : WebRemotePlaybackState::kDisconnected), 81 : WebRemotePlaybackState::kDisconnected),
59 availability_(WebRemotePlaybackAvailability::kUnknown), 82 availability_(WebRemotePlaybackAvailability::kUnknown),
(...skipping 19 matching lines...) Expand all
79 return promise; 102 return promise;
80 } 103 }
81 104
82 if (MemoryCoordinator::IsLowEndDevice()) { 105 if (MemoryCoordinator::IsLowEndDevice()) {
83 resolver->Reject(DOMException::Create( 106 resolver->Reject(DOMException::Create(
84 kNotSupportedError, 107 kNotSupportedError,
85 "Availability monitoring is not supported on this device.")); 108 "Availability monitoring is not supported on this device."));
86 return promise; 109 return promise;
87 } 110 }
88 111
89 int id; 112 int id = WatchAvailabilityInternal(new AvailabilityCallback(callback));
90 do {
91 id = GetExecutionContext()->CircularSequentialID();
92 } while (
93 !availability_callbacks_
94 .insert(id, TraceWrapperMember<RemotePlaybackAvailabilityCallback>(
95 this, callback))
96 .is_new_entry);
97
98 // Report the current availability via the callback.
99 // TODO(yuryu): Wrapping notifyInitialAvailability with WTF::Closure as
100 // InspectorInstrumentation requires a globally unique pointer to track tasks.
101 // We can remove the wrapper if InspectorInstrumentation returns a task id.
102 std::unique_ptr<WTF::Closure> task = WTF::Bind(
103 &RemotePlayback::NotifyInitialAvailability, WrapPersistent(this), id);
104 probe::AsyncTaskScheduled(GetExecutionContext(), "watchAvailabilityCallback",
105 task.get());
106 TaskRunnerHelper::Get(TaskType::kMediaElementEvent, GetExecutionContext())
107 ->PostTask(BLINK_FROM_HERE,
108 WTF::Bind(RunNotifyInitialAvailabilityTask,
109 WrapPersistent(GetExecutionContext()),
110 WTF::Passed(std::move(task))));
111 113
112 // TODO(avayvod): Currently the availability is tracked for each media element 114 // TODO(avayvod): Currently the availability is tracked for each media element
113 // as soon as it's created, we probably want to limit that to when the 115 // as soon as it's created, we probably want to limit that to when the
114 // page/element is visible (see https://crbug.com/597281) and has default 116 // page/element is visible (see https://crbug.com/597281) and has default
115 // controls. If there are no default controls, we should also start tracking 117 // controls. If there are no default controls, we should also start tracking
116 // availability on demand meaning the Promise returned by watchAvailability() 118 // availability on demand meaning the Promise returned by watchAvailability()
117 // will be resolved asynchronously. 119 // will be resolved asynchronously.
118 resolver->Resolve(id); 120 resolver->Resolve(id);
119 return promise; 121 return promise;
120 } 122 }
121 123
122 ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* script_state, 124 ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* script_state,
123 int id) { 125 int id) {
124 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 126 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
125 ScriptPromise promise = resolver->Promise(); 127 ScriptPromise promise = resolver->Promise();
126 128
127 if (media_element_->FastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { 129 if (media_element_->FastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
128 resolver->Reject(DOMException::Create( 130 resolver->Reject(DOMException::Create(
129 kInvalidStateError, "disableRemotePlayback attribute is present.")); 131 kInvalidStateError, "disableRemotePlayback attribute is present."));
130 return promise; 132 return promise;
131 } 133 }
132 134
133 auto iter = availability_callbacks_.Find(id); 135 if (!CancelWatchAvailabilityInternal(id)) {
134 if (iter == availability_callbacks_.end()) {
135 resolver->Reject(DOMException::Create( 136 resolver->Reject(DOMException::Create(
136 kNotFoundError, "A callback with the given id is not found.")); 137 kNotFoundError, "A callback with the given id is not found."));
137 return promise; 138 return promise;
138 } 139 }
139 140
140 availability_callbacks_.erase(iter);
141
142 resolver->Resolve(); 141 resolver->Resolve();
143 return promise; 142 return promise;
144 } 143 }
145 144
146 ScriptPromise RemotePlayback::cancelWatchAvailability( 145 ScriptPromise RemotePlayback::cancelWatchAvailability(
147 ScriptState* script_state) { 146 ScriptState* script_state) {
148 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 147 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
149 ScriptPromise promise = resolver->Promise(); 148 ScriptPromise promise = resolver->Promise();
150 149
151 if (media_element_->FastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { 150 if (media_element_->FastHasAttribute(HTMLNames::disableremoteplaybackAttr)) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 192 }
194 193
195 if (availability_ == WebRemotePlaybackAvailability::kSourceNotSupported || 194 if (availability_ == WebRemotePlaybackAvailability::kSourceNotSupported ||
196 availability_ == WebRemotePlaybackAvailability::kSourceNotCompatible) { 195 availability_ == WebRemotePlaybackAvailability::kSourceNotCompatible) {
197 resolver->Reject(DOMException::Create( 196 resolver->Reject(DOMException::Create(
198 kNotSupportedError, 197 kNotSupportedError,
199 "The currentSrc is not compatible with remote playback")); 198 "The currentSrc is not compatible with remote playback"));
200 return promise; 199 return promise;
201 } 200 }
202 201
203 if (state_ == WebRemotePlaybackState::kDisconnected) { 202 prompt_promise_resolver_ = resolver;
204 prompt_promise_resolver_ = resolver; 203 PromptInternal();
205 media_element_->RequestRemotePlayback();
206 } else {
207 prompt_promise_resolver_ = resolver;
208 media_element_->RequestRemotePlaybackControl();
209 }
210 204
211 return promise; 205 return promise;
212 } 206 }
213 207
214 String RemotePlayback::state() const { 208 String RemotePlayback::state() const {
215 return RemotePlaybackStateToString(state_); 209 return RemotePlaybackStateToString(state_);
216 } 210 }
217 211
218 bool RemotePlayback::HasPendingActivity() const { 212 bool RemotePlayback::HasPendingActivity() const {
219 return HasEventListeners() || !availability_callbacks_.IsEmpty() || 213 return HasEventListeners() || !availability_callbacks_.IsEmpty() ||
220 prompt_promise_resolver_; 214 prompt_promise_resolver_;
221 } 215 }
222 216
217 void RemotePlayback::PromptInternal() {
218 if (state_ == WebRemotePlaybackState::kDisconnected)
219 media_element_->RequestRemotePlayback();
220 else
221 media_element_->RequestRemotePlaybackControl();
222 }
223
224 int RemotePlayback::WatchAvailabilityInternal(AvailabilityCallback* callback) {
225 int id;
226 do {
227 id = GetExecutionContext()->CircularSequentialID();
228 } while (!availability_callbacks_.insert(id, callback).is_new_entry);
229
230 // Report the current availability via the callback.
231 // TODO(yuryu): Wrapping notifyInitialAvailability with WTF::Closure as
232 // InspectorInstrumentation requires a globally unique pointer to track tasks.
233 // We can remove the wrapper if InspectorInstrumentation returns a task id.
234 std::unique_ptr<WTF::Closure> task = WTF::Bind(
235 &RemotePlayback::NotifyInitialAvailability, WrapPersistent(this), id);
236 probe::AsyncTaskScheduled(GetExecutionContext(), "watchAvailabilityCallback",
237 task.get());
238 TaskRunnerHelper::Get(TaskType::kMediaElementEvent, GetExecutionContext())
239 ->PostTask(BLINK_FROM_HERE,
240 WTF::Bind(RunNotifyInitialAvailabilityTask,
241 WrapPersistent(GetExecutionContext()),
242 WTF::Passed(std::move(task))));
243 return id;
244 }
245
246 bool RemotePlayback::CancelWatchAvailabilityInternal(int id) {
247 auto iter = availability_callbacks_.Find(id);
248 if (iter == availability_callbacks_.end())
249 return false;
250 availability_callbacks_.erase(iter);
251 return true;
252 }
253
223 void RemotePlayback::NotifyInitialAvailability(int callback_id) { 254 void RemotePlayback::NotifyInitialAvailability(int callback_id) {
224 // May not find the callback if the website cancels it fast enough. 255 // May not find the callback if the website cancels it fast enough.
225 auto iter = availability_callbacks_.Find(callback_id); 256 auto iter = availability_callbacks_.Find(callback_id);
226 if (iter == availability_callbacks_.end()) 257 if (iter == availability_callbacks_.end())
227 return; 258 return;
228 259
229 iter->value->call(this, RemotePlaybackAvailable()); 260 iter->value->Run(this, RemotePlaybackAvailable());
230 } 261 }
231 262
232 void RemotePlayback::StateChanged(WebRemotePlaybackState state) { 263 void RemotePlayback::StateChanged(WebRemotePlaybackState state) {
233 if (state_ == state) 264 if (state_ == state)
234 return; 265 return;
235 266
236 if (prompt_promise_resolver_) { 267 if (prompt_promise_resolver_) {
237 // Changing state to Disconnected from "disconnected" or "connecting" means 268 // Changing state to Disconnected from "disconnected" or "connecting" means
238 // that establishing connection with remote playback device failed. 269 // that establishing connection with remote playback device failed.
239 // Changing state to anything else means the state change intended by 270 // Changing state to anything else means the state change intended by
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 if (availability_ == availability) 302 if (availability_ == availability)
272 return; 303 return;
273 304
274 bool old_availability = RemotePlaybackAvailable(); 305 bool old_availability = RemotePlaybackAvailable();
275 availability_ = availability; 306 availability_ = availability;
276 bool new_availability = RemotePlaybackAvailable(); 307 bool new_availability = RemotePlaybackAvailable();
277 if (new_availability == old_availability) 308 if (new_availability == old_availability)
278 return; 309 return;
279 310
280 for (auto& callback : availability_callbacks_.Values()) 311 for (auto& callback : availability_callbacks_.Values())
281 callback->call(this, new_availability); 312 callback->Run(this, new_availability);
282 } 313 }
283 314
284 void RemotePlayback::PromptCancelled() { 315 void RemotePlayback::PromptCancelled() {
285 if (!prompt_promise_resolver_) 316 if (!prompt_promise_resolver_)
286 return; 317 return;
287 318
288 prompt_promise_resolver_->Reject( 319 prompt_promise_resolver_->Reject(
289 DOMException::Create(kNotAllowedError, "The prompt was dismissed.")); 320 DOMException::Create(kNotAllowedError, "The prompt was dismissed."));
290 prompt_promise_resolver_ = nullptr; 321 prompt_promise_resolver_ = nullptr;
291 } 322 }
(...skipping 15 matching lines...) Expand all
307 media_element_->RequestRemotePlaybackStop(); 338 media_element_->RequestRemotePlaybackStop();
308 } 339 }
309 340
310 DEFINE_TRACE(RemotePlayback) { 341 DEFINE_TRACE(RemotePlayback) {
311 visitor->Trace(availability_callbacks_); 342 visitor->Trace(availability_callbacks_);
312 visitor->Trace(prompt_promise_resolver_); 343 visitor->Trace(prompt_promise_resolver_);
313 visitor->Trace(media_element_); 344 visitor->Trace(media_element_);
314 EventTargetWithInlineData::Trace(visitor); 345 EventTargetWithInlineData::Trace(visitor);
315 } 346 }
316 347
317 DEFINE_TRACE_WRAPPERS(RemotePlayback) {
318 for (auto callback : availability_callbacks_.Values()) {
319 visitor->TraceWrappers(callback);
320 }
321 EventTargetWithInlineData::TraceWrappers(visitor);
322 }
323
324 } // namespace blink 348 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698