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