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

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

Issue 1827853002: [Android, RemotePlayback] Implement HTMLMediaElement.remote.connect(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remote-playback-availability
Patch Set: Fixed timing for rejecting the promises Created 4 years, 8 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 "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 {
127 // We may get a "disconnected" state change while in the "disconnected"
128 // state if initiated connection fails. So cleanup the promise resolvers
129 // before checking if anything changed.
130 // TODO(avayvod): cleanup this logic when we implementing the "connecting"
131 // state.
132 if (state != WebRemotePlaybackState::Disconnected) {
133 for (auto& resolver : m_connectPromiseResolvers)
134 resolver->resolve(true);
135 } else {
136 for (auto& resolver : m_connectPromiseResolvers)
137 resolver->reject(DOMException::create(AbortError, "Failed to connect to the remote device."));
138 }
139 m_connectPromiseResolvers.clear();
140
92 if (m_state == state) 141 if (m_state == state)
93 return; 142 return;
94 143
95 m_state = state; 144 m_state = state;
96 dispatchEvent(Event::create(EventTypeNames::statechange)); 145 dispatchEvent(Event::create(EventTypeNames::statechange));
97 } 146 }
98 147
99 void RemotePlayback::availabilityChanged(bool available) 148 void RemotePlayback::availabilityChanged(bool available)
100 { 149 {
101 if (m_availability == available) 150 if (m_availability == available)
102 return; 151 return;
103 152
104 m_availability = available; 153 m_availability = available;
105 for (auto& availabilityObject : m_availabilityObjects) 154 for (auto& availabilityObject : m_availabilityObjects)
106 availabilityObject->availabilityChanged(available); 155 availabilityObject->availabilityChanged(available);
107 } 156 }
108 157
109 DEFINE_TRACE(RemotePlayback) 158 DEFINE_TRACE(RemotePlayback)
110 { 159 {
111 visitor->trace(m_availabilityObjects); 160 visitor->trace(m_availabilityObjects);
161 visitor->trace(m_mediaElement);
162 visitor->trace(m_connectPromiseResolvers);
112 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor); 163 RefCountedGarbageCollectedEventTargetWithInlineData<RemotePlayback>::trace(v isitor);
113 DOMWindowProperty::trace(visitor); 164 DOMWindowProperty::trace(visitor);
114 } 165 }
115 166
116 } // namespace blink 167 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698