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_KEY_REQUEST,
37    PROVIDE_KEY_RESPONSE,
38    REMOVE_KEYS,
39    RESTORE_KEYS,
40    QUERY_KEY_STATUS,
41    GET_PROVISION_REQUEST,
42    PROVIDE_PROVISION_RESPONSE,
43    GET_SECURE_STOPS,
44    RELEASE_SECURE_STOPS,
45    GET_PROPERTY_STRING,
46    GET_PROPERTY_BYTE_ARRAY,
47    SET_PROPERTY_STRING,
48    SET_PROPERTY_BYTE_ARRAY,
49    SET_CIPHER_ALGORITHM,
50    SET_MAC_ALGORITHM,
51    ENCRYPT,
52    DECRYPT,
53    SIGN,
54    SIGN_RSA,
55    VERIFY,
56    SET_LISTENER,
57    GET_SECURE_STOP,
58    RELEASE_ALL_SECURE_STOPS
59};
60
61struct BpDrm : public BpInterface<IDrm> {
62    explicit BpDrm(const sp<IBinder> &impl)
63        : BpInterface<IDrm>(impl) {
64    }
65
66    virtual status_t initCheck() const {
67        Parcel data, reply;
68        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
69        status_t status = remote()->transact(INIT_CHECK, data, &reply);
70        if (status != OK) {
71            return status;
72        }
73
74        return reply.readInt32();
75    }
76
77    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
78        Parcel data, reply;
79        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
80        data.write(uuid, 16);
81        data.writeString8(mimeType);
82        status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
83        if (status != OK) {
84            ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
85            return false;
86        }
87
88        return reply.readInt32() != 0;
89    }
90
91    virtual status_t createPlugin(const uint8_t uuid[16],
92                                  const String8& appPackageName) {
93        Parcel data, reply;
94        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
95        data.write(uuid, 16);
96        data.writeString8(appPackageName);
97        status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
98        if (status != OK) {
99            ALOGE("createPlugin: binder call failed: %d", status);
100            return status;
101        }
102
103        return reply.readInt32();
104    }
105
106    virtual status_t destroyPlugin() {
107        Parcel data, reply;
108        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
109        status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
110        if (status != OK) {
111            return status;
112        }
113
114        return reply.readInt32();
115    }
116
117    virtual status_t openSession(Vector<uint8_t> &sessionId) {
118        Parcel data, reply;
119        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
120
121        status_t status = remote()->transact(OPEN_SESSION, data, &reply);
122        if (status != OK) {
123            return status;
124        }
125        readVector(reply, sessionId);
126
127        return reply.readInt32();
128    }
129
130    virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
131        Parcel data, reply;
132        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
133
134        writeVector(data, sessionId);
135        status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
136        if (status != OK) {
137            return status;
138        }
139
140        return reply.readInt32();
141    }
142
143    virtual status_t
144        getKeyRequest(Vector<uint8_t> const &sessionId,
145                      Vector<uint8_t> const &initData,
146                      String8 const &mimeType, DrmPlugin::KeyType keyType,
147                      KeyedVector<String8, String8> const &optionalParameters,
148                      Vector<uint8_t> &request, String8 &defaultUrl,
149                      DrmPlugin::KeyRequestType *keyRequestType) {
150        Parcel data, reply;
151        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
152
153        writeVector(data, sessionId);
154        writeVector(data, initData);
155        data.writeString8(mimeType);
156        data.writeInt32((uint32_t)keyType);
157
158        data.writeInt32(optionalParameters.size());
159        for (size_t i = 0; i < optionalParameters.size(); ++i) {
160            data.writeString8(optionalParameters.keyAt(i));
161            data.writeString8(optionalParameters.valueAt(i));
162        }
163
164        status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
165        if (status != OK) {
166            return status;
167        }
168
169        readVector(reply, request);
170        defaultUrl = reply.readString8();
171        *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
172
173        return reply.readInt32();
174    }
175
176    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
177                                        Vector<uint8_t> const &response,
178                                        Vector<uint8_t> &keySetId) {
179        Parcel data, reply;
180        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
181        writeVector(data, sessionId);
182        writeVector(data, response);
183
184        status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
185        if (status != OK) {
186            return status;
187        }
188
189        readVector(reply, keySetId);
190
191        return reply.readInt32();
192    }
193
194    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
195        Parcel data, reply;
196        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
197
198        writeVector(data, keySetId);
199        status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
200        if (status != OK) {
201            return status;
202        }
203
204        return reply.readInt32();
205    }
206
207    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
208                                 Vector<uint8_t> const &keySetId) {
209        Parcel data, reply;
210        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
211
212        writeVector(data, sessionId);
213        writeVector(data, keySetId);
214        status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
215        if (status != OK) {
216            return status;
217        }
218
219        return reply.readInt32();
220    }
221
222    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
223                                        KeyedVector<String8, String8> &infoMap) const {
224        Parcel data, reply;
225        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
226
227        writeVector(data, sessionId);
228        status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
229        if (status != OK) {
230            return status;
231        }
232
233        infoMap.clear();
234        size_t count = reply.readInt32();
235        for (size_t i = 0; i < count; i++) {
236            String8 key = reply.readString8();
237            String8 value = reply.readString8();
238            infoMap.add(key, value);
239        }
240        return reply.readInt32();
241    }
242
243    virtual status_t getProvisionRequest(String8 const &certType,
244                                         String8 const &certAuthority,
245                                         Vector<uint8_t> &request,
246                                         String8 &defaultUrl) {
247        Parcel data, reply;
248        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
249
250        data.writeString8(certType);
251        data.writeString8(certAuthority);
252        status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
253        if (status != OK) {
254            return status;
255        }
256
257        readVector(reply, request);
258        defaultUrl = reply.readString8();
259
260        return reply.readInt32();
261    }
262
263    virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
264                                              Vector<uint8_t> &certificate,
265                                              Vector<uint8_t> &wrappedKey) {
266        Parcel data, reply;
267        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
268
269        writeVector(data, response);
270        status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
271        if (status != OK) {
272            return status;
273        }
274
275        readVector(reply, certificate);
276        readVector(reply, wrappedKey);
277
278        return reply.readInt32();
279    }
280
281    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
282        Parcel data, reply;
283        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
284
285        status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
286        if (status != OK) {
287            return status;
288        }
289
290        secureStops.clear();
291        uint32_t count = reply.readInt32();
292        for (size_t i = 0; i < count; i++) {
293            Vector<uint8_t> secureStop;
294            readVector(reply, secureStop);
295            secureStops.push_back(secureStop);
296        }
297        return reply.readInt32();
298    }
299
300    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
301        Parcel data, reply;
302        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
303
304        writeVector(data, ssid);
305        status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
306        if (status != OK) {
307            return status;
308        }
309
310        readVector(reply, secureStop);
311        return reply.readInt32();
312    }
313
314    virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
315        Parcel data, reply;
316        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
317
318        writeVector(data, ssRelease);
319        status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
320        if (status != OK) {
321            return status;
322        }
323
324        return reply.readInt32();
325    }
326
327    virtual status_t releaseAllSecureStops() {
328        Parcel data, reply;
329        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
330
331        status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
332        if (status != OK) {
333            return status;
334        }
335
336        return reply.readInt32();
337    }
338
339    virtual status_t getPropertyString(String8 const &name, String8 &value) const {
340        Parcel data, reply;
341        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
342
343        data.writeString8(name);
344        status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
345        if (status != OK) {
346            return status;
347        }
348
349        value = reply.readString8();
350        return reply.readInt32();
351    }
352
353    virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
354        Parcel data, reply;
355        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
356
357        data.writeString8(name);
358        status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
359        if (status != OK) {
360            return status;
361        }
362
363        readVector(reply, value);
364        return reply.readInt32();
365    }
366
367    virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
368        Parcel data, reply;
369        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
370
371        data.writeString8(name);
372        data.writeString8(value);
373        status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
374        if (status != OK) {
375            return status;
376        }
377
378        return reply.readInt32();
379    }
380
381    virtual status_t setPropertyByteArray(String8 const &name,
382                                          Vector<uint8_t> const &value) const {
383        Parcel data, reply;
384        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
385
386        data.writeString8(name);
387        writeVector(data, value);
388        status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
389        if (status != OK) {
390            return status;
391        }
392
393        return reply.readInt32();
394    }
395
396
397    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
398                                        String8 const &algorithm) {
399        Parcel data, reply;
400        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
401
402        writeVector(data, sessionId);
403        data.writeString8(algorithm);
404        status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
405        if (status != OK) {
406            return status;
407        }
408        return reply.readInt32();
409    }
410
411    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
412                                     String8 const &algorithm) {
413        Parcel data, reply;
414        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
415
416        writeVector(data, sessionId);
417        data.writeString8(algorithm);
418        status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
419        if (status != OK) {
420            return status;
421        }
422        return reply.readInt32();
423    }
424
425    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
426                             Vector<uint8_t> const &keyId,
427                             Vector<uint8_t> const &input,
428                             Vector<uint8_t> const &iv,
429                             Vector<uint8_t> &output) {
430        Parcel data, reply;
431        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
432
433        writeVector(data, sessionId);
434        writeVector(data, keyId);
435        writeVector(data, input);
436        writeVector(data, iv);
437
438        status_t status = remote()->transact(ENCRYPT, data, &reply);
439        if (status != OK) {
440            return status;
441        }
442        readVector(reply, output);
443
444        return reply.readInt32();
445    }
446
447    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
448                             Vector<uint8_t> const &keyId,
449                             Vector<uint8_t> const &input,
450                             Vector<uint8_t> const &iv,
451                             Vector<uint8_t> &output) {
452        Parcel data, reply;
453        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
454
455        writeVector(data, sessionId);
456        writeVector(data, keyId);
457        writeVector(data, input);
458        writeVector(data, iv);
459
460        status_t status = remote()->transact(DECRYPT, data, &reply);
461        if (status != OK) {
462            return status;
463        }
464        readVector(reply, output);
465
466        return reply.readInt32();
467    }
468
469    virtual status_t sign(Vector<uint8_t> const &sessionId,
470                          Vector<uint8_t> const &keyId,
471                          Vector<uint8_t> const &message,
472                          Vector<uint8_t> &signature) {
473        Parcel data, reply;
474        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
475
476        writeVector(data, sessionId);
477        writeVector(data, keyId);
478        writeVector(data, message);
479
480        status_t status = remote()->transact(SIGN, data, &reply);
481        if (status != OK) {
482            return status;
483        }
484        readVector(reply, signature);
485
486        return reply.readInt32();
487    }
488
489    virtual status_t verify(Vector<uint8_t> const &sessionId,
490                            Vector<uint8_t> const &keyId,
491                            Vector<uint8_t> const &message,
492                            Vector<uint8_t> const &signature,
493                            bool &match) {
494        Parcel data, reply;
495        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
496
497        writeVector(data, sessionId);
498        writeVector(data, keyId);
499        writeVector(data, message);
500        writeVector(data, signature);
501
502        status_t status = remote()->transact(VERIFY, data, &reply);
503        if (status != OK) {
504            return status;
505        }
506        match = (bool)reply.readInt32();
507        return reply.readInt32();
508    }
509
510    virtual status_t signRSA(Vector<uint8_t> const &sessionId,
511                             String8 const &algorithm,
512                             Vector<uint8_t> const &message,
513                             Vector<uint8_t> const &wrappedKey,
514                             Vector<uint8_t> &signature) {
515        Parcel data, reply;
516        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
517
518        writeVector(data, sessionId);
519        data.writeString8(algorithm);
520        writeVector(data, message);
521        writeVector(data, wrappedKey);
522
523        status_t status = remote()->transact(SIGN_RSA, data, &reply);
524        if (status != OK) {
525            return status;
526        }
527        readVector(reply, signature);
528
529        return reply.readInt32();
530    }
531
532    virtual status_t setListener(const sp<IDrmClient>& listener) {
533        Parcel data, reply;
534        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
535        data.writeStrongBinder(IInterface::asBinder(listener));
536        status_t status = remote()->transact(SET_LISTENER, data, &reply);
537        if (status != OK) {
538            return status;
539        }
540        return reply.readInt32();
541    }
542
543private:
544    void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
545        uint32_t size = reply.readInt32();
546        vector.insertAt((size_t)0, size);
547        reply.read(vector.editArray(), size);
548    }
549
550    void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
551        data.writeInt32(vector.size());
552        data.write(vector.array(), vector.size());
553    }
554
555    DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
556};
557
558IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
559
560////////////////////////////////////////////////////////////////////////////////
561
562void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
563    uint32_t size = data.readInt32();
564    vector.insertAt((size_t)0, size);
565    data.read(vector.editArray(), size);
566}
567
568void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
569    reply->writeInt32(vector.size());
570    reply->write(vector.array(), vector.size());
571}
572
573status_t BnDrm::onTransact(
574    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
575    switch (code) {
576        case INIT_CHECK:
577        {
578            CHECK_INTERFACE(IDrm, data, reply);
579            reply->writeInt32(initCheck());
580            return OK;
581        }
582
583        case IS_CRYPTO_SUPPORTED:
584        {
585            CHECK_INTERFACE(IDrm, data, reply);
586            uint8_t uuid[16];
587            data.read(uuid, sizeof(uuid));
588            String8 mimeType = data.readString8();
589            reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
590            return OK;
591        }
592
593        case CREATE_PLUGIN:
594        {
595            CHECK_INTERFACE(IDrm, data, reply);
596            uint8_t uuid[16];
597            data.read(uuid, sizeof(uuid));
598            String8 appPackageName = data.readString8();
599            reply->writeInt32(createPlugin(uuid, appPackageName));
600            return OK;
601        }
602
603        case DESTROY_PLUGIN:
604        {
605            CHECK_INTERFACE(IDrm, data, reply);
606            reply->writeInt32(destroyPlugin());
607            return OK;
608        }
609
610        case OPEN_SESSION:
611        {
612            CHECK_INTERFACE(IDrm, data, reply);
613            Vector<uint8_t> sessionId;
614            status_t result = openSession(sessionId);
615            writeVector(reply, sessionId);
616            reply->writeInt32(result);
617            return OK;
618        }
619
620        case CLOSE_SESSION:
621        {
622            CHECK_INTERFACE(IDrm, data, reply);
623            Vector<uint8_t> sessionId;
624            readVector(data, sessionId);
625            reply->writeInt32(closeSession(sessionId));
626            return OK;
627        }
628
629        case GET_KEY_REQUEST:
630        {
631            CHECK_INTERFACE(IDrm, data, reply);
632            Vector<uint8_t> sessionId, initData;
633
634            readVector(data, sessionId);
635            readVector(data, initData);
636            String8 mimeType = data.readString8();
637            DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
638
639            KeyedVector<String8, String8> optionalParameters;
640            uint32_t count = data.readInt32();
641            for (size_t i = 0; i < count; ++i) {
642                String8 key, value;
643                key = data.readString8();
644                value = data.readString8();
645                optionalParameters.add(key, value);
646            }
647
648            Vector<uint8_t> request;
649            String8 defaultUrl;
650            DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
651
652            status_t result = getKeyRequest(sessionId, initData, mimeType,
653                    keyType, optionalParameters, request, defaultUrl,
654                    &keyRequestType);
655
656            writeVector(reply, request);
657            reply->writeString8(defaultUrl);
658            reply->writeInt32(static_cast<int32_t>(keyRequestType));
659            reply->writeInt32(result);
660            return OK;
661        }
662
663        case PROVIDE_KEY_RESPONSE:
664        {
665            CHECK_INTERFACE(IDrm, data, reply);
666            Vector<uint8_t> sessionId, response, keySetId;
667            readVector(data, sessionId);
668            readVector(data, response);
669            uint32_t result = provideKeyResponse(sessionId, response, keySetId);
670            writeVector(reply, keySetId);
671            reply->writeInt32(result);
672            return OK;
673        }
674
675        case REMOVE_KEYS:
676        {
677            CHECK_INTERFACE(IDrm, data, reply);
678            Vector<uint8_t> keySetId;
679            readVector(data, keySetId);
680            reply->writeInt32(removeKeys(keySetId));
681            return OK;
682        }
683
684        case RESTORE_KEYS:
685        {
686            CHECK_INTERFACE(IDrm, data, reply);
687            Vector<uint8_t> sessionId, keySetId;
688            readVector(data, sessionId);
689            readVector(data, keySetId);
690            reply->writeInt32(restoreKeys(sessionId, keySetId));
691            return OK;
692        }
693
694        case QUERY_KEY_STATUS:
695        {
696            CHECK_INTERFACE(IDrm, data, reply);
697            Vector<uint8_t> sessionId;
698            readVector(data, sessionId);
699            KeyedVector<String8, String8> infoMap;
700            status_t result = queryKeyStatus(sessionId, infoMap);
701            size_t count = infoMap.size();
702            reply->writeInt32(count);
703            for (size_t i = 0; i < count; ++i) {
704                reply->writeString8(infoMap.keyAt(i));
705                reply->writeString8(infoMap.valueAt(i));
706            }
707            reply->writeInt32(result);
708            return OK;
709        }
710
711        case GET_PROVISION_REQUEST:
712        {
713            CHECK_INTERFACE(IDrm, data, reply);
714            String8 certType = data.readString8();
715            String8 certAuthority = data.readString8();
716
717            Vector<uint8_t> request;
718            String8 defaultUrl;
719            status_t result = getProvisionRequest(certType, certAuthority,
720                                                  request, defaultUrl);
721            writeVector(reply, request);
722            reply->writeString8(defaultUrl);
723            reply->writeInt32(result);
724            return OK;
725        }
726
727        case PROVIDE_PROVISION_RESPONSE:
728        {
729            CHECK_INTERFACE(IDrm, data, reply);
730            Vector<uint8_t> response;
731            Vector<uint8_t> certificate;
732            Vector<uint8_t> wrappedKey;
733            readVector(data, response);
734            status_t result = provideProvisionResponse(response, certificate, wrappedKey);
735            writeVector(reply, certificate);
736            writeVector(reply, wrappedKey);
737            reply->writeInt32(result);
738            return OK;
739        }
740
741        case GET_SECURE_STOPS:
742        {
743            CHECK_INTERFACE(IDrm, data, reply);
744            List<Vector<uint8_t> > secureStops;
745            status_t result = getSecureStops(secureStops);
746            size_t count = secureStops.size();
747            reply->writeInt32(count);
748            List<Vector<uint8_t> >::iterator iter = secureStops.begin();
749            while(iter != secureStops.end()) {
750                size_t size = iter->size();
751                reply->writeInt32(size);
752                reply->write(iter->array(), iter->size());
753                iter++;
754            }
755            reply->writeInt32(result);
756            return OK;
757        }
758
759        case GET_SECURE_STOP:
760        {
761            CHECK_INTERFACE(IDrm, data, reply);
762            Vector<uint8_t> ssid, secureStop;
763            readVector(data, ssid);
764            status_t result = getSecureStop(ssid, secureStop);
765            writeVector(reply, secureStop);
766            reply->writeInt32(result);
767            return OK;
768        }
769
770        case RELEASE_SECURE_STOPS:
771        {
772            CHECK_INTERFACE(IDrm, data, reply);
773            Vector<uint8_t> ssRelease;
774            readVector(data, ssRelease);
775            reply->writeInt32(releaseSecureStops(ssRelease));
776            return OK;
777        }
778
779        case RELEASE_ALL_SECURE_STOPS:
780        {
781            CHECK_INTERFACE(IDrm, data, reply);
782            reply->writeInt32(releaseAllSecureStops());
783            return OK;
784        }
785
786        case GET_PROPERTY_STRING:
787        {
788            CHECK_INTERFACE(IDrm, data, reply);
789            String8 name = data.readString8();
790            String8 value;
791            status_t result = getPropertyString(name, value);
792            reply->writeString8(value);
793            reply->writeInt32(result);
794            return OK;
795        }
796
797        case GET_PROPERTY_BYTE_ARRAY:
798        {
799            CHECK_INTERFACE(IDrm, data, reply);
800            String8 name = data.readString8();
801            Vector<uint8_t> value;
802            status_t result = getPropertyByteArray(name, value);
803            writeVector(reply, value);
804            reply->writeInt32(result);
805            return OK;
806        }
807
808        case SET_PROPERTY_STRING:
809        {
810            CHECK_INTERFACE(IDrm, data, reply);
811            String8 name = data.readString8();
812            String8 value = data.readString8();
813            reply->writeInt32(setPropertyString(name, value));
814            return OK;
815        }
816
817        case SET_PROPERTY_BYTE_ARRAY:
818        {
819            CHECK_INTERFACE(IDrm, data, reply);
820            String8 name = data.readString8();
821            Vector<uint8_t> value;
822            readVector(data, value);
823            reply->writeInt32(setPropertyByteArray(name, value));
824            return OK;
825        }
826
827        case SET_CIPHER_ALGORITHM:
828        {
829            CHECK_INTERFACE(IDrm, data, reply);
830            Vector<uint8_t> sessionId;
831            readVector(data, sessionId);
832            String8 algorithm = data.readString8();
833            reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
834            return OK;
835        }
836
837        case SET_MAC_ALGORITHM:
838        {
839            CHECK_INTERFACE(IDrm, data, reply);
840            Vector<uint8_t> sessionId;
841            readVector(data, sessionId);
842            String8 algorithm = data.readString8();
843            reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
844            return OK;
845        }
846
847        case ENCRYPT:
848        {
849            CHECK_INTERFACE(IDrm, data, reply);
850            Vector<uint8_t> sessionId, keyId, input, iv, output;
851            readVector(data, sessionId);
852            readVector(data, keyId);
853            readVector(data, input);
854            readVector(data, iv);
855            uint32_t result = encrypt(sessionId, keyId, input, iv, output);
856            writeVector(reply, output);
857            reply->writeInt32(result);
858            return OK;
859        }
860
861        case DECRYPT:
862        {
863            CHECK_INTERFACE(IDrm, data, reply);
864            Vector<uint8_t> sessionId, keyId, input, iv, output;
865            readVector(data, sessionId);
866            readVector(data, keyId);
867            readVector(data, input);
868            readVector(data, iv);
869            uint32_t result = decrypt(sessionId, keyId, input, iv, output);
870            writeVector(reply, output);
871            reply->writeInt32(result);
872            return OK;
873        }
874
875        case SIGN:
876        {
877            CHECK_INTERFACE(IDrm, data, reply);
878            Vector<uint8_t> sessionId, keyId, message, signature;
879            readVector(data, sessionId);
880            readVector(data, keyId);
881            readVector(data, message);
882            uint32_t result = sign(sessionId, keyId, message, signature);
883            writeVector(reply, signature);
884            reply->writeInt32(result);
885            return OK;
886        }
887
888        case VERIFY:
889        {
890            CHECK_INTERFACE(IDrm, data, reply);
891            Vector<uint8_t> sessionId, keyId, message, signature;
892            readVector(data, sessionId);
893            readVector(data, keyId);
894            readVector(data, message);
895            readVector(data, signature);
896            bool match = false;
897            uint32_t result = verify(sessionId, keyId, message, signature, match);
898            reply->writeInt32(match);
899            reply->writeInt32(result);
900            return OK;
901        }
902
903        case SIGN_RSA:
904        {
905            CHECK_INTERFACE(IDrm, data, reply);
906            Vector<uint8_t> sessionId, message, wrappedKey, signature;
907            readVector(data, sessionId);
908            String8 algorithm = data.readString8();
909            readVector(data, message);
910            readVector(data, wrappedKey);
911            uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
912            writeVector(reply, signature);
913            reply->writeInt32(result);
914            return OK;
915        }
916
917    case SET_LISTENER: {
918        CHECK_INTERFACE(IDrm, data, reply);
919        sp<IDrmClient> listener =
920            interface_cast<IDrmClient>(data.readStrongBinder());
921        reply->writeInt32(setListener(listener));
922        return NO_ERROR;
923    } break;
924
925    default:
926        return BBinder::onTransact(code, data, reply, flags);
927    }
928}
929
930}  // namespace android
931