IDrm.cpp revision 441a78d5e224e0d67f9b52fa9adc795c6944159b
1/*
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
552