blob: 3b13ec699c133e5904c23b665da5138872ecdac2 [file] [log] [blame]
Jeff Tinkercc82dc62013-02-08 10:18:35 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "IDrm"
19#include <utils/Log.h>
20
21#include <binder/Parcel.h>
22#include <media/IDrm.h>
23#include <media/stagefright/MediaErrors.h>
24#include <media/stagefright/foundation/ADebug.h>
25#include <media/stagefright/foundation/AString.h>
26
27namespace android {
28
29enum {
30 INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
31 IS_CRYPTO_SUPPORTED,
32 CREATE_PLUGIN,
33 DESTROY_PLUGIN,
34 OPEN_SESSION,
35 CLOSE_SESSION,
36 GET_LICENSE_REQUEST,
37 PROVIDE_LICENSE_RESPONSE,
38 REMOVE_LICENSE,
39 QUERY_LICENSE_STATUS,
40 GET_PROVISION_REQUEST,
41 PROVIDE_PROVISION_RESPONSE,
42 GET_SECURE_STOPS,
43 RELEASE_SECURE_STOPS,
44 GET_PROPERTY_STRING,
45 GET_PROPERTY_BYTE_ARRAY,
46 SET_PROPERTY_STRING,
47 SET_PROPERTY_BYTE_ARRAY
48};
49
50struct BpDrm : public BpInterface<IDrm> {
51 BpDrm(const sp<IBinder> &impl)
52 : BpInterface<IDrm>(impl) {
53 }
54
55 virtual status_t initCheck() const {
56 Parcel data, reply;
57 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
58 remote()->transact(INIT_CHECK, data, &reply);
59
60 return reply.readInt32();
61 }
62
63 virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) {
64 Parcel data, reply;
65 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
66 data.write(uuid, 16);
67 remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
68
69 return reply.readInt32() != 0;
70 }
71
72 virtual status_t createPlugin(const uint8_t uuid[16]) {
73 Parcel data, reply;
74 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
75 data.write(uuid, 16);
76
77 remote()->transact(CREATE_PLUGIN, data, &reply);
78
79 return reply.readInt32();
80 }
81
82 virtual status_t destroyPlugin() {
83 Parcel data, reply;
84 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
85 remote()->transact(DESTROY_PLUGIN, data, &reply);
86
87 return reply.readInt32();
88 }
89
90 virtual status_t openSession(Vector<uint8_t> &sessionId) {
91 Parcel data, reply;
92 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
93
94 remote()->transact(OPEN_SESSION, data, &reply);
95 uint32_t size = reply.readInt32();
96 sessionId.insertAt((size_t)0, size);
97 reply.read(sessionId.editArray(), size);
98
99 return reply.readInt32();
100 }
101
102 virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
103 Parcel data, reply;
104 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
105
106 data.writeInt32(sessionId.size());
107 data.write(sessionId.array(), sessionId.size());
108 remote()->transact(CLOSE_SESSION, data, &reply);
109
110 return reply.readInt32();
111 }
112
113 virtual status_t
114 getLicenseRequest(Vector<uint8_t> const &sessionId,
115 Vector<uint8_t> const &initData,
116 String8 const &mimeType, DrmPlugin::LicenseType licenseType,
117 KeyedVector<String8, String8> const &optionalParameters,
118 Vector<uint8_t> &request, String8 &defaultUrl) {
119 Parcel data, reply;
120 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
121
122 data.writeInt32(sessionId.size());
123 data.write(sessionId.array(), sessionId.size());
124
125 data.writeInt32(initData.size());
126 data.write(initData.array(), initData.size());
127
128 data.writeString8(mimeType);
129 data.writeInt32((uint32_t)licenseType);
130
131 data.writeInt32(optionalParameters.size());
132 for (size_t i = 0; i < optionalParameters.size(); ++i) {
133 data.writeString8(optionalParameters.keyAt(i));
134 data.writeString8(optionalParameters.valueAt(i));
135 }
136 remote()->transact(GET_LICENSE_REQUEST, data, &reply);
137
138 uint32_t len = reply.readInt32();
139 request.insertAt((size_t)0, len);
140 reply.read(request.editArray(), len);
141 defaultUrl = reply.readString8();
142
143 return reply.readInt32();
144 }
145
146 virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
147 Vector<uint8_t> const &response) {
148 Parcel data, reply;
149 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
150
151 data.writeInt32(sessionId.size());
152 data.write(sessionId.array(), sessionId.size());
153 data.writeInt32(response.size());
154 data.write(response.array(), response.size());
155 remote()->transact(PROVIDE_LICENSE_RESPONSE, data, &reply);
156
157 return reply.readInt32();
158 }
159
160 virtual status_t removeLicense(Vector<uint8_t> const &sessionId) {
161 Parcel data, reply;
162 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
163
164 data.writeInt32(sessionId.size());
165 data.write(sessionId.array(), sessionId.size());
166 remote()->transact(REMOVE_LICENSE, data, &reply);
167
168 return reply.readInt32();
169 }
170
171 virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
172 KeyedVector<String8, String8> &infoMap) const {
173 Parcel data, reply;
174 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
175
176 data.writeInt32(sessionId.size());
177 data.write(sessionId.array(), sessionId.size());
178
179 remote()->transact(QUERY_LICENSE_STATUS, data, &reply);
180
181 infoMap.clear();
182 size_t count = reply.readInt32();
183 for (size_t i = 0; i < count; i++) {
184 String8 key = reply.readString8();
185 String8 value = reply.readString8();
186 infoMap.add(key, value);
187 }
188 return reply.readInt32();
189 }
190
191 virtual status_t getProvisionRequest(Vector<uint8_t> &request,
192 String8 &defaultUrl) {
193 Parcel data, reply;
194 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
195
196 remote()->transact(GET_PROVISION_REQUEST, data, &reply);
197
198 uint32_t len = reply.readInt32();
199 request.insertAt((size_t)0, len);
200 reply.read(request.editArray(), len);
201 defaultUrl = reply.readString8();
202
203 return reply.readInt32();
204 }
205
206 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) {
207 Parcel data, reply;
208 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
209
210 data.writeInt32(response.size());
211 data.write(response.array(), response.size());
212 remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
213
214 return reply.readInt32();
215 }
216
217 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
218 Parcel data, reply;
219 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
220
221 remote()->transact(GET_SECURE_STOPS, data, &reply);
222
223 secureStops.clear();
224 uint32_t count = reply.readInt32();
225 for (size_t i = 0; i < count; i++) {
226 Vector<uint8_t> secureStop;
227 uint32_t len = reply.readInt32();
228 secureStop.insertAt((size_t)0, len);
229 reply.read(secureStop.editArray(), len);
230 secureStops.push_back(secureStop);
231 }
232 return reply.readInt32();
233 }
234
235 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
236 Parcel data, reply;
237 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
238
239 data.writeInt32(ssRelease.size());
240 data.write(ssRelease.array(), ssRelease.size());
241 remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
242
243 return reply.readInt32();
244 }
245
246 virtual status_t getPropertyString(String8 const &name, String8 &value) const {
247 Parcel data, reply;
248 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
249
250 data.writeString8(name);
251 remote()->transact(GET_PROPERTY_STRING, data, &reply);
252
253 value = reply.readString8();
254 return reply.readInt32();
255 }
256
257 virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
258 Parcel data, reply;
259 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
260
261 data.writeString8(name);
262 remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
263
264 uint32_t len = reply.readInt32();
265 value.insertAt((size_t)0, len);
266 reply.read(value.editArray(), len);
267
268 return reply.readInt32();
269 }
270
271 virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
272 Parcel data, reply;
273 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
274
275 data.writeString8(name);
276 data.writeString8(value);
277 remote()->transact(SET_PROPERTY_STRING, data, &reply);
278
279 return reply.readInt32();
280 }
281
282 virtual status_t setPropertyByteArray(String8 const &name,
283 Vector<uint8_t> const &value) const {
284 Parcel data, reply;
285 data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
286
287 data.writeString8(name);
288 data.writeInt32(value.size());
289 data.write(value.array(), value.size());
290 remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
291
292 return reply.readInt32();
293 }
294
295
296private:
297 DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
298};
299
300IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
301
302////////////////////////////////////////////////////////////////////////////////
303
304status_t BnDrm::onTransact(
305 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
306 switch (code) {
307 case INIT_CHECK:
308 {
309 CHECK_INTERFACE(IDrm, data, reply);
310 reply->writeInt32(initCheck());
311 return OK;
312 }
313
314 case IS_CRYPTO_SUPPORTED:
315 {
316 CHECK_INTERFACE(IDrm, data, reply);
317 uint8_t uuid[16];
318 data.read(uuid, sizeof(uuid));
319 reply->writeInt32(isCryptoSchemeSupported(uuid));
320 return OK;
321 }
322
323 case CREATE_PLUGIN:
324 {
325 CHECK_INTERFACE(IDrm, data, reply);
326 uint8_t uuid[16];
327 data.read(uuid, sizeof(uuid));
328 reply->writeInt32(createPlugin(uuid));
329 return OK;
330 }
331
332 case DESTROY_PLUGIN:
333 {
334 CHECK_INTERFACE(IDrm, data, reply);
335 reply->writeInt32(destroyPlugin());
336 return OK;
337 }
338
339 case OPEN_SESSION:
340 {
341 CHECK_INTERFACE(IDrm, data, reply);
342 Vector<uint8_t> sessionId;
343 status_t result = openSession(sessionId);
344 reply->writeInt32(sessionId.size());
345 reply->write(sessionId.array(), sessionId.size());
346 reply->writeInt32(result);
347 return OK;
348 }
349
350 case CLOSE_SESSION:
351 {
352 CHECK_INTERFACE(IDrm, data, reply);
353 Vector<uint8_t> sessionId;
354 uint32_t size = data.readInt32();
355 sessionId.insertAt((size_t)0, size);
356 data.read(sessionId.editArray(), size);
357 reply->writeInt32(closeSession(sessionId));
358 return OK;
359 }
360
361 case GET_LICENSE_REQUEST:
362 {
363 CHECK_INTERFACE(IDrm, data, reply);
364 Vector<uint8_t> sessionId;
365 uint32_t size = data.readInt32();
366 sessionId.insertAt((size_t)0, size);
367 data.read(sessionId.editArray(), size);
368
369 Vector<uint8_t> initData;
370 size = data.readInt32();
371 initData.insertAt((size_t)0, size);
372 data.read(initData.editArray(), size);
373
374 String8 mimeType = data.readString8();
375 DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)data.readInt32();
376
377 KeyedVector<String8, String8> optionalParameters;
378 uint32_t count = data.readInt32();
379 for (size_t i = 0; i < count; ++i) {
380 String8 key, value;
381 key = data.readString8();
382 value = data.readString8();
383 optionalParameters.add(key, value);
384 }
385
386 Vector<uint8_t> request;
387 String8 defaultUrl;
388
389 status_t result = getLicenseRequest(sessionId, initData,
390 mimeType, licenseType,
391 optionalParameters,
392 request, defaultUrl);
393 reply->writeInt32(request.size());
394 reply->write(request.array(), request.size());
395 reply->writeString8(defaultUrl);
396 reply->writeInt32(result);
397 return OK;
398 }
399
400 case PROVIDE_LICENSE_RESPONSE:
401 {
402 CHECK_INTERFACE(IDrm, data, reply);
403 Vector<uint8_t> sessionId;
404 uint32_t size = data.readInt32();
405 sessionId.insertAt((size_t)0, size);
406 data.read(sessionId.editArray(), size);
407 Vector<uint8_t> response;
408 size = data.readInt32();
409 response.insertAt((size_t)0, size);
410 data.read(response.editArray(), size);
411
412 reply->writeInt32(provideLicenseResponse(sessionId, response));
413 return OK;
414 }
415
416 case REMOVE_LICENSE:
417 {
418 CHECK_INTERFACE(IDrm, data, reply);
419 Vector<uint8_t> sessionId;
420 uint32_t size = data.readInt32();
421 sessionId.insertAt((size_t)0, size);
422 data.read(sessionId.editArray(), size);
423 reply->writeInt32(removeLicense(sessionId));
424 return OK;
425 }
426
427 case QUERY_LICENSE_STATUS:
428 {
429 CHECK_INTERFACE(IDrm, data, reply);
430 Vector<uint8_t> sessionId;
431 uint32_t size = data.readInt32();
432 sessionId.insertAt((size_t)0, size);
433 data.read(sessionId.editArray(), size);
434 KeyedVector<String8, String8> infoMap;
435
436 status_t result = queryLicenseStatus(sessionId, infoMap);
437
438 size_t count = infoMap.size();
439 reply->writeInt32(count);
440 for (size_t i = 0; i < count; ++i) {
441 reply->writeString8(infoMap.keyAt(i));
442 reply->writeString8(infoMap.valueAt(i));
443 }
444 reply->writeInt32(result);
445 return OK;
446 }
447
448 case GET_PROVISION_REQUEST:
449 {
450 CHECK_INTERFACE(IDrm, data, reply);
451 Vector<uint8_t> request;
452 String8 defaultUrl;
453 status_t result = getProvisionRequest(request, defaultUrl);
454 reply->writeInt32(request.size());
455 reply->write(request.array(), request.size());
456 reply->writeString8(defaultUrl);
457 reply->writeInt32(result);
458 return OK;
459 }
460
461 case PROVIDE_PROVISION_RESPONSE:
462 {
463 CHECK_INTERFACE(IDrm, data, reply);
464 Vector<uint8_t> response;
465 uint32_t size = data.readInt32();
466 response.insertAt((size_t)0, size);
467 data.read(response.editArray(), size);
468 reply->writeInt32(provideProvisionResponse(response));
469
470 return OK;
471 }
472
473 case GET_SECURE_STOPS:
474 {
475 CHECK_INTERFACE(IDrm, data, reply);
476 List<Vector<uint8_t> > secureStops;
477 status_t result = getSecureStops(secureStops);
478 size_t count = secureStops.size();
479 reply->writeInt32(count);
480 List<Vector<uint8_t> >::iterator iter = secureStops.begin();
481 while(iter != secureStops.end()) {
482 size_t size = iter->size();
483 reply->writeInt32(size);
484 reply->write(iter->array(), iter->size());
485 }
486 reply->writeInt32(result);
487 return OK;
488 }
489
490 case RELEASE_SECURE_STOPS:
491 {
492 CHECK_INTERFACE(IDrm, data, reply);
493 Vector<uint8_t> ssRelease;
494 uint32_t size = data.readInt32();
495 ssRelease.insertAt((size_t)0, size);
496 data.read(ssRelease.editArray(), size);
497 reply->writeInt32(releaseSecureStops(ssRelease));
498 return OK;
499 }
500
501 case GET_PROPERTY_STRING:
502 {
503 CHECK_INTERFACE(IDrm, data, reply);
504 String8 name = data.readString8();
505 String8 value;
506 status_t result = getPropertyString(name, value);
507 reply->writeString8(value);
508 reply->writeInt32(result);
509 return OK;
510 }
511
512 case GET_PROPERTY_BYTE_ARRAY:
513 {
514 CHECK_INTERFACE(IDrm, data, reply);
515 String8 name = data.readString8();
516 Vector<uint8_t> value;
517 status_t result = getPropertyByteArray(name, value);
518 reply->writeInt32(value.size());
519 reply->write(value.array(), value.size());
520 reply->writeInt32(result);
521 return OK;
522 }
523
524 case SET_PROPERTY_STRING:
525 {
526 CHECK_INTERFACE(IDrm, data, reply);
527 String8 name = data.readString8();
528 String8 value = data.readString8();
529 reply->writeInt32(setPropertyString(name, value));
530 return OK;
531 }
532
533 case SET_PROPERTY_BYTE_ARRAY:
534 {
535 CHECK_INTERFACE(IDrm, data, reply);
536 String8 name = data.readString8();
537 Vector<uint8_t> value;
538 size_t count = data.readInt32();
539 value.insertAt((size_t)0, count);
540 data.read(value.editArray(), count);
541 reply->writeInt32(setPropertyByteArray(name, value));
542 return OK;
543 }
544
545 default:
546 return BBinder::onTransact(code, data, reply, flags);
547 }
548}
549
550} // namespace android
551