| OLD | NEW |
| 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 "webkit/renderer/media/crypto/proxy_decryptor.h" | 5 #include "webkit/renderer/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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 key_error_cb_(key_error_cb), | 63 key_error_cb_(key_error_cb), |
| 64 key_message_cb_(key_message_cb), | 64 key_message_cb_(key_message_cb), |
| 65 need_key_cb_(need_key_cb), | 65 need_key_cb_(need_key_cb), |
| 66 weak_ptr_factory_(this) { | 66 weak_ptr_factory_(this) { |
| 67 } | 67 } |
| 68 | 68 |
| 69 ProxyDecryptor::~ProxyDecryptor() { | 69 ProxyDecryptor::~ProxyDecryptor() { |
| 70 // Destroy the decryptor explicitly before destroying the plugin. | 70 // Destroy the decryptor explicitly before destroying the plugin. |
| 71 { | 71 { |
| 72 base::AutoLock auto_lock(lock_); | 72 base::AutoLock auto_lock(lock_); |
| 73 decryptor_.reset(); | 73 media_keys_.reset(); |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | 77 // TODO(xhwang): Support multiple decryptor notification request (e.g. from |
| 78 // video and audio decoders). The current implementation is okay for the current | 78 // video and audio decoders). The current implementation is okay for the current |
| 79 // media pipeline since we initialize audio and video decoders in sequence. | 79 // media pipeline since we initialize audio and video decoders in sequence. |
| 80 // But ProxyDecryptor should not depend on media pipeline's implementation | 80 // But ProxyDecryptor should not depend on media pipeline's implementation |
| 81 // detail. | 81 // detail. |
| 82 void ProxyDecryptor::SetDecryptorReadyCB( | 82 void ProxyDecryptor::SetDecryptorReadyCB( |
| 83 const media::DecryptorReadyCB& decryptor_ready_cb) { | 83 const media::DecryptorReadyCB& decryptor_ready_cb) { |
| 84 base::AutoLock auto_lock(lock_); | 84 base::AutoLock auto_lock(lock_); |
| 85 | 85 |
| 86 // Cancels the previous decryptor request. | 86 // Cancels the previous decryptor request. |
| 87 if (decryptor_ready_cb.is_null()) { | 87 if (decryptor_ready_cb.is_null()) { |
| 88 if (!decryptor_ready_cb_.is_null()) | 88 if (!decryptor_ready_cb_.is_null()) |
| 89 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); | 89 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); |
| 90 return; | 90 return; |
| 91 } | 91 } |
| 92 | 92 |
| 93 // Normal decryptor request. | 93 // Normal decryptor request. |
| 94 DCHECK(decryptor_ready_cb_.is_null()); | 94 DCHECK(decryptor_ready_cb_.is_null()); |
| 95 if (decryptor_) { | 95 if (media_keys_) { |
| 96 decryptor_ready_cb.Run(decryptor_.get()); | 96 decryptor_ready_cb.Run(media_keys_->GetDecryptor()); |
| 97 return; | 97 return; |
| 98 } | 98 } |
| 99 decryptor_ready_cb_ = decryptor_ready_cb; | 99 decryptor_ready_cb_ = decryptor_ready_cb; |
| 100 } | 100 } |
| 101 | 101 |
| 102 bool ProxyDecryptor::InitializeCDM(const std::string& key_system) { | 102 bool ProxyDecryptor::InitializeCDM(const std::string& key_system) { |
| 103 DVLOG(1) << "InitializeCDM: key_system = " << key_system; | 103 DVLOG(1) << "InitializeCDM: key_system = " << key_system; |
| 104 | 104 |
| 105 base::AutoLock auto_lock(lock_); | 105 base::AutoLock auto_lock(lock_); |
| 106 | 106 |
| 107 DCHECK(!decryptor_); | 107 DCHECK(!media_keys_); |
| 108 decryptor_ = CreateDecryptor(key_system); | 108 media_keys_ = CreateMediaKeys(key_system); |
| 109 | 109 |
| 110 return decryptor_ != NULL; | 110 return media_keys_ != NULL; |
| 111 } | 111 } |
| 112 | 112 |
| 113 | |
| 114 bool ProxyDecryptor::GenerateKeyRequest(const std::string& type, | 113 bool ProxyDecryptor::GenerateKeyRequest(const std::string& type, |
| 115 const uint8* init_data, | 114 const uint8* init_data, |
| 116 int init_data_length) { | 115 int init_data_length) { |
| 117 DCHECK(decryptor_); | 116 if (!media_keys_->GenerateKeyRequest(type, init_data, init_data_length)) { |
| 118 | 117 media_keys_.reset(); |
| 119 if (!decryptor_->GetMediaKeys()->GenerateKeyRequest( | |
| 120 type, init_data, init_data_length)) { | |
| 121 decryptor_.reset(); | |
| 122 return false; | 118 return false; |
| 123 } | 119 } |
| 124 | 120 |
| 125 if (!decryptor_ready_cb_.is_null()) | 121 if (!decryptor_ready_cb_.is_null()) |
| 126 base::ResetAndReturn(&decryptor_ready_cb_).Run(decryptor_.get()); | 122 base::ResetAndReturn(&decryptor_ready_cb_).Run(media_keys_->GetDecryptor()); |
| 127 | 123 |
| 128 return true; | 124 return true; |
| 129 } | 125 } |
| 130 | 126 |
| 131 void ProxyDecryptor::AddKey(const uint8* key, | 127 void ProxyDecryptor::AddKey(const uint8* key, |
| 132 int key_length, | 128 int key_length, |
| 133 const uint8* init_data, | 129 const uint8* init_data, |
| 134 int init_data_length, | 130 int init_data_length, |
| 135 const std::string& session_id) { | 131 const std::string& session_id) { |
| 136 DVLOG(1) << "AddKey()"; | 132 DVLOG(1) << "AddKey()"; |
| 137 | 133 |
| 138 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 134 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 139 decryptor_->GetMediaKeys()->AddKey( | 135 media_keys_->AddKey(key, key_length, init_data, init_data_length, session_id); |
| 140 key, key_length, init_data, init_data_length, session_id); | |
| 141 } | 136 } |
| 142 | 137 |
| 143 void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) { | 138 void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) { |
| 144 DVLOG(1) << "CancelKeyRequest()"; | 139 DVLOG(1) << "CancelKeyRequest()"; |
| 145 | 140 |
| 146 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 141 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 147 decryptor_->GetMediaKeys()->CancelKeyRequest(session_id); | 142 media_keys_->CancelKeyRequest(session_id); |
| 148 } | 143 } |
| 149 | 144 |
| 150 #if defined(ENABLE_PEPPER_CDMS) | 145 #if defined(ENABLE_PEPPER_CDMS) |
| 151 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( | 146 scoped_ptr<media::MediaKeys> ProxyDecryptor::CreatePpapiDecryptor( |
| 152 const std::string& key_system) { | 147 const std::string& key_system) { |
| 153 DCHECK(web_media_player_client_); | 148 DCHECK(web_media_player_client_); |
| 154 DCHECK(web_frame_); | 149 DCHECK(web_frame_); |
| 155 | 150 |
| 156 std::string plugin_type = GetPepperType(key_system); | 151 std::string plugin_type = GetPepperType(key_system); |
| 157 DCHECK(!plugin_type.empty()); | 152 DCHECK(!plugin_type.empty()); |
| 158 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = | 153 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = |
| 159 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); | 154 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); |
| 160 if (!plugin_instance.get()) { | 155 if (!plugin_instance.get()) { |
| 161 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; | 156 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; |
| 162 return scoped_ptr<media::Decryptor>(); | 157 return scoped_ptr<media::MediaKeys>(); |
| 163 } | 158 } |
| 164 | 159 |
| 165 scoped_ptr<webkit_media::PpapiDecryptor> decryptor = PpapiDecryptor::Create( | 160 scoped_ptr<webkit_media::PpapiDecryptor> decryptor = PpapiDecryptor::Create( |
| 166 key_system, | 161 key_system, |
| 167 plugin_instance, | 162 plugin_instance, |
| 168 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 163 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 169 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 164 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 170 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 165 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 171 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()), | 166 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()), |
| 172 base::Bind(&ProxyDecryptor::DestroyHelperPlugin, | 167 base::Bind(&ProxyDecryptor::DestroyHelperPlugin, |
| 173 weak_ptr_factory_.GetWeakPtr())); | 168 weak_ptr_factory_.GetWeakPtr())); |
| 174 | 169 |
| 175 if (!decryptor) | 170 if (!decryptor) |
| 176 DestroyHelperPlugin(); | 171 DestroyHelperPlugin(); |
| 177 // Else the new object will call destroy_plugin_cb to destroy Helper Plugin. | 172 // Else the new object will call destroy_plugin_cb to destroy Helper Plugin. |
| 178 | 173 |
| 179 return scoped_ptr<media::Decryptor>(decryptor.Pass()); | 174 return scoped_ptr<media::MediaKeys>(decryptor.Pass()); |
| 180 } | 175 } |
| 181 #endif // defined(ENABLE_PEPPER_CDMS) | 176 #endif // defined(ENABLE_PEPPER_CDMS) |
| 182 | 177 |
| 183 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( | 178 scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( |
| 184 const std::string& key_system) { | 179 const std::string& key_system) { |
| 185 if (CanUseAesDecryptor(key_system)) | 180 if (CanUseAesDecryptor(key_system)) { |
| 186 return scoped_ptr<media::Decryptor>(new media::AesDecryptor( | 181 return scoped_ptr<media::MediaKeys>(new media::AesDecryptor( |
| 187 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 182 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 188 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 183 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 189 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 184 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 190 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); | 185 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 186 } |
| 191 | 187 |
| 192 #if defined(ENABLE_PEPPER_CDMS) | 188 #if defined(ENABLE_PEPPER_CDMS) |
| 193 // We only support AesDecryptor and PpapiDecryptor. So if we cannot | 189 // We only support AesDecryptor and PpapiDecryptor. So if we cannot |
| 194 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given | 190 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given |
| 195 // |key_system|. | 191 // |key_system|. |
| 196 return CreatePpapiDecryptor(key_system); | 192 return CreatePpapiDecryptor(key_system); |
| 197 #else | 193 #else |
| 198 return scoped_ptr<media::Decryptor>(); | 194 return scoped_ptr<media::MediaKeys>(); |
| 199 #endif // defined(ENABLE_PEPPER_CDMS) | 195 #endif // defined(ENABLE_PEPPER_CDMS) |
| 200 } | 196 } |
| 201 | 197 |
| 202 void ProxyDecryptor::KeyAdded(const std::string& session_id) { | 198 void ProxyDecryptor::KeyAdded(const std::string& session_id) { |
| 203 key_added_cb_.Run(session_id); | 199 key_added_cb_.Run(session_id); |
| 204 } | 200 } |
| 205 | 201 |
| 206 void ProxyDecryptor::KeyError(const std::string& session_id, | 202 void ProxyDecryptor::KeyError(const std::string& session_id, |
| 207 media::MediaKeys::KeyError error_code, | 203 media::MediaKeys::KeyError error_code, |
| 208 int system_code) { | 204 int system_code) { |
| 209 key_error_cb_.Run(session_id, error_code, system_code); | 205 key_error_cb_.Run(session_id, error_code, system_code); |
| 210 } | 206 } |
| 211 | 207 |
| 212 void ProxyDecryptor::KeyMessage(const std::string& session_id, | 208 void ProxyDecryptor::KeyMessage(const std::string& session_id, |
| 213 const std::string& message, | 209 const std::string& message, |
| 214 const std::string& default_url) { | 210 const std::string& default_url) { |
| 215 key_message_cb_.Run(session_id, message, default_url); | 211 key_message_cb_.Run(session_id, message, default_url); |
| 216 } | 212 } |
| 217 | 213 |
| 218 void ProxyDecryptor::NeedKey(const std::string& session_id, | 214 void ProxyDecryptor::NeedKey(const std::string& session_id, |
| 219 const std::string& type, | 215 const std::string& type, |
| 220 scoped_ptr<uint8[]> init_data, | 216 scoped_ptr<uint8[]> init_data, |
| 221 int init_data_size) { | 217 int init_data_size) { |
| 222 need_key_cb_.Run(session_id, type, init_data.Pass(), init_data_size); | 218 need_key_cb_.Run(session_id, type, init_data.Pass(), init_data_size); |
| 223 } | 219 } |
| 224 | 220 |
| 225 } // namespace webkit_media | 221 } // namespace webkit_media |
| OLD | NEW |