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

Side by Side Diff: media/cdm/ppapi/external_clear_key/clear_key_cdm.cc

Issue 2085063002: media: Add OutputProtectionProxy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
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/ppapi/external_clear_key/clear_key_cdm.h" 5 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <sstream> 9 #include <sstream>
10 #include <utility> 10 #include <utility>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 static bool InitializeFFmpegLibraries() { 51 static bool InitializeFFmpegLibraries() {
52 media::InitializeMediaLibrary(); 52 media::InitializeMediaLibrary();
53 return true; 53 return true;
54 } 54 }
55 static bool g_ffmpeg_lib_initialized = InitializeFFmpegLibraries(); 55 static bool g_ffmpeg_lib_initialized = InitializeFFmpegLibraries();
56 56
57 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 57 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
58 58
59 const char kClearKeyCdmVersion[] = "0.1.0.1"; 59 const char kClearKeyCdmVersion[] = "0.1.0.1";
60 const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; 60 const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey";
61
62 // Variants of external clear key key system to test different scenarios.
61 const char kExternalClearKeyDecryptOnlyKeySystem[] = 63 const char kExternalClearKeyDecryptOnlyKeySystem[] =
62 "org.chromium.externalclearkey.decryptonly"; 64 "org.chromium.externalclearkey.decryptonly";
63 const char kExternalClearKeyFileIOTestKeySystem[] = 65 const char kExternalClearKeyFileIOTestKeySystem[] =
64 "org.chromium.externalclearkey.fileiotest"; 66 "org.chromium.externalclearkey.fileiotest";
67 const char kExternalClearKeyOutputProtectionTestKeySystem[] =
68 "org.chromium.externalclearkey.outputprotectiontest";
65 const char kExternalClearKeyCrashKeySystem[] = 69 const char kExternalClearKeyCrashKeySystem[] =
66 "org.chromium.externalclearkey.crash"; 70 "org.chromium.externalclearkey.crash";
67 71
68 // Constants for the enumalted session that can be loaded by LoadSession(). 72 // Constants for the enumalted session that can be loaded by LoadSession().
69 // These constants need to be in sync with 73 // These constants need to be in sync with
70 // chrome/test/data/media/encrypted_media_utils.js 74 // chrome/test/data/media/encrypted_media_utils.js
71 const char kLoadableSessionId[] = "LoadableSession"; 75 const char kLoadableSessionId[] = "LoadableSession";
72 const uint8_t kLoadableSessionKeyId[] = "0123456789012345"; 76 const uint8_t kLoadableSessionKeyId[] = "0123456789012345";
73 const uint8_t kLoadableSessionKey[] = {0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 77 const uint8_t kLoadableSessionKey[] = {0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14,
74 0xd2, 0x7b, 0x68, 0xef, 0x12, 0x2a, 78 0xd2, 0x7b, 0x68, 0xef, 0x12, 0x2a,
75 0xfc, 0xe4, 0xae, 0x3c}; 79 0xfc, 0xe4, 0xae, 0x3c};
76 80
77 const int64_t kSecondsPerMinute = 60; 81 const int64_t kSecondsPerMinute = 60;
78 const int64_t kMsPerSecond = 1000; 82 const int64_t kMsPerSecond = 1000;
79 const int64_t kInitialTimerDelayMs = 200; 83 const int64_t kInitialTimerDelayMs = 200;
80 const int64_t kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond; 84 const int64_t kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond;
81 // Renewal message header. For prefixed EME, if a key message starts with 85 // Renewal message header. For prefixed EME, if a key message starts with
82 // |kRenewalHeader|, it's a renewal message. Otherwise, it's a key request. 86 // |kRenewalHeader|, it's a renewal message. Otherwise, it's a key request.
83 // FIXME(jrummell): Remove this once prefixed EME goes away. 87 // FIXME(jrummell): Remove this once prefixed EME goes away.
84 const char kRenewalHeader[] = "RENEWAL"; 88 const char kRenewalHeader[] = "RENEWAL";
85 // CDM file IO test result header. 89
86 const char kFileIOTestResultHeader[] = "FILEIOTESTRESULT"; 90 // CDM unit test result header. Must be in sync with UNIT_TEST_RESULT_HEADER in
91 // media/test/data/eme_player_js/globals.js.
92 const char kUnitTestResultHeader[] = "UNIT_TEST_RESULT";
87 93
88 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is 94 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is
89 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. 95 // empty, an empty (end-of-stream) media::DecoderBuffer is returned.
90 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( 96 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom(
91 const cdm::InputBuffer& input_buffer) { 97 const cdm::InputBuffer& input_buffer) {
92 if (!input_buffer.data) { 98 if (!input_buffer.data) {
93 DCHECK(!input_buffer.data_size); 99 DCHECK(!input_buffer.data_size);
94 return media::DecoderBuffer::CreateEOSBuffer(); 100 return media::DecoderBuffer::CreateEOSBuffer();
95 } 101 }
96 102
(...skipping 15 matching lines...) Expand all
112 input_buffer.iv_size), 118 input_buffer.iv_size),
113 subsamples)); 119 subsamples));
114 120
115 output_buffer->set_decrypt_config(std::move(decrypt_config)); 121 output_buffer->set_decrypt_config(std::move(decrypt_config));
116 output_buffer->set_timestamp( 122 output_buffer->set_timestamp(
117 base::TimeDelta::FromMicroseconds(input_buffer.timestamp)); 123 base::TimeDelta::FromMicroseconds(input_buffer.timestamp));
118 124
119 return output_buffer; 125 return output_buffer;
120 } 126 }
121 127
122 static std::string GetFileIOTestResultMessage(bool success) { 128 static std::string GetUnitTestResultMessage(bool success) {
123 std::string message(kFileIOTestResultHeader); 129 std::string message(kUnitTestResultHeader);
124 message += success ? '1' : '0'; 130 message += success ? '1' : '0';
125 return message; 131 return message;
126 } 132 }
127 133
128 static cdm::Error ConvertException(media::MediaKeys::Exception exception_code) { 134 static cdm::Error ConvertException(media::MediaKeys::Exception exception_code) {
129 switch (exception_code) { 135 switch (exception_code) {
130 case media::MediaKeys::NOT_SUPPORTED_ERROR: 136 case media::MediaKeys::NOT_SUPPORTED_ERROR:
131 return cdm::kNotSupportedError; 137 return cdm::kNotSupportedError;
132 case media::MediaKeys::INVALID_STATE_ERROR: 138 case media::MediaKeys::INVALID_STATE_ERROR:
133 return cdm::kInvalidStateError; 139 return cdm::kInvalidStateError;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 void* CreateCdmInstance(int cdm_interface_version, 231 void* CreateCdmInstance(int cdm_interface_version,
226 const char* key_system, uint32_t key_system_size, 232 const char* key_system, uint32_t key_system_size,
227 GetCdmHostFunc get_cdm_host_func, 233 GetCdmHostFunc get_cdm_host_func,
228 void* user_data) { 234 void* user_data) {
229 DVLOG(1) << "CreateCdmInstance()"; 235 DVLOG(1) << "CreateCdmInstance()";
230 236
231 std::string key_system_string(key_system, key_system_size); 237 std::string key_system_string(key_system, key_system_size);
232 if (key_system_string != kExternalClearKeyKeySystem && 238 if (key_system_string != kExternalClearKeyKeySystem &&
233 key_system_string != kExternalClearKeyDecryptOnlyKeySystem && 239 key_system_string != kExternalClearKeyDecryptOnlyKeySystem &&
234 key_system_string != kExternalClearKeyFileIOTestKeySystem && 240 key_system_string != kExternalClearKeyFileIOTestKeySystem &&
241 key_system_string != kExternalClearKeyOutputProtectionTestKeySystem &&
235 key_system_string != kExternalClearKeyCrashKeySystem) { 242 key_system_string != kExternalClearKeyCrashKeySystem) {
236 DVLOG(1) << "Unsupported key system:" << key_system_string; 243 DVLOG(1) << "Unsupported key system:" << key_system_string;
237 return NULL; 244 return NULL;
238 } 245 }
239 246
240 if (cdm_interface_version != media::ClearKeyCdmInterface::kVersion) 247 if (cdm_interface_version != media::ClearKeyCdmInterface::kVersion)
241 return NULL; 248 return NULL;
242 249
243 media::ClearKeyCdmHost* host = static_cast<media::ClearKeyCdmHost*>( 250 media::ClearKeyCdmHost* host = static_cast<media::ClearKeyCdmHost*>(
244 get_cdm_host_func(media::ClearKeyCdmHost::kVersion, user_data)); 251 get_cdm_host_func(media::ClearKeyCdmHost::kVersion, user_data));
(...skipping 17 matching lines...) Expand all
262 : decryptor_(new AesDecryptor( 269 : decryptor_(new AesDecryptor(
263 origin, 270 origin,
264 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), 271 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)),
265 base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), 272 base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)),
266 base::Bind(&ClearKeyCdm::OnSessionKeysChange, 273 base::Bind(&ClearKeyCdm::OnSessionKeysChange,
267 base::Unretained(this)))), 274 base::Unretained(this)))),
268 host_(host), 275 host_(host),
269 key_system_(key_system), 276 key_system_(key_system),
270 has_received_keys_change_event_for_emulated_loadsession_(false), 277 has_received_keys_change_event_for_emulated_loadsession_(false),
271 timer_delay_ms_(kInitialTimerDelayMs), 278 timer_delay_ms_(kInitialTimerDelayMs),
272 renewal_timer_set_(false) { 279 renewal_timer_set_(false),
280 is_running_output_protection_test_(false) {
273 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 281 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
274 channel_count_ = 0; 282 channel_count_ = 0;
275 bits_per_channel_ = 0; 283 bits_per_channel_ = 0;
276 samples_per_second_ = 0; 284 samples_per_second_ = 0;
277 output_timestamp_base_in_microseconds_ = kNoTimestamp; 285 output_timestamp_base_in_microseconds_ = kNoTimestamp;
278 total_samples_generated_ = 0; 286 total_samples_generated_ = 0;
279 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 287 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
280 } 288 }
281 289
282 ClearKeyCdm::~ClearKeyCdm() {} 290 ClearKeyCdm::~ClearKeyCdm() {}
(...skipping 16 matching lines...) Expand all
299 new media::CdmCallbackPromise<std::string>( 307 new media::CdmCallbackPromise<std::string>(
300 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this), 308 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this),
301 promise_id), 309 promise_id),
302 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), 310 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this),
303 promise_id))); 311 promise_id)));
304 decryptor_->CreateSessionAndGenerateRequest( 312 decryptor_->CreateSessionAndGenerateRequest(
305 ConvertSessionType(session_type), ConvertInitDataType(init_data_type), 313 ConvertSessionType(session_type), ConvertInitDataType(init_data_type),
306 std::vector<uint8_t>(init_data, init_data + init_data_size), 314 std::vector<uint8_t>(init_data, init_data + init_data_size),
307 std::move(promise)); 315 std::move(promise));
308 316
309 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) 317 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) {
310 StartFileIOTest(); 318 StartFileIOTest();
319 } else if (key_system_ == kExternalClearKeyOutputProtectionTestKeySystem) {
320 StartOutputProtectionTest();
321 }
311 } 322 }
312 323
313 // Loads a emulated stored session. Currently only |kLoadableSessionId| 324 // Loads a emulated stored session. Currently only |kLoadableSessionId|
314 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is 325 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is
315 // supported. 326 // supported.
316 void ClearKeyCdm::LoadSession(uint32_t promise_id, 327 void ClearKeyCdm::LoadSession(uint32_t promise_id,
317 cdm::SessionType session_type, 328 cdm::SessionType session_type,
318 const char* session_id, 329 const char* session_id,
319 uint32_t session_id_length) { 330 uint32_t session_id_length) {
320 DVLOG(1) << __FUNCTION__; 331 DVLOG(1) << __FUNCTION__;
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 698
688 void ClearKeyCdm::OnPlatformChallengeResponse( 699 void ClearKeyCdm::OnPlatformChallengeResponse(
689 const cdm::PlatformChallengeResponse& response) { 700 const cdm::PlatformChallengeResponse& response) {
690 NOTIMPLEMENTED(); 701 NOTIMPLEMENTED();
691 } 702 }
692 703
693 void ClearKeyCdm::OnQueryOutputProtectionStatus( 704 void ClearKeyCdm::OnQueryOutputProtectionStatus(
694 cdm::QueryResult result, 705 cdm::QueryResult result,
695 uint32_t link_mask, 706 uint32_t link_mask,
696 uint32_t output_protection_mask) { 707 uint32_t output_protection_mask) {
697 NOTIMPLEMENTED(); 708 if (!is_running_output_protection_test_) {
709 NOTREACHED() << "OnQueryOutputProtectionStatus() called unexpectedly.";
710 return;
711 }
712
713 is_running_output_protection_test_ = false;
714
715 // On ChromeOS, status query will fail on Linux ChromeOS build. So we ignore
716 // the query result. On all other platforms, status query should succeed.
717 // TODO(xhwang): Check how to make status query work on ChromeOS in tests.
xhwang 2016/06/21 20:07:18 +kcwu: Any idea how to get this working in a test
kcwu 2016/06/23 09:07:40 Sorry for late reply. How about using base::SysIn
718 #if !defined(OS_CHROMEOS)
719 if (result != cdm::kQuerySucceeded) {
720 OnUnitTestComplete(false);
721 return;
722 }
723 #endif
724 OnUnitTestComplete(true);
698 }; 725 };
699 726
700 void ClearKeyCdm::LoadLoadableSession() { 727 void ClearKeyCdm::LoadLoadableSession() {
701 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, 728 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey,
702 sizeof(kLoadableSessionKey), 729 sizeof(kLoadableSessionKey),
703 kLoadableSessionKeyId, 730 kLoadableSessionKeyId,
704 sizeof(kLoadableSessionKeyId) - 1); 731 sizeof(kLoadableSessionKeyId) - 1);
705 std::unique_ptr<media::SimpleCdmPromise> promise( 732 std::unique_ptr<media::SimpleCdmPromise> promise(
706 new media::CdmCallbackPromise<>( 733 new media::CdmCallbackPromise<>(
707 base::Bind(&ClearKeyCdm::OnLoadSessionUpdated, 734 base::Bind(&ClearKeyCdm::OnLoadSessionUpdated,
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 923
897 int samples_generated = GenerateFakeAudioFramesFromDuration( 924 int samples_generated = GenerateFakeAudioFramesFromDuration(
898 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(), 925 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(),
899 audio_frames); 926 audio_frames);
900 total_samples_generated_ += samples_generated; 927 total_samples_generated_ += samples_generated;
901 928
902 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess; 929 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess;
903 } 930 }
904 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 931 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
905 932
933 void ClearKeyCdm::OnUnitTestComplete(bool success) {
934 std::string message = GetUnitTestResultMessage(success);
935 host_->OnSessionMessage(last_session_id_.data(), last_session_id_.length(),
936 cdm::kLicenseRequest, message.data(),
937 message.length(), NULL, 0);
938 }
939
906 void ClearKeyCdm::StartFileIOTest() { 940 void ClearKeyCdm::StartFileIOTest() {
907 file_io_test_runner_.reset(new FileIOTestRunner( 941 file_io_test_runner_.reset(new FileIOTestRunner(
908 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); 942 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_))));
909 file_io_test_runner_->RunAllTests( 943 file_io_test_runner_->RunAllTests(
910 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); 944 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this)));
911 } 945 }
912 946
913 void ClearKeyCdm::OnFileIOTestComplete(bool success) { 947 void ClearKeyCdm::OnFileIOTestComplete(bool success) {
914 DVLOG(1) << __FUNCTION__ << ": " << success; 948 DVLOG(1) << __FUNCTION__ << ": " << success;
915 std::string message = GetFileIOTestResultMessage(success); 949 OnUnitTestComplete(success);
916 host_->OnSessionMessage(last_session_id_.data(), last_session_id_.length(),
917 cdm::kLicenseRequest, message.data(),
918 message.length(), NULL, 0);
919 file_io_test_runner_.reset(); 950 file_io_test_runner_.reset();
920 } 951 }
921 952
953 void ClearKeyCdm::StartOutputProtectionTest() {
954 is_running_output_protection_test_ = true;
955 host_->QueryOutputProtectionStatus();
956 }
957
922 } // namespace media 958 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698