• 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     vector.insertAt((size_t)0, size);
565     data.read(vector.editArray(), size);
566 }
567 
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const568 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
569     reply->writeInt32(vector.size());
570     reply->write(vector.array(), vector.size());
571 }
572 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)573 status_t BnDrm::onTransact(
574     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
575     switch (code) {
576         case INIT_CHECK:
577         {
578             CHECK_INTERFACE(IDrm, data, reply);
579             reply->writeInt32(initCheck());
580             return OK;
581         }
582 
583         case IS_CRYPTO_SUPPORTED:
584         {
585             CHECK_INTERFACE(IDrm, data, reply);
586             uint8_t uuid[16];
587             data.read(uuid, sizeof(uuid));
588             String8 mimeType = data.readString8();
589             reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
590             return OK;
591         }
592 
593         case CREATE_PLUGIN:
594         {
595             CHECK_INTERFACE(IDrm, data, reply);
596             uint8_t uuid[16];
597             data.read(uuid, sizeof(uuid));
598             String8 appPackageName = data.readString8();
599             reply->writeInt32(createPlugin(uuid, appPackageName));
600             return OK;
601         }
602 
603         case DESTROY_PLUGIN:
604         {
605             CHECK_INTERFACE(IDrm, data, reply);
606             reply->writeInt32(destroyPlugin());
607             return OK;
608         }
609 
610         case OPEN_SESSION:
611         {
612             CHECK_INTERFACE(IDrm, data, reply);
613             Vector<uint8_t> sessionId;
614             status_t result = openSession(sessionId);
615             writeVector(reply, sessionId);
616             reply->writeInt32(result);
617             return OK;
618         }
619 
620         case CLOSE_SESSION:
621         {
622             CHECK_INTERFACE(IDrm, data, reply);
623             Vector<uint8_t> sessionId;
624             readVector(data, sessionId);
625             reply->writeInt32(closeSession(sessionId));
626             return OK;
627         }
628 
629         case GET_KEY_REQUEST:
630         {
631             CHECK_INTERFACE(IDrm, data, reply);
632             Vector<uint8_t> sessionId, initData;
633 
634             readVector(data, sessionId);
635             readVector(data, initData);
636             String8 mimeType = data.readString8();
637             DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
638 
639             KeyedVector<String8, String8> optionalParameters;
640             uint32_t count = data.readInt32();
641             for (size_t i = 0; i < count; ++i) {
642                 String8 key, value;
643                 key = data.readString8();
644                 value = data.readString8();
645                 optionalParameters.add(key, value);
646             }
647 
648             Vector<uint8_t> request;
649             String8 defaultUrl;
650             DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
651 
652             status_t result = getKeyRequest(sessionId, initData, mimeType,
653                     keyType, optionalParameters, request, defaultUrl,
654                     &keyRequestType);
655 
656             writeVector(reply, request);
657             reply->writeString8(defaultUrl);
658             reply->writeInt32(static_cast<int32_t>(keyRequestType));
659             reply->writeInt32(result);
660             return OK;
661         }
662 
663         case PROVIDE_KEY_RESPONSE:
664         {
665             CHECK_INTERFACE(IDrm, data, reply);
666             Vector<uint8_t> sessionId, response, keySetId;
667             readVector(data, sessionId);
668             readVector(data, response);
669             uint32_t result = provideKeyResponse(sessionId, response, keySetId);
670             writeVector(reply, keySetId);
671             reply->writeInt32(result);
672             return OK;
673         }
674 
675         case REMOVE_KEYS:
676         {
677             CHECK_INTERFACE(IDrm, data, reply);
678             Vector<uint8_t> keySetId;
679             readVector(data, keySetId);
680             reply->writeInt32(removeKeys(keySetId));
681             return OK;
682         }
683 
684         case RESTORE_KEYS:
685         {
686             CHECK_INTERFACE(IDrm, data, reply);
687             Vector<uint8_t> sessionId, keySetId;
688             readVector(data, sessionId);
689             readVector(data, keySetId);
690             reply->writeInt32(restoreKeys(sessionId, keySetId));
691             return OK;
692         }
693 
694         case QUERY_KEY_STATUS:
695         {
696             CHECK_INTERFACE(IDrm, data, reply);
697             Vector<uint8_t> sessionId;
698             readVector(data, sessionId);
699             KeyedVector<String8, String8> infoMap;
700             status_t result = queryKeyStatus(sessionId, infoMap);
701             size_t count = infoMap.size();
702             reply->writeInt32(count);
703             for (size_t i = 0; i < count; ++i) {
704                 reply->writeString8(infoMap.keyAt(i));
705                 reply->writeString8(infoMap.valueAt(i));
706             }
707             reply->writeInt32(result);
708             return OK;
709         }
710 
711         case GET_PROVISION_REQUEST:
712         {
713             CHECK_INTERFACE(IDrm, data, reply);
714             String8 certType = data.readString8();
715             String8 certAuthority = data.readString8();
716 
717             Vector<uint8_t> request;
718             String8 defaultUrl;
719             status_t result = getProvisionRequest(certType, certAuthority,
720                                                   request, defaultUrl);
721             writeVector(reply, request);
722             reply->writeString8(defaultUrl);
723             reply->writeInt32(result);
724             return OK;
725         }
726 
727         case PROVIDE_PROVISION_RESPONSE:
728         {
729             CHECK_INTERFACE(IDrm, data, reply);
730             Vector<uint8_t> response;
731             Vector<uint8_t> certificate;
732             Vector<uint8_t> wrappedKey;
733             readVector(data, response);
734             status_t result = provideProvisionResponse(response, certificate, wrappedKey);
735             writeVector(reply, certificate);
736             writeVector(reply, wrappedKey);
737             reply->writeInt32(result);
738             return OK;
739         }
740 
741         case GET_SECURE_STOPS:
742         {
743             CHECK_INTERFACE(IDrm, data, reply);
744             List<Vector<uint8_t> > secureStops;
745             status_t result = getSecureStops(secureStops);
746             size_t count = secureStops.size();
747             reply->writeInt32(count);
748             List<Vector<uint8_t> >::iterator iter = secureStops.begin();
749             while(iter != secureStops.end()) {
750                 size_t size = iter->size();
751                 reply->writeInt32(size);
752                 reply->write(iter->array(), iter->size());
753                 iter++;
754             }
755             reply->writeInt32(result);
756             return OK;
757         }
758 
759         case GET_SECURE_STOP:
760         {
761             CHECK_INTERFACE(IDrm, data, reply);
762             Vector<uint8_t> ssid, secureStop;
763             readVector(data, ssid);
764             status_t result = getSecureStop(ssid, secureStop);
765             writeVector(reply, secureStop);
766             reply->writeInt32(result);
767             return OK;
768         }
769 
770         case RELEASE_SECURE_STOPS:
771         {
772             CHECK_INTERFACE(IDrm, data, reply);
773             Vector<uint8_t> ssRelease;
774             readVector(data, ssRelease);
775             reply->writeInt32(releaseSecureStops(ssRelease));
776             return OK;
777         }
778 
779         case RELEASE_ALL_SECURE_STOPS:
780         {
781             CHECK_INTERFACE(IDrm, data, reply);
782             reply->writeInt32(releaseAllSecureStops());
783             return OK;
784         }
785 
786         case GET_PROPERTY_STRING:
787         {
788             CHECK_INTERFACE(IDrm, data, reply);
789             String8 name = data.readString8();
790             String8 value;
791             status_t result = getPropertyString(name, value);
792             reply->writeString8(value);
793             reply->writeInt32(result);
794             return OK;
795         }
796 
797         case GET_PROPERTY_BYTE_ARRAY:
798         {
799             CHECK_INTERFACE(IDrm, data, reply);
800             String8 name = data.readString8();
801             Vector<uint8_t> value;
802             status_t result = getPropertyByteArray(name, value);
803             writeVector(reply, value);
804             reply->writeInt32(result);
805             return OK;
806         }
807 
808         case SET_PROPERTY_STRING:
809         {
810             CHECK_INTERFACE(IDrm, data, reply);
811             String8 name = data.readString8();
812             String8 value = data.readString8();
813             reply->writeInt32(setPropertyString(name, value));
814             return OK;
815         }
816 
817         case SET_PROPERTY_BYTE_ARRAY:
818         {
819             CHECK_INTERFACE(IDrm, data, reply);
820             String8 name = data.readString8();
821             Vector<uint8_t> value;
822             readVector(data, value);
823             reply->writeInt32(setPropertyByteArray(name, value));
824             return OK;
825         }
826 
827         case SET_CIPHER_ALGORITHM:
828         {
829             CHECK_INTERFACE(IDrm, data, reply);
830             Vector<uint8_t> sessionId;
831             readVector(data, sessionId);
832             String8 algorithm = data.readString8();
833             reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
834             return OK;
835         }
836 
837         case SET_MAC_ALGORITHM:
838         {
839             CHECK_INTERFACE(IDrm, data, reply);
840             Vector<uint8_t> sessionId;
841             readVector(data, sessionId);
842             String8 algorithm = data.readString8();
843             reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
844             return OK;
845         }
846 
847         case ENCRYPT:
848         {
849             CHECK_INTERFACE(IDrm, data, reply);
850             Vector<uint8_t> sessionId, keyId, input, iv, output;
851             readVector(data, sessionId);
852             readVector(data, keyId);
853             readVector(data, input);
854             readVector(data, iv);
855             uint32_t result = encrypt(sessionId, keyId, input, iv, output);
856             writeVector(reply, output);
857             reply->writeInt32(result);
858             return OK;
859         }
860 
861         case DECRYPT:
862         {
863             CHECK_INTERFACE(IDrm, data, reply);
864             Vector<uint8_t> sessionId, keyId, input, iv, output;
865             readVector(data, sessionId);
866             readVector(data, keyId);
867             readVector(data, input);
868             readVector(data, iv);
869             uint32_t result = decrypt(sessionId, keyId, input, iv, output);
870             writeVector(reply, output);
871             reply->writeInt32(result);
872             return OK;
873         }
874 
875         case SIGN:
876         {
877             CHECK_INTERFACE(IDrm, data, reply);
878             Vector<uint8_t> sessionId, keyId, message, signature;
879             readVector(data, sessionId);
880             readVector(data, keyId);
881             readVector(data, message);
882             uint32_t result = sign(sessionId, keyId, message, signature);
883             writeVector(reply, signature);
884             reply->writeInt32(result);
885             return OK;
886         }
887 
888         case VERIFY:
889         {
890             CHECK_INTERFACE(IDrm, data, reply);
891             Vector<uint8_t> sessionId, keyId, message, signature;
892             readVector(data, sessionId);
893             readVector(data, keyId);
894             readVector(data, message);
895             readVector(data, signature);
896             bool match = false;
897             uint32_t result = verify(sessionId, keyId, message, signature, match);
898             reply->writeInt32(match);
899             reply->writeInt32(result);
900             return OK;
901         }
902 
903         case SIGN_RSA:
904         {
905             CHECK_INTERFACE(IDrm, data, reply);
906             Vector<uint8_t> sessionId, message, wrappedKey, signature;
907             readVector(data, sessionId);
908             String8 algorithm = data.readString8();
909             readVector(data, message);
910             readVector(data, wrappedKey);
911             uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
912             writeVector(reply, signature);
913             reply->writeInt32(result);
914             return OK;
915         }
916 
917     case SET_LISTENER: {
918         CHECK_INTERFACE(IDrm, data, reply);
919         sp<IDrmClient> listener =
920             interface_cast<IDrmClient>(data.readStrongBinder());
921         reply->writeInt32(setListener(listener));
922         return NO_ERROR;
923     } break;
924 
925     default:
926         return BBinder::onTransact(code, data, reply, flags);
927     }
928 }
929 
930 }  // namespace android
931