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