Chromium Code Reviews| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "media/crypto/aes_decryptor.h" | 10 #include "media/crypto/aes_decryptor.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 const media::KeyErrorCB& key_error_cb, | 61 const media::KeyErrorCB& key_error_cb, |
| 62 const media::KeyMessageCB& key_message_cb, | 62 const media::KeyMessageCB& key_message_cb, |
| 63 const media::NeedKeyCB& need_key_cb) | 63 const media::NeedKeyCB& need_key_cb) |
| 64 : web_media_player_client_(web_media_player_client), | 64 : web_media_player_client_(web_media_player_client), |
| 65 web_frame_(web_frame), | 65 web_frame_(web_frame), |
| 66 did_create_helper_plugin_(false), | 66 did_create_helper_plugin_(false), |
| 67 key_added_cb_(key_added_cb), | 67 key_added_cb_(key_added_cb), |
| 68 key_error_cb_(key_error_cb), | 68 key_error_cb_(key_error_cb), |
| 69 key_message_cb_(key_message_cb), | 69 key_message_cb_(key_message_cb), |
| 70 need_key_cb_(need_key_cb), | 70 need_key_cb_(need_key_cb), |
| 71 decryptor_(NULL), | |
| 71 weak_ptr_factory_(this) { | 72 weak_ptr_factory_(this) { |
| 72 } | 73 } |
| 73 | 74 |
| 74 ProxyDecryptor::~ProxyDecryptor() { | 75 ProxyDecryptor::~ProxyDecryptor() { |
| 75 // Destroy the decryptor explicitly before destroying the plugin. | 76 // Destroy the decryptor explicitly before destroying the plugin. |
| 76 { | 77 { |
| 77 base::AutoLock auto_lock(lock_); | 78 base::AutoLock auto_lock(lock_); |
| 78 decryptor_.reset(); | 79 media_keys_.reset(); |
| 80 decryptor_ = NULL; | |
| 79 } | 81 } |
| 80 | 82 |
| 81 #if defined(ENABLE_PEPPER_CDMS) | 83 #if defined(ENABLE_PEPPER_CDMS) |
| 82 if (did_create_helper_plugin_) | 84 if (did_create_helper_plugin_) |
| 83 DestroyHelperPlugin(web_media_player_client_); | 85 DestroyHelperPlugin(web_media_player_client_); |
| 84 #endif | 86 #endif |
| 85 | 87 |
| 86 web_media_player_client_ = NULL; // We should be done using it now. | 88 web_media_player_client_ = NULL; // We should be done using it now. |
| 87 } | 89 } |
| 88 | 90 |
| 89 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | 91 // TODO(xhwang): Support multiple decryptor notification request (e.g. from |
| 90 // video and audio decoders). The current implementation is okay for the current | 92 // video and audio decoders). The current implementation is okay for the current |
| 91 // media pipeline since we initialize audio and video decoders in sequence. | 93 // media pipeline since we initialize audio and video decoders in sequence. |
| 92 // But ProxyDecryptor should not depend on media pipeline's implementation | 94 // But ProxyDecryptor should not depend on media pipeline's implementation |
| 93 // detail. | 95 // detail. |
| 94 void ProxyDecryptor::SetDecryptorReadyCB( | 96 void ProxyDecryptor::SetDecryptorReadyCB( |
| 95 const media::DecryptorReadyCB& decryptor_ready_cb) { | 97 const media::DecryptorReadyCB& decryptor_ready_cb) { |
| 96 base::AutoLock auto_lock(lock_); | 98 base::AutoLock auto_lock(lock_); |
| 97 | 99 |
| 98 // Cancels the previous decryptor request. | 100 // Cancels the previous decryptor request. |
| 99 if (decryptor_ready_cb.is_null()) { | 101 if (decryptor_ready_cb.is_null()) { |
| 100 if (!decryptor_ready_cb_.is_null()) | 102 if (!decryptor_ready_cb_.is_null()) |
| 101 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); | 103 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); |
| 102 return; | 104 return; |
| 103 } | 105 } |
| 104 | 106 |
| 105 // Normal decryptor request. | 107 // Normal decryptor request. |
| 106 DCHECK(decryptor_ready_cb_.is_null()); | 108 DCHECK(decryptor_ready_cb_.is_null()); |
| 107 if (decryptor_) { | 109 if (decryptor_) { |
| 108 decryptor_ready_cb.Run(decryptor_.get()); | 110 decryptor_ready_cb.Run(decryptor_); |
| 109 return; | 111 return; |
| 110 } | 112 } |
| 111 decryptor_ready_cb_ = decryptor_ready_cb; | 113 decryptor_ready_cb_ = decryptor_ready_cb; |
| 112 } | 114 } |
| 113 | 115 |
| 114 bool ProxyDecryptor::GenerateKeyRequest(const std::string& key_system, | 116 bool ProxyDecryptor::GenerateKeyRequest(const std::string& key_system, |
| 115 const std::string& type, | 117 const std::string& type, |
| 116 const uint8* init_data, | 118 const uint8* init_data, |
| 117 int init_data_length) { | 119 int init_data_length) { |
| 118 // We do not support run-time switching of decryptors. GenerateKeyRequest() | 120 // We do not support run-time switching of decryptors. GenerateKeyRequest() |
| 119 // only creates a new decryptor when |decryptor_| is not initialized. | 121 // only creates a new decryptor when |decryptor_| is not initialized. |
| 120 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; | 122 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; |
| 121 | 123 |
| 122 base::AutoLock auto_lock(lock_); | 124 base::AutoLock auto_lock(lock_); |
| 123 | 125 |
|
ddorwin
2013/05/24 20:39:12
We should probably
DCHECK((media_keys_ == NULL)
xhwang
2013/05/24 23:15:56
This is not necessary now.
| |
| 124 if (!decryptor_) { | 126 if (!media_keys_) { |
| 125 decryptor_ = CreateDecryptor(key_system); | 127 if (!CreateDecryptor(key_system)) { |
| 126 if (!decryptor_) { | |
| 127 key_error_cb_.Run( | 128 key_error_cb_.Run( |
| 128 key_system, std::string(), media::Decryptor::kClientError, 0); | 129 key_system, std::string(), media::MediaKeys::kClientError, 0); |
| 129 return false; | 130 return false; |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 | 133 |
| 133 if (!decryptor_->GenerateKeyRequest(key_system, type, | 134 DCHECK(decryptor_); |
| 134 init_data, init_data_length)) { | 135 |
| 135 decryptor_.reset(); | 136 if (!media_keys_->GenerateKeyRequest(key_system, type, |
|
ddorwin
2013/05/24 20:39:12
We only use media_keys_ in three places. This clas
xhwang
2013/05/24 23:15:56
Done.
| |
| 137 init_data, init_data_length)) { | |
| 138 media_keys_.reset(); | |
| 139 decryptor_ = NULL; | |
| 136 return false; | 140 return false; |
| 137 } | 141 } |
| 138 | 142 |
| 139 if (!decryptor_ready_cb_.is_null()) | 143 if (!decryptor_ready_cb_.is_null()) |
| 140 base::ResetAndReturn(&decryptor_ready_cb_).Run(decryptor_.get()); | 144 base::ResetAndReturn(&decryptor_ready_cb_).Run(decryptor_); |
| 141 | 145 |
| 142 return true; | 146 return true; |
| 143 } | 147 } |
| 144 | 148 |
| 145 void ProxyDecryptor::AddKey(const std::string& key_system, | 149 void ProxyDecryptor::AddKey(const std::string& key_system, |
| 146 const uint8* key, | 150 const uint8* key, |
| 147 int key_length, | 151 int key_length, |
| 148 const uint8* init_data, | 152 const uint8* init_data, |
| 149 int init_data_length, | 153 int init_data_length, |
| 150 const std::string& session_id) { | 154 const std::string& session_id) { |
| 151 DVLOG(1) << "AddKey()"; | 155 DVLOG(1) << "AddKey()"; |
| 152 | 156 |
| 153 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 157 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 154 decryptor_->AddKey(key_system, key, key_length, init_data, init_data_length, | 158 media_keys_->AddKey( |
| 155 session_id); | 159 key_system, key, key_length, init_data, init_data_length, session_id); |
| 156 } | 160 } |
| 157 | 161 |
| 158 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, | 162 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, |
| 159 const std::string& session_id) { | 163 const std::string& session_id) { |
| 160 DVLOG(1) << "CancelKeyRequest()"; | 164 DVLOG(1) << "CancelKeyRequest()"; |
| 161 | 165 |
| 162 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 166 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 163 decryptor_->CancelKeyRequest(key_system, session_id); | 167 media_keys_->CancelKeyRequest(key_system, session_id); |
| 164 } | 168 } |
| 165 | 169 |
| 166 #if defined(ENABLE_PEPPER_CDMS) | 170 #if defined(ENABLE_PEPPER_CDMS) |
| 167 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( | 171 scoped_ptr<PpapiDecryptor> ProxyDecryptor::CreatePpapiDecryptor( |
| 168 const std::string& key_system) { | 172 const std::string& key_system) { |
| 169 DCHECK(web_media_player_client_); | 173 DCHECK(web_media_player_client_); |
| 170 DCHECK(web_frame_); | 174 DCHECK(web_frame_); |
| 171 | 175 |
| 172 std::string plugin_type = GetPepperType(key_system); | 176 std::string plugin_type = GetPepperType(key_system); |
| 173 DCHECK(!plugin_type.empty()); | 177 DCHECK(!plugin_type.empty()); |
| 174 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = | 178 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = |
| 175 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); | 179 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); |
| 176 did_create_helper_plugin_ = plugin_instance != NULL; | 180 did_create_helper_plugin_ = plugin_instance != NULL; |
| 177 if (!did_create_helper_plugin_) { | 181 if (!did_create_helper_plugin_) { |
| 178 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; | 182 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; |
| 179 return scoped_ptr<media::Decryptor>(); | 183 return scoped_ptr<PpapiDecryptor>(); |
| 180 } | 184 } |
| 181 | 185 |
| 182 return scoped_ptr<media::Decryptor>(new PpapiDecryptor( | 186 return scoped_ptr<PpapiDecryptor>(new PpapiDecryptor( |
| 183 plugin_instance, | 187 plugin_instance, |
| 184 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 188 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 185 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 189 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 186 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 190 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 187 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); | 191 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 188 } | 192 } |
| 189 #endif // defined(ENABLE_PEPPER_CDMS) | 193 #endif // defined(ENABLE_PEPPER_CDMS) |
| 190 | 194 |
| 191 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( | 195 bool ProxyDecryptor::CreateDecryptor(const std::string& key_system) { |
| 192 const std::string& key_system) { | 196 if (CanUseAesDecryptor(key_system)) { |
| 193 if (CanUseAesDecryptor(key_system)) | 197 scoped_ptr<media::AesDecryptor> aes_decryptor(new media::AesDecryptor( |
|
ddorwin
2013/05/24 20:39:12
media_keys_ =
xhwang
2013/05/24 23:15:56
This change is reverted.
| |
| 194 return scoped_ptr<media::Decryptor>(new media::AesDecryptor( | |
| 195 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 198 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 196 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 199 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 197 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 200 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 198 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); | 201 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 202 decryptor_ = aes_decryptor.get(); | |
| 203 media_keys_ = aes_decryptor.Pass(); | |
| 204 return true; | |
| 205 } | |
| 199 | 206 |
| 200 #if defined(ENABLE_PEPPER_CDMS) | 207 #if defined(ENABLE_PEPPER_CDMS) |
| 201 // We only support AesDecryptor and PpapiDecryptor. So if we cannot | 208 // We only support AesDecryptor and PpapiDecryptor. So if we cannot |
| 202 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given | 209 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given |
| 203 // |key_system|. | 210 // |key_system|. |
| 204 return CreatePpapiDecryptor(key_system); | 211 scoped_ptr<PpapiDecryptor> ppapi_decryptor = CreatePpapiDecryptor(key_system); |
|
ddorwin
2013/05/24 20:39:12
same
xhwang
2013/05/24 23:15:56
This change is reverted.
| |
| 205 #else | 212 if (ppapi_decryptor) { |
| 206 return scoped_ptr<media::Decryptor>(); | 213 decryptor_ = ppapi_decryptor.get(); |
| 214 media_keys_ = ppapi_decryptor.Pass(); | |
| 215 return true; | |
| 216 } | |
| 207 #endif // defined(ENABLE_PEPPER_CDMS) | 217 #endif // defined(ENABLE_PEPPER_CDMS) |
| 218 | |
| 219 return false; | |
| 208 } | 220 } |
| 209 | 221 |
| 210 void ProxyDecryptor::KeyAdded(const std::string& key_system, | 222 void ProxyDecryptor::KeyAdded(const std::string& key_system, |
| 211 const std::string& session_id) { | 223 const std::string& session_id) { |
| 212 key_added_cb_.Run(key_system, session_id); | 224 key_added_cb_.Run(key_system, session_id); |
| 213 } | 225 } |
| 214 | 226 |
| 215 void ProxyDecryptor::KeyError(const std::string& key_system, | 227 void ProxyDecryptor::KeyError(const std::string& key_system, |
| 216 const std::string& session_id, | 228 const std::string& session_id, |
| 217 media::Decryptor::KeyError error_code, | 229 media::MediaKeys::KeyError error_code, |
| 218 int system_code) { | 230 int system_code) { |
| 219 key_error_cb_.Run(key_system, session_id, error_code, system_code); | 231 key_error_cb_.Run(key_system, session_id, error_code, system_code); |
| 220 } | 232 } |
| 221 | 233 |
| 222 void ProxyDecryptor::KeyMessage(const std::string& key_system, | 234 void ProxyDecryptor::KeyMessage(const std::string& key_system, |
| 223 const std::string& session_id, | 235 const std::string& session_id, |
| 224 const std::string& message, | 236 const std::string& message, |
| 225 const std::string& default_url) { | 237 const std::string& default_url) { |
| 226 key_message_cb_.Run(key_system, session_id, message, default_url); | 238 key_message_cb_.Run(key_system, session_id, message, default_url); |
| 227 } | 239 } |
| 228 | 240 |
| 229 void ProxyDecryptor::NeedKey(const std::string& key_system, | 241 void ProxyDecryptor::NeedKey(const std::string& key_system, |
| 230 const std::string& session_id, | 242 const std::string& session_id, |
| 231 const std::string& type, | 243 const std::string& type, |
| 232 scoped_ptr<uint8[]> init_data, | 244 scoped_ptr<uint8[]> init_data, |
| 233 int init_data_size) { | 245 int init_data_size) { |
| 234 need_key_cb_.Run(key_system, session_id, type, | 246 need_key_cb_.Run(key_system, session_id, type, |
| 235 init_data.Pass(), init_data_size); | 247 init_data.Pass(), init_data_size); |
| 236 } | 248 } |
| 237 | 249 |
| 238 } // namespace webkit_media | 250 } // namespace webkit_media |
| OLD | NEW |