OLD | NEW |
---|---|
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 "webkit/media/crypto/proxy_decryptor.h" | 5 #include "webkit/media/crypto/proxy_decryptor.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 DCHECK(encrypted); | 56 DCHECK(encrypted); |
57 DCHECK(encrypted->GetDecryptConfig()); | 57 DCHECK(encrypted->GetDecryptConfig()); |
58 std::string key_id = encrypted->GetDecryptConfig()->key_id(); | 58 std::string key_id = encrypted->GetDecryptConfig()->key_id(); |
59 scoped_array<uint8> key_id_array(new uint8[key_id.size()]); | 59 scoped_array<uint8> key_id_array(new uint8[key_id.size()]); |
60 memcpy(key_id_array.get(), key_id.data(), key_id.size()); | 60 memcpy(key_id_array.get(), key_id.data(), key_id.size()); |
61 client->NeedKey("", "", key_id_array.Pass(), key_id.size()); | 61 client->NeedKey("", "", key_id_array.Pass(), key_id.size()); |
62 } | 62 } |
63 | 63 |
64 ProxyDecryptor::ProxyDecryptor( | 64 ProxyDecryptor::ProxyDecryptor( |
65 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 65 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
66 media::DecryptorClient* decryptor_client, | 66 const KeyAddedCB& key_added_cb, |
67 const KeyErrorCB& key_error_cb, | |
68 const KeyMessageCB& key_message_cb, | |
69 const NeedKeyCB& need_key_cb, | |
67 WebKit::WebMediaPlayerClient* web_media_player_client, | 70 WebKit::WebMediaPlayerClient* web_media_player_client, |
68 WebKit::WebFrame* web_frame) | 71 WebKit::WebFrame* web_frame) |
69 : decryption_message_loop_(message_loop), | 72 : decryption_message_loop_(message_loop), |
70 client_(decryptor_client), | 73 key_added_cb_(key_added_cb), |
74 key_error_cb_(key_error_cb), | |
75 key_message_cb_(key_message_cb), | |
76 need_key_cb_(need_key_cb), | |
71 web_media_player_client_(web_media_player_client), | 77 web_media_player_client_(web_media_player_client), |
72 web_frame_(web_frame), | 78 web_frame_(web_frame), |
73 is_waiting_for_decryptor_(false), | 79 is_waiting_for_decryptor_(false), |
74 is_canceling_decrypt_(false), | 80 is_canceling_decrypt_(false), |
75 has_new_key_added_(false) { | 81 has_new_key_added_(false) { |
76 } | 82 } |
77 | 83 |
78 ProxyDecryptor::~ProxyDecryptor() { | 84 ProxyDecryptor::~ProxyDecryptor() { |
79 } | 85 } |
80 | 86 |
(...skipping 24 matching lines...) Expand all Loading... | |
105 int init_data_length) { | 111 int init_data_length) { |
106 // We do not support run-time switching of decryptors. GenerateKeyRequest() | 112 // We do not support run-time switching of decryptors. GenerateKeyRequest() |
107 // only creates a new decryptor when |decryptor_| is not initialized. | 113 // only creates a new decryptor when |decryptor_| is not initialized. |
108 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; | 114 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; |
109 | 115 |
110 base::AutoLock auto_lock(lock_); | 116 base::AutoLock auto_lock(lock_); |
111 | 117 |
112 if (!decryptor_) { | 118 if (!decryptor_) { |
113 decryptor_ = CreateDecryptor(key_system); | 119 decryptor_ = CreateDecryptor(key_system); |
114 if (!decryptor_) { | 120 if (!decryptor_) { |
115 client_->KeyError(key_system, "", media::Decryptor::kUnknownError, 0); | 121 KeyError(key_system, "", media::Decryptor::kUnknownError, 0); |
116 return false; | 122 return false; |
117 } | 123 } |
118 } | 124 } |
119 | 125 |
120 if (!decryptor_->GenerateKeyRequest(key_system, | 126 if (!decryptor_->GenerateKeyRequest(key_system, |
121 init_data, init_data_length)) { | 127 init_data, init_data_length)) { |
122 decryptor_.reset(); | 128 decryptor_.reset(); |
123 return false; | 129 return false; |
124 } | 130 } |
125 | 131 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 { | 178 { |
173 base::AutoLock auto_lock(lock_); | 179 base::AutoLock auto_lock(lock_); |
174 decryptor = decryptor_.get(); | 180 decryptor = decryptor_.get(); |
175 } | 181 } |
176 if (!decryptor) { | 182 if (!decryptor) { |
177 DVLOG(1) << "Decrypt(): decryptor not initialized."; | 183 DVLOG(1) << "Decrypt(): decryptor not initialized."; |
178 | 184 |
179 // TODO(xhwang): The same NeedKey may be fired here and multiple times in | 185 // TODO(xhwang): The same NeedKey may be fired here and multiple times in |
180 // OnBufferDecrypted(). While the spec says only one NeedKey should be | 186 // OnBufferDecrypted(). While the spec says only one NeedKey should be |
181 // fired. Leave them as is since the spec about this may change. | 187 // fired. Leave them as is since the spec about this may change. |
182 FireNeedKey(client_, encrypted); | 188 FireNeedKey(this, encrypted); |
183 return; | 189 return; |
184 } | 190 } |
185 | 191 |
186 DecryptPendingBuffer(); | 192 DecryptPendingBuffer(); |
187 } | 193 } |
188 | 194 |
189 void ProxyDecryptor::CancelDecrypt(StreamType stream_type) { | 195 void ProxyDecryptor::CancelDecrypt(StreamType stream_type) { |
190 DVLOG(1) << "CancelDecrypt()"; | 196 DVLOG(1) << "CancelDecrypt()"; |
191 DCHECK(decryption_message_loop_->BelongsToCurrentThread()); | 197 DCHECK(decryption_message_loop_->BelongsToCurrentThread()); |
192 DCHECK_EQ(stream_type, kVideo); // Only support video decrypt-only for now. | 198 DCHECK_EQ(stream_type, kVideo); // Only support video decrypt-only for now. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
235 } | 241 } |
236 | 242 |
237 void ProxyDecryptor::ResetDecoder(StreamType stream_type) { | 243 void ProxyDecryptor::ResetDecoder(StreamType stream_type) { |
238 NOTREACHED() << "ProxyDecryptor does not support audio/video decoding"; | 244 NOTREACHED() << "ProxyDecryptor does not support audio/video decoding"; |
239 } | 245 } |
240 | 246 |
241 void ProxyDecryptor::DeinitializeDecoder(StreamType stream_type) { | 247 void ProxyDecryptor::DeinitializeDecoder(StreamType stream_type) { |
242 NOTREACHED() << "ProxyDecryptor does not support audio/video decoding"; | 248 NOTREACHED() << "ProxyDecryptor does not support audio/video decoding"; |
243 } | 249 } |
244 | 250 |
251 void ProxyDecryptor::KeyAdded(const std::string& key_system, | |
252 const std::string& session_id) { | |
253 key_added_cb_.Run(key_system, session_id); | |
254 } | |
255 | |
256 void ProxyDecryptor::KeyError(const std::string& key_system, | |
257 const std::string& session_id, | |
258 Decryptor::KeyError error_code, | |
259 int system_code) { | |
260 key_error_cb_.Run(key_system, session_id, error_code, system_code); | |
261 } | |
262 | |
263 void ProxyDecryptor::KeyMessage(const std::string& key_system, | |
264 const std::string& session_id, | |
265 scoped_array<uint8> message, | |
266 int message_length, | |
267 const std::string& default_url) { | |
268 key_message_cb_.Run( | |
269 key_system, session_id, message.Pass(), message_length, default_url); | |
270 } | |
271 | |
272 void ProxyDecryptor::NeedKey(const std::string& key_system, | |
273 const std::string& session_id, | |
274 scoped_array<uint8> init_data, | |
275 int init_data_length) { | |
276 need_key_cb_.Run(key_system, session_id, init_data.Pass(), init_data_length); | |
277 } | |
Ami GONE FROM CHROMIUM
2012/10/23 06:52:22
This collection of functions is a pretty strong sm
xhwang
2012/10/23 07:32:13
If we remove DecryptorClient and use callbacks exc
Ami GONE FROM CHROMIUM
2012/10/23 07:42:54
I /think/ so...
But it's late and I'm not as famil
| |
278 | |
245 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( | 279 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( |
246 const std::string& key_system) { | 280 const std::string& key_system) { |
247 DCHECK(client_); | |
248 DCHECK(web_media_player_client_); | 281 DCHECK(web_media_player_client_); |
249 DCHECK(web_frame_); | 282 DCHECK(web_frame_); |
250 | 283 |
251 std::string plugin_type = GetPluginType(key_system); | 284 std::string plugin_type = GetPluginType(key_system); |
252 DCHECK(!plugin_type.empty()); | 285 DCHECK(!plugin_type.empty()); |
253 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = | 286 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = |
254 CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_); | 287 CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_); |
255 if (!plugin_instance) { | 288 if (!plugin_instance) { |
256 DVLOG(1) << "PpapiDecryptor: plugin instance creation failed."; | 289 DVLOG(1) << "PpapiDecryptor: plugin instance creation failed."; |
257 return scoped_ptr<media::Decryptor>(); | 290 return scoped_ptr<media::Decryptor>(); |
258 } | 291 } |
259 | 292 |
260 return scoped_ptr<media::Decryptor>(new PpapiDecryptor(client_, | 293 return scoped_ptr<media::Decryptor>(new PpapiDecryptor(this, |
261 plugin_instance)); | 294 plugin_instance)); |
262 } | 295 } |
263 | 296 |
264 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( | 297 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( |
265 const std::string& key_system) { | 298 const std::string& key_system) { |
266 DCHECK(client_); | |
267 | |
268 if (CanUseAesDecryptor(key_system)) | 299 if (CanUseAesDecryptor(key_system)) |
269 return scoped_ptr<media::Decryptor>(new media::AesDecryptor(client_)); | 300 return scoped_ptr<media::Decryptor>(new media::AesDecryptor(this)); |
270 | 301 |
271 // We only support AesDecryptor and PpapiDecryptor. So if we cannot | 302 // We only support AesDecryptor and PpapiDecryptor. So if we cannot |
272 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given | 303 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given |
273 // |key_system|. | 304 // |key_system|. |
274 return CreatePpapiDecryptor(key_system); | 305 return CreatePpapiDecryptor(key_system); |
275 } | 306 } |
276 | 307 |
277 void ProxyDecryptor::OnNewKeyAdded() { | 308 void ProxyDecryptor::OnNewKeyAdded() { |
278 if (!decryption_message_loop_->BelongsToCurrentThread()) { | 309 if (!decryption_message_loop_->BelongsToCurrentThread()) { |
279 // TODO(xhwang): Using base::Unretained may cause race during destruction | 310 // TODO(xhwang): Using base::Unretained may cause race during destruction |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 DCHECK_EQ(status, media::Decryptor::kNoKey); | 379 DCHECK_EQ(status, media::Decryptor::kNoKey); |
349 DVLOG(1) << "OnBufferDecrypted(): kNoKey fired"; | 380 DVLOG(1) << "OnBufferDecrypted(): kNoKey fired"; |
350 if (need_to_try_again_if_nokey_is_returned) { | 381 if (need_to_try_again_if_nokey_is_returned) { |
351 DecryptPendingBuffer(); | 382 DecryptPendingBuffer(); |
352 return; | 383 return; |
353 } | 384 } |
354 | 385 |
355 // TODO(xhwang): The same NeedKey may be fired multiple times here and also | 386 // TODO(xhwang): The same NeedKey may be fired multiple times here and also |
356 // in Decrypt(). While the spec says only one NeedKey should be fired. Leave | 387 // in Decrypt(). While the spec says only one NeedKey should be fired. Leave |
357 // them as is since the spec about this may change. | 388 // them as is since the spec about this may change. |
358 FireNeedKey(client_, pending_buffer_to_decrypt_); | 389 FireNeedKey(this, pending_buffer_to_decrypt_); |
359 } | 390 } |
360 | 391 |
361 } // namespace webkit_media | 392 } // namespace webkit_media |
OLD | NEW |