| 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/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 8 #include "base/logging.h" | 9 #include "base/logging.h" |
| 9 #include "media/base/decryptor_client.h" | |
| 10 #include "media/crypto/aes_decryptor.h" | 10 #include "media/crypto/aes_decryptor.h" |
| 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
| 13 #include "webkit/media/crypto/key_systems.h" | 13 #include "webkit/media/crypto/key_systems.h" |
| 14 #include "webkit/media/crypto/ppapi_decryptor.h" | 14 #include "webkit/media/crypto/ppapi_decryptor.h" |
| 15 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 15 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 16 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" | 16 #include "webkit/plugins/ppapi/ppapi_webplugin_impl.h" |
| 17 // TODO(xhwang): Put this include after "ppapi_plugin_instance.h" for definition | 17 // 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. | 18 // of "uint8_t", which WebMediaPlayer.h uses without including a header for it. |
| 19 // See: https://bugs.webkit.org/show_bug.cgi?id=92031 | 19 // See: https://bugs.webkit.org/show_bug.cgi?id=92031 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 35 return NULL; | 35 return NULL; |
| 36 | 36 |
| 37 DCHECK(!web_plugin->isPlaceholder()); // Prevented by WebKit. | 37 DCHECK(!web_plugin->isPlaceholder()); // Prevented by WebKit. |
| 38 // Only Pepper plugins are supported, so it must be a ppapi object. | 38 // Only Pepper plugins are supported, so it must be a ppapi object. |
| 39 webkit::ppapi::WebPluginImpl* ppapi_plugin = | 39 webkit::ppapi::WebPluginImpl* ppapi_plugin = |
| 40 static_cast<webkit::ppapi::WebPluginImpl*>(web_plugin); | 40 static_cast<webkit::ppapi::WebPluginImpl*>(web_plugin); |
| 41 return ppapi_plugin->instance(); | 41 return ppapi_plugin->instance(); |
| 42 } | 42 } |
| 43 | 43 |
| 44 ProxyDecryptor::ProxyDecryptor( | 44 ProxyDecryptor::ProxyDecryptor( |
| 45 media::DecryptorClient* decryptor_client, | |
| 46 WebKit::WebMediaPlayerClient* web_media_player_client, | 45 WebKit::WebMediaPlayerClient* web_media_player_client, |
| 47 WebKit::WebFrame* web_frame) | 46 WebKit::WebFrame* web_frame, |
| 48 : client_(decryptor_client), | 47 const media::KeyAddedCB& key_added_cb, |
| 49 web_media_player_client_(web_media_player_client), | 48 const media::KeyErrorCB& key_error_cb, |
| 50 web_frame_(web_frame) { | 49 const media::KeyMessageCB& key_message_cb, |
| 50 const media::NeedKeyCB& need_key_cb) |
| 51 : web_media_player_client_(web_media_player_client), |
| 52 web_frame_(web_frame), |
| 53 key_added_cb_(key_added_cb), |
| 54 key_error_cb_(key_error_cb), |
| 55 key_message_cb_(key_message_cb), |
| 56 need_key_cb_(need_key_cb), |
| 57 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 51 } | 58 } |
| 52 | 59 |
| 53 ProxyDecryptor::~ProxyDecryptor() { | 60 ProxyDecryptor::~ProxyDecryptor() { |
| 54 } | 61 } |
| 55 | 62 |
| 56 // TODO(xhwang): Support multiple decryptor notification request (e.g. from | 63 // TODO(xhwang): Support multiple decryptor notification request (e.g. from |
| 57 // video and audio decoders). The current implementation is okay for the current | 64 // video and audio decoders). The current implementation is okay for the current |
| 58 // media pipeline since we initialize audio and video decoders in sequence. | 65 // media pipeline since we initialize audio and video decoders in sequence. |
| 59 // But ProxyDecryptor should not depend on media pipeline's implementation | 66 // But ProxyDecryptor should not depend on media pipeline's implementation |
| 60 // detail. | 67 // detail. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 84 int init_data_length) { | 91 int init_data_length) { |
| 85 // We do not support run-time switching of decryptors. GenerateKeyRequest() | 92 // We do not support run-time switching of decryptors. GenerateKeyRequest() |
| 86 // only creates a new decryptor when |decryptor_| is not initialized. | 93 // only creates a new decryptor when |decryptor_| is not initialized. |
| 87 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; | 94 DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; |
| 88 | 95 |
| 89 base::AutoLock auto_lock(lock_); | 96 base::AutoLock auto_lock(lock_); |
| 90 | 97 |
| 91 if (!decryptor_) { | 98 if (!decryptor_) { |
| 92 decryptor_ = CreateDecryptor(key_system); | 99 decryptor_ = CreateDecryptor(key_system); |
| 93 if (!decryptor_) { | 100 if (!decryptor_) { |
| 94 client_->KeyError(key_system, "", media::Decryptor::kUnknownError, 0); | 101 key_error_cb_.Run(key_system, "", media::Decryptor::kUnknownError, 0); |
| 95 return false; | 102 return false; |
| 96 } | 103 } |
| 97 } | 104 } |
| 98 | 105 |
| 99 if (!decryptor_->GenerateKeyRequest(key_system, type, | 106 if (!decryptor_->GenerateKeyRequest(key_system, type, |
| 100 init_data, init_data_length)) { | 107 init_data, init_data_length)) { |
| 101 decryptor_.reset(); | 108 decryptor_.reset(); |
| 102 return false; | 109 return false; |
| 103 } | 110 } |
| 104 | 111 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 124 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, | 131 void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, |
| 125 const std::string& session_id) { | 132 const std::string& session_id) { |
| 126 DVLOG(1) << "CancelKeyRequest()"; | 133 DVLOG(1) << "CancelKeyRequest()"; |
| 127 | 134 |
| 128 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. | 135 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. |
| 129 decryptor_->CancelKeyRequest(key_system, session_id); | 136 decryptor_->CancelKeyRequest(key_system, session_id); |
| 130 } | 137 } |
| 131 | 138 |
| 132 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( | 139 scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( |
| 133 const std::string& key_system) { | 140 const std::string& key_system) { |
| 134 DCHECK(client_); | |
| 135 DCHECK(web_media_player_client_); | 141 DCHECK(web_media_player_client_); |
| 136 DCHECK(web_frame_); | 142 DCHECK(web_frame_); |
| 137 | 143 |
| 138 std::string plugin_type = GetPluginType(key_system); | 144 std::string plugin_type = GetPluginType(key_system); |
| 139 DCHECK(!plugin_type.empty()); | 145 DCHECK(!plugin_type.empty()); |
| 140 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = | 146 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance = |
| 141 CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_); | 147 CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_); |
| 142 if (!plugin_instance) { | 148 if (!plugin_instance) { |
| 143 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; | 149 DVLOG(1) << "ProxyDecryptor: plugin instance creation failed."; |
| 144 return scoped_ptr<media::Decryptor>(); | 150 return scoped_ptr<media::Decryptor>(); |
| 145 } | 151 } |
| 146 | 152 |
| 147 return scoped_ptr<media::Decryptor>(new PpapiDecryptor(client_, | 153 return scoped_ptr<media::Decryptor>(new PpapiDecryptor( |
| 148 plugin_instance)); | 154 plugin_instance, |
| 155 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 156 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 157 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 158 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 149 } | 159 } |
| 150 | 160 |
| 151 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( | 161 scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( |
| 152 const std::string& key_system) { | 162 const std::string& key_system) { |
| 153 DCHECK(client_); | |
| 154 | |
| 155 if (CanUseAesDecryptor(key_system)) | 163 if (CanUseAesDecryptor(key_system)) |
| 156 return scoped_ptr<media::Decryptor>(new media::AesDecryptor(client_)); | 164 return scoped_ptr<media::Decryptor>(new media::AesDecryptor( |
| 165 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), |
| 166 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), |
| 167 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), |
| 168 base::Bind(&ProxyDecryptor::NeedKey, weak_ptr_factory_.GetWeakPtr()))); |
| 157 | 169 |
| 158 // We only support AesDecryptor and PpapiDecryptor. So if we cannot | 170 // We only support AesDecryptor and PpapiDecryptor. So if we cannot |
| 159 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given | 171 // use the AesDecryptor, then we'll try to create a PpapiDecryptor for given |
| 160 // |key_system|. | 172 // |key_system|. |
| 161 return CreatePpapiDecryptor(key_system); | 173 return CreatePpapiDecryptor(key_system); |
| 162 } | 174 } |
| 163 | 175 |
| 176 void ProxyDecryptor::KeyAdded(const std::string& key_system, |
| 177 const std::string& session_id) { |
| 178 key_added_cb_.Run(key_system, session_id); |
| 179 } |
| 180 |
| 181 void ProxyDecryptor::KeyError(const std::string& key_system, |
| 182 const std::string& session_id, |
| 183 media::Decryptor::KeyError error_code, |
| 184 int system_code) { |
| 185 key_error_cb_.Run(key_system, session_id, error_code, system_code); |
| 186 } |
| 187 |
| 188 void ProxyDecryptor::KeyMessage(const std::string& key_system, |
| 189 const std::string& session_id, |
| 190 const std::string& message, |
| 191 const std::string& default_url) { |
| 192 key_message_cb_.Run(key_system, session_id, message, default_url); |
| 193 } |
| 194 |
| 195 void ProxyDecryptor::NeedKey(const std::string& key_system, |
| 196 const std::string& session_id, |
| 197 const std::string& type, |
| 198 scoped_array<uint8> init_data, |
| 199 int init_data_size) { |
| 200 need_key_cb_.Run(key_system, session_id, type, |
| 201 init_data.Pass(), init_data_size); |
| 202 } |
| 203 |
| 164 } // namespace webkit_media | 204 } // namespace webkit_media |
| OLD | NEW |