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

Side by Side Diff: media/filters/pipeline_integration_test.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: One more trybot issue Created 6 years, 6 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
« no previous file with comments | « media/cdm/ppapi/supported_cdm_versions.h ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/pipeline_integration_test_base.h" 5 #include "media/filters/pipeline_integration_test_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "media/base/cdm_promise.h"
12 #include "media/base/decoder_buffer.h" 13 #include "media/base/decoder_buffer.h"
13 #include "media/base/media_keys.h" 14 #include "media/base/media_keys.h"
14 #include "media/base/media_switches.h" 15 #include "media/base/media_switches.h"
15 #include "media/base/test_data_util.h" 16 #include "media/base/test_data_util.h"
16 #include "media/cdm/aes_decryptor.h" 17 #include "media/cdm/aes_decryptor.h"
17 #include "media/cdm/json_web_key.h" 18 #include "media/cdm/json_web_key.h"
18 #include "media/filters/chunk_demuxer.h" 19 #include "media/filters/chunk_demuxer.h"
19 20
20 using testing::_; 21 using testing::_;
21 using testing::AnyNumber; 22 using testing::AnyNumber;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 108
108 // Note: Tests using this class only exercise the DecryptingDemuxerStream path. 109 // Note: Tests using this class only exercise the DecryptingDemuxerStream path.
109 // They do not exercise the Decrypting{Audio|Video}Decoder path. 110 // They do not exercise the Decrypting{Audio|Video}Decoder path.
110 class FakeEncryptedMedia { 111 class FakeEncryptedMedia {
111 public: 112 public:
112 // Defines the behavior of the "app" that responds to EME events. 113 // Defines the behavior of the "app" that responds to EME events.
113 class AppBase { 114 class AppBase {
114 public: 115 public:
115 virtual ~AppBase() {} 116 virtual ~AppBase() {}
116 117
117 virtual void OnSessionCreated(uint32 session_id, 118 virtual void OnSessionMessage(const std::string& web_session_id,
118 const std::string& web_session_id) = 0;
119
120 virtual void OnSessionMessage(uint32 session_id,
121 const std::vector<uint8>& message, 119 const std::vector<uint8>& message,
122 const GURL& destination_url) = 0; 120 const GURL& destination_url) = 0;
123 121
124 virtual void OnSessionReady(uint32 session_id) = 0; 122 virtual void OnSessionReady(const std::string& web_session_id) = 0;
125 123
126 virtual void OnSessionClosed(uint32 session_id) = 0; 124 virtual void OnSessionClosed(const std::string& web_session_id) = 0;
127 125
128 // Errors are not expected unless overridden. 126 // Errors are not expected unless overridden.
129 virtual void OnSessionError(uint32 session_id, 127 virtual void OnSessionError(const std::string& web_session_id,
130 MediaKeys::KeyError error_code, 128 const std::string& error_name,
131 uint32 system_code) { 129 uint32 system_code,
130 const std::string& error_message) {
132 FAIL() << "Unexpected Key Error"; 131 FAIL() << "Unexpected Key Error";
133 } 132 }
134 133
135 virtual void NeedKey(const std::string& type, 134 virtual void NeedKey(const std::string& type,
136 const std::vector<uint8>& init_data, 135 const std::vector<uint8>& init_data,
137 AesDecryptor* decryptor) = 0; 136 AesDecryptor* decryptor) = 0;
138 }; 137 };
139 138
140 FakeEncryptedMedia(AppBase* app) 139 FakeEncryptedMedia(AppBase* app)
141 : decryptor_(base::Bind(&FakeEncryptedMedia::OnSessionCreated, 140 : decryptor_(base::Bind(&FakeEncryptedMedia::OnSessionMessage,
142 base::Unretained(this)),
143 base::Bind(&FakeEncryptedMedia::OnSessionMessage,
144 base::Unretained(this)),
145 base::Bind(&FakeEncryptedMedia::OnSessionReady,
146 base::Unretained(this)),
147 base::Bind(&FakeEncryptedMedia::OnSessionClosed,
148 base::Unretained(this)),
149 base::Bind(&FakeEncryptedMedia::OnSessionError,
150 base::Unretained(this))), 141 base::Unretained(this))),
151 app_(app) {} 142 app_(app) {}
152 143
153 AesDecryptor* decryptor() { 144 AesDecryptor* decryptor() {
154 return &decryptor_; 145 return &decryptor_;
155 } 146 }
156 147
157 // Callbacks for firing session events. Delegate to |app_|. 148 // Callbacks for firing session events. Delegate to |app_|.
158 void OnSessionCreated(uint32 session_id, const std::string& web_session_id) { 149 void OnSessionMessage(const std::string& web_session_id,
159 app_->OnSessionCreated(session_id, web_session_id); 150 const std::vector<uint8>& message,
151 const GURL& destination_url) {
152 app_->OnSessionMessage(web_session_id, message, destination_url);
160 } 153 }
161 154
162 void OnSessionMessage(uint32 session_id, 155 void OnSessionReady(const std::string& web_session_id) {
163 const std::vector<uint8>& message, 156 app_->OnSessionReady(web_session_id);
164 const GURL& destination_url) {
165 app_->OnSessionMessage(session_id, message, destination_url);
166 } 157 }
167 158
168 void OnSessionReady(uint32 session_id) { 159 void OnSessionClosed(const std::string& web_session_id) {
169 app_->OnSessionReady(session_id); 160 app_->OnSessionClosed(web_session_id);
170 } 161 }
171 162
172 void OnSessionClosed(uint32 session_id) { 163 void OnSessionError(const std::string& web_session_id,
173 app_->OnSessionClosed(session_id); 164 const std::string& error_name,
174 } 165 uint32 system_code,
175 166 const std::string& error_message) {
176 void OnSessionError(uint32 session_id, 167 app_->OnSessionError(
177 MediaKeys::KeyError error_code, 168 web_session_id, error_name, system_code, error_message);
178 uint32 system_code) {
179 app_->OnSessionError(session_id, error_code, system_code);
180 } 169 }
181 170
182 void NeedKey(const std::string& type, 171 void NeedKey(const std::string& type,
183 const std::vector<uint8>& init_data) { 172 const std::vector<uint8>& init_data) {
184 app_->NeedKey(type, init_data, &decryptor_); 173 app_->NeedKey(type, init_data, &decryptor_);
185 } 174 }
186 175
187 private: 176 private:
188 AesDecryptor decryptor_; 177 AesDecryptor decryptor_;
189 scoped_ptr<AppBase> app_; 178 scoped_ptr<AppBase> app_;
190 }; 179 };
191 180
181 enum PromiseResult { RESOLVED, REJECTED };
182
192 // Provides |kSecretKey| in response to needkey. 183 // Provides |kSecretKey| in response to needkey.
193 class KeyProvidingApp : public FakeEncryptedMedia::AppBase { 184 class KeyProvidingApp : public FakeEncryptedMedia::AppBase {
194 public: 185 public:
195 KeyProvidingApp() : current_session_id_(0) {} 186 KeyProvidingApp() {}
196 187
197 virtual void OnSessionCreated(uint32 session_id, 188 void OnResolveWithSession(PromiseResult expected,
198 const std::string& web_session_id) OVERRIDE { 189 const std::string& web_session_id) {
199 EXPECT_GT(session_id, 0u); 190 EXPECT_EQ(expected, RESOLVED);
200 EXPECT_FALSE(web_session_id.empty()); 191 EXPECT_GT(web_session_id.length(), 0ul);
192 current_session_id_ = web_session_id;
201 } 193 }
202 194
203 virtual void OnSessionMessage(uint32 session_id, 195 void OnResolve(PromiseResult expected) {
196 EXPECT_EQ(expected, RESOLVED);
197 }
198
199 void OnReject(PromiseResult expected,
200 media::MediaKeys::Exception exception_code,
201 uint32 system_code,
202 const std::string& error_message) {
203 EXPECT_EQ(expected, REJECTED);
204 }
205
206 scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected) {
207 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise(
208 base::Bind(
209 &KeyProvidingApp::OnResolve, base::Unretained(this), expected),
210 base::Bind(
211 &KeyProvidingApp::OnReject, base::Unretained(this), expected)));
212 return promise.Pass();
213 }
214
215 scoped_ptr<NewSessionCdmPromise> CreateSessionPromise(
216 PromiseResult expected) {
217 scoped_ptr<media::NewSessionCdmPromise> promise(
218 new media::NewSessionCdmPromise(
219 base::Bind(&KeyProvidingApp::OnResolveWithSession,
220 base::Unretained(this),
221 expected),
222 base::Bind(
223 &KeyProvidingApp::OnReject, base::Unretained(this), expected)));
224 return promise.Pass();
225 }
226
227 virtual void OnSessionMessage(const std::string& web_session_id,
204 const std::vector<uint8>& message, 228 const std::vector<uint8>& message,
205 const GURL& destination_url) OVERRIDE { 229 const GURL& destination_url) OVERRIDE {
206 EXPECT_GT(session_id, 0u); 230 EXPECT_FALSE(web_session_id.empty());
207 EXPECT_FALSE(message.empty()); 231 EXPECT_FALSE(message.empty());
208 232 EXPECT_EQ(current_session_id_, web_session_id);
209 current_session_id_ = session_id;
210 } 233 }
211 234
212 virtual void OnSessionReady(uint32 session_id) OVERRIDE { 235 virtual void OnSessionReady(const std::string& web_session_id) OVERRIDE {
213 EXPECT_GT(session_id, 0u); 236 EXPECT_EQ(current_session_id_, web_session_id);
214 } 237 }
215 238
216 virtual void OnSessionClosed(uint32 session_id) OVERRIDE { 239 virtual void OnSessionClosed(const std::string& web_session_id) OVERRIDE {
217 EXPECT_GT(session_id, 0u); 240 EXPECT_EQ(current_session_id_, web_session_id);
218 } 241 }
219 242
220 virtual void NeedKey(const std::string& type, 243 virtual void NeedKey(const std::string& type,
221 const std::vector<uint8>& init_data, 244 const std::vector<uint8>& init_data,
222 AesDecryptor* decryptor) OVERRIDE { 245 AesDecryptor* decryptor) OVERRIDE {
223 if (current_session_id_ == 0u) { 246 if (current_session_id_.empty()) {
224 EXPECT_TRUE( 247 decryptor->CreateSession(type,
225 decryptor->CreateSession(12, type, kInitData, arraysize(kInitData))); 248 kInitData,
249 arraysize(kInitData),
250 MediaKeys::TEMPORARY_SESSION,
251 CreateSessionPromise(RESOLVED));
252 EXPECT_FALSE(current_session_id_.empty());
226 } 253 }
227 254
228 EXPECT_EQ(current_session_id_, 12u);
229
230 // Clear Key really needs the key ID in |init_data|. For WebM, they are the 255 // Clear Key really needs the key ID in |init_data|. For WebM, they are the
231 // same, but this is not the case for ISO CENC. Therefore, provide the 256 // same, but this is not the case for ISO CENC. Therefore, provide the
232 // correct key ID. 257 // correct key ID.
233 const uint8* key_id = init_data.empty() ? NULL : &init_data[0]; 258 const uint8* key_id = init_data.empty() ? NULL : &init_data[0];
234 size_t key_id_length = init_data.size(); 259 size_t key_id_length = init_data.size();
235 if (type == kMP4AudioType || type == kMP4VideoType) { 260 if (type == kMP4AudioType || type == kMP4VideoType) {
236 key_id = kKeyId; 261 key_id = kKeyId;
237 key_id_length = arraysize(kKeyId); 262 key_id_length = arraysize(kKeyId);
238 } 263 }
239 264
240 // Convert key into a JSON structure and then add it. 265 // Convert key into a JSON structure and then add it.
241 std::string jwk = GenerateJWKSet( 266 std::string jwk = GenerateJWKSet(
242 kSecretKey, arraysize(kSecretKey), key_id, key_id_length); 267 kSecretKey, arraysize(kSecretKey), key_id, key_id_length);
243 decryptor->UpdateSession(current_session_id_, 268 decryptor->UpdateSession(current_session_id_,
244 reinterpret_cast<const uint8*>(jwk.data()), 269 reinterpret_cast<const uint8*>(jwk.data()),
245 jwk.size()); 270 jwk.size(),
271 CreatePromise(RESOLVED));
246 } 272 }
247 273
248 uint32 current_session_id_; 274 std::string current_session_id_;
249 }; 275 };
250 276
251 class RotatingKeyProvidingApp : public KeyProvidingApp { 277 class RotatingKeyProvidingApp : public KeyProvidingApp {
252 public: 278 public:
253 RotatingKeyProvidingApp() : num_distint_need_key_calls_(0) {} 279 RotatingKeyProvidingApp() : num_distint_need_key_calls_(0) {}
254 virtual ~RotatingKeyProvidingApp() { 280 virtual ~RotatingKeyProvidingApp() {
255 // Expect that NeedKey is fired multiple times with different |init_data|. 281 // Expect that NeedKey is fired multiple times with different |init_data|.
256 EXPECT_GT(num_distint_need_key_calls_, 1u); 282 EXPECT_GT(num_distint_need_key_calls_, 1u);
257 } 283 }
258 284
259 virtual void NeedKey(const std::string& type, 285 virtual void NeedKey(const std::string& type,
260 const std::vector<uint8>& init_data, 286 const std::vector<uint8>& init_data,
261 AesDecryptor* decryptor) OVERRIDE { 287 AesDecryptor* decryptor) OVERRIDE {
262 // Skip the request if the |init_data| has been seen. 288 // Skip the request if the |init_data| has been seen.
263 if (init_data == prev_init_data_) 289 if (init_data == prev_init_data_)
264 return; 290 return;
265 prev_init_data_ = init_data; 291 prev_init_data_ = init_data;
266 ++num_distint_need_key_calls_; 292 ++num_distint_need_key_calls_;
267 293
268 EXPECT_TRUE(decryptor->CreateSession(current_session_id_ + 1, 294 decryptor->CreateSession(type,
269 type, 295 vector_as_array(&init_data),
270 vector_as_array(&init_data), 296 init_data.size(),
271 init_data.size())); 297 MediaKeys::TEMPORARY_SESSION,
298 CreateSessionPromise(RESOLVED));
272 299
273 std::vector<uint8> key_id; 300 std::vector<uint8> key_id;
274 std::vector<uint8> key; 301 std::vector<uint8> key;
275 EXPECT_TRUE(GetKeyAndKeyId(init_data, &key, &key_id)); 302 EXPECT_TRUE(GetKeyAndKeyId(init_data, &key, &key_id));
276 303
277 // Convert key into a JSON structure and then add it. 304 // Convert key into a JSON structure and then add it.
278 std::string jwk = GenerateJWKSet(vector_as_array(&key), 305 std::string jwk = GenerateJWKSet(vector_as_array(&key),
279 key.size(), 306 key.size(),
280 vector_as_array(&key_id), 307 vector_as_array(&key_id),
281 key_id.size()); 308 key_id.size());
282 decryptor->UpdateSession(current_session_id_, 309 decryptor->UpdateSession(current_session_id_,
283 reinterpret_cast<const uint8*>(jwk.data()), 310 reinterpret_cast<const uint8*>(jwk.data()),
284 jwk.size()); 311 jwk.size(),
312 CreatePromise(RESOLVED));
285 } 313 }
286 314
287 private: 315 private:
288 bool GetKeyAndKeyId(std::vector<uint8> init_data, 316 bool GetKeyAndKeyId(std::vector<uint8> init_data,
289 std::vector<uint8>* key, 317 std::vector<uint8>* key,
290 std::vector<uint8>* key_id) { 318 std::vector<uint8>* key_id) {
291 // For WebM, init_data is key_id; for ISO CENC, init_data should contain 319 // For WebM, init_data is key_id; for ISO CENC, init_data should contain
292 // the key_id. We assume key_id is in the end of init_data here (that is 320 // the key_id. We assume key_id is in the end of init_data here (that is
293 // only a reasonable assumption for WebM and clear key ISO CENC). 321 // only a reasonable assumption for WebM and clear key ISO CENC).
294 DCHECK_GE(init_data.size(), arraysize(kKeyId)); 322 DCHECK_GE(init_data.size(), arraysize(kKeyId));
(...skipping 19 matching lines...) Expand all
314 return false; 342 return false;
315 } 343 }
316 344
317 std::vector<uint8> prev_init_data_; 345 std::vector<uint8> prev_init_data_;
318 uint32 num_distint_need_key_calls_; 346 uint32 num_distint_need_key_calls_;
319 }; 347 };
320 348
321 // Ignores needkey and does not perform a license request 349 // Ignores needkey and does not perform a license request
322 class NoResponseApp : public FakeEncryptedMedia::AppBase { 350 class NoResponseApp : public FakeEncryptedMedia::AppBase {
323 public: 351 public:
324 virtual void OnSessionCreated(uint32 session_id, 352 virtual void OnSessionMessage(const std::string& web_session_id,
325 const std::string& web_session_id) OVERRIDE { 353 const std::vector<uint8>& message,
326 EXPECT_GT(session_id, 0u); 354 const GURL& default_url) OVERRIDE {
327 EXPECT_FALSE(web_session_id.empty()); 355 EXPECT_FALSE(web_session_id.empty());
356 EXPECT_FALSE(message.empty());
357 FAIL() << "Unexpected Message";
328 } 358 }
329 359
330 virtual void OnSessionMessage(uint32 session_id, 360 virtual void OnSessionReady(const std::string& web_session_id) OVERRIDE {
331 const std::vector<uint8>& message, 361 EXPECT_FALSE(web_session_id.empty());
332 const GURL& default_url) OVERRIDE {
333 EXPECT_GT(session_id, 0u);
334 EXPECT_FALSE(message.empty());
335 FAIL() << "Unexpected KeyMessage";
336 }
337
338 virtual void OnSessionReady(uint32 session_id) OVERRIDE {
339 EXPECT_GT(session_id, 0u);
340 FAIL() << "Unexpected Ready"; 362 FAIL() << "Unexpected Ready";
341 } 363 }
342 364
343 virtual void OnSessionClosed(uint32 session_id) OVERRIDE { 365 virtual void OnSessionClosed(const std::string& web_session_id) OVERRIDE {
344 EXPECT_GT(session_id, 0u); 366 EXPECT_FALSE(web_session_id.empty());
345 FAIL() << "Unexpected Closed"; 367 FAIL() << "Unexpected Closed";
346 } 368 }
347 369
348 virtual void NeedKey(const std::string& type, 370 virtual void NeedKey(const std::string& type,
349 const std::vector<uint8>& init_data, 371 const std::vector<uint8>& init_data,
350 AesDecryptor* decryptor) OVERRIDE { 372 AesDecryptor* decryptor) OVERRIDE {
351 } 373 }
352 }; 374 };
353 375
354 // Helper class that emulates calls made on the ChunkDemuxer by the 376 // Helper class that emulates calls made on the ChunkDemuxer by the
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 } 1486 }
1465 1487
1466 // For MediaSource tests, generate two sets of tests: one using FrameProcessor, 1488 // For MediaSource tests, generate two sets of tests: one using FrameProcessor,
1467 // and one using LegacyFrameProcessor. 1489 // and one using LegacyFrameProcessor.
1468 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, PipelineIntegrationTest, 1490 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, PipelineIntegrationTest,
1469 Values(false)); 1491 Values(false));
1470 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest, 1492 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest,
1471 Values(true)); 1493 Values(true));
1472 1494
1473 } // namespace media 1495 } // namespace media
OLDNEW
« no previous file with comments | « media/cdm/ppapi/supported_cdm_versions.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698