Home | History | Annotate | Download | only in libmediadrm
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "IDrm"
     19 #include <utils/Log.h>
     20 
     21 #include <binder/Parcel.h>
     22 #include <media/IDrm.h>
     23 #include <media/stagefright/MediaErrors.h>
     24 #include <media/stagefright/foundation/ADebug.h>
     25 #include <media/stagefright/foundation/AString.h>
     26 
     27 namespace android {
     28 
     29 enum {
     30     INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
     31     IS_CRYPTO_SUPPORTED,
     32     CREATE_PLUGIN,
     33     DESTROY_PLUGIN,
     34     OPEN_SESSION,
     35     CLOSE_SESSION,
     36     GET_KEY_REQUEST,
     37     PROVIDE_KEY_RESPONSE,
     38     REMOVE_KEYS,
     39     RESTORE_KEYS,
     40     QUERY_KEY_STATUS,
     41     GET_PROVISION_REQUEST,
     42     PROVIDE_PROVISION_RESPONSE,
     43     GET_SECURE_STOPS,
     44     RELEASE_SECURE_STOPS,
     45     GET_PROPERTY_STRING,
     46     GET_PROPERTY_BYTE_ARRAY,
     47     SET_PROPERTY_STRING,
     48     SET_PROPERTY_BYTE_ARRAY,
     49     SET_CIPHER_ALGORITHM,
     50     SET_MAC_ALGORITHM,
     51     ENCRYPT,
     52     DECRYPT,
     53     SIGN,
     54     SIGN_RSA,
     55     VERIFY,
     56     SET_LISTENER,
     57     GET_SECURE_STOP,
     58     RELEASE_ALL_SECURE_STOPS
     59 };
     60 
     61 struct BpDrm : public BpInterface<IDrm> {
     62     explicit BpDrm(const sp<IBinder> &impl)
     63         : BpInterface<IDrm>(impl) {
     64     }
     65 
     66     virtual status_t initCheck() const {
     67         Parcel data, reply;
     68         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
     69         status_t status = remote()->transact(INIT_CHECK, data, &reply);
     70         if (status != OK) {
     71             return status;
     72         }
     73 
     74         return reply.readInt32();
     75     }
     76 
     77     virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
     78         Parcel data, reply;
     79         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
     80         data.write(uuid, 16);
     81         data.writeString8(mimeType);
     82         status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
     83         if (status != OK) {
     84             ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
     85             return false;
     86         }
     87 
     88         return reply.readInt32() != 0;
     89     }
     90 
     91     virtual status_t createPlugin(const uint8_t uuid[16],
     92                                   const String8& appPackageName) {
     93         Parcel data, reply;
     94         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
     95         data.write(uuid, 16);
     96         data.writeString8(appPackageName);
     97         status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
     98         if (status != OK) {
     99             ALOGE("createPlugin: binder call failed: %d", status);
    100             return status;
    101         }
    102 
    103         return reply.readInt32();
    104     }
    105 
    106     virtual status_t destroyPlugin() {
    107         Parcel data, reply;
    108         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    109         status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
    110         if (status != OK) {
    111             return status;
    112         }
    113 
    114         return reply.readInt32();
    115     }
    116 
    117     virtual status_t openSession(Vector<uint8_t> &sessionId) {
    118         Parcel data, reply;
    119         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    120 
    121         status_t status = remote()->transact(OPEN_SESSION, data, &reply);
    122         if (status != OK) {
    123             return status;
    124         }
    125         readVector(reply, sessionId);
    126 
    127         return reply.readInt32();
    128     }
    129 
    130     virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
    131         Parcel data, reply;
    132         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    133 
    134         writeVector(data, sessionId);
    135         status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
    136         if (status != OK) {
    137             return status;
    138         }
    139 
    140         return reply.readInt32();
    141     }
    142 
    143     virtual status_t
    144         getKeyRequest(Vector<uint8_t> const &sessionId,
    145                       Vector<uint8_t> const &initData,
    146                       String8 const &mimeType, DrmPlugin::KeyType keyType,
    147                       KeyedVector<String8, String8> const &optionalParameters,
    148                       Vector<uint8_t> &request, String8 &defaultUrl,
    149                       DrmPlugin::KeyRequestType *keyRequestType) {
    150         Parcel data, reply;
    151         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    152 
    153         writeVector(data, sessionId);
    154         writeVector(data, initData);
    155         data.writeString8(mimeType);
    156         data.writeInt32((uint32_t)keyType);
    157 
    158         data.writeInt32(optionalParameters.size());
    159         for (size_t i = 0; i < optionalParameters.size(); ++i) {
    160             data.writeString8(optionalParameters.keyAt(i));
    161             data.writeString8(optionalParameters.valueAt(i));
    162         }
    163 
    164         status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
    165         if (status != OK) {
    166             return status;
    167         }
    168 
    169         readVector(reply, request);
    170         defaultUrl = reply.readString8();
    171         *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
    172 
    173         return reply.readInt32();
    174     }
    175 
    176     virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
    177                                         Vector<uint8_t> const &response,
    178                                         Vector<uint8_t> &keySetId) {
    179         Parcel data, reply;
    180         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    181         writeVector(data, sessionId);
    182         writeVector(data, response);
    183 
    184         status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
    185         if (status != OK) {
    186             return status;
    187         }
    188 
    189         readVector(reply, keySetId);
    190 
    191         return reply.readInt32();
    192     }
    193 
    194     virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
    195         Parcel data, reply;
    196         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    197 
    198         writeVector(data, keySetId);
    199         status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
    200         if (status != OK) {
    201             return status;
    202         }
    203 
    204         return reply.readInt32();
    205     }
    206 
    207     virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
    208                                  Vector<uint8_t> const &keySetId) {
    209         Parcel data, reply;
    210         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    211 
    212         writeVector(data, sessionId);
    213         writeVector(data, keySetId);
    214         status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
    215         if (status != OK) {
    216             return status;
    217         }
    218 
    219         return reply.readInt32();
    220     }
    221 
    222     virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
    223                                         KeyedVector<String8, String8> &infoMap) const {
    224         Parcel data, reply;
    225         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    226 
    227         writeVector(data, sessionId);
    228         status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
    229         if (status != OK) {
    230             return status;
    231         }
    232 
    233         infoMap.clear();
    234         size_t count = reply.readInt32();
    235         for (size_t i = 0; i < count; i++) {
    236             String8 key = reply.readString8();
    237             String8 value = reply.readString8();
    238             infoMap.add(key, value);
    239         }
    240         return reply.readInt32();
    241     }
    242 
    243     virtual status_t getProvisionRequest(String8 const &certType,
    244                                          String8 const &certAuthority,
    245                                          Vector<uint8_t> &request,
    246                                          String8 &defaultUrl) {
    247         Parcel data, reply;
    248         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    249 
    250         data.writeString8(certType);
    251         data.writeString8(certAuthority);
    252         status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
    253         if (status != OK) {
    254             return status;
    255         }
    256 
    257         readVector(reply, request);
    258         defaultUrl = reply.readString8();
    259 
    260         return reply.readInt32();
    261     }
    262 
    263     virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
    264                                               Vector<uint8_t> &certificate,
    265                                               Vector<uint8_t> &wrappedKey) {
    266         Parcel data, reply;
    267         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    268 
    269         writeVector(data, response);
    270         status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
    271         if (status != OK) {
    272             return status;
    273         }
    274 
    275         readVector(reply, certificate);
    276         readVector(reply, wrappedKey);
    277 
    278         return reply.readInt32();
    279     }
    280 
    281     virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
    282         Parcel data, reply;
    283         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    284 
    285         status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
    286         if (status != OK) {
    287             return status;
    288         }
    289 
    290         secureStops.clear();
    291         uint32_t count = reply.readInt32();
    292         for (size_t i = 0; i < count; i++) {
    293             Vector<uint8_t> secureStop;
    294             readVector(reply, secureStop);
    295             secureStops.push_back(secureStop);
    296         }
    297         return reply.readInt32();
    298     }
    299 
    300     virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
    301         Parcel data, reply;
    302         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    303 
    304         writeVector(data, ssid);
    305         status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
    306         if (status != OK) {
    307             return status;
    308         }
    309 
    310         readVector(reply, secureStop);
    311         return reply.readInt32();
    312     }
    313 
    314     virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
    315         Parcel data, reply;
    316         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    317 
    318         writeVector(data, ssRelease);
    319         status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
    320         if (status != OK) {
    321             return status;
    322         }
    323 
    324         return reply.readInt32();
    325     }
    326 
    327     virtual status_t releaseAllSecureStops() {
    328         Parcel data, reply;
    329         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    330 
    331         status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
    332         if (status != OK) {
    333             return status;
    334         }
    335 
    336         return reply.readInt32();
    337     }
    338 
    339     virtual status_t getPropertyString(String8 const &name, String8 &value) const {
    340         Parcel data, reply;
    341         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    342 
    343         data.writeString8(name);
    344         status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
    345         if (status != OK) {
    346             return status;
    347         }
    348 
    349         value = reply.readString8();
    350         return reply.readInt32();
    351     }
    352 
    353     virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
    354         Parcel data, reply;
    355         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    356 
    357         data.writeString8(name);
    358         status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
    359         if (status != OK) {
    360             return status;
    361         }
    362 
    363         readVector(reply, value);
    364         return reply.readInt32();
    365     }
    366 
    367     virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
    368         Parcel data, reply;
    369         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    370 
    371         data.writeString8(name);
    372         data.writeString8(value);
    373         status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
    374         if (status != OK) {
    375             return status;
    376         }
    377 
    378         return reply.readInt32();
    379     }
    380 
    381     virtual status_t setPropertyByteArray(String8 const &name,
    382                                           Vector<uint8_t> const &value) const {
    383         Parcel data, reply;
    384         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    385 
    386         data.writeString8(name);
    387         writeVector(data, value);
    388         status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
    389         if (status != OK) {
    390             return status;
    391         }
    392 
    393         return reply.readInt32();
    394     }
    395 
    396 
    397     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
    398                                         String8 const &algorithm) {
    399         Parcel data, reply;
    400         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    401 
    402         writeVector(data, sessionId);
    403         data.writeString8(algorithm);
    404         status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
    405         if (status != OK) {
    406             return status;
    407         }
    408         return reply.readInt32();
    409     }
    410 
    411     virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
    412                                      String8 const &algorithm) {
    413         Parcel data, reply;
    414         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    415 
    416         writeVector(data, sessionId);
    417         data.writeString8(algorithm);
    418         status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
    419         if (status != OK) {
    420             return status;
    421         }
    422         return reply.readInt32();
    423     }
    424 
    425     virtual status_t encrypt(Vector<uint8_t> const &sessionId,
    426                              Vector<uint8_t> const &keyId,
    427                              Vector<uint8_t> const &input,
    428                              Vector<uint8_t> const &iv,
    429                              Vector<uint8_t> &output) {
    430         Parcel data, reply;
    431         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    432 
    433         writeVector(data, sessionId);
    434         writeVector(data, keyId);
    435         writeVector(data, input);
    436         writeVector(data, iv);
    437 
    438         status_t status = remote()->transact(ENCRYPT, data, &reply);
    439         if (status != OK) {
    440             return status;
    441         }
    442         readVector(reply, output);
    443 
    444         return reply.readInt32();
    445     }
    446 
    447     virtual status_t decrypt(Vector<uint8_t> const &sessionId,
    448                              Vector<uint8_t> const &keyId,
    449                              Vector<uint8_t> const &input,
    450                              Vector<uint8_t> const &iv,
    451                              Vector<uint8_t> &output) {
    452         Parcel data, reply;
    453         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    454 
    455         writeVector(data, sessionId);
    456         writeVector(data, keyId);
    457         writeVector(data, input);
    458         writeVector(data, iv);
    459 
    460         status_t status = remote()->transact(DECRYPT, data, &reply);
    461         if (status != OK) {
    462             return status;
    463         }
    464         readVector(reply, output);
    465 
    466         return reply.readInt32();
    467     }
    468 
    469     virtual status_t sign(Vector<uint8_t> const &sessionId,
    470                           Vector<uint8_t> const &keyId,
    471                           Vector<uint8_t> const &message,
    472                           Vector<uint8_t> &signature) {
    473         Parcel data, reply;
    474         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    475 
    476         writeVector(data, sessionId);
    477         writeVector(data, keyId);
    478         writeVector(data, message);
    479 
    480         status_t status = remote()->transact(SIGN, data, &reply);
    481         if (status != OK) {
    482             return status;
    483         }
    484         readVector(reply, signature);
    485 
    486         return reply.readInt32();
    487     }
    488 
    489     virtual status_t verify(Vector<uint8_t> const &sessionId,
    490                             Vector<uint8_t> const &keyId,
    491                             Vector<uint8_t> const &message,
    492                             Vector<uint8_t> const &signature,
    493                             bool &match) {
    494         Parcel data, reply;
    495         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    496 
    497         writeVector(data, sessionId);
    498         writeVector(data, keyId);
    499         writeVector(data, message);
    500         writeVector(data, signature);
    501 
    502         status_t status = remote()->transact(VERIFY, data, &reply);
    503         if (status != OK) {
    504             return status;
    505         }
    506         match = (bool)reply.readInt32();
    507         return reply.readInt32();
    508     }
    509 
    510     virtual status_t signRSA(Vector<uint8_t> const &sessionId,
    511                              String8 const &algorithm,
    512                              Vector<uint8_t> const &message,
    513                              Vector<uint8_t> const &wrappedKey,
    514                              Vector<uint8_t> &signature) {
    515         Parcel data, reply;
    516         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    517 
    518         writeVector(data, sessionId);
    519         data.writeString8(algorithm);
    520         writeVector(data, message);
    521         writeVector(data, wrappedKey);
    522 
    523         status_t status = remote()->transact(SIGN_RSA, data, &reply);
    524         if (status != OK) {
    525             return status;
    526         }
    527         readVector(reply, signature);
    528 
    529         return reply.readInt32();
    530     }
    531 
    532     virtual status_t setListener(const sp<IDrmClient>& listener) {
    533         Parcel data, reply;
    534         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
    535         data.writeStrongBinder(IInterface::asBinder(listener));
    536         status_t status = remote()->transact(SET_LISTENER, data, &reply);
    537         if (status != OK) {
    538             return status;
    539         }
    540         return reply.readInt32();
    541     }
    542 
    543 private:
    544     void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
    545         uint32_t size = reply.readInt32();
    546         vector.insertAt((size_t)0, size);
    547         reply.read(vector.editArray(), size);
    548     }
    549 
    550     void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
    551         data.writeInt32(vector.size());
    552         data.write(vector.array(), vector.size());
    553     }
    554 
    555     DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
    556 };
    557 
    558 IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
    559 
    560 ////////////////////////////////////////////////////////////////////////////////
    561 
    562 void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
    563     uint32_t size = data.readInt32();
    564     if (vector.insertAt((size_t)0, size) < 0) {
    565         vector.clear();
    566     }
    567     if (data.read(vector.editArray(), size) != NO_ERROR) {
    568         vector.clear();
    569         android_errorWriteWithInfoLog(0x534e4554, "62872384", -1, NULL, 0);
    570     }
    571 }
    572 
    573 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
    574     reply->writeInt32(vector.size());
    575     reply->write(vector.array(), vector.size());
    576 }
    577 
    578 status_t BnDrm::onTransact(
    579     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    580     switch (code) {
    581         case INIT_CHECK:
    582         {
    583             CHECK_INTERFACE(IDrm, data, reply);
    584             reply->writeInt32(initCheck());
    585             return OK;
    586         }
    587 
    588         case IS_CRYPTO_SUPPORTED:
    589         {
    590             CHECK_INTERFACE(IDrm, data, reply);
    591             uint8_t uuid[16];
    592             data.read(uuid, sizeof(uuid));
    593             String8 mimeType = data.readString8();
    594             reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
    595             return OK;
    596         }
    597 
    598         case CREATE_PLUGIN:
    599         {
    600             CHECK_INTERFACE(IDrm, data, reply);
    601             uint8_t uuid[16];
    602             data.read(uuid, sizeof(uuid));
    603             String8 appPackageName = data.readString8();
    604             reply->writeInt32(createPlugin(uuid, appPackageName));
    605             return OK;
    606         }
    607 
    608         case DESTROY_PLUGIN:
    609         {
    610             CHECK_INTERFACE(IDrm, data, reply);
    611             reply->writeInt32(destroyPlugin());
    612             return OK;
    613         }
    614 
    615         case OPEN_SESSION:
    616         {
    617             CHECK_INTERFACE(IDrm, data, reply);
    618             Vector<uint8_t> sessionId;
    619             status_t result = openSession(sessionId);
    620             writeVector(reply, sessionId);
    621             reply->writeInt32(result);
    622             return OK;
    623         }
    624 
    625         case CLOSE_SESSION:
    626         {
    627             CHECK_INTERFACE(IDrm, data, reply);
    628             Vector<uint8_t> sessionId;
    629             readVector(data, sessionId);
    630             reply->writeInt32(closeSession(sessionId));
    631             return OK;
    632         }
    633 
    634         case GET_KEY_REQUEST:
    635         {
    636             CHECK_INTERFACE(IDrm, data, reply);
    637             Vector<uint8_t> sessionId, initData;
    638 
    639             readVector(data, sessionId);
    640             readVector(data, initData);
    641             String8 mimeType = data.readString8();
    642             DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
    643 
    644             KeyedVector<String8, String8> optionalParameters;
    645             uint32_t count = data.readInt32();
    646             for (size_t i = 0; i < count; ++i) {
    647                 String8 key, value;
    648                 key = data.readString8();
    649                 value = data.readString8();
    650                 optionalParameters.add(key, value);
    651             }
    652 
    653             Vector<uint8_t> request;
    654             String8 defaultUrl;
    655             DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
    656 
    657             status_t result = getKeyRequest(sessionId, initData, mimeType,
    658                     keyType, optionalParameters, request, defaultUrl,
    659                     &keyRequestType);
    660 
    661             writeVector(reply, request);
    662             reply->writeString8(defaultUrl);
    663             reply->writeInt32(static_cast<int32_t>(keyRequestType));
    664             reply->writeInt32(result);
    665             return OK;
    666         }
    667 
    668         case PROVIDE_KEY_RESPONSE:
    669         {
    670             CHECK_INTERFACE(IDrm, data, reply);
    671             Vector<uint8_t> sessionId, response, keySetId;
    672             readVector(data, sessionId);
    673             readVector(data, response);
    674             uint32_t result = provideKeyResponse(sessionId, response, keySetId);
    675             writeVector(reply, keySetId);
    676             reply->writeInt32(result);
    677             return OK;
    678         }
    679 
    680         case REMOVE_KEYS:
    681         {
    682             CHECK_INTERFACE(IDrm, data, reply);
    683             Vector<uint8_t> keySetId;
    684             readVector(data, keySetId);
    685             reply->writeInt32(removeKeys(keySetId));
    686             return OK;
    687         }
    688 
    689         case RESTORE_KEYS:
    690         {
    691             CHECK_INTERFACE(IDrm, data, reply);
    692             Vector<uint8_t> sessionId, keySetId;
    693             readVector(data, sessionId);
    694             readVector(data, keySetId);
    695             reply->writeInt32(restoreKeys(sessionId, keySetId));
    696             return OK;
    697         }
    698 
    699         case QUERY_KEY_STATUS:
    700         {
    701             CHECK_INTERFACE(IDrm, data, reply);
    702             Vector<uint8_t> sessionId;
    703             readVector(data, sessionId);
    704             KeyedVector<String8, String8> infoMap;
    705             status_t result = queryKeyStatus(sessionId, infoMap);
    706             size_t count = infoMap.size();
    707             reply->writeInt32(count);
    708             for (size_t i = 0; i < count; ++i) {
    709                 reply->writeString8(infoMap.keyAt(i));
    710                 reply->writeString8(infoMap.valueAt(i));
    711             }
    712             reply->writeInt32(result);
    713             return OK;
    714         }
    715 
    716         case GET_PROVISION_REQUEST:
    717         {
    718             CHECK_INTERFACE(IDrm, data, reply);
    719             String8 certType = data.readString8();
    720             String8 certAuthority = data.readString8();
    721 
    722             Vector<uint8_t> request;
    723             String8 defaultUrl;
    724             status_t result = getProvisionRequest(certType, certAuthority,
    725                                                   request, defaultUrl);
    726             writeVector(reply, request);
    727             reply->writeString8(defaultUrl);
    728             reply->writeInt32(result);
    729             return OK;
    730         }
    731 
    732         case PROVIDE_PROVISION_RESPONSE:
    733         {
    734             CHECK_INTERFACE(IDrm, data, reply);
    735             Vector<uint8_t> response;
    736             Vector<uint8_t> certificate;
    737             Vector<uint8_t> wrappedKey;
    738             readVector(data, response);
    739             status_t result = provideProvisionResponse(response, certificate, wrappedKey);
    740             writeVector(reply, certificate);
    741             writeVector(reply, wrappedKey);
    742             reply->writeInt32(result);
    743             return OK;
    744         }
    745 
    746         case GET_SECURE_STOPS:
    747         {
    748             CHECK_INTERFACE(IDrm, data, reply);
    749             List<Vector<uint8_t> > secureStops;
    750             status_t result = getSecureStops(secureStops);
    751             size_t count = secureStops.size();
    752             reply->writeInt32(count);
    753             List<Vector<uint8_t> >::iterator iter = secureStops.begin();
    754             while(iter != secureStops.end()) {
    755                 size_t size = iter->size();
    756                 reply->writeInt32(size);
    757                 reply->write(iter->array(), iter->size());
    758                 iter++;
    759             }
    760             reply->writeInt32(result);
    761             return OK;
    762         }
    763 
    764         case GET_SECURE_STOP:
    765         {
    766             CHECK_INTERFACE(IDrm, data, reply);
    767             Vector<uint8_t> ssid, secureStop;
    768             readVector(data, ssid);
    769             status_t result = getSecureStop(ssid, secureStop);
    770             writeVector(reply, secureStop);
    771             reply->writeInt32(result);
    772             return OK;
    773         }
    774 
    775         case RELEASE_SECURE_STOPS:
    776         {
    777             CHECK_INTERFACE(IDrm, data, reply);
    778             Vector<uint8_t> ssRelease;
    779             readVector(data, ssRelease);
    780             reply->writeInt32(releaseSecureStops(ssRelease));
    781             return OK;
    782         }
    783 
    784         case RELEASE_ALL_SECURE_STOPS:
    785         {
    786             CHECK_INTERFACE(IDrm, data, reply);
    787             reply->writeInt32(releaseAllSecureStops());
    788             return OK;
    789         }
    790 
    791         case GET_PROPERTY_STRING:
    792         {
    793             CHECK_INTERFACE(IDrm, data, reply);
    794             String8 name = data.readString8();
    795             String8 value;
    796             status_t result = getPropertyString(name, value);
    797             reply->writeString8(value);
    798             reply->writeInt32(result);
    799             return OK;
    800         }
    801 
    802         case GET_PROPERTY_BYTE_ARRAY:
    803         {
    804             CHECK_INTERFACE(IDrm, data, reply);
    805             String8 name = data.readString8();
    806             Vector<uint8_t> value;
    807             status_t result = getPropertyByteArray(name, value);
    808             writeVector(reply, value);
    809             reply->writeInt32(result);
    810             return OK;
    811         }
    812 
    813         case SET_PROPERTY_STRING:
    814         {
    815             CHECK_INTERFACE(IDrm, data, reply);
    816             String8 name = data.readString8();
    817             String8 value = data.readString8();
    818             reply->writeInt32(setPropertyString(name, value));
    819             return OK;
    820         }
    821 
    822         case SET_PROPERTY_BYTE_ARRAY:
    823         {
    824             CHECK_INTERFACE(IDrm, data, reply);
    825             String8 name = data.readString8();
    826             Vector<uint8_t> value;
    827             readVector(data, value);
    828             reply->writeInt32(setPropertyByteArray(name, value));
    829             return OK;
    830         }
    831 
    832         case SET_CIPHER_ALGORITHM:
    833         {
    834             CHECK_INTERFACE(IDrm, data, reply);
    835             Vector<uint8_t> sessionId;
    836             readVector(data, sessionId);
    837             String8 algorithm = data.readString8();
    838             reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
    839             return OK;
    840         }
    841 
    842         case SET_MAC_ALGORITHM:
    843         {
    844             CHECK_INTERFACE(IDrm, data, reply);
    845             Vector<uint8_t> sessionId;
    846             readVector(data, sessionId);
    847             String8 algorithm = data.readString8();
    848             reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
    849             return OK;
    850         }
    851 
    852         case ENCRYPT:
    853         {
    854             CHECK_INTERFACE(IDrm, data, reply);
    855             Vector<uint8_t> sessionId, keyId, input, iv, output;
    856             readVector(data, sessionId);
    857             readVector(data, keyId);
    858             readVector(data, input);
    859             readVector(data, iv);
    860             uint32_t result = encrypt(sessionId, keyId, input, iv, output);
    861             writeVector(reply, output);
    862             reply->writeInt32(result);
    863             return OK;
    864         }
    865 
    866         case DECRYPT:
    867         {
    868             CHECK_INTERFACE(IDrm, data, reply);
    869             Vector<uint8_t> sessionId, keyId, input, iv, output;
    870             readVector(data, sessionId);
    871             readVector(data, keyId);
    872             readVector(data, input);
    873             readVector(data, iv);
    874             uint32_t result = decrypt(sessionId, keyId, input, iv, output);
    875             writeVector(reply, output);
    876             reply->writeInt32(result);
    877             return OK;
    878         }
    879 
    880         case SIGN:
    881         {
    882             CHECK_INTERFACE(IDrm, data, reply);
    883             Vector<uint8_t> sessionId, keyId, message, signature;
    884             readVector(data, sessionId);
    885             readVector(data, keyId);
    886             readVector(data, message);
    887             uint32_t result = sign(sessionId, keyId, message, signature);
    888             writeVector(reply, signature);
    889             reply->writeInt32(result);
    890             return OK;
    891         }
    892 
    893         case VERIFY:
    894         {
    895             CHECK_INTERFACE(IDrm, data, reply);
    896             Vector<uint8_t> sessionId, keyId, message, signature;
    897             readVector(data, sessionId);
    898             readVector(data, keyId);
    899             readVector(data, message);
    900             readVector(data, signature);
    901             bool match = false;
    902             uint32_t result = verify(sessionId, keyId, message, signature, match);
    903             reply->writeInt32(match);
    904             reply->writeInt32(result);
    905             return OK;
    906         }
    907 
    908         case SIGN_RSA:
    909         {
    910             CHECK_INTERFACE(IDrm, data, reply);
    911             Vector<uint8_t> sessionId, message, wrappedKey, signature;
    912             readVector(data, sessionId);
    913             String8 algorithm = data.readString8();
    914             readVector(data, message);
    915             readVector(data, wrappedKey);
    916             uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
    917             writeVector(reply, signature);
    918             reply->writeInt32(result);
    919             return OK;
    920         }
    921 
    922     case SET_LISTENER: {
    923         CHECK_INTERFACE(IDrm, data, reply);
    924         sp<IDrmClient> listener =
    925             interface_cast<IDrmClient>(data.readStrongBinder());
    926         reply->writeInt32(setListener(listener));
    927         return NO_ERROR;
    928     } break;
    929 
    930     default:
    931         return BBinder::onTransact(code, data, reply, flags);
    932     }
    933 }
    934 
    935 }  // namespace android
    936