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

Side by Side Diff: content/renderer/media/android/proxy_media_keys.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/android/proxy_media_keys.h" 5 #include "content/renderer/media/android/proxy_media_keys.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "content/renderer/media/android/renderer_media_player_manager.h" 11 #include "content/renderer/media/android/renderer_media_player_manager.h"
12 #include "content/renderer/media/crypto/key_systems.h" 12 #include "content/renderer/media/crypto/key_systems.h"
13 13
14 namespace content { 14 namespace content {
15 15
16 int ProxyMediaKeys::next_cdm_id_ = 16 int ProxyMediaKeys::next_cdm_id_ =
17 RendererMediaPlayerManager::kInvalidCdmId + 1; 17 RendererMediaPlayerManager::kInvalidCdmId + 1;
18 18
19 scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( 19 scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create(
20 const std::string& key_system, 20 const std::string& key_system,
21 const GURL& security_origin, 21 const GURL& security_origin,
22 RendererMediaPlayerManager* manager, 22 RendererMediaPlayerManager* manager,
23 const media::SessionCreatedCB& session_created_cb,
24 const media::SessionMessageCB& session_message_cb, 23 const media::SessionMessageCB& session_message_cb,
25 const media::SessionReadyCB& session_ready_cb, 24 const media::SessionReadyCB& session_ready_cb,
26 const media::SessionClosedCB& session_closed_cb, 25 const media::SessionClosedCB& session_closed_cb,
27 const media::SessionErrorCB& session_error_cb) { 26 const media::SessionErrorCB& session_error_cb) {
28 DCHECK(manager); 27 DCHECK(manager);
29 scoped_ptr<ProxyMediaKeys> proxy_media_keys( 28 scoped_ptr<ProxyMediaKeys> proxy_media_keys(
30 new ProxyMediaKeys(manager, 29 new ProxyMediaKeys(manager,
31 session_created_cb,
32 session_message_cb, 30 session_message_cb,
33 session_ready_cb, 31 session_ready_cb,
34 session_closed_cb, 32 session_closed_cb,
35 session_error_cb)); 33 session_error_cb));
36 proxy_media_keys->InitializeCdm(key_system, security_origin); 34 proxy_media_keys->InitializeCdm(key_system, security_origin);
37 return proxy_media_keys.Pass(); 35 return proxy_media_keys.Pass();
38 } 36 }
39 37
40 ProxyMediaKeys::~ProxyMediaKeys() { 38 ProxyMediaKeys::~ProxyMediaKeys() {
41 manager_->DestroyCdm(cdm_id_); 39 manager_->DestroyCdm(cdm_id_);
xhwang 2014/05/05 20:46:42 We should check session_id_to_promise_map_, reject
jrummell 2014/05/08 23:37:45 Done.
42 } 40 }
43 41
44 bool ProxyMediaKeys::CreateSession(uint32 session_id, 42 void ProxyMediaKeys::CreateSession(
prabhur 2014/05/05 17:57:29 Do we need a bool return value as before to indica
jrummell 2014/05/08 23:37:45 Nope. The promise will be resolved or rejected, po
45 const std::string& content_type, 43 const std::string& init_data_type,
46 const uint8* init_data, 44 const uint8* init_data,
47 int init_data_length) { 45 int init_data_length,
46 SessionType session_type,
47 scoped_ptr<media::MediaKeysSessionPromise> promise) {
48 // TODO(xhwang): Move these checks up to blink and DCHECK here. 48 // TODO(xhwang): Move these checks up to blink and DCHECK here.
49 // See http://crbug.com/342510 49 // See http://crbug.com/342510
50 CdmHostMsg_CreateSession_ContentType session_type; 50 CdmHostMsg_CreateSession_ContentType session_content_type;
51 if (content_type == "audio/mp4" || content_type == "video/mp4") { 51 if (init_data_type == "audio/mp4" || init_data_type == "video/mp4") {
prabhur 2014/05/05 17:57:29 Is the value expected to be always lower case? i.e
jrummell 2014/05/08 23:37:45 The spec states "Initialization data type strings
52 session_type = CREATE_SESSION_TYPE_MP4; 52 session_content_type = CREATE_SESSION_TYPE_MP4;
xhwang 2014/05/05 20:46:42 I don't feel "session_content_type" is an improvem
jrummell 2014/05/08 23:37:45 Done.
53 } else if (content_type == "audio/webm" || content_type == "video/webm") { 53 } else if (init_data_type == "audio/webm" || init_data_type == "video/webm") {
54 session_type = CREATE_SESSION_TYPE_WEBM; 54 session_content_type = CREATE_SESSION_TYPE_WEBM;
55 } else { 55 } else {
56 DLOG(ERROR) << "Unsupported EME CreateSession content type of " 56 DLOG(ERROR) << "Unsupported EME CreateSession content type of "
57 << content_type; 57 << init_data_type;
58 return false; 58 promise->reject(
59 "NotSupportedError",
60 0,
61 "Unsupported EME CreateSession content type of " + init_data_type);
xhwang 2014/05/05 20:46:42 s/content/init data/?
jrummell 2014/05/08 23:37:45 Done.
62 promise.reset();
xhwang 2014/05/05 20:46:42 No need to reset because it'll go out of scope?
jrummell 2014/05/08 23:37:45 Done.
63 return;
59 } 64 }
60 65
66 uint32 session_id = CreateSessionId();
67 AddPromise(session_id, promise.Pass());
61 manager_->CreateSession( 68 manager_->CreateSession(
62 cdm_id_, 69 cdm_id_,
63 session_id, 70 session_id,
64 session_type, 71 session_content_type,
65 std::vector<uint8>(init_data, init_data + init_data_length)); 72 std::vector<uint8>(init_data, init_data + init_data_length));
66 return true;
67 } 73 }
68 74
69 void ProxyMediaKeys::LoadSession(uint32 session_id, 75 void ProxyMediaKeys::LoadSession(
70 const std::string& web_session_id) { 76 const std::string& web_session_id,
77 scoped_ptr<media::MediaKeysSessionPromise> promise) {
71 // TODO(xhwang): Check key system and platform support for LoadSession in 78 // TODO(xhwang): Check key system and platform support for LoadSession in
72 // blink and add NOTREACHED() here. 79 // blink and add NOTREACHED() here.
73 DLOG(ERROR) << "ProxyMediaKeys doesn't support session loading."; 80 DLOG(ERROR) << "ProxyMediaKeys doesn't support session loading.";
74 OnSessionError(session_id, media::MediaKeys::kUnknownError, 0); 81 promise->reject("NotSupportedError", 0, "LoadSession() is not implemented.");
xhwang 2014/05/05 20:46:42 Hmm, I feel we are exposing Blink details to chrom
82 promise.reset();
xhwang 2014/05/05 20:46:42 ditto about reset.
jrummell 2014/05/08 23:37:45 Done.
75 } 83 }
76 84
77 void ProxyMediaKeys::UpdateSession(uint32 session_id, 85 void ProxyMediaKeys::UpdateSession(
78 const uint8* response, 86 const std::string& web_session_id,
79 int response_length) { 87 const uint8* response,
88 int response_length,
89 scoped_ptr<media::MediaKeysSessionPromise> promise) {
90 uint32 session_id = LookupSessionId(web_session_id);
91 AddPromise(session_id, promise.Pass());
80 manager_->UpdateSession( 92 manager_->UpdateSession(
81 cdm_id_, 93 cdm_id_,
82 session_id, 94 session_id,
83 std::vector<uint8>(response, response + response_length)); 95 std::vector<uint8>(response, response + response_length));
84 } 96 }
85 97
86 void ProxyMediaKeys::ReleaseSession(uint32 session_id) { 98 void ProxyMediaKeys::ReleaseSession(
99 const std::string& web_session_id,
100 scoped_ptr<media::MediaKeysSessionPromise> promise) {
101 uint32 session_id = LookupSessionId(web_session_id);
102 AddPromise(session_id, promise.Pass());
87 manager_->ReleaseSession(cdm_id_, session_id); 103 manager_->ReleaseSession(cdm_id_, session_id);
88 } 104 }
89 105
90 void ProxyMediaKeys::OnSessionCreated(uint32 session_id, 106 void ProxyMediaKeys::OnSessionCreated(uint32 session_id,
91 const std::string& web_session_id) { 107 const std::string& web_session_id) {
92 session_created_cb_.Run(session_id, web_session_id); 108 AssignWebSessionId(session_id, web_session_id);
109 scoped_ptr<media::MediaKeysSessionPromise> promise =
110 LookupPromise(session_id);
111 promise->resolve(web_session_id);
112 promise.reset();
93 } 113 }
94 114
95 void ProxyMediaKeys::OnSessionMessage(uint32 session_id, 115 void ProxyMediaKeys::OnSessionMessage(uint32 session_id,
96 const std::vector<uint8>& message, 116 const std::vector<uint8>& message,
97 const std::string& destination_url) { 117 const std::string& destination_url) {
98 session_message_cb_.Run(session_id, message, destination_url); 118 session_message_cb_.Run(
119 LookupWebSessionId(session_id), message, destination_url);
99 } 120 }
100 121
101 void ProxyMediaKeys::OnSessionReady(uint32 session_id) { 122 void ProxyMediaKeys::OnSessionReady(uint32 session_id) {
102 session_ready_cb_.Run(session_id); 123 std::string web_session_id = LookupWebSessionId(session_id);
124 scoped_ptr<media::MediaKeysSessionPromise> promise =
125 LookupPromise(session_id);
126 if (promise) {
127 promise->resolve();
128 promise.reset();
129 } else {
130 session_ready_cb_.Run(web_session_id);
xhwang 2014/05/05 20:46:42 OnSessionReady() should always be the result of an
jrummell 2014/05/08 23:37:45 Added comment.
131 }
103 } 132 }
104 133
105 void ProxyMediaKeys::OnSessionClosed(uint32 session_id) { 134 void ProxyMediaKeys::OnSessionClosed(uint32 session_id) {
106 session_closed_cb_.Run(session_id); 135 std::string web_session_id = LookupWebSessionId(session_id);
136 DropWebSessionId(web_session_id);
137 scoped_ptr<media::MediaKeysSessionPromise> promise =
138 LookupPromise(session_id);
139 if (promise) {
140 promise->resolve();
141 promise.reset();
142 } else {
143 session_closed_cb_.Run(web_session_id);
144 }
xhwang 2014/05/05 20:46:42 We need to comment why the "else" is a legit case
jrummell 2014/05/08 23:37:45 Done.
107 } 145 }
108 146
109 void ProxyMediaKeys::OnSessionError(uint32 session_id, 147 void ProxyMediaKeys::OnSessionError(uint32 session_id,
110 media::MediaKeys::KeyError error_code, 148 media::MediaKeys::KeyError error_code,
111 uint32 system_code) { 149 uint32 system_code) {
112 session_error_cb_.Run(session_id, error_code, system_code); 150 std::string web_session_id = LookupWebSessionId(session_id);
151 scoped_ptr<media::MediaKeysSessionPromise> promise =
152 LookupPromise(session_id);
153 if (promise) {
154 promise->reject("InvalidStateError", 0, std::string());
155 promise.reset();
156 } else {
157 session_error_cb_.Run(
158 web_session_id, "InvalidStateError", system_code, std::string());
159 }
xhwang 2014/05/05 20:46:42 ditto about adding a comment, that the sessionErro
jrummell 2014/05/08 23:37:45 Done.
113 } 160 }
114 161
115 int ProxyMediaKeys::GetCdmId() const { 162 int ProxyMediaKeys::GetCdmId() const {
116 return cdm_id_; 163 return cdm_id_;
117 } 164 }
118 165
119 ProxyMediaKeys::ProxyMediaKeys( 166 ProxyMediaKeys::ProxyMediaKeys(
120 RendererMediaPlayerManager* manager, 167 RendererMediaPlayerManager* manager,
121 const media::SessionCreatedCB& session_created_cb,
122 const media::SessionMessageCB& session_message_cb, 168 const media::SessionMessageCB& session_message_cb,
123 const media::SessionReadyCB& session_ready_cb, 169 const media::SessionReadyCB& session_ready_cb,
124 const media::SessionClosedCB& session_closed_cb, 170 const media::SessionClosedCB& session_closed_cb,
125 const media::SessionErrorCB& session_error_cb) 171 const media::SessionErrorCB& session_error_cb)
126 : manager_(manager), 172 : manager_(manager),
127 cdm_id_(next_cdm_id_++), 173 cdm_id_(next_cdm_id_++),
128 session_created_cb_(session_created_cb),
129 session_message_cb_(session_message_cb), 174 session_message_cb_(session_message_cb),
130 session_ready_cb_(session_ready_cb), 175 session_ready_cb_(session_ready_cb),
131 session_closed_cb_(session_closed_cb), 176 session_closed_cb_(session_closed_cb),
132 session_error_cb_(session_error_cb) { 177 session_error_cb_(session_error_cb),
178 next_session_id_(1) {
133 } 179 }
134 180
135 void ProxyMediaKeys::InitializeCdm(const std::string& key_system, 181 void ProxyMediaKeys::InitializeCdm(const std::string& key_system,
136 const GURL& security_origin) { 182 const GURL& security_origin) {
137 manager_->InitializeCdm(cdm_id_, this, key_system, security_origin); 183 manager_->InitializeCdm(cdm_id_, this, key_system, security_origin);
138 } 184 }
139 185
186 uint32_t ProxyMediaKeys::CreateSessionId() {
187 return next_session_id_++;
188 }
189
190 void ProxyMediaKeys::AssignWebSessionId(uint32_t session_id,
191 const std::string& web_session_id) {
192 web_session_to_session_id_map_.insert(
193 std::make_pair(web_session_id, session_id));
194 }
195
196 uint32_t ProxyMediaKeys::LookupSessionId(const std::string& web_session_id) {
197 return web_session_to_session_id_map_.find(web_session_id)->second;
198 }
199
200 std::string ProxyMediaKeys::LookupWebSessionId(uint32_t session_id) {
201 std::map<std::string, uint32_t>::iterator it;
202 for (it = web_session_to_session_id_map_.begin();
203 it != web_session_to_session_id_map_.end();
204 ++it) {
205 if (it->second == session_id)
206 return it->first;
207 }
208 // Possible to get an error creating a session, so no |web_session_id|
209 // available.
210 return std::string();
211 }
212
213 void ProxyMediaKeys::DropWebSessionId(std::string web_session_id) {
214 web_session_to_session_id_map_.erase(web_session_id);
215 }
216
217 void ProxyMediaKeys::AddPromise(
218 uint32_t session_id,
219 scoped_ptr<media::MediaKeysSessionPromise> promise) {
220 // Should only be one promise outstanding for any |session_id|.
221 DCHECK(session_id_to_promise_map_.find(session_id) ==
222 session_id_to_promise_map_.end());
223 session_id_to_promise_map_.insert(
224 std::make_pair(session_id, promise.release()));
225 }
226
227 scoped_ptr<media::MediaKeysSessionPromise> ProxyMediaKeys::LookupPromise(
228 uint32_t session_id) {
229 std::map<uint32_t, media::MediaKeysSessionPromise*>::iterator it =
230 session_id_to_promise_map_.find(session_id);
231 // May not be a promise associated with this session for asynchronous events.
232 if (it == session_id_to_promise_map_.end())
233 return scoped_ptr<media::MediaKeysSessionPromise>();
234 scoped_ptr<media::MediaKeysSessionPromise> result(it->second);
235 session_id_to_promise_map_.erase(it);
236 return result.Pass();
237 }
238
140 } // namespace content 239 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698