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