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