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

Side by Side Diff: third_party/WebKit/Source/modules/mediasession/MediaSession.cpp

Issue 2426653002: Adding mojo MediaSessionClient to support media controls (Closed)
Patch Set: Addressed haraken's comments Created 4 years, 2 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/mediasession/MediaSession.h" 5 #include "modules/mediasession/MediaSession.h"
6 6
7 #include "bindings/core/v8/ScriptState.h" 7 #include "bindings/core/v8/ScriptState.h"
8 #include "core/dom/Document.h" 8 #include "core/dom/Document.h"
9 #include "core/dom/ExecutionContext.h" 9 #include "core/dom/ExecutionContext.h"
10 #include "core/events/Event.h"
10 #include "core/frame/LocalFrame.h" 11 #include "core/frame/LocalFrame.h"
11 #include "modules/EventTargetModules.h" 12 #include "modules/EventTargetModules.h"
12 #include "modules/mediasession/MediaMetadata.h" 13 #include "modules/mediasession/MediaMetadata.h"
13 #include "modules/mediasession/MediaMetadataSanitizer.h" 14 #include "modules/mediasession/MediaMetadataSanitizer.h"
14 #include "public/platform/InterfaceProvider.h" 15 #include "public/platform/InterfaceProvider.h"
15 #include <memory> 16 #include <memory>
16 17
17 namespace blink { 18 namespace blink {
18 19
20 namespace {
21
22 // Map from MediaSessionAction to EventTypeName.
23 const Vector<AtomicString>& getActionEnumToEventNameVec() {
24 DEFINE_THREAD_SAFE_STATIC_LOCAL(
25 Vector<AtomicString>, actionEnumToEventNameVec, []() {
haraken 2016/10/18 19:42:37 I'm asking why we need to create the vector in the
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 OK, Done. Using switch is much cleaner. The cost i
26 Vector<AtomicString>* vec = new Vector<AtomicString>();
27 // Must be in the same order. HashMap cannot be used since 0 is reserved
28 // and cannot be used as key.
29 vec->append(EventTypeNames::play);
30 vec->append(EventTypeNames::pause);
31 vec->append(EventTypeNames::playpause);
32 vec->append(EventTypeNames::previoustrack);
33 vec->append(EventTypeNames::nexttrack);
34 vec->append(EventTypeNames::seekforward);
35 vec->append(EventTypeNames::seekbackward);
36
37 return vec;
38 }());
39 return actionEnumToEventNameVec;
40 }
41
42 using StringToActionEnumMap =
43 HashMap<AtomicString, blink::mojom::blink::MediaSessionAction>;
44
45 // Map from EventTypeName to MediaSessionAction.
46 const StringToActionEnumMap& getEventNameToActionEnumMap() {
47 DEFINE_THREAD_SAFE_STATIC_LOCAL(
48 StringToActionEnumMap, eventNameToActionEnumMap, []() {
haraken 2016/10/18 19:42:37 Ditto.
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Done.
49 StringToActionEnumMap* map = new StringToActionEnumMap();
50 map->add(EventTypeNames::play,
51 blink::mojom::blink::MediaSessionAction::PLAY);
52 map->add(EventTypeNames::pause,
53 blink::mojom::blink::MediaSessionAction::PAUSE);
54 map->add(EventTypeNames::playpause,
55 blink::mojom::blink::MediaSessionAction::PLAY_PAUSE);
56 map->add(EventTypeNames::previoustrack,
57 blink::mojom::blink::MediaSessionAction::PREVIOUS_TRACK);
58 map->add(EventTypeNames::nexttrack,
59 blink::mojom::blink::MediaSessionAction::NEXT_TRACK);
60 map->add(EventTypeNames::seekforward,
61 blink::mojom::blink::MediaSessionAction::SEEK_FORWARD);
62 map->add(EventTypeNames::seekbackward,
63 blink::mojom::blink::MediaSessionAction::SEEK_BACKWARD);
64
65 return map;
66 }());
67 return eventNameToActionEnumMap;
68 }
69
70 } // anonymous namespace
71
19 MediaSession::MediaSession(ScriptState* scriptState) 72 MediaSession::MediaSession(ScriptState* scriptState)
20 : m_scriptState(scriptState) {} 73 : m_scriptState(scriptState), m_clientBinding(this) {}
21 74
22 MediaSession* MediaSession::create(ScriptState* scriptState) { 75 MediaSession* MediaSession::create(ScriptState* scriptState) {
23 return new MediaSession(scriptState); 76 return new MediaSession(scriptState);
24 } 77 }
25 78
79 void MediaSession::dispose() {
80 m_clientBinding.Close();
81 }
82
26 void MediaSession::setMetadata(MediaMetadata* metadata) { 83 void MediaSession::setMetadata(MediaMetadata* metadata) {
27 if (mojom::blink::MediaSessionService* service = 84 if (mojom::blink::MediaSessionService* service =
28 getService(m_scriptState.get())) { 85 getService(m_scriptState.get())) {
29 service->SetMetadata( 86 service->SetMetadata(
30 MediaMetadataSanitizer::sanitizeAndConvertToMojo(metadata)); 87 MediaMetadataSanitizer::sanitizeAndConvertToMojo(metadata));
31 } 88 }
32 } 89 }
33 90
34 MediaMetadata* MediaSession::metadata() const { 91 MediaMetadata* MediaSession::metadata() const {
35 return m_metadata; 92 return m_metadata;
(...skipping 12 matching lines...) Expand all
48 if (!m_service) { 105 if (!m_service) {
49 InterfaceProvider* interfaceProvider = nullptr; 106 InterfaceProvider* interfaceProvider = nullptr;
50 DCHECK(scriptState->getExecutionContext()->isDocument()) 107 DCHECK(scriptState->getExecutionContext()->isDocument())
51 << "MediaSession::getService() is only available from a frame"; 108 << "MediaSession::getService() is only available from a frame";
52 Document* document = toDocument(scriptState->getExecutionContext()); 109 Document* document = toDocument(scriptState->getExecutionContext());
53 if (document->frame()) 110 if (document->frame())
54 interfaceProvider = document->frame()->interfaceProvider(); 111 interfaceProvider = document->frame()->interfaceProvider();
55 112
56 if (interfaceProvider) 113 if (interfaceProvider)
57 interfaceProvider->getInterface(mojo::GetProxy(&m_service)); 114 interfaceProvider->getInterface(mojo::GetProxy(&m_service));
115
116 m_service->SetClient(m_clientBinding.CreateInterfacePtrAndBind());
whywhat 2016/10/18 21:02:57 hm, at this point, if document->frame() is null or
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Done.
58 } 117 }
59 return m_service.get(); 118 return m_service.get();
60 } 119 }
61 120
62 bool MediaSession::addEventListenerInternal( 121 bool MediaSession::addEventListenerInternal(
63 const AtomicString& eventType, 122 const AtomicString& eventType,
64 EventListener* listener, 123 EventListener* listener,
65 const AddEventListenerOptionsResolved& options) { 124 const AddEventListenerOptionsResolved& options) {
66 // TODO(zqzhang): Notify MediaSessionService the handler has been set. See 125 bool result =
67 // https://crbug.com/656563 126 EventTarget::addEventListenerInternal(eventType, listener, options);
whywhat 2016/10/18 21:02:57 nit: do you have to do call the base class method
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Ahh, I was afraid of threading issue. Seems not a
68 return EventTarget::addEventListenerInternal(eventType, listener, options); 127
128 const auto& map = getEventNameToActionEnumMap();
129 auto iter = map.find(eventType);
130 if (iter != map.end()) {
131 if (mojom::blink::MediaSessionService* service =
132 getService(m_scriptState.get())) {
133 service->EnableAction(iter->value);
134 }
135 }
136 return result;
69 } 137 }
70 138
71 bool MediaSession::removeEventListenerInternal( 139 bool MediaSession::removeEventListenerInternal(
72 const AtomicString& eventType, 140 const AtomicString& eventType,
73 const EventListener* listener, 141 const EventListener* listener,
74 const EventListenerOptions& options) { 142 const EventListenerOptions& options) {
75 // TODO(zqzhang): Notify MediaSessionService the handler has been unset. See 143 bool result =
whywhat 2016/10/18 21:02:57 nit: ditto
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Done.
76 // https://crbug.com/656563 144 EventTarget::removeEventListenerInternal(eventType, listener, options);
77 return EventTarget::removeEventListenerInternal(eventType, listener, options); 145
146 const auto& map = getEventNameToActionEnumMap();
147 auto iter = map.find(eventType);
148 if (iter != map.end()) {
149 if (mojom::blink::MediaSessionService* service =
whywhat 2016/10/18 21:02:57 nit: what if the service returned is nullptr?
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Then it won't reach the `then` branch :)
150 getService(m_scriptState.get())) {
151 service->DisableAction(iter->value);
152 }
153 }
154 return result;
155 }
156
157 void MediaSession::DidReceivedAction(
158 blink::mojom::blink::MediaSessionAction action) {
159 LOG(INFO) << static_cast<int>(action);
160 const auto& vec = getActionEnumToEventNameVec();
whywhat 2016/10/18 21:02:57 do the opposite switch statement function (like mo
Zhiqiang Zhang (Slow) 2016/10/19 12:52:06 Done.
161 if (static_cast<int>(action) >= 0 &&
162 static_cast<size_t>(action) < vec.size()) {
163 dispatchEvent(Event::create(vec[static_cast<int>(action)]));
164 }
78 } 165 }
79 166
80 DEFINE_TRACE(MediaSession) { 167 DEFINE_TRACE(MediaSession) {
81 visitor->trace(m_metadata); 168 visitor->trace(m_metadata);
82 EventTargetWithInlineData::trace(visitor); 169 EventTargetWithInlineData::trace(visitor);
83 } 170 }
84 171
85 } // namespace blink 172 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698