Chromium Code Reviews| Index: third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| index bddeb4b1c5ef5001569be2140ada60a7eb849d03..bab59635aed2f24b87946aef688c6e1507824e59 100644 |
| --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| @@ -5,13 +5,14 @@ |
| #include "modules/remoteplayback/RemotePlayback.h" |
| #include "bindings/core/v8/ScriptPromiseResolver.h" |
| +#include "bindings/modules/v8/RemotePlaybackAvailabilityCallback.h" |
| #include "core/HTMLNames.h" |
| #include "core/dom/DOMException.h" |
| #include "core/dom/Document.h" |
| +#include "core/dom/ExecutionContextTask.h" |
| #include "core/events/Event.h" |
| #include "core/html/HTMLMediaElement.h" |
| #include "modules/EventTargetModules.h" |
| -#include "modules/remoteplayback/RemotePlaybackAvailability.h" |
| #include "platform/UserGestureIndicator.h" |
| namespace blink { |
| @@ -64,25 +65,88 @@ ExecutionContext* RemotePlayback::getExecutionContext() const { |
| return &m_mediaElement->document(); |
| } |
| -ScriptPromise RemotePlayback::getAvailability(ScriptState* scriptState) { |
| +ScriptPromise RemotePlayback::watchAvailability( |
| + ScriptState* scriptState, |
| + RemotePlaybackAvailabilityCallback* callback) { |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| ScriptPromise promise = resolver->promise(); |
| + if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { |
| + resolver->reject(DOMException::create( |
| + InvalidStateError, "disableRemotePlayback attribute is present.")); |
| + return promise; |
| + } |
| + |
| + // TODO(avayvod): implement steps 4 and 5 of the algorithm. |
| + // https://crbug.com/655233 |
| + int id; |
| + do { |
| + id = getExecutionContext()->circularSequentialID(); |
| + } while (!m_availabilityCallbacks.add(id, callback).isNewEntry); |
| + |
| + if (!m_scriptState) |
| + m_scriptState = scriptState; |
| + |
| + // Report the current availability via the callback. |
| + getExecutionContext()->postTask( |
| + BLINK_FROM_HERE, |
| + createSameThreadTask(&RemotePlayback::notifyInitialAvailability, |
| + 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
|
| + "watchAvailabilityCallback"); |
| + |
| // TODO(avayvod): Currently the availability is tracked for each media element |
| // as soon as it's created, we probably want to limit that to when the |
| // page/element is visible (see https://crbug.com/597281) and has default |
| // controls. If there are no default controls, we should also start tracking |
| - // availability on demand meaning the Promise returned by getAvailability() |
| + // availability on demand meaning the Promise returned by watchAvailability() |
| // will be resolved asynchronously. |
| - RemotePlaybackAvailability* availability = |
| - RemotePlaybackAvailability::take(resolver, m_availability); |
| - m_availabilityObjects.append(availability); |
| - resolver->resolve(availability); |
| + resolver->resolve(id); |
| + return promise; |
| +} |
| + |
| +ScriptPromise RemotePlayback::cancelWatchAvailability(ScriptState* scriptState, |
| + int id) { |
| + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| + ScriptPromise promise = resolver->promise(); |
| + |
| + if (m_mediaElement->fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) { |
| + resolver->reject(DOMException::create( |
| + InvalidStateError, "disableRemotePlayback attribute is present.")); |
| + return promise; |
| + } |
| + |
| + auto iter = m_availabilityCallbacks.find(id); |
| + if (iter == m_availabilityCallbacks.end()) { |
| + resolver->reject(DOMException::create( |
| + 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/ ?
|
| + return promise; |
| + } |
| + |
| + m_availabilityCallbacks.remove(iter); |
| + |
| + resolver->resolve(); |
| + return promise; |
| +} |
| + |
| +ScriptPromise RemotePlayback::cancelWatchAvailability( |
| + ScriptState* scriptState) { |
| + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| + ScriptPromise promise = resolver->promise(); |
| + |
| + 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
|
| + resolver->reject(DOMException::create( |
| + InvalidStateError, "disableRemotePlayback attribute is present.")); |
| + return promise; |
| + } |
| + |
| + m_availabilityCallbacks.clear(); |
| + |
| + resolver->resolve(); |
| return promise; |
| } |
| ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) { |
| - // TODO(avayvod): implement steps 4, 5, 8, 9 of the algorithm. |
| + // TODO(avayvod): implement steps 5, 8, 9 of the algorithm. |
| // https://crbug.com/647441 |
| ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| ScriptPromise promise = resolver->promise(); |
| @@ -126,10 +190,19 @@ String RemotePlayback::state() const { |
| } |
| bool RemotePlayback::hasPendingActivity() const { |
| - return hasEventListeners() || !m_availabilityObjects.isEmpty() || |
| + return hasEventListeners() || !m_availabilityCallbacks.isEmpty() || |
| m_promptPromiseResolver; |
| } |
| +void RemotePlayback::notifyInitialAvailability(int callbackId) { |
| + // May not find the callback if the website cancels it fast enough. |
| + auto iter = m_availabilityCallbacks.find(callbackId); |
| + if (iter == m_availabilityCallbacks.end()) |
| + return; |
| + |
| + iter->value->call(m_scriptState.get(), this, m_availability); |
| +} |
| + |
| void RemotePlayback::stateChanged(WebRemotePlaybackState state) { |
| // We may get a "disconnected" state change while in the "disconnected" |
| // state if initiated connection fails. So cleanup the promise resolvers |
| @@ -167,8 +240,8 @@ void RemotePlayback::availabilityChanged(bool available) { |
| return; |
| m_availability = available; |
| - for (auto& availabilityObject : m_availabilityObjects) |
| - availabilityObject->availabilityChanged(available); |
| + for (auto& callback : m_availabilityCallbacks.values()) |
| + callback->call(m_scriptState.get(), this, m_availability); |
| } |
| void RemotePlayback::promptCancelled() { |
| @@ -181,7 +254,7 @@ void RemotePlayback::promptCancelled() { |
| } |
| DEFINE_TRACE(RemotePlayback) { |
| - visitor->trace(m_availabilityObjects); |
| + visitor->trace(m_availabilityCallbacks); |
| visitor->trace(m_promptPromiseResolver); |
| visitor->trace(m_mediaElement); |
| EventTargetWithInlineData::trace(visitor); |