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

Side by Side Diff: media/cdm/json_web_key_unittest.cc

Issue 2568463003: media: Rename MediaKeys to ContentDecryptionModule (Closed)
Patch Set: comments addressed Created 4 years 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/json_web_key.cc ('k') | media/cdm/ppapi/external_clear_key/clear_key_cdm.h » ('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 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 "media/cdm/json_web_key.h" 5 #include "media/cdm/json_web_key.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "media/base/content_decryption_module.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
14 15
15 namespace media { 16 namespace media {
16 17
17 class JSONWebKeyTest : public testing::Test { 18 class JSONWebKeyTest : public testing::Test {
18 public: 19 public:
19 JSONWebKeyTest() {} 20 JSONWebKeyTest() {}
20 21
21 protected: 22 protected:
22 void ExtractJWKKeysAndExpect(const std::string& jwk, 23 void ExtractJWKKeysAndExpect(const std::string& jwk,
23 bool expected_result, 24 bool expected_result,
24 size_t expected_number_of_keys) { 25 size_t expected_number_of_keys) {
25 DCHECK(!jwk.empty()); 26 DCHECK(!jwk.empty());
26 KeyIdAndKeyPairs keys; 27 KeyIdAndKeyPairs keys;
27 MediaKeys::SessionType session_type; 28 ContentDecryptionModule::SessionType session_type;
28 EXPECT_EQ(expected_result, 29 EXPECT_EQ(expected_result,
29 ExtractKeysFromJWKSet(jwk, &keys, &session_type)); 30 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
30 EXPECT_EQ(expected_number_of_keys, keys.size()); 31 EXPECT_EQ(expected_number_of_keys, keys.size());
31 } 32 }
32 33
33 void ExtractSessionTypeAndExpect(const std::string& jwk, 34 void ExtractSessionTypeAndExpect(
34 bool expected_result, 35 const std::string& jwk,
35 MediaKeys::SessionType expected_type) { 36 bool expected_result,
37 ContentDecryptionModule::SessionType expected_type) {
36 DCHECK(!jwk.empty()); 38 DCHECK(!jwk.empty());
37 KeyIdAndKeyPairs keys; 39 KeyIdAndKeyPairs keys;
38 MediaKeys::SessionType session_type; 40 ContentDecryptionModule::SessionType session_type;
39 EXPECT_EQ(expected_result, 41 EXPECT_EQ(expected_result,
40 ExtractKeysFromJWKSet(jwk, &keys, &session_type)); 42 ExtractKeysFromJWKSet(jwk, &keys, &session_type));
41 if (expected_result) { 43 if (expected_result) {
42 // Only check if successful. 44 // Only check if successful.
43 EXPECT_EQ(expected_type, session_type); 45 EXPECT_EQ(expected_type, session_type);
44 } 46 }
45 } 47 }
46 48
47 void CreateLicenseAndExpect(const uint8_t* key_id, 49 void CreateLicenseAndExpect(const uint8_t* key_id,
48 int key_id_length, 50 int key_id_length,
49 MediaKeys::SessionType session_type, 51 ContentDecryptionModule::SessionType session_type,
50 const std::string& expected_result) { 52 const std::string& expected_result) {
51 std::vector<uint8_t> result; 53 std::vector<uint8_t> result;
52 KeyIdList key_ids; 54 KeyIdList key_ids;
53 key_ids.push_back(std::vector<uint8_t>(key_id, key_id + key_id_length)); 55 key_ids.push_back(std::vector<uint8_t>(key_id, key_id + key_id_length));
54 CreateLicenseRequest(key_ids, session_type, &result); 56 CreateLicenseRequest(key_ids, session_type, &result);
55 std::string s(result.begin(), result.end()); 57 std::string s(result.begin(), result.end());
56 EXPECT_EQ(expected_result, s); 58 EXPECT_EQ(expected_result, s);
57 } 59 }
58 60
59 void ExtractKeyFromLicenseAndExpect(const std::string& license, 61 void ExtractKeyFromLicenseAndExpect(const std::string& license,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":" 106 "{\"keys\":[{\"k\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":"
105 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}", 107 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":\"oct\"}]}",
106 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3))); 108 GenerateJWKSet(data3, arraysize(data3), data3, arraysize(data3)));
107 109
108 KeyIdAndKeyPairs keys; 110 KeyIdAndKeyPairs keys;
109 keys.push_back( 111 keys.push_back(
110 MakeKeyIdAndKeyPair(data1, arraysize(data1), data1, arraysize(data1))); 112 MakeKeyIdAndKeyPair(data1, arraysize(data1), data1, arraysize(data1)));
111 EXPECT_EQ( 113 EXPECT_EQ(
112 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":" 114 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
113 "\"temporary\"}", 115 "\"temporary\"}",
114 GenerateJWKSet(keys, MediaKeys::TEMPORARY_SESSION)); 116 GenerateJWKSet(keys, ContentDecryptionModule::TEMPORARY_SESSION));
115 keys.push_back( 117 keys.push_back(
116 MakeKeyIdAndKeyPair(data2, arraysize(data2), data2, arraysize(data2))); 118 MakeKeyIdAndKeyPair(data2, arraysize(data2), data2, arraysize(data2)));
117 EXPECT_EQ( 119 EXPECT_EQ(
118 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":" 120 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
119 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}],\"type\":\"persistent-" 121 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"}],\"type\":\"persistent-"
120 "license\"}", 122 "license\"}",
121 GenerateJWKSet(keys, MediaKeys::PERSISTENT_LICENSE_SESSION)); 123 GenerateJWKSet(keys,
124 ContentDecryptionModule::PERSISTENT_LICENSE_SESSION));
122 keys.push_back( 125 keys.push_back(
123 MakeKeyIdAndKeyPair(data3, arraysize(data3), data3, arraysize(data3))); 126 MakeKeyIdAndKeyPair(data3, arraysize(data3), data3, arraysize(data3)));
124 EXPECT_EQ( 127 EXPECT_EQ(
125 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":" 128 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"},{\"k\":"
126 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"},{\"k\":" 129 "\"AQIDBA\",\"kid\":\"AQIDBA\",\"kty\":\"oct\"},{\"k\":"
127 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":" 130 "\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kid\":\"AQIDBAUGBwgJCgsMDQ4PEA\",\"kty\":"
128 "\"oct\"}],\"type\":\"persistent-release-message\"}", 131 "\"oct\"}],\"type\":\"persistent-release-message\"}",
129 GenerateJWKSet(keys, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION)); 132 GenerateJWKSet(
133 keys, ContentDecryptionModule::PERSISTENT_RELEASE_MESSAGE_SESSION));
130 } 134 }
131 135
132 TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) { 136 TEST_F(JSONWebKeyTest, ExtractValidJWKKeys) {
133 // Try an empty 'keys' dictionary. 137 // Try an empty 'keys' dictionary.
134 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0); 138 ExtractJWKKeysAndExpect("{ \"keys\": [] }", true, 0);
135 139
136 // Try a key list with one entry. 140 // Try a key list with one entry.
137 const std::string kJwksOneEntry = 141 const std::string kJwksOneEntry =
138 "{" 142 "{"
139 " \"keys\": [" 143 " \"keys\": ["
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" 394 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
391 " }" 395 " }"
392 " ]" 396 " ]"
393 "}"; 397 "}";
394 ExtractJWKKeysAndExpect(kJwksWithWrongAlg, true, 1); 398 ExtractJWKKeysAndExpect(kJwksWithWrongAlg, true, 1);
395 } 399 }
396 400
397 TEST_F(JSONWebKeyTest, SessionType) { 401 TEST_F(JSONWebKeyTest, SessionType) {
398 ExtractSessionTypeAndExpect( 402 ExtractSessionTypeAndExpect(
399 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", true, 403 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}]}", true,
400 MediaKeys::TEMPORARY_SESSION); 404 ContentDecryptionModule::TEMPORARY_SESSION);
401 ExtractSessionTypeAndExpect( 405 ExtractSessionTypeAndExpect(
402 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":" 406 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
403 "\"temporary\"}", 407 "\"temporary\"}",
404 true, MediaKeys::TEMPORARY_SESSION); 408 true, ContentDecryptionModule::TEMPORARY_SESSION);
405 ExtractSessionTypeAndExpect( 409 ExtractSessionTypeAndExpect(
406 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":" 410 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
407 "\"persistent-license\"}", 411 "\"persistent-license\"}",
408 true, MediaKeys::PERSISTENT_LICENSE_SESSION); 412 true, ContentDecryptionModule::PERSISTENT_LICENSE_SESSION);
409 ExtractSessionTypeAndExpect( 413 ExtractSessionTypeAndExpect(
410 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":" 414 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
411 "\"persistent-release-message\"}", 415 "\"persistent-release-message\"}",
412 true, MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION); 416 true, ContentDecryptionModule::PERSISTENT_RELEASE_MESSAGE_SESSION);
413 ExtractSessionTypeAndExpect( 417 ExtractSessionTypeAndExpect(
414 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":" 418 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":"
415 "\"unknown\"}", 419 "\"unknown\"}",
416 false, MediaKeys::TEMPORARY_SESSION); 420 false, ContentDecryptionModule::TEMPORARY_SESSION);
417 ExtractSessionTypeAndExpect( 421 ExtractSessionTypeAndExpect(
418 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}", 422 "{\"keys\":[{\"k\":\"AQI\",\"kid\":\"AQI\",\"kty\":\"oct\"}],\"type\":3}",
419 false, MediaKeys::TEMPORARY_SESSION); 423 false, ContentDecryptionModule::TEMPORARY_SESSION);
420 } 424 }
421 425
422 TEST_F(JSONWebKeyTest, CreateLicense) { 426 TEST_F(JSONWebKeyTest, CreateLicense) {
423 const uint8_t data1[] = {0x01, 0x02}; 427 const uint8_t data1[] = {0x01, 0x02};
424 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04}; 428 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
425 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 429 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
426 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; 430 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
427 431
428 CreateLicenseAndExpect(data1, 432 CreateLicenseAndExpect(data1, arraysize(data1),
429 arraysize(data1), 433 ContentDecryptionModule::TEMPORARY_SESSION,
430 MediaKeys::TEMPORARY_SESSION,
431 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}"); 434 "{\"kids\":[\"AQI\"],\"type\":\"temporary\"}");
432 CreateLicenseAndExpect( 435 CreateLicenseAndExpect(
433 data1, arraysize(data1), MediaKeys::PERSISTENT_LICENSE_SESSION, 436 data1, arraysize(data1),
437 ContentDecryptionModule::PERSISTENT_LICENSE_SESSION,
434 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}"); 438 "{\"kids\":[\"AQI\"],\"type\":\"persistent-license\"}");
435 CreateLicenseAndExpect( 439 CreateLicenseAndExpect(
436 data1, arraysize(data1), MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION, 440 data1, arraysize(data1),
441 ContentDecryptionModule::PERSISTENT_RELEASE_MESSAGE_SESSION,
437 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}"); 442 "{\"kids\":[\"AQI\"],\"type\":\"persistent-release-message\"}");
438 CreateLicenseAndExpect(data2, 443 CreateLicenseAndExpect(data2, arraysize(data2),
439 arraysize(data2), 444 ContentDecryptionModule::TEMPORARY_SESSION,
440 MediaKeys::TEMPORARY_SESSION,
441 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}"); 445 "{\"kids\":[\"AQIDBA\"],\"type\":\"temporary\"}");
442 CreateLicenseAndExpect(data3, arraysize(data3), 446 CreateLicenseAndExpect(data3, arraysize(data3),
443 MediaKeys::PERSISTENT_LICENSE_SESSION, 447 ContentDecryptionModule::PERSISTENT_LICENSE_SESSION,
444 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":" 448 "{\"kids\":[\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
445 "\"persistent-license\"}"); 449 "\"persistent-license\"}");
446 } 450 }
447 451
448 TEST_F(JSONWebKeyTest, ExtractLicense) { 452 TEST_F(JSONWebKeyTest, ExtractLicense) {
449 const uint8_t data1[] = {0x01, 0x02}; 453 const uint8_t data1[] = {0x01, 0x02};
450 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04}; 454 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
451 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 455 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
452 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; 456 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
453 457
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 &encoded_text); 503 &encoded_text);
500 EXPECT_EQ(encoded_text, "+/37/fv9+w=="); 504 EXPECT_EQ(encoded_text, "+/37/fv9+w==");
501 EXPECT_NE(encoded_text.find('+'), std::string::npos); 505 EXPECT_NE(encoded_text.find('+'), std::string::npos);
502 EXPECT_NE(encoded_text.find('/'), std::string::npos); 506 EXPECT_NE(encoded_text.find('/'), std::string::npos);
503 EXPECT_NE(encoded_text.find('='), std::string::npos); 507 EXPECT_NE(encoded_text.find('='), std::string::npos);
504 508
505 // base64url characters '-' and '_' not in base64 encoding. 509 // base64url characters '-' and '_' not in base64 encoding.
506 EXPECT_EQ(encoded_text.find('-'), std::string::npos); 510 EXPECT_EQ(encoded_text.find('-'), std::string::npos);
507 EXPECT_EQ(encoded_text.find('_'), std::string::npos); 511 EXPECT_EQ(encoded_text.find('_'), std::string::npos);
508 512
509 CreateLicenseAndExpect(data1, arraysize(data1), MediaKeys::TEMPORARY_SESSION, 513 CreateLicenseAndExpect(data1, arraysize(data1),
514 ContentDecryptionModule::TEMPORARY_SESSION,
510 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}"); 515 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}");
511 516
512 ExtractKeyFromLicenseAndExpect( 517 ExtractKeyFromLicenseAndExpect(
513 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1, 518 "{\"kids\":[\"-_37_fv9-w\"],\"type\":\"temporary\"}", true, data1,
514 arraysize(data1)); 519 arraysize(data1));
515 } 520 }
516 521
517 TEST_F(JSONWebKeyTest, MultipleKeys) { 522 TEST_F(JSONWebKeyTest, MultipleKeys) {
518 const uint8_t data1[] = {0x01, 0x02}; 523 const uint8_t data1[] = {0x01, 0x02};
519 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04}; 524 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
520 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 525 const uint8_t data3[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
521 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; 526 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
522 527
523 std::vector<uint8_t> result; 528 std::vector<uint8_t> result;
524 KeyIdList key_ids; 529 KeyIdList key_ids;
525 key_ids.push_back(std::vector<uint8_t>(data1, data1 + arraysize(data1))); 530 key_ids.push_back(std::vector<uint8_t>(data1, data1 + arraysize(data1)));
526 key_ids.push_back(std::vector<uint8_t>(data2, data2 + arraysize(data2))); 531 key_ids.push_back(std::vector<uint8_t>(data2, data2 + arraysize(data2)));
527 key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3))); 532 key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3)));
528 CreateLicenseRequest(key_ids, MediaKeys::TEMPORARY_SESSION, &result); 533 CreateLicenseRequest(key_ids, ContentDecryptionModule::TEMPORARY_SESSION,
534 &result);
529 std::string s(result.begin(), result.end()); 535 std::string s(result.begin(), result.end());
530 EXPECT_EQ( 536 EXPECT_EQ(
531 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":" 537 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"],\"type\":"
532 "\"temporary\"}", 538 "\"temporary\"}",
533 s); 539 s);
534 } 540 }
535 541
536 TEST_F(JSONWebKeyTest, ExtractKeyIds) { 542 TEST_F(JSONWebKeyTest, ExtractKeyIds) {
537 const uint8_t data1[] = {0x01, 0x02}; 543 const uint8_t data1[] = {0x01, 0x02};
538 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04}; 544 const uint8_t data2[] = {0x01, 0x02, 0x03, 0x04};
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3))); 641 key_ids.push_back(std::vector<uint8_t>(data3, data3 + arraysize(data3)));
636 std::vector<uint8_t> init_data3; 642 std::vector<uint8_t> init_data3;
637 CreateKeyIdsInitData(key_ids, &init_data3); 643 CreateKeyIdsInitData(key_ids, &init_data3);
638 std::string result3(init_data3.begin(), init_data3.end()); 644 std::string result3(init_data3.begin(), init_data3.end());
639 EXPECT_EQ(result3, 645 EXPECT_EQ(result3,
640 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}"); 646 "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}");
641 } 647 }
642 648
643 } // namespace media 649 } // namespace media
644 650
OLDNEW
« no previous file with comments | « media/cdm/json_web_key.cc ('k') | media/cdm/ppapi/external_clear_key/clear_key_cdm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698