Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 9 #include "core/events/Event.h" | 9 #include "core/events/Event.h" |
| 10 #include "core/html/HTMLMediaElement.h" | 10 #include "core/html/HTMLMediaElement.h" |
| 11 #include "modules/EventTargetModules.h" | 11 #include "modules/EventTargetModules.h" |
| 12 #include "modules/remoteplayback/RemotePlaybackAvailability.h" | 12 #include "modules/remoteplayback/RemotePlaybackAvailability.h" |
| 13 #include "platform/UserGestureIndicator.h" | |
| 13 | 14 |
| 14 namespace blink { | 15 namespace blink { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 const AtomicString& remotePlaybackStateToString(WebRemotePlaybackState state) | 19 const AtomicString& remotePlaybackStateToString(WebRemotePlaybackState state) |
| 19 { | 20 { |
| 20 DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected", Atomic String::ConstructFromLiteral)); | 21 DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected", Atomic String::ConstructFromLiteral)); |
| 21 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected", AtomicString::ConstructFromLiteral)); | 22 DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected", AtomicString::ConstructFromLiteral)); |
| 22 | 23 |
| 23 switch (state) { | 24 switch (state) { |
| 24 case WebRemotePlaybackState::Connected: | 25 case WebRemotePlaybackState::Connected: |
| 25 return connectedValue; | 26 return connectedValue; |
| 26 case WebRemotePlaybackState::Disconnected: | 27 case WebRemotePlaybackState::Disconnected: |
| 27 return disconnectedValue; | 28 return disconnectedValue; |
| 28 } | 29 } |
| 29 | 30 |
| 30 ASSERT_NOT_REACHED(); | 31 ASSERT_NOT_REACHED(); |
| 31 return disconnectedValue; | 32 return disconnectedValue; |
| 32 } | 33 } |
| 33 | 34 |
| 34 } // anonymous namespace | 35 } // anonymous namespace |
| 35 | 36 |
| 36 // static | 37 // static |
| 37 RemotePlayback* RemotePlayback::create(HTMLMediaElement& element) | 38 RemotePlayback* RemotePlayback::create(HTMLMediaElement& element) |
| 38 { | 39 { |
| 39 ASSERT(element.document().frame()); | 40 ASSERT(element.document().frame()); |
| 40 | 41 |
| 41 RemotePlayback* remotePlayback = new RemotePlayback( | 42 RemotePlayback* remotePlayback = new RemotePlayback(element); |
| 42 element.document().frame(), | |
| 43 element.isPlayingRemotely() ? WebRemotePlaybackState::Connected : WebRem otePlaybackState::Disconnected, | |
| 44 element.hasRemoteRoutes()); | |
| 45 element.setRemotePlaybackClient(remotePlayback); | 43 element.setRemotePlaybackClient(remotePlayback); |
| 46 | 44 |
| 47 return remotePlayback; | 45 return remotePlayback; |
| 48 } | 46 } |
| 49 | 47 |
| 50 RemotePlayback::RemotePlayback(LocalFrame* frame, WebRemotePlaybackState state, bool availability) | 48 RemotePlayback::RemotePlayback(HTMLMediaElement& element) |
| 51 : DOMWindowProperty(frame) | 49 : DOMWindowProperty(element.document().frame()) |
| 52 , m_state(state) | 50 , m_state(element.isPlayingRemotely() ? WebRemotePlaybackState::Connected : WebRemotePlaybackState::Disconnected) |
| 53 , m_availability(availability) | 51 , m_availability(element.hasRemoteRoutes()) |
| 52 , m_mediaElement(&element) | |
| 54 { | 53 { |
| 55 } | 54 } |
| 56 | 55 |
| 57 const AtomicString& RemotePlayback::interfaceName() const | 56 const AtomicString& RemotePlayback::interfaceName() const |
| 58 { | 57 { |
| 59 return EventTargetNames::RemotePlayback; | 58 return EventTargetNames::RemotePlayback; |
| 60 } | 59 } |
| 61 | 60 |
| 62 ExecutionContext* RemotePlayback::getExecutionContext() const | 61 ExecutionContext* RemotePlayback::getExecutionContext() const |
| 63 { | 62 { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 75 // as soon as it's created, we probably want to limit that to when the page/ element | 74 // as soon as it's created, we probably want to limit that to when the page/ element |
| 76 // is visible (see https://crbug.com/597281) and has default controls. If th ere's | 75 // is visible (see https://crbug.com/597281) and has default controls. If th ere's |
| 77 // no default controls, we should also start tracking availability on demand | 76 // no default controls, we should also start tracking availability on demand |
| 78 // meaning the Promise returned by getAvailability() will be resolved asynch ronously. | 77 // meaning the Promise returned by getAvailability() will be resolved asynch ronously. |
| 79 RemotePlaybackAvailability* availability = RemotePlaybackAvailability::take( resolver, m_availability); | 78 RemotePlaybackAvailability* availability = RemotePlaybackAvailability::take( resolver, m_availability); |
| 80 m_availabilityObjects.append(availability); | 79 m_availabilityObjects.append(availability); |
| 81 resolver->resolve(availability); | 80 resolver->resolve(availability); |
| 82 return promise; | 81 return promise; |
| 83 } | 82 } |
| 84 | 83 |
| 84 ScriptPromise RemotePlayback::connect(ScriptState* scriptState) | |
| 85 { | |
| 86 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
| 87 ScriptPromise promise = resolver->promise(); | |
| 88 | |
| 89 // TODO(avayvod): should we have a flag or reuse the one for the Presentatio nRequest::start(). | |
|
mlamouri (slow - plz ping)
2016/03/24 10:47:06
nit: "a flag to disable user gesture requirement".
whywhat
2016/03/24 16:08:40
Done.
| |
| 90 if (!UserGestureIndicator::processingUserGesture()) { | |
| 91 resolver->reject(DOMException::create(InvalidAccessError, "RemotePlaybac k::connect() requires user gesture.")); | |
| 92 return promise; | |
| 93 } | |
| 94 | |
| 95 if (!m_mediaElement) { | |
| 96 resolver->reject(DOMException::create(InvalidStateError, "The RemotePlay back is no longer associated with a media element.")); | |
| 97 return promise; | |
| 98 } | |
| 99 | |
| 100 m_connectPromiseResolvers.append(resolver); | |
|
mlamouri (slow - plz ping)
2016/03/24 10:47:06
Should you add a TODO that we are only resolving t
whywhat
2016/03/24 16:08:40
We're actually getting a disconnected state change
| |
| 101 if (m_state == WebRemotePlaybackState::Disconnected) | |
| 102 m_mediaElement->requestRemotePlayback(); | |
| 103 else | |
| 104 m_mediaElement->requestRemotePlaybackControl(); | |
| 105 | |
| 106 return promise; | |
| 107 } | |
| 108 | |
| 85 String RemotePlayback::state() const | 109 String RemotePlayback::state() const |
| 86 { | 110 { |
| 87 return remotePlaybackStateToString(m_state); | 111 return remotePlaybackStateToString(m_state); |
| 88 } | 112 } |
| 89 | 113 |
| 90 void RemotePlayback::stateChanged(WebRemotePlaybackState state) | 114 void RemotePlayback::stateChanged(WebRemotePlaybackState state) |
| 91 { | 115 { |
| 92 if (m_state == state) | 116 if (m_state == state) |
| 93 return; | 117 return; |
| 94 | 118 |
| 119 if (state != WebRemotePlaybackState::Disconnected) { | |
| 120 for (auto& resolver : m_connectPromiseResolvers) | |
| 121 resolver->resolve(true); | |
| 122 m_connectPromiseResolvers.clear(); | |
| 123 } | |
| 124 | |
| 95 m_state = state; | 125 m_state = state; |
| 96 dispatchEvent(Event::create(EventTypeNames::statechange)); | 126 dispatchEvent(Event::create(EventTypeNames::statechange)); |
| 97 } | 127 } |
| 98 | 128 |
| 99 void RemotePlayback::availabilityChanged(bool available) | 129 void RemotePlayback::availabilityChanged(bool available) |
| 100 { | 130 { |
| 101 if (m_availability == available) | 131 if (m_availability == available) |
| 102 return; | 132 return; |
| 103 | 133 |
| 104 m_availability = available; | 134 m_availability = available; |
| 105 for (auto& availabilityObject : m_availabilityObjects) | 135 for (auto& availabilityObject : m_availabilityObjects) |
| 106 availabilityObject->availabilityChanged(available); | 136 availabilityObject->availabilityChanged(available); |
| 107 } | 137 } |
| 108 | 138 |
| 109 DEFINE_TRACE(RemotePlayback) | 139 DEFINE_TRACE(RemotePlayback) |
| 110 { | 140 { |
| 111 visitor->trace(m_availabilityObjects); | 141 visitor->trace(m_availabilityObjects); |
| 142 visitor->trace(m_mediaElement); | |
| 143 visitor->trace(m_connectPromiseResolvers); | |
| 112 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor); | 144 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor); |
| 113 DOMWindowProperty::trace(visitor); | 145 DOMWindowProperty::trace(visitor); |
| 114 } | 146 } |
| 115 | 147 |
| 116 } // namespace blink | 148 } // namespace blink |
| OLD | NEW |