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 
27 namespace android {
28 
29 enum {
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 
61 struct BpDrm : public BpInterface<IDrm> {
BpDrmandroid::BpDrm62     BpDrm(const sp<IBinder> &impl)
63         : BpInterface<IDrm>(impl) {
64     }
65 
initCheckandroid::BpDrm66     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 
isCryptoSchemeSupportedandroid::BpDrm77     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 
createPluginandroid::BpDrm91     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 
destroyPluginandroid::BpDrm104     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 
openSessionandroid::BpDrm115     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 
closeSessionandroid::BpDrm128     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
getKeyRequestandroid::BpDrm142         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 
provideKeyResponseandroid::BpDrm174     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 
removeKeysandroid::BpDrm192     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 
restoreKeysandroid::BpDrm205     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 
queryKeyStatusandroid::BpDrm220     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 
getProvisionRequestandroid::BpDrm241     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 
provideProvisionResponseandroid::BpDrm261     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 
getSecureStopsandroid::BpDrm279     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 
getSecureStopandroid::BpDrm298     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 
releaseSecureStopsandroid::BpDrm312     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 
releaseAllSecureStopsandroid::BpDrm325     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 
getPropertyStringandroid::BpDrm337     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 
getPropertyByteArrayandroid::BpDrm351     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 
setPropertyStringandroid::BpDrm365     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 
setPropertyByteArrayandroid::BpDrm379     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 
setCipherAlgorithmandroid::BpDrm395     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 
setMacAlgorithmandroid::BpDrm409     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 
encryptandroid::BpDrm423     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 
decryptandroid::BpDrm445     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 
signandroid::BpDrm467     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 
verifyandroid::BpDrm487     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 
signRSAandroid::BpDrm508     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 
setListenerandroid::BpDrm530     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 
541 private:
readVectorandroid::BpDrm542     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 
writeVectorandroid::BpDrm548     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 
556 IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 
readVector(const Parcel & data,Vector<uint8_t> & vector) const560 void 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 
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const566 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
567     reply->writeInt32(vector.size());
568     reply->write(vector.array(), vector.size());
569 }
570 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)571 status_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