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

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

Issue 10545036: Add PPAPI decryptor interfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert change to ppapi_tests.gypi. 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.
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>
6 #include <string>
7
8 #include "base/basictypes.h"
9 #include "base/string_number_conversions.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/cpp/completion_callback.h"
13 #include "ppapi/cpp/core.h"
14 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/module.h"
16 #include "ppapi/cpp/resource.h"
17 #include "ppapi/cpp/var.h"
18 #include "ppapi/cpp/dev/buffer_dev.h"
19 #include "ppapi/cpp/dev/content_decryptor_dev.h"
20 #include "ppapi/shared_impl/var.h"
21 #include "ppapi/utility/completion_callback_factory.h"
22
23 using ppapi::StringVar;
24
25 namespace {
26
27 struct DecryptorMessage {
28 DecryptorMessage() : media_error(0), system_error(0) {}
29 std::string key_system;
30 std::string session_id;
31 std::string default_url;
32 std::string message_data;
33 uint16 media_error;
34 uint16 system_error;
35 };
36
37 struct DecryptedBlock {
38 DecryptedBlock() : callback(PP_MakeCompletionCallback(NULL, NULL)) {}
39 PP_CompletionCallback callback;
40 std::string data;
41 };
42
43 bool IsMainThread() {
44 return pp::Module::Get()->core()->IsMainThread();
45 }
46
47 void CallOnMain(pp::CompletionCallback cb) {
48 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
49 }
50
51 } // namespace
52
53
54 // A wrapper class responsible for managing interaction between the browser and
55 // a Content Decryption Module (CDM).
56 class CDMWrapper : public pp::Instance,
57 public pp::ContentDecryptor_Dev {
58 public:
59 CDMWrapper(PP_Instance instance, pp::Module* module);
60 virtual ~CDMWrapper() {}
61
62 // PPP_ContentDecryptor_Dev methods
63 virtual bool GenerateKeyRequest(PP_Var key_system, PP_Resource init_data);
64 virtual bool AddKey(PP_Var session_id, PP_Resource key);
65 virtual bool CancelKeyRequest(PP_Var session_id);
66 virtual bool Decrypt(PP_Resource encrypted_block,
67 PP_CompletionCallback callback);
68
69 virtual bool DecryptAndDecode(PP_Resource encrypted_block,
70 PP_CompletionCallback callback) {
71 return false;
72 }
73
74 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
75 return true;
76 }
77
78 private:
79 PP_Resource StringToBufferResource(const std::string& str);
80
81 // <code>PPB_ContentDecryptor_Dev</code> dispatchers. These are passed to
82 // <code>callback_factory_</code> to ensure that calls into
83 // <code>PPP_ContentDecryptor_Dev</code> are asynchronous.
84 void NeedKey(int32 result, const DecryptorMessage& decryptor_message);
85 void KeyAdded(int32 result, const DecryptorMessage& decryptor_message);
86 void KeyMessage(int32 result, const DecryptorMessage& decryptor_message);
87 void KeyError(int32 result, const DecryptorMessage& decryptor_message);
88 void DeliverBlock(int32 result, const DecryptedBlock& decrypted_block);
89
90 pp::CompletionCallbackFactory<CDMWrapper> callback_factory_;
91
92 virtual bool IsValidSessionId(std::string session_id) {
93 // TODO(tomfinegan): The CDM MUST handle multiple session IDs. This simple
94 // implementation exists for testing purposes.
95 return (!session_id_.empty() && session_id == session_id_);
96 }
97
98 // TODO(tomfinegan): This needs to be mappable to init data (key IDs in the
99 // WebM case). For WebM it most likely will be 1 key ID and 1 session per
100 // stream. For now we'll just use a random number.
101 uint32 next_session_id_;
102 std::string session_id_;
103
104 // Key ID obtained from init data passed to <code>GenerateKeyRequest</code>.
105 // As-is: WebM video specific; Inadequate for WebM with encrypted audio (A/V
106 // will not have same key ID/key/session ID). Probably inadequate for ISO.
107 std::string key_id_;
108
109 // TODO(tomfinegan): Should these be multimaps of session_id:key_system and
110 // session_id:key? Or am I completely confused? :)
111 std::string key_;
112 std::string key_system_;
113 };
114
115 CDMWrapper::CDMWrapper(PP_Instance instance,
116 pp::Module* module)
117 : pp::Instance(instance),
118 pp::ContentDecryptor_Dev(this),
119 next_session_id_(0) {
120 callback_factory_.Initialize(this);
121 }
122
123 bool CDMWrapper::GenerateKeyRequest(PP_Var key_system_arg,
124 PP_Resource init_data) {
125 if (init_data) {
126 pp::Buffer_Dev init_buffer(init_data);
127 if (!init_buffer.data() || init_buffer.size() == 0) {
128 return false;
129 }
130
131 // TODO(tomfinegan): Testing only implementation; init data will not always
132 // be the key ID.
133 key_id_.assign(reinterpret_cast<char*>(init_buffer.data()),
134 init_buffer.size());
135 }
136
137 StringVar* key_system_var = StringVar::FromPPVar(key_system_arg);
138
139 // TODO(tomfinegan): confirm support for the key system.
140
141 DecryptorMessage decryptor_message;
142 key_system_ = key_system_var->value();
143 decryptor_message.key_system = key_system_;
144 session_id_ = base::UintToString(next_session_id_++);
145 decryptor_message.session_id = session_id_;
146 decryptor_message.default_url = "http://www.google.com";
147 decryptor_message.message_data = "key request";
148
149 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage,
150 decryptor_message));
151 return true;
152 }
153
154 bool CDMWrapper::AddKey(PP_Var session_id_var, PP_Resource key) {
155 if (!IsValidSessionId(StringVar::FromPPVar(session_id_var)->value()))
156 return false;
157
158 pp::Buffer_Dev key_buffer(key);
159 if (!key_buffer.data())
160 return false;
161
162 key_.assign(reinterpret_cast<char*>(key_buffer.data()), key_buffer.size());
163
164 DecryptorMessage decryptor_message;
165 decryptor_message.key_system = key_system_;
166 decryptor_message.session_id = session_id_;
167 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyAdded,
168 decryptor_message));
169 return true;
170 }
171
172 bool CDMWrapper::CancelKeyRequest(PP_Var session_id_var) {
173 std::string session_id = StringVar::FromPPVar(session_id_var)->value();
174
175 if (!IsValidSessionId(session_id))
176 return false;
177
178 // TODO(tomfinegan): cancel pending key request in CDM.
179
180 return true;
181 }
182
183 bool CDMWrapper::Decrypt(PP_Resource encrypted_block,
184 PP_CompletionCallback callback) {
185 pp::Buffer_Dev block_buffer(encrypted_block);
186 if (!block_buffer.data() || !callback.func) {
187 return false;
188 }
189
190 DecryptedBlock decrypted_block;
191 decrypted_block.callback = callback;
192 decrypted_block.data = "Pretend I'm decrypted data!";
193 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::DeliverBlock,
194 decrypted_block));
195 return true;
196 }
197
198 PP_Resource CDMWrapper::StringToBufferResource(const std::string& str) {
199 if (str.empty())
200 return 0;
201
202 pp::Buffer_Dev buffer(this, str.size());
203 if (!buffer.data())
204 return 0;
205
206 memcpy(buffer.data(), str.data(), str.size());
207 return buffer.detach();
208 }
209
210 void CDMWrapper::NeedKey(int32 result,
211 const DecryptorMessage& decryptor_message) {
212 PP_Var key_system = StringVar::StringToPPVar(decryptor_message.key_system);
213 PP_Var session_id = StringVar::StringToPPVar(decryptor_message.session_id);
214 PP_Resource init_data =
215 StringToBufferResource(decryptor_message.message_data);
216 pp::ContentDecryptor_Dev::NeedKey(key_system, session_id, init_data);
217 }
218
219 void CDMWrapper::KeyAdded(int32 result,
220 const DecryptorMessage& decryptor_message) {
221 PP_Var key_system = StringVar::StringToPPVar(decryptor_message.key_system);
222 PP_Var session_id = StringVar::StringToPPVar(decryptor_message.session_id);
223 pp::ContentDecryptor_Dev::KeyAdded(key_system, session_id);
224 }
225
226 void CDMWrapper::KeyMessage(int32 result,
227 const DecryptorMessage& decryptor_message) {
228 PP_Var key_system = StringVar::StringToPPVar(decryptor_message.key_system);
229 PP_Var session_id = StringVar::StringToPPVar(decryptor_message.session_id);
230 PP_Resource message =
231 StringToBufferResource(decryptor_message.message_data);
232 PP_Var default_url =
233 StringVar::StringToPPVar(decryptor_message.default_url);
234 pp::ContentDecryptor_Dev::KeyMessage(key_system,
235 session_id,
236 message,
237 default_url);
238 }
239
240 void CDMWrapper::KeyError(int32 result,
241 const DecryptorMessage& decryptor_message) {
242 PP_Var key_system = StringVar::StringToPPVar(decryptor_message.key_system);
243 PP_Var session_id = StringVar::StringToPPVar(decryptor_message.session_id);
244 pp::ContentDecryptor_Dev::KeyError(key_system,
245 session_id,
246 decryptor_message.media_error,
247 decryptor_message.system_error);
248 }
249
250 void CDMWrapper::DeliverBlock(int32 result,
251 const DecryptedBlock& decrypted_block) {
252 PP_Resource decrypted_resource = StringToBufferResource(
253 decrypted_block.data);
254 if (decrypted_resource) {
255 pp::ContentDecryptor_Dev::DeliverBlock(decrypted_resource,
256 decrypted_block.callback);
257 }
258 }
259
260 // This object is the global object representing this plugin library as long
261 // as it is loaded.
262 class MyModule : public pp::Module {
dmichael (off chromium) 2012/07/31 03:36:31 I'm confused about what this file is... is this t
Tom Finegan 2012/08/01 04:19:22 Don't worry-- it _is_ confusing. :) The pepper pl
263 public:
264 MyModule() : pp::Module() {}
265 virtual ~MyModule() {}
266
267 virtual pp::Instance* CreateInstance(PP_Instance instance) {
268 return new CDMWrapper(instance, this);
269 }
270 };
271
272 namespace pp {
273
274 // Factory function for your specialization of the Module object.
275 Module* CreateModule() {
276 return new MyModule();
277 }
278
279 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698