Home | History | Annotate | Download | only in mock
      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 "MockDrmCryptoPlugin"
     19 #include <utils/Log.h>
     20 
     21 
     22 #include "drm/DrmAPI.h"
     23 #include "MockDrmCryptoPlugin.h"
     24 #include "media/stagefright/MediaErrors.h"
     25 
     26 using namespace android;
     27 
     28 // Shared library entry point
     29 DrmFactory *createDrmFactory()
     30 {
     31     return new MockDrmFactory();
     32 }
     33 
     34 // Shared library entry point
     35 CryptoFactory *createCryptoFactory()
     36 {
     37     return new MockCryptoFactory();
     38 }
     39 
     40 const uint8_t mock_uuid[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
     41                                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
     42 
     43 namespace android {
     44 
     45     // MockDrmFactory
     46     bool MockDrmFactory::isCryptoSchemeSupported(const uint8_t uuid[16])
     47     {
     48         return (!memcmp(uuid, mock_uuid, sizeof(uuid)));
     49     }
     50 
     51     status_t MockDrmFactory::createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin)
     52     {
     53         *plugin = new MockDrmPlugin();
     54         return OK;
     55     }
     56 
     57     // MockCryptoFactory
     58     bool MockCryptoFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) const
     59     {
     60         return (!memcmp(uuid, mock_uuid, sizeof(uuid)));
     61     }
     62 
     63     status_t MockCryptoFactory::createPlugin(const uint8_t uuid[16], const void *data,
     64                                              size_t size, CryptoPlugin **plugin)
     65     {
     66         *plugin = new MockCryptoPlugin();
     67         return OK;
     68     }
     69 
     70 
     71     // MockDrmPlugin methods
     72 
     73     status_t MockDrmPlugin::openSession(Vector<uint8_t> &sessionId)
     74     {
     75         const size_t kSessionIdSize = 8;
     76 
     77         Mutex::Autolock lock(mLock);
     78         for (size_t i = 0; i < kSessionIdSize / sizeof(long); i++) {
     79             long r = random();
     80             sessionId.appendArray((uint8_t *)&r, sizeof(long));
     81         }
     82         mSessions.add(sessionId);
     83 
     84         ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).string());
     85         return OK;
     86     }
     87 
     88     status_t MockDrmPlugin::closeSession(Vector<uint8_t> const &sessionId)
     89     {
     90         Mutex::Autolock lock(mLock);
     91         ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).string());
     92         ssize_t index = findSession(sessionId);
     93         if (index == kNotFound) {
     94             ALOGD("Invalid sessionId");
     95             return BAD_VALUE;
     96         }
     97         mSessions.removeAt(index);
     98         return OK;
     99     }
    100 
    101 
    102     status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId,
    103                                           Vector<uint8_t> const &initData,
    104                                           String8 const &mimeType, KeyType keyType,
    105                                           KeyedVector<String8, String8> const &optionalParameters,
    106                                           Vector<uint8_t> &request, String8 &defaultUrl)
    107     {
    108         Mutex::Autolock lock(mLock);
    109         ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s"
    110               ", keyType=%d, optionalParameters=%s))",
    111               vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(),
    112               keyType, stringMapToString(optionalParameters).string());
    113 
    114         ssize_t index = findSession(sessionId);
    115         if (index == kNotFound) {
    116             ALOGD("Invalid sessionId");
    117             return BAD_VALUE;
    118         }
    119 
    120         // Properties used in mock test, set by mock plugin and verifed cts test app
    121         //   byte[] initData           -> mock-initdata
    122         //   string mimeType           -> mock-mimetype
    123         //   string keyType            -> mock-keytype
    124         //   string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2}
    125 
    126         mByteArrayProperties.add(String8("mock-initdata"), initData);
    127         mStringProperties.add(String8("mock-mimetype"), mimeType);
    128 
    129         String8 keyTypeStr;
    130         keyTypeStr.appendFormat("%d", (int)keyType);
    131         mStringProperties.add(String8("mock-keytype"), keyTypeStr);
    132 
    133         String8 params;
    134         for (size_t i = 0; i < optionalParameters.size(); i++) {
    135             params.appendFormat("%s{%s,%s}", i ? "," : "",
    136                                 optionalParameters.keyAt(i).string(),
    137                                 optionalParameters.valueAt(i).string());
    138         }
    139         mStringProperties.add(String8("mock-optparams"), params);
    140 
    141         // Properties used in mock test, set by cts test app returned from mock plugin
    142         //   byte[] mock-request       -> request
    143         //   string mock-default-url   -> defaultUrl
    144 
    145         index = mByteArrayProperties.indexOfKey(String8("mock-request"));
    146         if (index < 0) {
    147             ALOGD("Missing 'mock-request' parameter for mock");
    148             return BAD_VALUE;
    149         } else {
    150             request = mByteArrayProperties.valueAt(index);
    151         }
    152 
    153         index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
    154         if (index < 0) {
    155             ALOGD("Missing 'mock-defaultUrl' parameter for mock");
    156             return BAD_VALUE;
    157         } else {
    158             defaultUrl = mStringProperties.valueAt(index);
    159         }
    160         return OK;
    161     }
    162 
    163     status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId,
    164                                                Vector<uint8_t> const &response,
    165                                                Vector<uint8_t> &keySetId)
    166     {
    167         Mutex::Autolock lock(mLock);
    168         ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)",
    169               vectorToString(sessionId).string(), vectorToString(response).string());
    170         ssize_t index = findSession(sessionId);
    171         if (index == kNotFound) {
    172             ALOGD("Invalid sessionId");
    173             return BAD_VALUE;
    174         }
    175         if (response.size() == 0) {
    176             return BAD_VALUE;
    177         }
    178 
    179         // Properties used in mock test, set by mock plugin and verifed cts test app
    180         //   byte[] response            -> mock-response
    181         mByteArrayProperties.add(String8("mock-response"), response);
    182 
    183         const size_t kKeySetIdSize = 8;
    184 
    185         for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) {
    186             long r = random();
    187             keySetId.appendArray((uint8_t *)&r, sizeof(long));
    188         }
    189         mKeySets.add(keySetId);
    190 
    191         return OK;
    192     }
    193 
    194     status_t MockDrmPlugin::removeKeys(Vector<uint8_t> const &keySetId)
    195     {
    196         Mutex::Autolock lock(mLock);
    197         ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)",
    198               vectorToString(keySetId).string());
    199 
    200         ssize_t index = findKeySet(keySetId);
    201         if (index == kNotFound) {
    202             ALOGD("Invalid keySetId");
    203             return BAD_VALUE;
    204         }
    205         mKeySets.removeAt(index);
    206 
    207         return OK;
    208     }
    209 
    210     status_t MockDrmPlugin::restoreKeys(Vector<uint8_t> const &sessionId,
    211                                         Vector<uint8_t> const &keySetId)
    212     {
    213         Mutex::Autolock lock(mLock);
    214         ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)",
    215               vectorToString(sessionId).string(),
    216               vectorToString(keySetId).string());
    217         ssize_t index = findSession(sessionId);
    218         if (index == kNotFound) {
    219             ALOGD("Invalid sessionId");
    220             return BAD_VALUE;
    221         }
    222 
    223         index = findKeySet(keySetId);
    224         if (index == kNotFound) {
    225             ALOGD("Invalid keySetId");
    226             return BAD_VALUE;
    227         }
    228 
    229         return OK;
    230     }
    231 
    232     status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId,
    233                                                KeyedVector<String8, String8> &infoMap) const
    234     {
    235         ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)",
    236               vectorToString(sessionId).string());
    237 
    238         ssize_t index = findSession(sessionId);
    239         if (index == kNotFound) {
    240             ALOGD("Invalid sessionId");
    241             return BAD_VALUE;
    242         }
    243 
    244         infoMap.add(String8("purchaseDuration"), String8("1000"));
    245         infoMap.add(String8("licenseDuration"), String8("100"));
    246         return OK;
    247     }
    248 
    249     status_t MockDrmPlugin::getProvisionRequest(Vector<uint8_t> &request,
    250                                                 String8 &defaultUrl)
    251     {
    252         Mutex::Autolock lock(mLock);
    253         ALOGD("MockDrmPlugin::getProvisionRequest()");
    254 
    255         // Properties used in mock test, set by cts test app returned from mock plugin
    256         //   byte[] mock-request       -> request
    257         //   string mock-default-url   -> defaultUrl
    258 
    259         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request"));
    260         if (index < 0) {
    261             ALOGD("Missing 'mock-request' parameter for mock");
    262             return BAD_VALUE;
    263         } else {
    264             request = mByteArrayProperties.valueAt(index);
    265         }
    266 
    267         index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
    268         if (index < 0) {
    269             ALOGD("Missing 'mock-defaultUrl' parameter for mock");
    270             return BAD_VALUE;
    271         } else {
    272             defaultUrl = mStringProperties.valueAt(index);
    273         }
    274         return OK;
    275     }
    276 
    277     status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response)
    278     {
    279         Mutex::Autolock lock(mLock);
    280         ALOGD("MockDrmPlugin::provideProvisionResponse(%s)",
    281               vectorToString(response).string());
    282 
    283         // Properties used in mock test, set by mock plugin and verifed cts test app
    284         //   byte[] response            -> mock-response
    285 
    286         mByteArrayProperties.add(String8("mock-response"), response);
    287         return OK;
    288     }
    289 
    290     status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops)
    291     {
    292         Mutex::Autolock lock(mLock);
    293         ALOGD("MockDrmPlugin::getSecureStops()");
    294 
    295         // Properties used in mock test, set by cts test app returned from mock plugin
    296         //   byte[] mock-secure-stop1  -> first secure stop in list
    297         //   byte[] mock-secure-stop2  -> second secure stop in list
    298 
    299         Vector<uint8_t> ss1, ss2;
    300         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1"));
    301         if (index < 0) {
    302             ALOGD("Missing 'mock-secure-stop1' parameter for mock");
    303             return BAD_VALUE;
    304         } else {
    305             ss1 = mByteArrayProperties.valueAt(index);
    306         }
    307 
    308         index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2"));
    309         if (index < 0) {
    310             ALOGD("Missing 'mock-secure-stop2' parameter for mock");
    311             return BAD_VALUE;
    312         } else {
    313             ss2 = mByteArrayProperties.valueAt(index);
    314         }
    315 
    316         secureStops.push_back(ss1);
    317         secureStops.push_back(ss2);
    318         return OK;
    319     }
    320 
    321     status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease)
    322     {
    323         Mutex::Autolock lock(mLock);
    324         ALOGD("MockDrmPlugin::releaseSecureStops(%s)",
    325               vectorToString(ssRelease).string());
    326 
    327         // Properties used in mock test, set by mock plugin and verifed cts test app
    328         //   byte[] secure-stop-release  -> mock-ssrelease
    329         mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease);
    330 
    331         return OK;
    332     }
    333 
    334     status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const
    335     {
    336         ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string());
    337         ssize_t index = mStringProperties.indexOfKey(name);
    338         if (index < 0) {
    339             ALOGD("no property for '%s'", name.string());
    340             return BAD_VALUE;
    341         }
    342         value = mStringProperties.valueAt(index);
    343         return OK;
    344     }
    345 
    346     status_t MockDrmPlugin::getPropertyByteArray(String8 const &name,
    347                                                  Vector<uint8_t> &value) const
    348     {
    349         ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string());
    350         ssize_t index = mByteArrayProperties.indexOfKey(name);
    351         if (index < 0) {
    352             ALOGD("no property for '%s'", name.string());
    353             return BAD_VALUE;
    354         }
    355         value = mByteArrayProperties.valueAt(index);
    356         return OK;
    357     }
    358 
    359     status_t MockDrmPlugin::setPropertyString(String8 const &name,
    360                                               String8 const &value)
    361     {
    362         Mutex::Autolock lock(mLock);
    363         ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",
    364               name.string(), value.string());
    365 
    366         if (name == "mock-send-event") {
    367             unsigned code, extra;
    368             sscanf(value.string(), "%d %d", &code, &extra);
    369             DrmPlugin::EventType eventType = (DrmPlugin::EventType)code;
    370 
    371             Vector<uint8_t> const *pSessionId = NULL;
    372             ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
    373             if (index >= 0) {
    374                 pSessionId = &mByteArrayProperties[index];
    375             }
    376 
    377             Vector<uint8_t> const *pData = NULL;
    378             index = mByteArrayProperties.indexOfKey(String8("mock-event-data"));
    379             if (index >= 0) {
    380                 pData = &mByteArrayProperties[index];
    381             }
    382             ALOGD("sending event from mock drm plugin: %d %d %s %s",
    383                   (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}",
    384                   pData ? vectorToString(*pData) : "{}");
    385 
    386             sendEvent(eventType, extra, pSessionId, pData);
    387         } else {
    388             mStringProperties.add(name, value);
    389         }
    390         return OK;
    391     }
    392 
    393     status_t MockDrmPlugin::setPropertyByteArray(String8 const &name,
    394                                                  Vector<uint8_t> const &value)
    395     {
    396         Mutex::Autolock lock(mLock);
    397         ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)",
    398               name.string(), vectorToString(value).string());
    399         mByteArrayProperties.add(name, value);
    400         return OK;
    401     }
    402 
    403     status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
    404                                                String8 const &algorithm)
    405     {
    406         Mutex::Autolock lock(mLock);
    407 
    408         ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
    409               vectorToString(sessionId).string(), algorithm.string());
    410 
    411         ssize_t index = findSession(sessionId);
    412         if (index == kNotFound) {
    413             ALOGD("Invalid sessionId");
    414             return BAD_VALUE;
    415         }
    416 
    417         if (algorithm == "AES/CBC/NoPadding") {
    418             return OK;
    419         }
    420         return BAD_VALUE;
    421     }
    422 
    423     status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId,
    424                                             String8 const &algorithm)
    425     {
    426         Mutex::Autolock lock(mLock);
    427 
    428         ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
    429               vectorToString(sessionId).string(), algorithm.string());
    430 
    431         ssize_t index = findSession(sessionId);
    432         if (index == kNotFound) {
    433             ALOGD("Invalid sessionId");
    434             return BAD_VALUE;
    435         }
    436 
    437         if (algorithm == "HmacSHA256") {
    438             return OK;
    439         }
    440         return BAD_VALUE;
    441     }
    442 
    443     status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId,
    444                                     Vector<uint8_t> const &keyId,
    445                                     Vector<uint8_t> const &input,
    446                                     Vector<uint8_t> const &iv,
    447                                     Vector<uint8_t> &output)
    448     {
    449         Mutex::Autolock lock(mLock);
    450         ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
    451               vectorToString(sessionId).string(),
    452               vectorToString(keyId).string(),
    453               vectorToString(input).string(),
    454               vectorToString(iv).string());
    455 
    456         ssize_t index = findSession(sessionId);
    457         if (index == kNotFound) {
    458             ALOGD("Invalid sessionId");
    459             return BAD_VALUE;
    460         }
    461 
    462         // Properties used in mock test, set by mock plugin and verifed cts test app
    463         //   byte[] keyId              -> mock-keyid
    464         //   byte[] input              -> mock-input
    465         //   byte[] iv                 -> mock-iv
    466         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    467         mByteArrayProperties.add(String8("mock-input"), input);
    468         mByteArrayProperties.add(String8("mock-iv"), iv);
    469 
    470         // Properties used in mock test, set by cts test app returned from mock plugin
    471         //   byte[] mock-output        -> output
    472         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
    473         if (index < 0) {
    474             ALOGD("Missing 'mock-request' parameter for mock");
    475             return BAD_VALUE;
    476         } else {
    477             output = mByteArrayProperties.valueAt(index);
    478         }
    479         return OK;
    480     }
    481 
    482     status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId,
    483                                     Vector<uint8_t> const &keyId,
    484                                     Vector<uint8_t> const &input,
    485                                     Vector<uint8_t> const &iv,
    486                                     Vector<uint8_t> &output)
    487     {
    488         Mutex::Autolock lock(mLock);
    489         ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
    490               vectorToString(sessionId).string(),
    491               vectorToString(keyId).string(),
    492               vectorToString(input).string(),
    493               vectorToString(iv).string());
    494 
    495         ssize_t index = findSession(sessionId);
    496         if (index == kNotFound) {
    497             ALOGD("Invalid sessionId");
    498             return BAD_VALUE;
    499         }
    500 
    501         // Properties used in mock test, set by mock plugin and verifed cts test app
    502         //   byte[] keyId              -> mock-keyid
    503         //   byte[] input              -> mock-input
    504         //   byte[] iv                 -> mock-iv
    505         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    506         mByteArrayProperties.add(String8("mock-input"), input);
    507         mByteArrayProperties.add(String8("mock-iv"), iv);
    508 
    509         // Properties used in mock test, set by cts test app returned from mock plugin
    510         //   byte[] mock-output        -> output
    511         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
    512         if (index < 0) {
    513             ALOGD("Missing 'mock-request' parameter for mock");
    514             return BAD_VALUE;
    515         } else {
    516             output = mByteArrayProperties.valueAt(index);
    517         }
    518         return OK;
    519     }
    520 
    521     status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId,
    522                                  Vector<uint8_t> const &keyId,
    523                                  Vector<uint8_t> const &message,
    524                                  Vector<uint8_t> &signature)
    525     {
    526         Mutex::Autolock lock(mLock);
    527         ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
    528               vectorToString(sessionId).string(),
    529               vectorToString(keyId).string(),
    530               vectorToString(message).string());
    531 
    532         ssize_t index = findSession(sessionId);
    533         if (index == kNotFound) {
    534             ALOGD("Invalid sessionId");
    535             return BAD_VALUE;
    536         }
    537 
    538         // Properties used in mock test, set by mock plugin and verifed cts test app
    539         //   byte[] keyId              -> mock-keyid
    540         //   byte[] message            -> mock-message
    541         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    542         mByteArrayProperties.add(String8("mock-message"), message);
    543 
    544         // Properties used in mock test, set by cts test app returned from mock plugin
    545         //   byte[] mock-signature        -> signature
    546         index = mByteArrayProperties.indexOfKey(String8("mock-signature"));
    547         if (index < 0) {
    548             ALOGD("Missing 'mock-request' parameter for mock");
    549             return BAD_VALUE;
    550         } else {
    551             signature = mByteArrayProperties.valueAt(index);
    552         }
    553         return OK;
    554     }
    555 
    556     status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId,
    557                                    Vector<uint8_t> const &keyId,
    558                                    Vector<uint8_t> const &message,
    559                                    Vector<uint8_t> const &signature,
    560                                    bool &match)
    561     {
    562         Mutex::Autolock lock(mLock);
    563         ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
    564               vectorToString(sessionId).string(),
    565               vectorToString(keyId).string(),
    566               vectorToString(message).string(),
    567               vectorToString(signature).string());
    568 
    569         ssize_t index = findSession(sessionId);
    570         if (index == kNotFound) {
    571             ALOGD("Invalid sessionId");
    572             return BAD_VALUE;
    573         }
    574 
    575         // Properties used in mock test, set by mock plugin and verifed cts test app
    576         //   byte[] keyId              -> mock-keyid
    577         //   byte[] message            -> mock-message
    578         //   byte[] signature          -> mock-signature
    579         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    580         mByteArrayProperties.add(String8("mock-message"), message);
    581         mByteArrayProperties.add(String8("mock-signature"), signature);
    582 
    583         // Properties used in mock test, set by cts test app returned from mock plugin
    584         //   String mock-match "1" or "0"         -> match
    585         index = mStringProperties.indexOfKey(String8("mock-match"));
    586         if (index < 0) {
    587             ALOGD("Missing 'mock-request' parameter for mock");
    588             return BAD_VALUE;
    589         } else {
    590             match = atol(mStringProperties.valueAt(index).string());
    591         }
    592         return OK;
    593     }
    594 
    595     ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const
    596     {
    597         ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size());
    598         for (size_t i = 0; i < mSessions.size(); ++i) {
    599             if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) {
    600                 return i;
    601             }
    602         }
    603         return kNotFound;
    604     }
    605 
    606     ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const
    607     {
    608         ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size());
    609         for (size_t i = 0; i < mKeySets.size(); ++i) {
    610             if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) {
    611                 return i;
    612             }
    613         }
    614         return kNotFound;
    615     }
    616 
    617 
    618     // Conversion utilities
    619     String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const
    620     {
    621         return arrayToString(vector.array(), vector.size());
    622     }
    623 
    624     String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const
    625     {
    626         String8 result("{ ");
    627         for (size_t i = 0; i < len; i++) {
    628             result.appendFormat("0x%02x ", array[i]);
    629         }
    630         result += "}";
    631         return result;
    632     }
    633 
    634     String8 MockDrmPlugin::stringMapToString(KeyedVector<String8, String8> map) const
    635     {
    636         String8 result("{ ");
    637         for (size_t i = 0; i < map.size(); i++) {
    638             result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "",
    639                                 map.keyAt(i).string(), map.valueAt(i).string());
    640         }
    641         return result + " }";
    642     }
    643 
    644     bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) {
    645         return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0);
    646     }
    647 
    648     //
    649     // Crypto Plugin
    650     //
    651 
    652     bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const
    653     {
    654         ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime);
    655         return false;
    656     }
    657 
    658     ssize_t
    659     MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16],
    660                               Mode mode, const void *srcPtr, const SubSample *subSamples,
    661                               size_t numSubSamples, void *dstPtr, AString *errorDetailMsg)
    662     {
    663         ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, "
    664               "subSamples=%s, dst=%p)",
    665               (int)secure,
    666               arrayToString(key, sizeof(key)).string(),
    667               arrayToString(iv, sizeof(iv)).string(),
    668               (int)mode, srcPtr,
    669               subSamplesToString(subSamples, numSubSamples).string(),
    670               dstPtr);
    671         return OK;
    672     }
    673 
    674     // Conversion utilities
    675     String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const
    676     {
    677         String8 result("{ ");
    678         for (size_t i = 0; i < len; i++) {
    679             result.appendFormat("0x%02x ", array[i]);
    680         }
    681         result += "}";
    682         return result;
    683     }
    684 
    685     String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples,
    686                                                  size_t numSubSamples) const
    687     {
    688         String8 result;
    689         for (size_t i = 0; i < numSubSamples; i++) {
    690             result.appendFormat("[%d] {clear:%d, encrypted:%d} ", i,
    691                                 subSamples[i].mNumBytesOfClearData,
    692                                 subSamples[i].mNumBytesOfEncryptedData);
    693         }
    694         return result;
    695     }
    696 
    697 };
    698