| 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 <cstring> // For std::memcpy. | 5 #include <cstring> // For memcpy. |
| 6 #include <vector> |
| 6 | 7 |
| 7 #include "base/compiler_specific.h" // For OVERRIDE. | 8 #include "base/compiler_specific.h" // For OVERRIDE. |
| 8 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
| 9 #include "ppapi/c/pp_stdint.h" | 10 #include "ppapi/c/pp_stdint.h" |
| 10 #include "ppapi/c/private/pp_content_decryptor.h" | 11 #include "ppapi/c/private/pp_content_decryptor.h" |
| 11 #include "ppapi/cpp/completion_callback.h" | 12 #include "ppapi/cpp/completion_callback.h" |
| 12 #include "ppapi/cpp/core.h" | 13 #include "ppapi/cpp/core.h" |
| 13 #include "ppapi/cpp/instance.h" | 14 #include "ppapi/cpp/instance.h" |
| 14 #include "ppapi/cpp/logging.h" | 15 #include "ppapi/cpp/logging.h" |
| 15 #include "ppapi/cpp/module.h" | 16 #include "ppapi/cpp/module.h" |
| 16 #include "ppapi/cpp/pass_ref.h" | 17 #include "ppapi/cpp/pass_ref.h" |
| 17 #include "ppapi/cpp/resource.h" | 18 #include "ppapi/cpp/resource.h" |
| 18 #include "ppapi/cpp/var.h" | 19 #include "ppapi/cpp/var.h" |
| 19 #include "ppapi/cpp/var_array_buffer.h" | 20 #include "ppapi/cpp/var_array_buffer.h" |
| 20 #include "ppapi/cpp/dev/buffer_dev.h" | 21 #include "ppapi/cpp/dev/buffer_dev.h" |
| 21 #include "ppapi/cpp/private/content_decryptor_private.h" | 22 #include "ppapi/cpp/private/content_decryptor_private.h" |
| 22 #include "ppapi/utility/completion_callback_factory.h" | 23 #include "ppapi/utility/completion_callback_factory.h" |
| 24 #include "webkit/media/crypto/ppapi/content_decryption_module.h" |
| 23 | 25 |
| 24 namespace { | 26 namespace { |
| 25 | 27 |
| 26 struct DecryptorMessage { | 28 // This must be consistent with MediaKeyError defined in the spec: |
| 27 DecryptorMessage() : media_error(0), system_code(0) {} | 29 // http://goo.gl/rbdnR |
| 28 std::string key_system; | 30 // TODO(xhwang): Add PP_MediaKeyError enum to avoid later static_cast in |
| 29 std::string session_id; | 31 // PluginInstance. |
| 30 std::string default_url; | 32 enum MediaKeyError { |
| 31 std::string message_data; | 33 kUnknownError = 1, |
| 32 int32_t media_error; | 34 kClientError, |
| 33 int32_t system_code; | 35 kServiceError, |
| 34 }; | 36 kOutputError, |
| 35 | 37 kHardwareChangeError, |
| 36 struct DecryptedBlock { | 38 kDomainError |
| 37 DecryptedBlock() { | |
| 38 std::memset(reinterpret_cast<void*>(&decrypted_block_info), | |
| 39 0, | |
| 40 sizeof(decrypted_block_info)); | |
| 41 } | |
| 42 std::string decrypted_data; | |
| 43 PP_DecryptedBlockInfo decrypted_block_info; | |
| 44 }; | 39 }; |
| 45 | 40 |
| 46 bool IsMainThread() { | 41 bool IsMainThread() { |
| 47 return pp::Module::Get()->core()->IsMainThread(); | 42 return pp::Module::Get()->core()->IsMainThread(); |
| 48 } | 43 } |
| 49 | 44 |
| 50 void CallOnMain(pp::CompletionCallback cb) { | 45 void CallOnMain(pp::CompletionCallback cb) { |
| 51 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls | 46 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls |
| 52 // off the main thread yet. Remove this once the change lands. | 47 // off the main thread yet. Remove this once the change lands. |
| 53 if (IsMainThread()) | 48 if (IsMainThread()) |
| 54 cb.Run(PP_OK); | 49 cb.Run(PP_OK); |
| 55 else | 50 else |
| 56 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); | 51 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); |
| 57 } | 52 } |
| 58 | 53 |
| 59 } // namespace | 54 } // namespace |
| 60 | 55 |
| 56 namespace webkit_media { |
| 61 | 57 |
| 62 // A wrapper class for abstracting away PPAPI interaction and threading for a | 58 // A wrapper class for abstracting away PPAPI interaction and threading for a |
| 63 // Content Decryption Module (CDM). | 59 // Content Decryption Module (CDM). |
| 64 class CDMWrapper : public pp::Instance, | 60 class CdmWrapper : public pp::Instance, |
| 65 public pp::ContentDecryptor_Private { | 61 public pp::ContentDecryptor_Private { |
| 66 public: | 62 public: |
| 67 CDMWrapper(PP_Instance instance, pp::Module* module); | 63 CdmWrapper(PP_Instance instance, pp::Module* module); |
| 68 virtual ~CDMWrapper() {} | 64 virtual ~CdmWrapper(); |
| 65 |
| 66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| 67 return true; |
| 68 } |
| 69 | 69 |
| 70 // PPP_ContentDecryptor_Private methods | 70 // PPP_ContentDecryptor_Private methods |
| 71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should |
| 72 // return false if the call was not forwarded to the CDM and should return |
| 73 // true otherwise. Once the call reaches the CDM, the call result/status |
| 74 // should be reported through the PPB_ContentDecryptor_Private interface. |
| 71 virtual bool GenerateKeyRequest(const std::string& key_system, | 75 virtual bool GenerateKeyRequest(const std::string& key_system, |
| 72 pp::VarArrayBuffer init_data) OVERRIDE; | 76 pp::VarArrayBuffer init_data) OVERRIDE; |
| 73 virtual bool AddKey(const std::string& session_id, | 77 virtual bool AddKey(const std::string& session_id, |
| 74 pp::VarArrayBuffer key, | 78 pp::VarArrayBuffer key, |
| 75 pp::VarArrayBuffer init_data) OVERRIDE; | 79 pp::VarArrayBuffer init_data) OVERRIDE; |
| 76 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; | 80 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; |
| 77 virtual bool Decrypt( | 81 virtual bool Decrypt( |
| 78 pp::Buffer_Dev encrypted_buffer, | 82 pp::Buffer_Dev encrypted_buffer, |
| 79 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 80 | |
| 81 virtual bool DecryptAndDecode( | 84 virtual bool DecryptAndDecode( |
| 82 pp::Buffer_Dev encrypted_buffer, | 85 pp::Buffer_Dev encrypted_buffer, |
| 83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE { | 86 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 84 return false; | |
| 85 } | |
| 86 | |
| 87 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | |
| 88 return true; | |
| 89 } | |
| 90 | 87 |
| 91 private: | 88 private: |
| 92 PP_Resource StringToBufferResource(const std::string& str); | 89 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the |
| 90 // buffer resource, and returns it. Returns a an invalid PP_Resource with an |
| 91 // ID of 0 on failure. Upon success, the returned Buffer resource has a |
| 92 // reference count of 1. |
| 93 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size); |
| 93 | 94 |
| 94 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 95 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to |
| 95 // <code>callback_factory_</code> to ensure that calls into | 96 // <code>callback_factory_</code> to ensure that calls into |
| 96 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. |
| 97 void NeedKey(int32_t result, const DecryptorMessage& decryptor_message); | 98 void KeyAdded(int32_t result, const std::string& session_id); |
| 98 void KeyAdded(int32_t result, const DecryptorMessage& decryptor_message); | 99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); |
| 99 void KeyMessage(int32_t result, const DecryptorMessage& decryptor_message); | 100 void KeyError(int32_t result, const std::string& session_id); |
| 100 void KeyError(int32_t result, const DecryptorMessage& decryptor_message); | 101 void DeliverBlock(int32_t result, |
| 101 void DeliverBlock(int32_t result, const DecryptedBlock& decrypted_block); | 102 const cdm::Status& status, |
| 102 | 103 cdm::OutputBuffer& output_buffer, |
| 103 pp::CompletionCallbackFactory<CDMWrapper> callback_factory_; | 104 const PP_DecryptTrackingInfo& tracking_info); |
| 105 |
| 106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; |
| 107 cdm::ContentDecryptionModule* cdm_; |
| 108 std::string key_system_; |
| 104 }; | 109 }; |
| 105 | 110 |
| 106 CDMWrapper::CDMWrapper(PP_Instance instance, | 111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) |
| 107 pp::Module* module) | |
| 108 : pp::Instance(instance), | 112 : pp::Instance(instance), |
| 109 pp::ContentDecryptor_Private(this) { | 113 pp::ContentDecryptor_Private(this), |
| 114 cdm_(NULL) { |
| 110 callback_factory_.Initialize(this); | 115 callback_factory_.Initialize(this); |
| 111 } | 116 } |
| 112 | 117 |
| 113 bool CDMWrapper::GenerateKeyRequest(const std::string& key_system, | 118 CdmWrapper::~CdmWrapper() { |
| 119 if (cdm_) |
| 120 DestroyCdmInstance(cdm_); |
| 121 } |
| 122 |
| 123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, |
| 114 pp::VarArrayBuffer init_data) { | 124 pp::VarArrayBuffer init_data) { |
| 115 PP_DCHECK(!key_system.empty() && init_data.ByteLength()); | 125 PP_DCHECK(!key_system.empty()); |
| 116 | 126 |
| 117 DecryptorMessage decryptor_message; | 127 if (!cdm_) { |
| 118 decryptor_message.key_system = key_system; | 128 cdm_ = CreateCdmInstance(); |
| 119 decryptor_message.session_id = "0"; | 129 if (!cdm_) |
| 120 decryptor_message.default_url = "http://www.google.com"; | 130 return false; |
| 121 decryptor_message.message_data = "GenerateKeyRequest"; | 131 } |
| 122 | 132 |
| 123 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, | 133 cdm::KeyMessage key_request; |
| 124 decryptor_message)); | 134 cdm::Status status = cdm_->GenerateKeyRequest( |
| 125 return true; | 135 reinterpret_cast<const uint8_t*>(init_data.Map()), |
| 126 } | 136 init_data.ByteLength(), |
| 127 | 137 &key_request); |
| 128 bool CDMWrapper::AddKey(const std::string& session_id, | 138 |
| 139 if (status != cdm::kSuccess || |
| 140 !key_request.message || |
| 141 key_request.message_size == 0) { |
| 142 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 143 std::string())); |
| 144 return true; |
| 145 } |
| 146 |
| 147 // TODO(xhwang): Remove unnecessary CallOnMain calls here and below once we |
| 148 // only support out-of-process. |
| 149 // If running out-of-process, PPB calls will always behave asynchronously |
| 150 // since IPC is involved. In that case, if we are already on main thread, |
| 151 // we don't need to use CallOnMain to help us call PPB call on main thread, |
| 152 // or to help call PPB asynchronously. |
| 153 key_system_ = key_system; |
| 154 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyMessage, |
| 155 key_request)); |
| 156 |
| 157 return true; |
| 158 } |
| 159 |
| 160 bool CdmWrapper::AddKey(const std::string& session_id, |
| 129 pp::VarArrayBuffer key, | 161 pp::VarArrayBuffer key, |
| 130 pp::VarArrayBuffer init_data) { | 162 pp::VarArrayBuffer init_data) { |
| 131 const std::string key_string(reinterpret_cast<char*>(key.Map()), | 163 const uint8_t* key_ptr = reinterpret_cast<const uint8_t*>(key.Map()); |
| 132 key.ByteLength()); | 164 int key_size = key.ByteLength(); |
| 133 const std::string init_data_string(reinterpret_cast<char*>(init_data.Map()), | 165 const uint8_t* init_data_ptr = |
| 134 init_data.ByteLength()); | 166 reinterpret_cast<const uint8_t*>(init_data.Map()); |
| 135 | 167 int init_data_size = init_data.ByteLength(); |
| 136 PP_DCHECK(!session_id.empty() && !key_string.empty()); | 168 |
| 137 | 169 if (!key_ptr || key_size <= 0 || !init_data_ptr || init_data_size <= 0) |
| 138 DecryptorMessage decryptor_message; | 170 return false; |
| 139 decryptor_message.key_system = "AddKey"; | 171 |
| 140 decryptor_message.session_id = "0"; | 172 PP_DCHECK(cdm_); |
| 141 decryptor_message.default_url = "http://www.google.com"; | 173 cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(), |
| 142 decryptor_message.message_data = "AddKey"; | 174 key_ptr, key_size, |
| 143 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyAdded, | 175 init_data_ptr, init_data_size); |
| 144 decryptor_message)); | 176 |
| 145 return true; | 177 if (status != cdm::kSuccess) { |
| 146 } | 178 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 147 | 179 session_id)); |
| 148 bool CDMWrapper::CancelKeyRequest(const std::string& session_id) { | 180 return true; |
| 149 // TODO(tomfinegan): cancel pending key request in CDM. | 181 } |
| 150 | 182 |
| 151 PP_DCHECK(!session_id.empty()); | 183 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyAdded, session_id)); |
| 152 | 184 return true; |
| 153 DecryptorMessage decryptor_message; | 185 } |
| 154 decryptor_message.key_system = "CancelKeyRequest"; | 186 |
| 155 decryptor_message.session_id = "0"; | 187 bool CdmWrapper::CancelKeyRequest(const std::string& session_id) { |
| 156 decryptor_message.default_url = "http://www.google.com"; | 188 PP_DCHECK(cdm_); |
| 157 decryptor_message.message_data = "CancelKeyRequest"; | 189 |
| 158 | 190 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(), |
| 159 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, | 191 session_id.size()); |
| 160 decryptor_message)); | 192 |
| 161 return true; | 193 if (status != cdm::kSuccess) { |
| 162 } | 194 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 163 | 195 session_id)); |
| 164 bool CDMWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, | 196 return true; |
| 197 } |
| 198 |
| 199 return true; |
| 200 } |
| 201 |
| 202 bool CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, |
| 165 const PP_EncryptedBlockInfo& encrypted_block_info) { | 203 const PP_EncryptedBlockInfo& encrypted_block_info) { |
| 166 PP_DCHECK(!encrypted_buffer.is_null()); | 204 PP_DCHECK(!encrypted_buffer.is_null()); |
| 167 | 205 PP_DCHECK(cdm_); |
| 168 DecryptedBlock decrypted_block; | 206 |
| 169 decrypted_block.decrypted_data = "Pretend I'm decrypted data!"; | 207 // TODO(xhwang): Simplify the following data conversion. |
| 170 decrypted_block.decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; | 208 cdm::InputBuffer input_buffer; |
| 171 decrypted_block.decrypted_block_info.tracking_info = | 209 input_buffer.data = reinterpret_cast<uint8_t*>(encrypted_buffer.data()); |
| 172 encrypted_block_info.tracking_info; | 210 input_buffer.data_size = encrypted_buffer.size(); |
| 173 | 211 input_buffer.data_offset = encrypted_block_info.data_offset; |
| 174 // TODO(tomfinegan): This would end up copying a lot of data in the real | 212 input_buffer.key_id = encrypted_block_info.key_id; |
| 175 // implementation if we continue passing std::strings around. It *might* not | 213 input_buffer.key_id_size = encrypted_block_info.key_id_size; |
| 176 // be such a big deal w/a real CDM. We may be able to simply pass a pointer | 214 input_buffer.iv = encrypted_block_info.iv; |
| 177 // into the CDM. Otherwise we could look into using std::tr1::shared_ptr | 215 input_buffer.iv_size = encrypted_block_info.iv_size; |
| 178 // instead of passing a giant std::string filled with encrypted data. | 216 input_buffer.checksum = encrypted_block_info.checksum; |
| 179 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::DeliverBlock, | 217 input_buffer.checksum_size = encrypted_block_info.checksum_size; |
| 180 decrypted_block)); | 218 input_buffer.num_subsamples = encrypted_block_info.num_subsamples; |
| 181 return true; | 219 std::vector<cdm::SubsampleEntry> subsamples; |
| 182 } | 220 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) { |
| 183 | 221 subsamples.push_back(cdm::SubsampleEntry( |
| 184 PP_Resource CDMWrapper::StringToBufferResource(const std::string& str) { | 222 encrypted_block_info.subsamples[i].clear_bytes, |
| 185 if (str.empty()) | 223 encrypted_block_info.subsamples[i].cipher_bytes)); |
| 224 } |
| 225 input_buffer.subsamples = &subsamples[0]; |
| 226 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; |
| 227 |
| 228 cdm::OutputBuffer output_buffer; |
| 229 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer); |
| 230 |
| 231 CallOnMain(callback_factory_.NewCallback( |
| 232 &CdmWrapper::DeliverBlock, |
| 233 status, |
| 234 output_buffer, |
| 235 encrypted_block_info.tracking_info)); |
| 236 |
| 237 return true; |
| 238 } |
| 239 |
| 240 bool CdmWrapper::DecryptAndDecode( |
| 241 pp::Buffer_Dev encrypted_buffer, |
| 242 const PP_EncryptedBlockInfo& encrypted_block_info) { |
| 243 return false; |
| 244 } |
| 245 |
| 246 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data, |
| 247 uint32_t data_size) { |
| 248 if (!data || !data_size) |
| 186 return 0; | 249 return 0; |
| 187 | 250 |
| 188 pp::Buffer_Dev buffer(this, str.size()); | 251 pp::Buffer_Dev buffer(this, data_size); |
| 189 if (!buffer.data()) | 252 if (!buffer.data()) |
| 190 return 0; | 253 return 0; |
| 191 | 254 |
| 192 std::memcpy(buffer.data(), str.data(), str.size()); | 255 memcpy(buffer.data(), data, data_size); |
| 256 |
| 193 return buffer.detach(); | 257 return buffer.detach(); |
| 194 } | 258 } |
| 195 | 259 |
| 196 void CDMWrapper::NeedKey(int32_t result, | 260 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { |
| 197 const DecryptorMessage& decryptor_message) { | 261 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); |
| 198 const std::string& message_data = decryptor_message.message_data; | 262 } |
| 199 pp::VarArrayBuffer init_data(message_data.size()); | 263 |
| 200 std::memcpy(init_data.Map(), message_data.data(), message_data.size()); | 264 void CdmWrapper::KeyMessage(int32_t result, |
| 201 pp::ContentDecryptor_Private::NeedKey(decryptor_message.key_system, | 265 cdm::KeyMessage& key_message) { |
| 202 decryptor_message.session_id, | 266 pp::Buffer_Dev message_buffer(MakeBufferResource(key_message.message, |
| 203 init_data); | 267 key_message.message_size)); |
| 204 } | 268 pp::ContentDecryptor_Private::KeyMessage( |
| 205 | 269 key_system_, |
| 206 void CDMWrapper::KeyAdded(int32_t result, | 270 std::string(key_message.session_id, key_message.session_id_size), |
| 207 const DecryptorMessage& decryptor_message) { | 271 message_buffer, |
| 208 pp::ContentDecryptor_Private::KeyAdded(decryptor_message.key_system, | 272 std::string(key_message.default_url, key_message.default_url_size)); |
| 209 decryptor_message.session_id); | 273 |
| 210 } | 274 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated |
| 211 | 275 // in another shared object. |
| 212 void CDMWrapper::KeyMessage(int32_t result, | 276 delete [] key_message.session_id; |
| 213 const DecryptorMessage& decryptor_message) { | 277 key_message.session_id = NULL; |
| 214 pp::Buffer_Dev message_buffer( | 278 delete [] key_message.message; |
| 215 StringToBufferResource(decryptor_message.message_data)); | 279 key_message.message = NULL; |
| 216 pp::ContentDecryptor_Private::KeyMessage(decryptor_message.key_system, | 280 delete [] key_message.default_url; |
| 217 decryptor_message.session_id, | 281 key_message.default_url = NULL; |
| 218 message_buffer, | 282 } |
| 219 decryptor_message.default_url); | 283 |
| 220 } | 284 // TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM |
| 221 | 285 // interface and in this function. |
| 222 void CDMWrapper::KeyError(int32_t result, | 286 void CdmWrapper::KeyError(int32_t result, const std::string& session_id) { |
| 223 const DecryptorMessage& decryptor_message) { | 287 pp::ContentDecryptor_Private::KeyError(key_system_, |
| 224 pp::ContentDecryptor_Private::KeyError(decryptor_message.key_system, | 288 session_id, |
| 225 decryptor_message.session_id, | 289 kUnknownError, |
| 226 decryptor_message.media_error, | 290 0); |
| 227 decryptor_message.system_code); | 291 } |
| 228 } | 292 |
| 229 | 293 void CdmWrapper::DeliverBlock(int32_t result, |
| 230 void CDMWrapper::DeliverBlock(int32_t result, | 294 const cdm::Status& status, |
| 231 const DecryptedBlock& decrypted_block) { | 295 cdm::OutputBuffer& output_buffer, |
| 232 pp::Buffer_Dev decrypted_buffer( | 296 const PP_DecryptTrackingInfo& tracking_info) { |
| 233 StringToBufferResource(decrypted_block.decrypted_data)); | 297 pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data, |
| 234 pp::ContentDecryptor_Private::DeliverBlock( | 298 output_buffer.data_size)); |
| 235 decrypted_buffer, | 299 |
| 236 decrypted_block.decrypted_block_info); | 300 PP_DecryptedBlockInfo decrypted_block_info; |
| 301 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; |
| 302 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; |
| 303 |
| 304 switch (status) { |
| 305 case cdm::kSuccess: |
| 306 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; |
| 307 break; |
| 308 case cdm::kErrorNoKey: |
| 309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; |
| 310 break; |
| 311 default: |
| 312 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; |
| 313 } |
| 314 |
| 315 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, |
| 316 decrypted_block_info); |
| 317 |
| 318 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated |
| 319 // in another shared object. |
| 320 delete [] output_buffer.data; |
| 321 output_buffer.data = NULL; |
| 237 } | 322 } |
| 238 | 323 |
| 239 // This object is the global object representing this plugin library as long | 324 // This object is the global object representing this plugin library as long |
| 240 // as it is loaded. | 325 // as it is loaded. |
| 241 class MyModule : public pp::Module { | 326 class MyModule : public pp::Module { |
| 242 public: | 327 public: |
| 243 MyModule() : pp::Module() {} | 328 MyModule() : pp::Module() {} |
| 244 virtual ~MyModule() {} | 329 virtual ~MyModule() {} |
| 245 | 330 |
| 246 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 331 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 247 return new CDMWrapper(instance, this); | 332 return new CdmWrapper(instance, this); |
| 248 } | 333 } |
| 249 }; | 334 }; |
| 250 | 335 |
| 336 } // namespace webkit_media |
| 337 |
| 251 namespace pp { | 338 namespace pp { |
| 252 | 339 |
| 253 // Factory function for your specialization of the Module object. | 340 // Factory function for your specialization of the Module object. |
| 254 Module* CreateModule() { | 341 Module* CreateModule() { |
| 255 return new MyModule(); | 342 return new webkit_media::MyModule(); |
| 256 } | 343 } |
| 257 | 344 |
| 258 } // namespace pp | 345 } // namespace pp |
| OLD | NEW |