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