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