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