Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: webkit/media/crypto/content_decryptor.cc

Issue 10827280: Add PPAPI decryptor implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Partially address xhwang's comments, and fix some StringVar crashiness Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
ddorwin 2012/08/15 22:03:22 Filename is misleading. It should be cdm_wrapper o
Tom Finegan 2012/08/16 16:15:45 Renamed to cdm_wrapper.cc; moved file to ppapi sub
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <cassert>
ddorwin 2012/08/15 22:03:22 Why not use DCHECK? Can we not use it in plugins?
Tom Finegan 2012/08/16 16:15:45 Removed.
6 #include <cstdio> // stderr; debugging via fprintf.
ddorwin 2012/08/15 22:03:22 TODO: Remove some of these.
Tom Finegan 2012/08/16 03:10:48 Done.
7 #include <cstring> // std::memcpy
8 #include <sstream> // std::ostringstream
9
10 #include "base/compiler_specific.h" // for OVERRIDE.
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/c/pp_stdint.h"
13 #include "ppapi/cpp/completion_callback.h"
14 #include "ppapi/cpp/core.h"
15 #include "ppapi/cpp/instance.h"
16 #include "ppapi/cpp/module.h"
17 #include "ppapi/cpp/pass_ref.h"
18 #include "ppapi/cpp/resource.h"
19 #include "ppapi/cpp/var.h"
20 #include "ppapi/cpp/var_array_buffer.h"
21 #include "ppapi/cpp/dev/buffer_dev.h"
22 #include "ppapi/cpp/private/content_decryptor_private.h"
23 #include "ppapi/utility/completion_callback_factory.h"
24
25 namespace {
26
27 struct DecryptorMessage {
28 DecryptorMessage() : media_error(0), system_code(0) {}
29 std::string key_system;
30 std::string session_id;
31 std::string default_url;
32 std::string message_data;
33 int32_t media_error;
34 int32_t system_code;
35 };
36
37 struct DecryptedBlock {
38 DecryptedBlock() : request_id(0) {}
39 int32_t request_id;
40 std::string data;
41 };
42
43 void CallOnMain(pp::CompletionCallback cb) {
44 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
45 }
46
47 } // namespace
48
49
50 // A wrapper class responsible for managing interaction between the browser and
ddorwin 2012/08/15 22:03:22 Maybe something like: ... for abstracting away PPA
Tom Finegan 2012/08/16 16:15:45 Done.
51 // a Content Decryption Module (CDM).
52 class CDMWrapper : public pp::Instance,
53 public pp::ContentDecryptor_Private {
54 public:
55 CDMWrapper(PP_Instance instance, pp::Module* module);
56 virtual ~CDMWrapper() {}
57
58 // PPP_ContentDecryptor_Private methods
59 virtual bool GenerateKeyRequest(const std::string& key_system,
60 pp::VarArrayBuffer init_data) OVERRIDE;
61 virtual bool AddKey(const std::string& session_id,
62 pp::VarArrayBuffer key) OVERRIDE;
63 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE;
64 virtual bool Decrypt(pp::Buffer_Dev encrypted_buffer,
65 int32_t request_id) OVERRIDE;
66
67 virtual bool DecryptAndDecode(pp::Buffer_Dev encrypted_buffer,
68 int32_t request_id) OVERRIDE {
69 return false;
70 }
71
72 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
73 return true;
74 }
75
76 private:
77 PP_Resource StringToBufferResource(const std::string& str);
78
79 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
80 // <code>callback_factory_</code> to ensure that calls into
81 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
82 void NeedKey(int32_t result, const DecryptorMessage& decryptor_message);
83 void KeyAdded(int32_t result, const DecryptorMessage& decryptor_message);
84 void KeyMessage(int32_t result, const DecryptorMessage& decryptor_message);
85 void KeyError(int32_t result, const DecryptorMessage& decryptor_message);
86 void DeliverBlock(int32_t result, const DecryptedBlock& decrypted_block);
87
88 pp::CompletionCallbackFactory<CDMWrapper> callback_factory_;
89 };
90
91 CDMWrapper::CDMWrapper(PP_Instance instance,
92 pp::Module* module)
93 : pp::Instance(instance),
94 pp::ContentDecryptor_Private(this) {
95 callback_factory_.Initialize(this);
96 }
97
98 bool CDMWrapper::GenerateKeyRequest(const std::string& key_system,
99 pp::VarArrayBuffer init_data) {
100
101 // TODO(tomfinegan): Testing only implementation; init_data will not always
102 // be the key ID, and this will be handled by the decryptor module anyway.
103 const std::string key_id(reinterpret_cast<char*>(init_data.Map()),
104 init_data.ByteLength());
105 if (key_id.empty() || key_system.empty())
106 return false;
107
108 DecryptorMessage decryptor_message;
109 decryptor_message.key_system = key_system;
110 decryptor_message.session_id = "0";
111 decryptor_message.default_url = "http://www.google.com";
112 decryptor_message.message_data = "key request";
113
114 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage,
115 decryptor_message));
116 return true;
117 }
118
119 bool CDMWrapper::AddKey(const std::string& session_id,
120 pp::VarArrayBuffer key) {
121 const std::string key_string(reinterpret_cast<char*>(key.Map()),
122 key.ByteLength());
123
124 if (session_id.empty() || key_string.empty())
125 return false;
126
127 DecryptorMessage decryptor_message;
128 decryptor_message.session_id = session_id;
129 decryptor_message.message_data = key_string;
130 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyAdded,
131 decryptor_message));
132 return true;
133 }
134
135 bool CDMWrapper::CancelKeyRequest(const std::string& session_id) {
136 if (session_id.empty())
137 return false;
138
139 // TODO(tomfinegan): cancel pending key request in CDM.
140
141 DecryptorMessage decryptor_message;
142 decryptor_message.session_id = session_id;
143 decryptor_message.message_data = "CancelKeyRequest";
144 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage,
145 decryptor_message));
146
147 return true;
148 }
149
150 bool CDMWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer,
151 int32_t request_id) {
152 if (!encrypted_buffer.data())
153 return false;
154
155 DecryptedBlock decrypted_block;
156 decrypted_block.request_id = request_id;
157 decrypted_block.data = "Pretend I'm decrypted data!";
158 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::DeliverBlock,
159 decrypted_block));
160 return true;
161 }
162
163 PP_Resource CDMWrapper::StringToBufferResource(const std::string& str) {
164 if (str.empty())
165 return 0;
166
167 pp::Buffer_Dev buffer(this, str.size());
168 if (!buffer.data())
169 return 0;
170
171 std::memcpy(buffer.data(), str.data(), str.size());
172 return buffer.detach();
173 }
174
175 void CDMWrapper::NeedKey(int32_t result,
176 const DecryptorMessage& decryptor_message) {
177 pp::ContentDecryptor_Private::NeedKey(decryptor_message.key_system,
178 decryptor_message.session_id,
179 decryptor_message.message_data);
180 }
181
182 void CDMWrapper::KeyAdded(int32_t result,
183 const DecryptorMessage& decryptor_message) {
184 pp::ContentDecryptor_Private::KeyAdded(decryptor_message.key_system,
185 decryptor_message.session_id);
186 }
187
188 void CDMWrapper::KeyMessage(int32_t result,
189 const DecryptorMessage& decryptor_message) {
190 pp::Buffer_Dev message_buffer(
191 StringToBufferResource(decryptor_message.message_data));
192 fprintf(stderr,
ddorwin 2012/08/15 22:03:22 Use the PPB_Console_Dev interface instead?
Tom Finegan 2012/08/16 16:15:45 Mainly because the output sent to PPB_Console_Dev
193 "CDMWrapper::KeyMessage sending KeyMessage via cpp wrapper!\n");
194 pp::ContentDecryptor_Private::KeyMessage(decryptor_message.key_system,
195 decryptor_message.session_id,
196 message_buffer,
197 decryptor_message.default_url);
198 }
199
200 void CDMWrapper::KeyError(int32_t result,
201 const DecryptorMessage& decryptor_message) {
202 pp::ContentDecryptor_Private::KeyError(decryptor_message.key_system,
203 decryptor_message.session_id,
204 decryptor_message.media_error,
205 decryptor_message.system_code);
206 }
207
208 void CDMWrapper::DeliverBlock(int32_t result,
209 const DecryptedBlock& decrypted_block) {
210 pp::Buffer_Dev decrypted_buffer(
211 StringToBufferResource(decrypted_block.data));
212 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer,
213 decrypted_block.request_id);
214 }
215
216 // This object is the global object representing this plugin library as long
217 // as it is loaded.
218 class MyModule : public pp::Module {
219 public:
220 MyModule() : pp::Module() {}
221 virtual ~MyModule() {}
222
223 virtual pp::Instance* CreateInstance(PP_Instance instance) {
224 return new CDMWrapper(instance, this);
225 }
226 };
227
228 namespace pp {
229
230 // Factory function for your specialization of the Module object.
231 Module* CreateModule() {
232 return new MyModule();
233 }
234
235 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698