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 |