| 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" |
| 11 #include "webkit/media/crypto/key_systems.h" |
| 12 |
| 13 #if defined(ENABLE_PEPPER_CDMS) |
| 11 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 13 #include "webkit/media/crypto/key_systems.h" | |
| 14 #include "webkit/media/crypto/ppapi_decryptor.h" | 16 #include "webkit/media/crypto/ppapi_decryptor.h" |
| 15 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 17 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 16 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" | 18 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" |
| 17 // TODO(xhwang): Put this include after "ppapi_plugin_instance.h" for definition | 19 // TODO(xhwang): Put this include after "ppapi_plugin_instance.h" for definition |
| 18 // of "uint8_t", which WebMediaPlayer.h uses without including a header for it. | 20 // of "uint8_t", which WebMediaPlayer.h uses without including a header for it. |
| 19 // See: https://bugs.webkit.org/show_bug.cgi?id=92031 | 21 // See: https://bugs.webkit.org/show_bug.cgi?id=92031 |
| 20 // Fix include order here when the bug is fixed. | 22 // Fix include order here when the bug is fixed. |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.
h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.
h" |
| 24 #endif // defined(ENABLE_PEPPER_CDMS) |
| 22 | 25 |
| 23 namespace webkit_media { | 26 namespace webkit_media { |
| 24 | 27 |
| 28 #if defined(ENABLE_PEPPER_CDMS) |
| 25 // Returns the PluginInstance associated with the Helper Plugin. | 29 // Returns the PluginInstance associated with the Helper Plugin. |
| 26 // If a non-NULL pointer is returned, the caller must call closeHelperPlugin() | 30 // If a non-NULL pointer is returned, the caller must call closeHelperPlugin() |
| 27 // when the Helper Plugin is no longer needed. | 31 // when the Helper Plugin is no longer needed. |
| 28 static scoped_refptr<webkit::ppapi::PluginInstance> CreateHelperPlugin( | 32 static scoped_refptr<webkit::ppapi::PluginInstance> CreateHelperPlugin( |
| 29 const std::string& plugin_type, | 33 const std::string& plugin_type, |
| 30 WebKit::WebMediaPlayerClient* web_media_player_client, | 34 WebKit::WebMediaPlayerClient* web_media_player_client, |
| 31 WebKit::WebFrame* web_frame) { | 35 WebKit::WebFrame* web_frame) { |
| 32 DCHECK(web_media_player_client); | 36 DCHECK(web_media_player_client); |
| 33 DCHECK(web_frame); | 37 DCHECK(web_frame); |
| 34 | 38 |
| 35 WebKit::WebPlugin* web_plugin = web_media_player_client->createHelperPlugin( | 39 WebKit::WebPlugin* web_plugin = web_media_player_client->createHelperPlugin( |
| 36 WebKit::WebString::fromUTF8(plugin_type), web_frame); | 40 WebKit::WebString::fromUTF8(plugin_type), web_frame); |
| 37 if (!web_plugin) | 41 if (!web_plugin) |
| 38 return NULL; | 42 return NULL; |
| 39 | 43 |
| 40 DCHECK(!web_plugin->isPlaceholder()); // Prevented by WebKit. | 44 DCHECK(!web_plugin->isPlaceholder()); // Prevented by WebKit. |
| 41 // Only Pepper plugins are supported, so it must be a ppapi object. | 45 // Only Pepper plugins are supported, so it must be a ppapi object. |
| 42 webkit::ppapi::WebPluginImpl* ppapi_plugin = | 46 webkit::ppapi::WebPluginImpl* ppapi_plugin = |
| 43 static_cast<webkit::ppapi::WebPluginImpl*>(web_plugin); | 47 static_cast<webkit::ppapi::WebPluginImpl*>(web_plugin); |
| 44 return ppapi_plugin->instance(); | 48 return ppapi_plugin->instance(); |
| 45 } | 49 } |
| 46 | 50 |
| 47 static void DestroyHelperPlugin( | 51 static void DestroyHelperPlugin( |
| 48 WebKit::WebMediaPlayerClient* web_media_player_client) { | 52 WebKit::WebMediaPlayerClient* web_media_player_client) { |
| 49 web_media_player_client->closeHelperPlugin(); | 53 web_media_player_client->closeHelperPlugin(); |
| 50 } | 54 } |
| 55 #endif // defined(ENABLE_PEPPER_CDMS) |
| 51 | 56 |
| 52 ProxyDecryptor::ProxyDecryptor( | 57 ProxyDecryptor::ProxyDecryptor( |
| 53 WebKit::WebMediaPlayerClient* web_media_player_client, | 58 WebKit::WebMediaPlayerClient* web_media_player_client, |
| 54 WebKit::WebFrame* web_frame, | 59 WebKit::WebFrame* web_frame, |
| 55 const media::KeyAddedCB& key_added_cb, | 60 const media::KeyAddedCB& key_added_cb, |
| 56 const media::KeyErrorCB& key_error_cb, | 61 const media::KeyErrorCB& key_error_cb, |
| 57 const media::KeyMessageCB& key_message_cb, | 62 const media::KeyMessageCB& key_message_cb, |
| 58 const media::NeedKeyCB& need_key_cb) | 63 const media::NeedKeyCB& need_key_cb) |
| 59 : web_media_player_client_(web_media_player_client), | 64 : web_media_player_client_(web_media_player_client), |
| 60 web_frame_(web_frame), | 65 web_frame_(web_frame), |
| 61 did_create_helper_plugin_(false), | 66 did_create_helper_plugin_(false), |
| 62 key_added_cb_(key_added_cb), | 67 key_added_cb_(key_added_cb), |
| 63 key_error_cb_(key_error_cb), | 68 key_error_cb_(key_error_cb), |
| 64 key_message_cb_(key_message_cb), | 69 key_message_cb_(key_message_cb), |
| 65 need_key_cb_(need_key_cb), | 70 need_key_cb_(need_key_cb), |
| 66 weak_ptr_factory_(this) { | 71 weak_ptr_factory_(this) { |
| 67 } | 72 } |
| 68 | 73 |
| 69 ProxyDecryptor::~ProxyDecryptor() { | 74 ProxyDecryptor::~ProxyDecryptor() { |
| 70 // Destroy the decryptor explicitly before destroying the plugin. | 75 // Destroy the decryptor explicitly before destroying the plugin. |
| 71 { | 76 { |
| 72 base::AutoLock auto_lock(lock_); | 77 base::AutoLock auto_lock(lock_); |
| 73 decryptor_.reset(); | 78 decryptor_.reset(); |
| 74 } | 79 } |
| 75 | 80 |
| 81 #if defined(ENABLE_PEPPER_CDMS) |
| 76 if (did_create_helper_plugin_) | 82 if (did_create_helper_plugin_) |
| 77 DestroyHelperPlugin(web_media_player_client_); | 83 DestroyHelperPlugin(web_media_player_client_); |
| 84 #endif |
| 78 | 85 |
| 79 web_media_player_client_ = NULL; // We should be done using it now. | 86 web_media_player_client_ = NULL; // We should be done using it now. |
| 80 } | 87 } |
| 81 | 88 |
| 82 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | 89 // TODO(xhwang): Support multiple decryptor notification request (e.g. from |
| 83 // video and audio decoders). The current implementation is okay for the current | 90 // video and audio decoders). The current implementation is okay for the current |
| 84 // media pipeline since we initialize audio and video decoders in sequence. | 91 // media pipeline since we initialize audio and video decoders in sequence. |
| 85 // But ProxyDecryptor should not depend on media pipeline's implementation | 92 // But ProxyDecryptor should not depend on media pipeline's implementation |
| 86 // detail. | 93 // detail. |
| 87 void ProxyDecryptor::SetDecryptorReadyCB( | 94 void ProxyDecryptor::SetDecryptorReadyCB( |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 } | 156 } |
| 150 | 157 |
| 151 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, | 158 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, |
| 152 const std::string& session_id) { | 159 const std::string& session_id) { |
| 153 DVLOG(1) << "CancelKeyRequest()"; | 160 DVLOG(1) << "CancelKeyRequest()"; |
| 154 | 161 |
| 155 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 162 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 156 decryptor_->CancelKeyRequest(key_system, session_id); | 163 decryptor_->CancelKeyRequest(key_system, session_id); |
| 157 } | 164 } |
| 158 | 165 |
| 166 #if defined(ENABLE_PEPPER_CDMS) |
| 159 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( | 167 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( |
| 160 const std::string& key_system) { | 168 const std::string& key_system) { |
| 161 DCHECK(web_media_player_client_); | 169 DCHECK(web_media_player_client_); |
| 162 DCHECK(web_frame_); | 170 DCHECK(web_frame_); |
| 163 | 171 |
| 164 std::string plugin_type = GetPluginType(key_system); | 172 std::string plugin_type = GetPepperType(key_system); |
| 165 DCHECK(!plugin_type.empty()); | 173 DCHECK(!plugin_type.empty()); |
| 166 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = | 174 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = |
| 167 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); | 175 CreateHelperPlugin(plugin_type, web_media_player_client_, web_frame_); |
| 168 did_create_helper_plugin_ = plugin_instance != NULL; | 176 did_create_helper_plugin_ = plugin_instance != NULL; |
| 169 if (!did_create_helper_plugin_) { | 177 if (!did_create_helper_plugin_) { |
| 170 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; | 178 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; |
| 171 return scoped_ptr<media::Decryptor>(); | 179 return scoped_ptr<media::Decryptor>(); |
| 172 } | 180 } |
| 173 | 181 |
| 174 return scoped_ptr<media::Decryptor>(new PpapiDecryptor( | 182 return scoped_ptr<media::Decryptor>(new PpapiDecryptor( |
| 175 plugin_instance, | 183 plugin_instance, |
| 176 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 184 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 177 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 185 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 178 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 186 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 179 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); | 187 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 180 } | 188 } |
| 189 #endif // defined(ENABLE_PEPPER_CDMS) |
| 181 | 190 |
| 182 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( | 191 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( |
| 183 const std::string& key_system) { | 192 const std::string& key_system) { |
| 184 if (CanUseAesDecryptor(key_system)) | 193 if (CanUseAesDecryptor(key_system)) |
| 185 return scoped_ptr<media::Decryptor>(new media::AesDecryptor( | 194 return scoped_ptr<media::Decryptor>(new media::AesDecryptor( |
| 186 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), | 195 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 187 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), | 196 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 188 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), | 197 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 189 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); | 198 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 190 | 199 |
| 200 #if defined(ENABLE_PEPPER_CDMS) |
| 191 // We only support AesDecryptor and PpapiDecryptor. So if we cannot | 201 // We only support AesDecryptor and PpapiDecryptor. So if we cannot |
| 192 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given | 202 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given |
| 193 // |key_system|. | 203 // |key_system|. |
| 194 return CreatePpapiDecryptor(key_system); | 204 return CreatePpapiDecryptor(key_system); |
| 205 #else |
| 206 return scoped_ptr<media::Decryptor>(); |
| 207 #endif // defined(ENABLE_PEPPER_CDMS) |
| 195 } | 208 } |
| 196 | 209 |
| 197 void ProxyDecryptor::KeyAdded(const std::string& key_system, | 210 void ProxyDecryptor::KeyAdded(const std::string& key_system, |
| 198 const std::string& session_id) { | 211 const std::string& session_id) { |
| 199 key_added_cb_.Run(key_system, session_id); | 212 key_added_cb_.Run(key_system, session_id); |
| 200 } | 213 } |
| 201 | 214 |
| 202 void ProxyDecryptor::KeyError(const std::string& key_system, | 215 void ProxyDecryptor::KeyError(const std::string& key_system, |
| 203 const std::string& session_id, | 216 const std::string& session_id, |
| 204 media::Decryptor::KeyError error_code, | 217 media::Decryptor::KeyError error_code, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 216 void ProxyDecryptor::NeedKey(const std::string& key_system, | 229 void ProxyDecryptor::NeedKey(const std::string& key_system, |
| 217 const std::string& session_id, | 230 const std::string& session_id, |
| 218 const std::string& type, | 231 const std::string& type, |
| 219 scoped_ptr<uint8[]> init_data, | 232 scoped_ptr<uint8[]> init_data, |
| 220 int init_data_size) { | 233 int init_data_size) { |
| 221 need_key_cb_.Run(key_system, session_id, type, | 234 need_key_cb_.Run(key_system, session_id, type, |
| 222 init_data.Pass(), init_data_size); | 235 init_data.Pass(), init_data_size); |
| 223 } | 236 } |
| 224 | 237 |
| 225 } // namespace webkit_media | 238 } // namespace webkit_media |
| OLD | NEW |