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(mock_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(mock_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(String8 const &certType,
    258                                                 String8 const &certAuthority,
    259                                                 Vector<uint8_t> &request,
    260                                                 String8 &defaultUrl)
    261     {
    262         Mutex::Autolock lock(mLock);
    263         ALOGD("MockDrmPlugin::getProvisionRequest()");
    264 
    265         // Properties used in mock test, set by cts test app returned from mock plugin
    266         //   byte[] mock-request       -> request
    267         //   string mock-default-url   -> defaultUrl
    268 
    269         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request"));
    270         if (index < 0) {
    271             ALOGD("Missing 'mock-request' parameter for mock");
    272             return BAD_VALUE;
    273         } else {
    274             request = mByteArrayProperties.valueAt(index);
    275         }
    276 
    277         index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
    278         if (index < 0) {
    279             ALOGD("Missing 'mock-defaultUrl' parameter for mock");
    280             return BAD_VALUE;
    281         } else {
    282             defaultUrl = mStringProperties.valueAt(index);
    283         }
    284         return OK;
    285     }
    286 
    287     status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response,
    288                                                      Vector<uint8_t> &certificate,
    289                                                      Vector<uint8_t> &wrappedKey)
    290     {
    291         Mutex::Autolock lock(mLock);
    292         ALOGD("MockDrmPlugin::provideProvisionResponse(%s)",
    293               vectorToString(response).string());
    294 
    295         // Properties used in mock test, set by mock plugin and verifed cts test app
    296         //   byte[] response            -> mock-response
    297 
    298         mByteArrayProperties.add(String8("mock-response"), response);
    299         return OK;
    300     }
    301 
    302     status_t MockDrmPlugin::unprovisionDevice()
    303     {
    304         ALOGD("MockDrmPlugin::unprovisionDevice()");
    305         return OK;
    306     }
    307 
    308     status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops)
    309     {
    310         Mutex::Autolock lock(mLock);
    311         ALOGD("MockDrmPlugin::getSecureStops()");
    312 
    313         // Properties used in mock test, set by cts test app returned from mock plugin
    314         //   byte[] mock-secure-stop1  -> first secure stop in list
    315         //   byte[] mock-secure-stop2  -> second secure stop in list
    316 
    317         Vector<uint8_t> ss1, ss2;
    318         ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1"));
    319         if (index < 0) {
    320             ALOGD("Missing 'mock-secure-stop1' parameter for mock");
    321             return BAD_VALUE;
    322         } else {
    323             ss1 = mByteArrayProperties.valueAt(index);
    324         }
    325 
    326         index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2"));
    327         if (index < 0) {
    328             ALOGD("Missing 'mock-secure-stop2' parameter for mock");
    329             return BAD_VALUE;
    330         } else {
    331             ss2 = mByteArrayProperties.valueAt(index);
    332         }
    333 
    334         secureStops.push_back(ss1);
    335         secureStops.push_back(ss2);
    336         return OK;
    337     }
    338 
    339     status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease)
    340     {
    341         Mutex::Autolock lock(mLock);
    342         ALOGD("MockDrmPlugin::releaseSecureStops(%s)",
    343               vectorToString(ssRelease).string());
    344 
    345         // Properties used in mock test, set by mock plugin and verifed cts test app
    346         //   byte[] secure-stop-release  -> mock-ssrelease
    347         mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease);
    348 
    349         return OK;
    350     }
    351 
    352     status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const
    353     {
    354         ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string());
    355         ssize_t index = mStringProperties.indexOfKey(name);
    356         if (index < 0) {
    357             ALOGD("no property for '%s'", name.string());
    358             return BAD_VALUE;
    359         }
    360         value = mStringProperties.valueAt(index);
    361         return OK;
    362     }
    363 
    364     status_t MockDrmPlugin::getPropertyByteArray(String8 const &name,
    365                                                  Vector<uint8_t> &value) const
    366     {
    367         ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string());
    368         ssize_t index = mByteArrayProperties.indexOfKey(name);
    369         if (index < 0) {
    370             ALOGD("no property for '%s'", name.string());
    371             return BAD_VALUE;
    372         }
    373         value = mByteArrayProperties.valueAt(index);
    374         return OK;
    375     }
    376 
    377     status_t MockDrmPlugin::setPropertyString(String8 const &name,
    378                                               String8 const &value)
    379     {
    380         Mutex::Autolock lock(mLock);
    381         ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",
    382               name.string(), value.string());
    383 
    384         if (name == "mock-send-event") {
    385             unsigned code, extra;
    386             sscanf(value.string(), "%d %d", &code, &extra);
    387             DrmPlugin::EventType eventType = (DrmPlugin::EventType)code;
    388 
    389             Vector<uint8_t> const *pSessionId = NULL;
    390             ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
    391             if (index >= 0) {
    392                 pSessionId = &mByteArrayProperties[index];
    393             }
    394 
    395             Vector<uint8_t> const *pData = NULL;
    396             index = mByteArrayProperties.indexOfKey(String8("mock-event-data"));
    397             if (index >= 0) {
    398                 pData = &mByteArrayProperties[index];
    399             }
    400             ALOGD("sending event from mock drm plugin: %d %d %s %s",
    401                   (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}",
    402                   pData ? vectorToString(*pData) : "{}");
    403 
    404             sendEvent(eventType, extra, pSessionId, pData);
    405         } else {
    406             mStringProperties.add(name, value);
    407         }
    408         return OK;
    409     }
    410 
    411     status_t MockDrmPlugin::setPropertyByteArray(String8 const &name,
    412                                                  Vector<uint8_t> const &value)
    413     {
    414         Mutex::Autolock lock(mLock);
    415         ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)",
    416               name.string(), vectorToString(value).string());
    417         mByteArrayProperties.add(name, value);
    418         return OK;
    419     }
    420 
    421     status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
    422                                                String8 const &algorithm)
    423     {
    424         Mutex::Autolock lock(mLock);
    425 
    426         ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
    427               vectorToString(sessionId).string(), algorithm.string());
    428 
    429         ssize_t index = findSession(sessionId);
    430         if (index == kNotFound) {
    431             ALOGD("Invalid sessionId");
    432             return BAD_VALUE;
    433         }
    434 
    435         if (algorithm == "AES/CBC/NoPadding") {
    436             return OK;
    437         }
    438         return BAD_VALUE;
    439     }
    440 
    441     status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId,
    442                                             String8 const &algorithm)
    443     {
    444         Mutex::Autolock lock(mLock);
    445 
    446         ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
    447               vectorToString(sessionId).string(), algorithm.string());
    448 
    449         ssize_t index = findSession(sessionId);
    450         if (index == kNotFound) {
    451             ALOGD("Invalid sessionId");
    452             return BAD_VALUE;
    453         }
    454 
    455         if (algorithm == "HmacSHA256") {
    456             return OK;
    457         }
    458         return BAD_VALUE;
    459     }
    460 
    461     status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId,
    462                                     Vector<uint8_t> const &keyId,
    463                                     Vector<uint8_t> const &input,
    464                                     Vector<uint8_t> const &iv,
    465                                     Vector<uint8_t> &output)
    466     {
    467         Mutex::Autolock lock(mLock);
    468         ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
    469               vectorToString(sessionId).string(),
    470               vectorToString(keyId).string(),
    471               vectorToString(input).string(),
    472               vectorToString(iv).string());
    473 
    474         ssize_t index = findSession(sessionId);
    475         if (index == kNotFound) {
    476             ALOGD("Invalid sessionId");
    477             return BAD_VALUE;
    478         }
    479 
    480         // Properties used in mock test, set by mock plugin and verifed cts test app
    481         //   byte[] keyId              -> mock-keyid
    482         //   byte[] input              -> mock-input
    483         //   byte[] iv                 -> mock-iv
    484         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    485         mByteArrayProperties.add(String8("mock-input"), input);
    486         mByteArrayProperties.add(String8("mock-iv"), iv);
    487 
    488         // Properties used in mock test, set by cts test app returned from mock plugin
    489         //   byte[] mock-output        -> output
    490         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
    491         if (index < 0) {
    492             ALOGD("Missing 'mock-request' parameter for mock");
    493             return BAD_VALUE;
    494         } else {
    495             output = mByteArrayProperties.valueAt(index);
    496         }
    497         return OK;
    498     }
    499 
    500     status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId,
    501                                     Vector<uint8_t> const &keyId,
    502                                     Vector<uint8_t> const &input,
    503                                     Vector<uint8_t> const &iv,
    504                                     Vector<uint8_t> &output)
    505     {
    506         Mutex::Autolock lock(mLock);
    507         ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
    508               vectorToString(sessionId).string(),
    509               vectorToString(keyId).string(),
    510               vectorToString(input).string(),
    511               vectorToString(iv).string());
    512 
    513         ssize_t index = findSession(sessionId);
    514         if (index == kNotFound) {
    515             ALOGD("Invalid sessionId");
    516             return BAD_VALUE;
    517         }
    518 
    519         // Properties used in mock test, set by mock plugin and verifed cts test app
    520         //   byte[] keyId              -> mock-keyid
    521         //   byte[] input              -> mock-input
    522         //   byte[] iv                 -> mock-iv
    523         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    524         mByteArrayProperties.add(String8("mock-input"), input);
    525         mByteArrayProperties.add(String8("mock-iv"), iv);
    526 
    527         // Properties used in mock test, set by cts test app returned from mock plugin
    528         //   byte[] mock-output        -> output
    529         index = mByteArrayProperties.indexOfKey(String8("mock-output"));
    530         if (index < 0) {
    531             ALOGD("Missing 'mock-request' parameter for mock");
    532             return BAD_VALUE;
    533         } else {
    534             output = mByteArrayProperties.valueAt(index);
    535         }
    536         return OK;
    537     }
    538 
    539     status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId,
    540                                  Vector<uint8_t> const &keyId,
    541                                  Vector<uint8_t> const &message,
    542                                  Vector<uint8_t> &signature)
    543     {
    544         Mutex::Autolock lock(mLock);
    545         ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
    546               vectorToString(sessionId).string(),
    547               vectorToString(keyId).string(),
    548               vectorToString(message).string());
    549 
    550         ssize_t index = findSession(sessionId);
    551         if (index == kNotFound) {
    552             ALOGD("Invalid sessionId");
    553             return BAD_VALUE;
    554         }
    555 
    556         // Properties used in mock test, set by mock plugin and verifed cts test app
    557         //   byte[] keyId              -> mock-keyid
    558         //   byte[] message            -> mock-message
    559         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    560         mByteArrayProperties.add(String8("mock-message"), message);
    561 
    562         // Properties used in mock test, set by cts test app returned from mock plugin
    563         //   byte[] mock-signature        -> signature
    564         index = mByteArrayProperties.indexOfKey(String8("mock-signature"));
    565         if (index < 0) {
    566             ALOGD("Missing 'mock-request' parameter for mock");
    567             return BAD_VALUE;
    568         } else {
    569             signature = mByteArrayProperties.valueAt(index);
    570         }
    571         return OK;
    572     }
    573 
    574     status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId,
    575                                    Vector<uint8_t> const &keyId,
    576                                    Vector<uint8_t> const &message,
    577                                    Vector<uint8_t> const &signature,
    578                                    bool &match)
    579     {
    580         Mutex::Autolock lock(mLock);
    581         ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
    582               vectorToString(sessionId).string(),
    583               vectorToString(keyId).string(),
    584               vectorToString(message).string(),
    585               vectorToString(signature).string());
    586 
    587         ssize_t index = findSession(sessionId);
    588         if (index == kNotFound) {
    589             ALOGD("Invalid sessionId");
    590             return BAD_VALUE;
    591         }
    592 
    593         // Properties used in mock test, set by mock plugin and verifed cts test app
    594         //   byte[] keyId              -> mock-keyid
    595         //   byte[] message            -> mock-message
    596         //   byte[] signature          -> mock-signature
    597         mByteArrayProperties.add(String8("mock-keyid"), keyId);
    598         mByteArrayProperties.add(String8("mock-message"), message);
    599         mByteArrayProperties.add(String8("mock-signature"), signature);
    600 
    601         // Properties used in mock test, set by cts test app returned from mock plugin
    602         //   String mock-match "1" or "0"         -> match
    603         index = mStringProperties.indexOfKey(String8("mock-match"));
    604         if (index < 0) {
    605             ALOGD("Missing 'mock-request' parameter for mock");
    606             return BAD_VALUE;
    607         } else {
    608             match = atol(mStringProperties.valueAt(index).string());
    609         }
    610         return OK;
    611     }
    612 
    613     status_t MockDrmPlugin::signRSA(Vector<uint8_t> const &sessionId,
    614                                     String8 const &algorithm,
    615                                     Vector<uint8_t> const &message,
    616                                     Vector<uint8_t> const &wrappedKey,
    617                                     Vector<uint8_t> &signature)
    618     {
    619         Mutex::Autolock lock(mLock);
    620         ALOGD("MockDrmPlugin::signRSA(sessionId=%s, algorithm=%s, keyId=%s, "
    621               "message=%s, signature=%s)",
    622               vectorToString(sessionId).string(),
    623               algorithm.string(),
    624               vectorToString(message).string(),
    625               vectorToString(wrappedKey).string(),
    626               vectorToString(signature).string());
    627 
    628         // Properties used in mock test, set by mock plugin and verifed cts test app
    629         //   byte[] wrappedKey         -> mock-wrappedkey
    630         //   byte[] message            -> mock-message
    631         //   byte[] signature          -> mock-signature
    632         mByteArrayProperties.add(String8("mock-sessionid"), sessionId);
    633         mStringProperties.add(String8("mock-algorithm"), algorithm);
    634         mByteArrayProperties.add(String8("mock-message"), message);
    635         mByteArrayProperties.add(String8("mock-wrappedkey"), wrappedKey);
    636         mByteArrayProperties.add(String8("mock-signature"), signature);
    637         return OK;
    638     }
    639 
    640     ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const
    641     {
    642         ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size());
    643         for (size_t i = 0; i < mSessions.size(); ++i) {
    644             if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) {
    645                 return i;
    646             }
    647         }
    648         return kNotFound;
    649     }
    650 
    651     ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const
    652     {
    653         ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size());
    654         for (size_t i = 0; i < mKeySets.size(); ++i) {
    655             if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) {
    656                 return i;
    657             }
    658         }
    659         return kNotFound;
    660     }
    661 
    662 
    663     // Conversion utilities
    664     String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const
    665     {
    666         return arrayToString(vector.array(), vector.size());
    667     }
    668 
    669     String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const
    670     {
    671         String8 result("{ ");
    672         for (size_t i = 0; i < len; i++) {
    673             result.appendFormat("0x%02x ", array[i]);
    674         }
    675         result += "}";
    676         return result;
    677     }
    678 
    679     String8 MockDrmPlugin::stringMapToString(KeyedVector<String8, String8> map) const
    680     {
    681         String8 result("{ ");
    682         for (size_t i = 0; i < map.size(); i++) {
    683             result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "",
    684                                 map.keyAt(i).string(), map.valueAt(i).string());
    685         }
    686         return result + " }";
    687     }
    688 
    689     bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) {
    690         return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0);
    691     }
    692 
    693     //
    694     // Crypto Plugin
    695     //
    696 
    697     bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const
    698     {
    699         ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime);
    700         return false;
    701     }
    702 
    703     ssize_t
    704     MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16],
    705                               Mode mode, const void *srcPtr, const SubSample *subSamples,
    706                               size_t numSubSamples, void *dstPtr, AString *errorDetailMsg)
    707     {
    708         ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, "
    709               "subSamples=%s, dst=%p)",
    710               (int)secure,
    711               arrayToString(key, sizeof(key)).string(),
    712               arrayToString(iv, sizeof(iv)).string(),
    713               (int)mode, srcPtr,
    714               subSamplesToString(subSamples, numSubSamples).string(),
    715               dstPtr);
    716         return OK;
    717     }
    718 
    719     // Conversion utilities
    720     String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const
    721     {
    722         String8 result("{ ");
    723         for (size_t i = 0; i < len; i++) {
    724             result.appendFormat("0x%02x ", array[i]);
    725         }
    726         result += "}";
    727         return result;
    728     }
    729 
    730     String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples,
    731                                                  size_t numSubSamples) const
    732     {
    733         String8 result;
    734         for (size_t i = 0; i < numSubSamples; i++) {
    735             result.appendFormat("[%zu] {clear:%zu, encrypted:%zu} ", i,
    736                                 subSamples[i].mNumBytesOfClearData,
    737                                 subSamples[i].mNumBytesOfEncryptedData);
    738         }
    739         return result;
    740     }
    741 
    742 };
    743