Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / media / crypto / ppapi_decryptor.cc
blob7b9c334abe9c18fa7c88a7c5be20160038c5347c
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
3 // found in the LICENSE file.
5 #include "webkit/media/crypto/ppapi_decryptor.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/message_loop.h"
14 #include "base/message_loop_proxy.h"
15 #include "media/base/audio_decoder_config.h"
16 #include "media/base/data_buffer.h"
17 #include "media/base/decoder_buffer.h"
18 #include "media/base/video_decoder_config.h"
19 #include "media/base/video_frame.h"
20 #include "webkit/media/crypto/key_systems.h"
21 #include "webkit/plugins/ppapi/content_decryptor_delegate.h"
22 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
24 namespace webkit_media {
26 PpapiDecryptor::PpapiDecryptor(
27 const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance,
28 const media::KeyAddedCB& key_added_cb,
29 const media::KeyErrorCB& key_error_cb,
30 const media::KeyMessageCB& key_message_cb,
31 const media::NeedKeyCB& need_key_cb)
32 : plugin_instance_(plugin_instance),
33 key_added_cb_(key_added_cb),
34 key_error_cb_(key_error_cb),
35 key_message_cb_(key_message_cb),
36 need_key_cb_(need_key_cb),
37 plugin_cdm_delegate_(NULL),
38 render_loop_proxy_(base::MessageLoopProxy::current()),
39 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
40 weak_this_(weak_ptr_factory_.GetWeakPtr()) {
41 DCHECK(plugin_instance_);
44 PpapiDecryptor::~PpapiDecryptor() {
45 plugin_cdm_delegate_ = NULL;
46 plugin_instance_ = NULL;
49 bool PpapiDecryptor::GenerateKeyRequest(const std::string& key_system,
50 const std::string& type,
51 const uint8* init_data,
52 int init_data_length) {
53 DVLOG(2) << "GenerateKeyRequest()";
54 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
56 if (!plugin_cdm_delegate_) {
57 plugin_cdm_delegate_ = plugin_instance_->GetContentDecryptorDelegate();
58 if (!plugin_cdm_delegate_) {
59 DVLOG(1) << "PpapiDecryptor: plugin cdm delegate creation failed.";
60 return false;
62 plugin_cdm_delegate_->SetKeyEventCallbacks(
63 base::Bind(&PpapiDecryptor::KeyAdded, weak_this_),
64 base::Bind(&PpapiDecryptor::KeyError, weak_this_),
65 base::Bind(&PpapiDecryptor::KeyMessage, weak_this_),
66 base::Bind(&PpapiDecryptor::NeedKey, weak_this_));
69 if (!plugin_cdm_delegate_->GenerateKeyRequest(
70 key_system, type, init_data, init_data_length)) {
71 ReportFailureToCallPlugin(key_system, std::string());
72 return false;
75 return true;
78 void PpapiDecryptor::AddKey(const std::string& key_system,
79 const uint8* key,
80 int key_length,
81 const uint8* init_data,
82 int init_data_length,
83 const std::string& session_id) {
84 DVLOG(2) << "AddKey()";
85 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
87 if (!plugin_cdm_delegate_->AddKey(
88 session_id, key, key_length, init_data, init_data_length)) {
89 ReportFailureToCallPlugin(key_system, session_id);
92 if (!new_audio_key_cb_.is_null())
93 new_audio_key_cb_.Run();
95 if (!new_video_key_cb_.is_null())
96 new_video_key_cb_.Run();
99 void PpapiDecryptor::CancelKeyRequest(const std::string& key_system,
100 const std::string& session_id) {
101 DVLOG(2) << "CancelKeyRequest()";
102 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
104 if (!plugin_cdm_delegate_->CancelKeyRequest(session_id))
105 ReportFailureToCallPlugin(key_system, session_id);
108 void PpapiDecryptor::RegisterNewKeyCB(StreamType stream_type,
109 const NewKeyCB& new_key_cb) {
110 switch (stream_type) {
111 case kAudio:
112 new_audio_key_cb_ = new_key_cb;
113 break;
114 case kVideo:
115 new_video_key_cb_ = new_key_cb;
116 break;
117 default:
118 NOTREACHED();
122 void PpapiDecryptor::Decrypt(
123 StreamType stream_type,
124 const scoped_refptr<media::DecoderBuffer>& encrypted,
125 const DecryptCB& decrypt_cb) {
126 if (!render_loop_proxy_->BelongsToCurrentThread()) {
127 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
128 &PpapiDecryptor::Decrypt, weak_this_,
129 stream_type, encrypted, decrypt_cb));
130 return;
133 DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
134 if (!plugin_cdm_delegate_->Decrypt(stream_type, encrypted, decrypt_cb))
135 decrypt_cb.Run(kError, NULL);
138 void PpapiDecryptor::CancelDecrypt(StreamType stream_type) {
139 DVLOG(1) << "CancelDecrypt() - stream_type: " << stream_type;
140 plugin_cdm_delegate_->CancelDecrypt(stream_type);
143 void PpapiDecryptor::InitializeAudioDecoder(
144 const media::AudioDecoderConfig& config,
145 const DecoderInitCB& init_cb) {
146 if (!render_loop_proxy_->BelongsToCurrentThread()) {
147 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
148 &PpapiDecryptor::InitializeAudioDecoder, weak_this_, config, init_cb));
149 return;
152 DVLOG(2) << "InitializeAudioDecoder()";
153 DCHECK(config.is_encrypted());
154 DCHECK(config.IsValidConfig());
156 audio_decoder_init_cb_ = init_cb;
157 if (!plugin_cdm_delegate_->InitializeAudioDecoder(config, base::Bind(
158 &PpapiDecryptor::OnDecoderInitialized, weak_this_, kAudio))) {
159 base::ResetAndReturn(&audio_decoder_init_cb_).Run(false);
160 return;
164 void PpapiDecryptor::InitializeVideoDecoder(
165 const media::VideoDecoderConfig& config,
166 const DecoderInitCB& init_cb) {
167 if (!render_loop_proxy_->BelongsToCurrentThread()) {
168 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
169 &PpapiDecryptor::InitializeVideoDecoder, weak_this_, config, init_cb));
170 return;
173 DVLOG(2) << "InitializeVideoDecoder()";
174 DCHECK(config.is_encrypted());
175 DCHECK(config.IsValidConfig());
177 video_decoder_init_cb_ = init_cb;
178 if (!plugin_cdm_delegate_->InitializeVideoDecoder(config, base::Bind(
179 &PpapiDecryptor::OnDecoderInitialized, weak_this_, kVideo))) {
180 base::ResetAndReturn(&video_decoder_init_cb_).Run(false);
181 return;
185 void PpapiDecryptor::DecryptAndDecodeAudio(
186 const scoped_refptr<media::DecoderBuffer>& encrypted,
187 const AudioDecodeCB& audio_decode_cb) {
188 if (!render_loop_proxy_->BelongsToCurrentThread()) {
189 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
190 &PpapiDecryptor::DecryptAndDecodeAudio, weak_this_,
191 encrypted, audio_decode_cb));
192 return;
195 DVLOG(3) << "DecryptAndDecodeAudio()";
196 if (!plugin_cdm_delegate_->DecryptAndDecodeAudio(encrypted, audio_decode_cb))
197 audio_decode_cb.Run(kError, AudioBuffers());
200 void PpapiDecryptor::DecryptAndDecodeVideo(
201 const scoped_refptr<media::DecoderBuffer>& encrypted,
202 const VideoDecodeCB& video_decode_cb) {
203 if (!render_loop_proxy_->BelongsToCurrentThread()) {
204 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
205 &PpapiDecryptor::DecryptAndDecodeVideo, weak_this_,
206 encrypted, video_decode_cb));
207 return;
210 DVLOG(3) << "DecryptAndDecodeVideo()";
211 if (!plugin_cdm_delegate_->DecryptAndDecodeVideo(encrypted, video_decode_cb))
212 video_decode_cb.Run(kError, NULL);
215 void PpapiDecryptor::ResetDecoder(StreamType stream_type) {
216 if (!render_loop_proxy_->BelongsToCurrentThread()) {
217 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
218 &PpapiDecryptor::ResetDecoder, weak_this_, stream_type));
219 return;
222 DVLOG(2) << "ResetDecoder() - stream_type: " << stream_type;
223 plugin_cdm_delegate_->ResetDecoder(stream_type);
226 void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) {
227 if (!render_loop_proxy_->BelongsToCurrentThread()) {
228 render_loop_proxy_->PostTask(FROM_HERE, base::Bind(
229 &PpapiDecryptor::DeinitializeDecoder, weak_this_, stream_type));
230 return;
233 DVLOG(2) << "DeinitializeDecoder() - stream_type: " << stream_type;
234 plugin_cdm_delegate_->DeinitializeDecoder(stream_type);
237 void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& key_system,
238 const std::string& session_id) {
239 DVLOG(1) << "Failed to call plugin.";
240 key_error_cb_.Run(key_system, session_id, kUnknownError, 0);
243 void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type,
244 bool success) {
245 switch (stream_type) {
246 case kAudio:
247 DCHECK(!audio_decoder_init_cb_.is_null());
248 base::ResetAndReturn(&audio_decoder_init_cb_).Run(success);
249 break;
250 case kVideo:
251 DCHECK(!video_decoder_init_cb_.is_null());
252 base::ResetAndReturn(&video_decoder_init_cb_).Run(success);
253 break;
254 default:
255 NOTREACHED();
259 void PpapiDecryptor::KeyAdded(const std::string& key_system,
260 const std::string& session_id) {
261 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
262 key_added_cb_.Run(key_system, session_id);
265 void PpapiDecryptor::KeyError(const std::string& key_system,
266 const std::string& session_id,
267 media::Decryptor::KeyError error_code,
268 int system_code) {
269 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
270 key_error_cb_.Run(key_system, session_id, error_code, system_code);
273 void PpapiDecryptor::KeyMessage(const std::string& key_system,
274 const std::string& session_id,
275 const std::string& message,
276 const std::string& default_url) {
277 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
278 key_message_cb_.Run(key_system, session_id, message, default_url);
281 void PpapiDecryptor::NeedKey(const std::string& key_system,
282 const std::string& session_id,
283 const std::string& type,
284 scoped_ptr<uint8[]> init_data,
285 int init_data_size) {
286 DCHECK(render_loop_proxy_->BelongsToCurrentThread());
287 need_key_cb_.Run(key_system, session_id, type,
288 init_data.Pass(), init_data_size);
291 } // namespace webkit_media