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     SIGN_RSA,
     55     VERIFY,
     56     SET_LISTENER,
     57     UNPROVISION_DEVICE
     58 };
     59 
     60 struct BpDrm : public BpInterface<IDrm> {
     61     BpDrm(const sp<IBinder> &impl)
     62         : BpInterface<IDrm>(impl) {
     63     }
     64 
     65     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 
     73     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 
     83     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 
     93     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 
    101     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 
    111     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
    122         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 
    148     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 
    161     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 
    171     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 
    183     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 
    201     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 
    218     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 
    233     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 
    242     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 
    258     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 
    268     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 
    279     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 
    290     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 
    301     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 
    314     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 
    325     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 
    336     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 
    355     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 
    374     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 
    391     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 
    409     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 
    428     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:
    437     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 
    443     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 
    455 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 
    461 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 
    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