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