blob: a4640e3ebea300d35093118dcf094969f74f52cb [file] [log] [blame]
[email protected]e5aeef02012-08-17 00:18:431// 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.
4
[email protected]9264e1502012-09-18 19:53:015#include <cstring>
6#include <string>
[email protected]d341e332012-08-28 18:57:407#include <vector>
[email protected]e5aeef02012-08-17 00:18:438
[email protected]9264e1502012-09-18 19:53:019#include "base/basictypes.h"
10#include "base/compiler_specific.h"
[email protected]e5aeef02012-08-17 00:18:4311#include "ppapi/c/pp_errors.h"
12#include "ppapi/c/pp_stdint.h"
[email protected]98ad9782012-08-22 04:06:2213#include "ppapi/c/private/pp_content_decryptor.h"
[email protected]e5aeef02012-08-17 00:18:4314#include "ppapi/cpp/completion_callback.h"
15#include "ppapi/cpp/core.h"
16#include "ppapi/cpp/instance.h"
17#include "ppapi/cpp/logging.h"
18#include "ppapi/cpp/module.h"
19#include "ppapi/cpp/pass_ref.h"
20#include "ppapi/cpp/resource.h"
21#include "ppapi/cpp/var.h"
22#include "ppapi/cpp/var_array_buffer.h"
23#include "ppapi/cpp/dev/buffer_dev.h"
24#include "ppapi/cpp/private/content_decryptor_private.h"
25#include "ppapi/utility/completion_callback_factory.h"
[email protected]9264e1502012-09-18 19:53:0126#include "webkit/media/crypto/ppapi/linked_ptr.h"
[email protected]d341e332012-08-28 18:57:4027#include "webkit/media/crypto/ppapi/content_decryption_module.h"
[email protected]e5aeef02012-08-17 00:18:4328
29namespace {
30
[email protected]d341e332012-08-28 18:57:4031// This must be consistent with MediaKeyError defined in the spec:
32// http://goo.gl/rbdnR
33// TODO(xhwang): Add PP_MediaKeyError enum to avoid later static_cast in
34// PluginInstance.
35enum MediaKeyError {
36 kUnknownError = 1,
37 kClientError,
38 kServiceError,
39 kOutputError,
40 kHardwareChangeError,
41 kDomainError
[email protected]e5aeef02012-08-17 00:18:4342};
43
[email protected]98ad9782012-08-22 04:06:2244bool IsMainThread() {
45 return pp::Module::Get()->core()->IsMainThread();
46}
47
[email protected]e5aeef02012-08-17 00:18:4348void CallOnMain(pp::CompletionCallback cb) {
[email protected]98ad9782012-08-22 04:06:2249 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls
50 // off the main thread yet. Remove this once the change lands.
51 if (IsMainThread())
52 cb.Run(PP_OK);
53 else
54 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
[email protected]e5aeef02012-08-17 00:18:4355}
56
57} // namespace
58
[email protected]d341e332012-08-28 18:57:4059namespace webkit_media {
[email protected]e5aeef02012-08-17 00:18:4360
[email protected]9264e1502012-09-18 19:53:0161// Provides access to memory owned by a pp::Buffer_Dev created by
62// PpbBufferAllocator::Allocate(). This class holds a reference to the
63// Buffer_Dev throughout its lifetime.
64class PpbBuffer : public cdm::Buffer {
65 public:
66 // cdm::Buffer methods.
67 virtual void Destroy() OVERRIDE { delete this; }
68
[email protected]7ed56ed2012-10-02 02:43:2769 virtual uint8_t* data() OVERRIDE {
[email protected]9264e1502012-09-18 19:53:0170 return static_cast<uint8_t*>(buffer_.data());
71 }
72
73 virtual int32_t size() const OVERRIDE { return buffer_.size(); }
74
75 pp::Buffer_Dev buffer_dev() const { return buffer_; }
76
77 private:
78 explicit PpbBuffer(pp::Buffer_Dev buffer) : buffer_(buffer) {}
79 virtual ~PpbBuffer() {}
80
81 pp::Buffer_Dev buffer_;
82
83 friend class PpbBufferAllocator;
84
85 DISALLOW_COPY_AND_ASSIGN(PpbBuffer);
86};
87
88class PpbBufferAllocator : public cdm::Allocator {
89 public:
90 explicit PpbBufferAllocator(pp::Instance* instance);
91 virtual ~PpbBufferAllocator();
92
93 // cdm::Allocator methods.
94 // Allocates a pp::Buffer_Dev of the specified size and wraps it in a
95 // PpbBuffer, which it returns. The caller own the returned buffer and must
96 // free it by calling ReleaseBuffer(). Returns NULL on failure.
97 virtual cdm::Buffer* Allocate(int32_t size) OVERRIDE;
98
99 private:
100 pp::Instance* const instance_;
101
102 DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator);
103};
104
[email protected]7ed56ed2012-10-02 02:43:27105class DecryptedBlockImpl : public cdm::DecryptedBlock {
106 public:
107 DecryptedBlockImpl() : buffer_(NULL), timestamp_(0) {}
108 virtual ~DecryptedBlockImpl();
109
110 virtual void set_buffer(cdm::Buffer* buffer) OVERRIDE;
111 virtual cdm::Buffer* buffer() OVERRIDE;
112
113 virtual void set_timestamp(int64_t timestamp) OVERRIDE;
114 virtual int64_t timestamp() const OVERRIDE;
115
116 private:
117 PpbBuffer* buffer_;
118 int64_t timestamp_;
119
120 DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
121};
122
[email protected]9264e1502012-09-18 19:53:01123class KeyMessageImpl : public cdm::KeyMessage {
124 public:
125 KeyMessageImpl() : message_(NULL) {}
126 virtual ~KeyMessageImpl();
127
128 // cdm::KeyMessage methods.
129 virtual void set_session_id(const char* session_id, int32_t length) OVERRIDE;
130 virtual const char* session_id() const OVERRIDE;
131 virtual int32_t session_id_length() const OVERRIDE;
132
133 virtual void set_message(cdm::Buffer* message) OVERRIDE;
[email protected]7ed56ed2012-10-02 02:43:27134 virtual cdm::Buffer* message() OVERRIDE;
[email protected]9264e1502012-09-18 19:53:01135
136 virtual void set_default_url(const char* default_url,
137 int32_t length) OVERRIDE;
138 virtual const char* default_url() const OVERRIDE;
139 virtual int32_t default_url_length() const OVERRIDE;
140
141 std::string session_id_string() const { return session_id_; }
142 std::string default_url_string() const { return default_url_; }
143
144 private:
145 PpbBuffer* message_;
146 std::string session_id_;
147 std::string default_url_;
148
149 DISALLOW_COPY_AND_ASSIGN(KeyMessageImpl);
150};
151
[email protected]7ed56ed2012-10-02 02:43:27152DecryptedBlockImpl::~DecryptedBlockImpl() {
153 if (buffer_)
154 buffer_->Destroy();
155}
[email protected]9264e1502012-09-18 19:53:01156
[email protected]7ed56ed2012-10-02 02:43:27157void DecryptedBlockImpl::set_buffer(cdm::Buffer* buffer) {
158 buffer_ = static_cast<PpbBuffer*>(buffer);
159}
[email protected]9264e1502012-09-18 19:53:01160
[email protected]7ed56ed2012-10-02 02:43:27161cdm::Buffer* DecryptedBlockImpl::buffer() {
162 return buffer_;
163}
[email protected]9264e1502012-09-18 19:53:01164
[email protected]7ed56ed2012-10-02 02:43:27165void DecryptedBlockImpl::set_timestamp(int64_t timestamp) {
166 timestamp_ = timestamp;
167}
[email protected]9264e1502012-09-18 19:53:01168
[email protected]7ed56ed2012-10-02 02:43:27169int64_t DecryptedBlockImpl::timestamp() const {
170 return timestamp_;
171}
[email protected]9264e1502012-09-18 19:53:01172
173KeyMessageImpl::~KeyMessageImpl() {
174 if (message_)
175 message_->Destroy();
176}
177
178void KeyMessageImpl::set_session_id(const char* session_id, int32_t length) {
179 session_id_.assign(session_id, length);
180}
181
182const char* KeyMessageImpl::session_id() const {
183 return session_id_.c_str();
184}
185
186int32_t KeyMessageImpl::session_id_length() const {
187 return session_id_.length();
188}
189
190void KeyMessageImpl::set_message(cdm::Buffer* buffer) {
191 message_ = static_cast<PpbBuffer*>(buffer);
192}
193
[email protected]7ed56ed2012-10-02 02:43:27194cdm::Buffer* KeyMessageImpl::message() {
[email protected]9264e1502012-09-18 19:53:01195 return message_;
196}
197
198void KeyMessageImpl::set_default_url(const char* default_url, int32_t length) {
199 default_url_.assign(default_url, length);
200}
201
202const char* KeyMessageImpl::default_url() const {
203 return default_url_.c_str();
204}
205
206int32_t KeyMessageImpl::default_url_length() const {
207 return default_url_.length();
208}
209
[email protected]e5aeef02012-08-17 00:18:43210// A wrapper class for abstracting away PPAPI interaction and threading for a
211// Content Decryption Module (CDM).
[email protected]d341e332012-08-28 18:57:40212class CdmWrapper : public pp::Instance,
[email protected]e5aeef02012-08-17 00:18:43213 public pp::ContentDecryptor_Private {
214 public:
[email protected]d341e332012-08-28 18:57:40215 CdmWrapper(PP_Instance instance, pp::Module* module);
216 virtual ~CdmWrapper();
[email protected]d341e332012-08-28 18:57:40217 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
218 return true;
219 }
[email protected]e5aeef02012-08-17 00:18:43220
221 // PPP_ContentDecryptor_Private methods
[email protected]d341e332012-08-28 18:57:40222 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should
223 // return false if the call was not forwarded to the CDM and should return
224 // true otherwise. Once the call reaches the CDM, the call result/status
225 // should be reported through the PPB_ContentDecryptor_Private interface.
[email protected]ea4ff802012-09-13 01:36:44226 virtual void GenerateKeyRequest(const std::string& key_system,
[email protected]e5aeef02012-08-17 00:18:43227 pp::VarArrayBuffer init_data) OVERRIDE;
[email protected]ea4ff802012-09-13 01:36:44228 virtual void AddKey(const std::string& session_id,
[email protected]98ad9782012-08-22 04:06:22229 pp::VarArrayBuffer key,
230 pp::VarArrayBuffer init_data) OVERRIDE;
[email protected]ea4ff802012-09-13 01:36:44231 virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE;
232 virtual void Decrypt(
[email protected]98ad9782012-08-22 04:06:22233 pp::Buffer_Dev encrypted_buffer,
234 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
[email protected]ea4ff802012-09-13 01:36:44235 virtual void DecryptAndDecode(
[email protected]98ad9782012-08-22 04:06:22236 pp::Buffer_Dev encrypted_buffer,
[email protected]d341e332012-08-28 18:57:40237 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
[email protected]e5aeef02012-08-17 00:18:43238
239 private:
[email protected]7ed56ed2012-10-02 02:43:27240 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock;
[email protected]9264e1502012-09-18 19:53:01241 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage;
[email protected]e5aeef02012-08-17 00:18:43242
243 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
244 // <code>callback_factory_</code> to ensure that calls into
245 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
[email protected]d341e332012-08-28 18:57:40246 void KeyAdded(int32_t result, const std::string& session_id);
[email protected]9264e1502012-09-18 19:53:01247 void KeyMessage(int32_t result, const LinkedKeyMessage& message);
[email protected]d341e332012-08-28 18:57:40248 void KeyError(int32_t result, const std::string& session_id);
249 void DeliverBlock(int32_t result,
250 const cdm::Status& status,
[email protected]7ed56ed2012-10-02 02:43:27251 const LinkedDecryptedBlock& decrypted_block,
[email protected]d341e332012-08-28 18:57:40252 const PP_DecryptTrackingInfo& tracking_info);
[email protected]e5aeef02012-08-17 00:18:43253
[email protected]9264e1502012-09-18 19:53:01254 PpbBufferAllocator allocator_;
[email protected]d341e332012-08-28 18:57:40255 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
256 cdm::ContentDecryptionModule* cdm_;
257 std::string key_system_;
[email protected]e5aeef02012-08-17 00:18:43258};
259
[email protected]9264e1502012-09-18 19:53:01260PpbBufferAllocator::PpbBufferAllocator(pp::Instance* instance)
261 : instance_(instance) {
262}
263
264PpbBufferAllocator::~PpbBufferAllocator() {
265}
266
267cdm::Buffer* PpbBufferAllocator::Allocate(int32_t size) {
268 PP_DCHECK(size > 0);
269
270 pp::Buffer_Dev buffer(instance_, size);
271 if (buffer.is_null())
272 return NULL;
273
274 return new PpbBuffer(buffer);
275}
276
[email protected]d341e332012-08-28 18:57:40277CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
[email protected]e5aeef02012-08-17 00:18:43278 : pp::Instance(instance),
[email protected]d341e332012-08-28 18:57:40279 pp::ContentDecryptor_Private(this),
[email protected]9264e1502012-09-18 19:53:01280 allocator_(this),
[email protected]d341e332012-08-28 18:57:40281 cdm_(NULL) {
[email protected]e5aeef02012-08-17 00:18:43282 callback_factory_.Initialize(this);
283}
284
[email protected]d341e332012-08-28 18:57:40285CdmWrapper::~CdmWrapper() {
286 if (cdm_)
287 DestroyCdmInstance(cdm_);
288}
289
[email protected]ea4ff802012-09-13 01:36:44290void CdmWrapper::GenerateKeyRequest(const std::string& key_system,
[email protected]e5aeef02012-08-17 00:18:43291 pp::VarArrayBuffer init_data) {
[email protected]d341e332012-08-28 18:57:40292 PP_DCHECK(!key_system.empty());
[email protected]e5aeef02012-08-17 00:18:43293
[email protected]d341e332012-08-28 18:57:40294 if (!cdm_) {
[email protected]9264e1502012-09-18 19:53:01295 cdm_ = CreateCdmInstance(&allocator_);
[email protected]d341e332012-08-28 18:57:40296 if (!cdm_)
[email protected]ea4ff802012-09-13 01:36:44297 return;
[email protected]d341e332012-08-28 18:57:40298 }
[email protected]e5aeef02012-08-17 00:18:43299
[email protected]9264e1502012-09-18 19:53:01300 LinkedKeyMessage key_request(new KeyMessageImpl());
[email protected]d341e332012-08-28 18:57:40301 cdm::Status status = cdm_->GenerateKeyRequest(
302 reinterpret_cast<const uint8_t*>(init_data.Map()),
303 init_data.ByteLength(),
[email protected]9264e1502012-09-18 19:53:01304 key_request.get());
[email protected]0b959582012-10-01 23:13:27305 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]d341e332012-08-28 18:57:40306 if (status != cdm::kSuccess ||
[email protected]9264e1502012-09-18 19:53:01307 !key_request->message() ||
308 key_request->message()->size() == 0) {
[email protected]d341e332012-08-28 18:57:40309 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError,
310 std::string()));
[email protected]ea4ff802012-09-13 01:36:44311 return;
[email protected]d341e332012-08-28 18:57:40312 }
313
314 // TODO(xhwang): Remove unnecessary CallOnMain calls here and below once we
315 // only support out-of-process.
316 // If running out-of-process, PPB calls will always behave asynchronously
317 // since IPC is involved. In that case, if we are already on main thread,
318 // we don't need to use CallOnMain to help us call PPB call on main thread,
319 // or to help call PPB asynchronously.
320 key_system_ = key_system;
321 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyMessage,
322 key_request));
[email protected]e5aeef02012-08-17 00:18:43323}
324
[email protected]ea4ff802012-09-13 01:36:44325void CdmWrapper::AddKey(const std::string& session_id,
[email protected]98ad9782012-08-22 04:06:22326 pp::VarArrayBuffer key,
327 pp::VarArrayBuffer init_data) {
[email protected]d341e332012-08-28 18:57:40328 const uint8_t* key_ptr = reinterpret_cast<const uint8_t*>(key.Map());
329 int key_size = key.ByteLength();
330 const uint8_t* init_data_ptr =
331 reinterpret_cast<const uint8_t*>(init_data.Map());
332 int init_data_size = init_data.ByteLength();
[email protected]e5aeef02012-08-17 00:18:43333
[email protected]d341e332012-08-28 18:57:40334 if (!key_ptr || key_size <= 0 || !init_data_ptr || init_data_size <= 0)
[email protected]ea4ff802012-09-13 01:36:44335 return;
[email protected]e5aeef02012-08-17 00:18:43336
[email protected]d341e332012-08-28 18:57:40337 PP_DCHECK(cdm_);
338 cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(),
339 key_ptr, key_size,
340 init_data_ptr, init_data_size);
[email protected]0b959582012-10-01 23:13:27341 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]d341e332012-08-28 18:57:40342 if (status != cdm::kSuccess) {
343 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError,
344 session_id));
[email protected]ea4ff802012-09-13 01:36:44345 return;
[email protected]d341e332012-08-28 18:57:40346 }
347
348 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyAdded, session_id));
[email protected]e5aeef02012-08-17 00:18:43349}
350
[email protected]ea4ff802012-09-13 01:36:44351void CdmWrapper::CancelKeyRequest(const std::string& session_id) {
[email protected]d341e332012-08-28 18:57:40352 PP_DCHECK(cdm_);
[email protected]d341e332012-08-28 18:57:40353 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(),
354 session_id.size());
[email protected]0b959582012-10-01 23:13:27355 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]d341e332012-08-28 18:57:40356 if (status != cdm::kSuccess) {
357 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError,
358 session_id));
[email protected]d341e332012-08-28 18:57:40359 }
[email protected]e5aeef02012-08-17 00:18:43360}
361
[email protected]ea4ff802012-09-13 01:36:44362void CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer,
[email protected]98ad9782012-08-22 04:06:22363 const PP_EncryptedBlockInfo& encrypted_block_info) {
[email protected]e5aeef02012-08-17 00:18:43364 PP_DCHECK(!encrypted_buffer.is_null());
[email protected]d341e332012-08-28 18:57:40365 PP_DCHECK(cdm_);
[email protected]e5aeef02012-08-17 00:18:43366
[email protected]d341e332012-08-28 18:57:40367 // TODO(xhwang): Simplify the following data conversion.
368 cdm::InputBuffer input_buffer;
369 input_buffer.data = reinterpret_cast<uint8_t*>(encrypted_buffer.data());
370 input_buffer.data_size = encrypted_buffer.size();
371 input_buffer.data_offset = encrypted_block_info.data_offset;
372 input_buffer.key_id = encrypted_block_info.key_id;
373 input_buffer.key_id_size = encrypted_block_info.key_id_size;
374 input_buffer.iv = encrypted_block_info.iv;
375 input_buffer.iv_size = encrypted_block_info.iv_size;
[email protected]d341e332012-08-28 18:57:40376 input_buffer.num_subsamples = encrypted_block_info.num_subsamples;
[email protected]5b9d6c342012-09-14 02:35:37377
[email protected]d341e332012-08-28 18:57:40378 std::vector<cdm::SubsampleEntry> subsamples;
[email protected]5b9d6c342012-09-14 02:35:37379 if (encrypted_block_info.num_subsamples > 0) {
380 subsamples.reserve(encrypted_block_info.num_subsamples);
381
382 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) {
383 subsamples.push_back(cdm::SubsampleEntry(
384 encrypted_block_info.subsamples[i].clear_bytes,
385 encrypted_block_info.subsamples[i].cipher_bytes));
386 }
387
388 input_buffer.subsamples = &subsamples[0];
[email protected]d341e332012-08-28 18:57:40389 }
[email protected]5b9d6c342012-09-14 02:35:37390
[email protected]d341e332012-08-28 18:57:40391 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp;
[email protected]98ad9782012-08-22 04:06:22392
[email protected]7ed56ed2012-10-02 02:43:27393 LinkedDecryptedBlock decrypted_block(new DecryptedBlockImpl());
394 cdm::Status status = cdm_->Decrypt(input_buffer, decrypted_block.get());
[email protected]d341e332012-08-28 18:57:40395
[email protected]d341e332012-08-28 18:57:40396 CallOnMain(callback_factory_.NewCallback(
397 &CdmWrapper::DeliverBlock,
398 status,
[email protected]7ed56ed2012-10-02 02:43:27399 decrypted_block,
[email protected]d341e332012-08-28 18:57:40400 encrypted_block_info.tracking_info));
[email protected]e5aeef02012-08-17 00:18:43401}
402
[email protected]ea4ff802012-09-13 01:36:44403void CdmWrapper::DecryptAndDecode(
[email protected]d341e332012-08-28 18:57:40404 pp::Buffer_Dev encrypted_buffer,
405 const PP_EncryptedBlockInfo& encrypted_block_info) {
[email protected]d341e332012-08-28 18:57:40406}
407
[email protected]d341e332012-08-28 18:57:40408void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) {
409 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id);
[email protected]e5aeef02012-08-17 00:18:43410}
411
[email protected]d341e332012-08-28 18:57:40412void CdmWrapper::KeyMessage(int32_t result,
[email protected]9264e1502012-09-18 19:53:01413 const LinkedKeyMessage& key_message) {
414 pp::Buffer_Dev message_buffer =
415 static_cast<const PpbBuffer*>(key_message->message())->buffer_dev();
[email protected]d341e332012-08-28 18:57:40416 pp::ContentDecryptor_Private::KeyMessage(
417 key_system_,
[email protected]9264e1502012-09-18 19:53:01418 key_message->session_id_string(),
[email protected]d341e332012-08-28 18:57:40419 message_buffer,
[email protected]9264e1502012-09-18 19:53:01420 key_message->default_url_string());
[email protected]e5aeef02012-08-17 00:18:43421}
422
[email protected]d341e332012-08-28 18:57:40423// TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM
424// interface and in this function.
425void CdmWrapper::KeyError(int32_t result, const std::string& session_id) {
426 pp::ContentDecryptor_Private::KeyError(key_system_,
427 session_id,
428 kUnknownError,
429 0);
[email protected]e5aeef02012-08-17 00:18:43430}
431
[email protected]d341e332012-08-28 18:57:40432void CdmWrapper::DeliverBlock(int32_t result,
433 const cdm::Status& status,
[email protected]7ed56ed2012-10-02 02:43:27434 const LinkedDecryptedBlock& decrypted_block,
[email protected]d341e332012-08-28 18:57:40435 const PP_DecryptTrackingInfo& tracking_info) {
[email protected]d341e332012-08-28 18:57:40436 PP_DecryptedBlockInfo decrypted_block_info;
437 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
[email protected]7ed56ed2012-10-02 02:43:27438 decrypted_block_info.tracking_info.timestamp = decrypted_block->timestamp();
[email protected]d341e332012-08-28 18:57:40439
440 switch (status) {
441 case cdm::kSuccess:
442 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
[email protected]7ed56ed2012-10-02 02:43:27443 PP_DCHECK(decrypted_block.get() && decrypted_block->buffer());
[email protected]d341e332012-08-28 18:57:40444 break;
[email protected]19e3c28a2012-09-06 12:35:21445 case cdm::kNoKey:
[email protected]d341e332012-08-28 18:57:40446 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
447 break;
[email protected]0b959582012-10-01 23:13:27448 case cdm::kSessionError:
[email protected]d341e332012-08-28 18:57:40449 default:
450 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
[email protected]0b959582012-10-01 23:13:27451 PP_DCHECK(false);
[email protected]d341e332012-08-28 18:57:40452 }
453
[email protected]4bc37112012-09-21 19:49:25454 const pp::Buffer_Dev& buffer =
[email protected]7ed56ed2012-10-02 02:43:27455 decrypted_block.get() && decrypted_block->buffer() ?
456 static_cast<PpbBuffer*>(decrypted_block->buffer())->buffer_dev() :
[email protected]4bc37112012-09-21 19:49:25457 pp::Buffer_Dev();
458
459 pp::ContentDecryptor_Private::DeliverBlock(buffer, decrypted_block_info);
[email protected]e5aeef02012-08-17 00:18:43460}
461
462// This object is the global object representing this plugin library as long
463// as it is loaded.
[email protected]9264e1502012-09-18 19:53:01464class CdmWrapperModule : public pp::Module {
[email protected]e5aeef02012-08-17 00:18:43465 public:
[email protected]9264e1502012-09-18 19:53:01466 CdmWrapperModule() : pp::Module() {}
467 virtual ~CdmWrapperModule() {}
[email protected]e5aeef02012-08-17 00:18:43468
469 virtual pp::Instance* CreateInstance(PP_Instance instance) {
[email protected]d341e332012-08-28 18:57:40470 return new CdmWrapper(instance, this);
[email protected]e5aeef02012-08-17 00:18:43471 }
472};
473
[email protected]d341e332012-08-28 18:57:40474} // namespace webkit_media
475
[email protected]e5aeef02012-08-17 00:18:43476namespace pp {
477
478// Factory function for your specialization of the Module object.
479Module* CreateModule() {
[email protected]9264e1502012-09-18 19:53:01480 return new webkit_media::CdmWrapperModule();
[email protected]e5aeef02012-08-17 00:18:43481}
482
483} // namespace pp