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 #if !ENABLE(OILPAN) | |
| 53 , m_mediaElement(element.createWeakPtr()) | |
| 54 #else | |
| 55 , m_mediaElement(&element) | |
| 56 #endif | |
| 54 { | 57 { |
| 55 } | 58 } |
| 56 | 59 |
| 60 #if ENABLE(OILPAN) | |
| 61 RemotePlayback::~RemotePlayback() = default; | |
| 62 #else | |
| 63 RemotePlayback::~RemotePlayback() | |
| 64 { | |
| 65 m_mediaElement->setRemotePlaybackClient(nullptr); | |
| 66 } | |
| 67 #endif | |
| 68 | |
| 57 const AtomicString& RemotePlayback::interfaceName() const | 69 const AtomicString& RemotePlayback::interfaceName() const |
| 58 { | 70 { |
| 59 return EventTargetNames::RemotePlayback; | 71 return EventTargetNames::RemotePlayback; |
| 60 } | 72 } |
| 61 | 73 |
| 62 ExecutionContext* RemotePlayback::getExecutionContext() const | 74 ExecutionContext* RemotePlayback::getExecutionContext() const |
| 63 { | 75 { |
| 64 if (!m_frame) | 76 if (!m_frame) |
| 65 return 0; | 77 return 0; |
| 66 return m_frame->document(); | 78 return m_frame->document(); |
| 67 } | 79 } |
| 68 | 80 |
| 69 ScriptPromise RemotePlayback::getAvailability(ScriptState* scriptState) | 81 ScriptPromise RemotePlayback::getAvailability(ScriptState* scriptState) |
| 70 { | 82 { |
| 71 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 83 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 72 ScriptPromise promise = resolver->promise(); | 84 ScriptPromise promise = resolver->promise(); |
| 73 | 85 |
| 74 // TODO(avayvod): currently the availability is tracked for each media eleme nt | 86 // TODO(avayvod): currently the availability is tracked for each media eleme nt |
| 75 // as soon as it's created, we probably want to limit that to when the page/ element | 87 // 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 | 88 // 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 | 89 // no default controls, we should also start tracking availability on demand |
| 78 // meaning the Promise returned by getAvailability() will be resolved asynch ronously. | 90 // meaning the Promise returned by getAvailability() will be resolved asynch ronously. |
| 79 RemotePlaybackAvailability* availability = RemotePlaybackAvailability::take( resolver, m_availability); | 91 RemotePlaybackAvailability* availability = RemotePlaybackAvailability::take( resolver, m_availability); |
| 80 m_availabilityObjects.append(availability); | 92 m_availabilityObjects.append(availability); |
| 81 resolver->resolve(availability); | 93 resolver->resolve(availability); |
| 82 return promise; | 94 return promise; |
| 83 } | 95 } |
| 84 | 96 |
| 97 ScriptPromise RemotePlayback::connect(ScriptState* scriptState) | |
| 98 { | |
| 99 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | |
| 100 ScriptPromise promise = resolver->promise(); | |
| 101 | |
| 102 // TODO(avayvod): should we have a separate flag to disable the user gesture | |
| 103 // requirement (for tests) or reuse the one for the PresentationRequest::sta rt()? | |
| 104 if (!UserGestureIndicator::processingUserGesture()) { | |
| 105 resolver->reject(DOMException::create(InvalidAccessError, "RemotePlaybac k::connect() requires user gesture.")); | |
| 106 return promise; | |
| 107 } | |
| 108 | |
| 109 if (m_state == WebRemotePlaybackState::Disconnected) { | |
| 110 m_connectPromiseResolvers.append(resolver); | |
| 111 m_mediaElement->requestRemotePlayback(); | |
| 112 } else { | |
| 113 m_mediaElement->requestRemotePlaybackControl(); | |
| 114 resolver->resolve(false); | |
| 115 } | |
| 116 | |
| 117 return promise; | |
| 118 } | |
| 119 | |
| 85 String RemotePlayback::state() const | 120 String RemotePlayback::state() const |
| 86 { | 121 { |
| 87 return remotePlaybackStateToString(m_state); | 122 return remotePlaybackStateToString(m_state); |
| 88 } | 123 } |
| 89 | 124 |
| 90 void RemotePlayback::stateChanged(WebRemotePlaybackState state) | 125 void RemotePlayback::stateChanged(WebRemotePlaybackState state) |
| 91 { | 126 { |
| 92 if (m_state == state) | 127 if (m_state == state) |
| 93 return; | 128 return; |
| 94 | 129 |
| 130 if (state != WebRemotePlaybackState::Disconnected) { | |
| 131 for (auto& resolver : m_connectPromiseResolvers) | |
| 132 resolver->resolve(true); | |
| 133 } else { | |
| 134 for (auto& resolver : m_connectPromiseResolvers) | |
| 135 resolver->reject(DOMException::create(AbortError, "Failed to connect to the remote device.")); | |
|
mlamouri (slow - plz ping)
2016/03/31 10:15:39
That sounds like dead code. I'm not sure how you c
whywhat
2016/03/31 10:57:09
Good catch. I actually prefer resolving the pendin
| |
| 136 } | |
| 137 m_connectPromiseResolvers.clear(); | |
| 138 | |
| 95 m_state = state; | 139 m_state = state; |
| 96 dispatchEvent(Event::create(EventTypeNames::statechange)); | 140 dispatchEvent(Event::create(EventTypeNames::statechange)); |
| 97 } | 141 } |
| 98 | 142 |
| 99 void RemotePlayback::availabilityChanged(bool available) | 143 void RemotePlayback::availabilityChanged(bool available) |
| 100 { | 144 { |
| 101 if (m_availability == available) | 145 if (m_availability == available) |
| 102 return; | 146 return; |
| 103 | 147 |
| 104 m_availability = available; | 148 m_availability = available; |
| 105 for (auto& availabilityObject : m_availabilityObjects) | 149 for (auto& availabilityObject : m_availabilityObjects) |
| 106 availabilityObject->availabilityChanged(available); | 150 availabilityObject->availabilityChanged(available); |
| 107 } | 151 } |
| 108 | 152 |
| 109 DEFINE_TRACE(RemotePlayback) | 153 DEFINE_TRACE(RemotePlayback) |
| 110 { | 154 { |
| 111 visitor->trace(m_availabilityObjects); | 155 visitor->trace(m_availabilityObjects); |
| 156 visitor->trace(m_mediaElement); | |
| 157 visitor->trace(m_connectPromiseResolvers); | |
| 112 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor); | 158 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor); |
| 113 DOMWindowProperty::trace(visitor); | 159 DOMWindowProperty::trace(visitor); |
| 114 } | 160 } |
| 115 | 161 |
| 116 } // namespace blink | 162 } // namespace blink |
| OLD | NEW |