diff options
| author | Jeff Tinker <jtinker@google.com> | 2013-09-11 18:40:44 -0700 | 
|---|---|---|
| committer | Jeff Tinker <jtinker@google.com> | 2013-09-11 18:40:44 -0700 | 
| commit | 34486800a022857b45c3882624449980c5cb6907 (patch) | |
| tree | 06e1a76a831666df008d5ba344b2c8e34bce27ef /drm/mediadrm | |
| parent | fe346c707f59d763ded93bc3d27b51f0c0408258 (diff) | |
| download | frameworks_av-34486800a022857b45c3882624449980c5cb6907.zip frameworks_av-34486800a022857b45c3882624449980c5cb6907.tar.gz frameworks_av-34486800a022857b45c3882624449980c5cb6907.tar.bz2  | |
Fix MediaDrm cts tests
Moving the build of the mock MediaDrm plugin back to
frameworks/av since it can't be installed by cts.
b/10668350
Change-Id: Id662bdb0775389b458f86a299392217f2d959422
Diffstat (limited to 'drm/mediadrm')
| -rw-r--r-- | drm/mediadrm/plugins/mock/Android.mk | 38 | ||||
| -rw-r--r-- | drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp | 705 | ||||
| -rw-r--r-- | drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h | 156 | 
3 files changed, 899 insertions, 0 deletions
diff --git a/drm/mediadrm/plugins/mock/Android.mk b/drm/mediadrm/plugins/mock/Android.mk new file mode 100644 index 0000000..ada23a2 --- /dev/null +++ b/drm/mediadrm/plugins/mock/Android.mk @@ -0,0 +1,38 @@ +# +# Copyright (C) 2013 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +#      http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ +    MockDrmCryptoPlugin.cpp + +LOCAL_MODULE := libmockdrmcryptoplugin + +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm + +LOCAL_SHARED_LIBRARIES := \ +    libutils liblog + +LOCAL_C_INCLUDES += \ +    $(TOP)/frameworks/av/include \ +    $(TOP)/frameworks/native/include/media + +# Set the following flag to enable the decryption passthru flow +#LOCAL_CFLAGS += -DENABLE_PASSTHRU_DECRYPTION + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp new file mode 100644 index 0000000..f2cadf7 --- /dev/null +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -0,0 +1,705 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "MockDrmCryptoPlugin" +#include <utils/Log.h> + + +#include "drm/DrmAPI.h" +#include "MockDrmCryptoPlugin.h" +#include "media/stagefright/MediaErrors.h" + +using namespace android; + +// Shared library entry point +DrmFactory *createDrmFactory() +{ +    return new MockDrmFactory(); +} + +// Shared library entry point +CryptoFactory *createCryptoFactory() +{ +    return new MockCryptoFactory(); +} + +const uint8_t mock_uuid[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, +                               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; + +namespace android { + +    // MockDrmFactory +    bool MockDrmFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) +    { +        return (!memcmp(uuid, mock_uuid, sizeof(uuid))); +    } + +    bool MockDrmFactory::isContentTypeSupported(const String8 &mimeType) +    { +        if (mimeType != "video/mp4") { +            return false; +        } +        return true; +    } + +    status_t MockDrmFactory::createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin) +    { +        *plugin = new MockDrmPlugin(); +        return OK; +    } + +    // MockCryptoFactory +    bool MockCryptoFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) const +    { +        return (!memcmp(uuid, mock_uuid, sizeof(uuid))); +    } + +    status_t MockCryptoFactory::createPlugin(const uint8_t uuid[16], const void *data, +                                             size_t size, CryptoPlugin **plugin) +    { +        *plugin = new MockCryptoPlugin(); +        return OK; +    } + + +    // MockDrmPlugin methods + +    status_t MockDrmPlugin::openSession(Vector<uint8_t> &sessionId) +    { +        const size_t kSessionIdSize = 8; + +        Mutex::Autolock lock(mLock); +        for (size_t i = 0; i < kSessionIdSize / sizeof(long); i++) { +            long r = random(); +            sessionId.appendArray((uint8_t *)&r, sizeof(long)); +        } +        mSessions.add(sessionId); + +        ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).string()); +        return OK; +    } + +    status_t MockDrmPlugin::closeSession(Vector<uint8_t> const &sessionId) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).string()); +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } +        mSessions.removeAt(index); +        return OK; +    } + + +    status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId, +                                          Vector<uint8_t> const &initData, +                                          String8 const &mimeType, KeyType keyType, +                                          KeyedVector<String8, String8> const &optionalParameters, +                                          Vector<uint8_t> &request, String8 &defaultUrl) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s" +              ", keyType=%d, optionalParameters=%s))", +              vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(), +              keyType, stringMapToString(optionalParameters).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] initData           -> mock-initdata +        //   string mimeType           -> mock-mimetype +        //   string keyType            -> mock-keytype +        //   string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2} + +        mByteArrayProperties.add(String8("mock-initdata"), initData); +        mStringProperties.add(String8("mock-mimetype"), mimeType); + +        String8 keyTypeStr; +        keyTypeStr.appendFormat("%d", (int)keyType); +        mStringProperties.add(String8("mock-keytype"), keyTypeStr); + +        String8 params; +        for (size_t i = 0; i < optionalParameters.size(); i++) { +            params.appendFormat("%s{%s,%s}", i ? "," : "", +                                optionalParameters.keyAt(i).string(), +                                optionalParameters.valueAt(i).string()); +        } +        mStringProperties.add(String8("mock-optparams"), params); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-request       -> request +        //   string mock-default-url   -> defaultUrl + +        index = mByteArrayProperties.indexOfKey(String8("mock-request")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            request = mByteArrayProperties.valueAt(index); +        } + +        index = mStringProperties.indexOfKey(String8("mock-defaultUrl")); +        if (index < 0) { +            ALOGD("Missing 'mock-defaultUrl' parameter for mock"); +            return BAD_VALUE; +        } else { +            defaultUrl = mStringProperties.valueAt(index); +        } +        return OK; +    } + +    status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId, +                                               Vector<uint8_t> const &response, +                                               Vector<uint8_t> &keySetId) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)", +              vectorToString(sessionId).string(), vectorToString(response).string()); +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } +        if (response.size() == 0) { +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] response            -> mock-response +        mByteArrayProperties.add(String8("mock-response"), response); + +        const size_t kKeySetIdSize = 8; + +        for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) { +            long r = random(); +            keySetId.appendArray((uint8_t *)&r, sizeof(long)); +        } +        mKeySets.add(keySetId); + +        return OK; +    } + +    status_t MockDrmPlugin::removeKeys(Vector<uint8_t> const &keySetId) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)", +              vectorToString(keySetId).string()); + +        ssize_t index = findKeySet(keySetId); +        if (index == kNotFound) { +            ALOGD("Invalid keySetId"); +            return BAD_VALUE; +        } +        mKeySets.removeAt(index); + +        return OK; +    } + +    status_t MockDrmPlugin::restoreKeys(Vector<uint8_t> const &sessionId, +                                        Vector<uint8_t> const &keySetId) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)", +              vectorToString(sessionId).string(), +              vectorToString(keySetId).string()); +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        index = findKeySet(keySetId); +        if (index == kNotFound) { +            ALOGD("Invalid keySetId"); +            return BAD_VALUE; +        } + +        return OK; +    } + +    status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId, +                                               KeyedVector<String8, String8> &infoMap) const +    { +        ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)", +              vectorToString(sessionId).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        infoMap.add(String8("purchaseDuration"), String8("1000")); +        infoMap.add(String8("licenseDuration"), String8("100")); +        return OK; +    } + +    status_t MockDrmPlugin::getProvisionRequest(Vector<uint8_t> &request, +                                                String8 &defaultUrl) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::getProvisionRequest()"); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-request       -> request +        //   string mock-default-url   -> defaultUrl + +        ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            request = mByteArrayProperties.valueAt(index); +        } + +        index = mStringProperties.indexOfKey(String8("mock-defaultUrl")); +        if (index < 0) { +            ALOGD("Missing 'mock-defaultUrl' parameter for mock"); +            return BAD_VALUE; +        } else { +            defaultUrl = mStringProperties.valueAt(index); +        } +        return OK; +    } + +    status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::provideProvisionResponse(%s)", +              vectorToString(response).string()); + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] response            -> mock-response + +        mByteArrayProperties.add(String8("mock-response"), response); +        return OK; +    } + +    status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::getSecureStops()"); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-secure-stop1  -> first secure stop in list +        //   byte[] mock-secure-stop2  -> second secure stop in list + +        Vector<uint8_t> ss1, ss2; +        ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1")); +        if (index < 0) { +            ALOGD("Missing 'mock-secure-stop1' parameter for mock"); +            return BAD_VALUE; +        } else { +            ss1 = mByteArrayProperties.valueAt(index); +        } + +        index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2")); +        if (index < 0) { +            ALOGD("Missing 'mock-secure-stop2' parameter for mock"); +            return BAD_VALUE; +        } else { +            ss2 = mByteArrayProperties.valueAt(index); +        } + +        secureStops.push_back(ss1); +        secureStops.push_back(ss2); +        return OK; +    } + +    status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::releaseSecureStops(%s)", +              vectorToString(ssRelease).string()); + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] secure-stop-release  -> mock-ssrelease +        mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease); + +        return OK; +    } + +    status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const +    { +        ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string()); +        ssize_t index = mStringProperties.indexOfKey(name); +        if (index < 0) { +            ALOGD("no property for '%s'", name.string()); +            return BAD_VALUE; +        } +        value = mStringProperties.valueAt(index); +        return OK; +    } + +    status_t MockDrmPlugin::getPropertyByteArray(String8 const &name, +                                                 Vector<uint8_t> &value) const +    { +        ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string()); +        ssize_t index = mByteArrayProperties.indexOfKey(name); +        if (index < 0) { +            ALOGD("no property for '%s'", name.string()); +            return BAD_VALUE; +        } +        value = mByteArrayProperties.valueAt(index); +        return OK; +    } + +    status_t MockDrmPlugin::setPropertyString(String8 const &name, +                                              String8 const &value) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)", +              name.string(), value.string()); + +        if (name == "mock-send-event") { +            unsigned code, extra; +            sscanf(value.string(), "%d %d", &code, &extra); +            DrmPlugin::EventType eventType = (DrmPlugin::EventType)code; + +            Vector<uint8_t> const *pSessionId = NULL; +            ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id")); +            if (index >= 0) { +                pSessionId = &mByteArrayProperties[index]; +            } + +            Vector<uint8_t> const *pData = NULL; +            index = mByteArrayProperties.indexOfKey(String8("mock-event-data")); +            if (index >= 0) { +                pData = &mByteArrayProperties[index]; +            } +            ALOGD("sending event from mock drm plugin: %d %d %s %s", +                  (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}", +                  pData ? vectorToString(*pData) : "{}"); + +            sendEvent(eventType, extra, pSessionId, pData); +        } else { +            mStringProperties.add(name, value); +        } +        return OK; +    } + +    status_t MockDrmPlugin::setPropertyByteArray(String8 const &name, +                                                 Vector<uint8_t> const &value) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)", +              name.string(), vectorToString(value).string()); +        mByteArrayProperties.add(name, value); +        return OK; +    } + +    status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId, +                                               String8 const &algorithm) +    { +        Mutex::Autolock lock(mLock); + +        ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)", +              vectorToString(sessionId).string(), algorithm.string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        if (algorithm == "AES/CBC/NoPadding") { +            return OK; +        } +        return BAD_VALUE; +    } + +    status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId, +                                            String8 const &algorithm) +    { +        Mutex::Autolock lock(mLock); + +        ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)", +              vectorToString(sessionId).string(), algorithm.string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        if (algorithm == "HmacSHA256") { +            return OK; +        } +        return BAD_VALUE; +    } + +    status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId, +                                    Vector<uint8_t> const &keyId, +                                    Vector<uint8_t> const &input, +                                    Vector<uint8_t> const &iv, +                                    Vector<uint8_t> &output) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", +              vectorToString(sessionId).string(), +              vectorToString(keyId).string(), +              vectorToString(input).string(), +              vectorToString(iv).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] keyId              -> mock-keyid +        //   byte[] input              -> mock-input +        //   byte[] iv                 -> mock-iv +        mByteArrayProperties.add(String8("mock-keyid"), keyId); +        mByteArrayProperties.add(String8("mock-input"), input); +        mByteArrayProperties.add(String8("mock-iv"), iv); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-output        -> output +        index = mByteArrayProperties.indexOfKey(String8("mock-output")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            output = mByteArrayProperties.valueAt(index); +        } +        return OK; +    } + +    status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId, +                                    Vector<uint8_t> const &keyId, +                                    Vector<uint8_t> const &input, +                                    Vector<uint8_t> const &iv, +                                    Vector<uint8_t> &output) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", +              vectorToString(sessionId).string(), +              vectorToString(keyId).string(), +              vectorToString(input).string(), +              vectorToString(iv).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] keyId              -> mock-keyid +        //   byte[] input              -> mock-input +        //   byte[] iv                 -> mock-iv +        mByteArrayProperties.add(String8("mock-keyid"), keyId); +        mByteArrayProperties.add(String8("mock-input"), input); +        mByteArrayProperties.add(String8("mock-iv"), iv); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-output        -> output +        index = mByteArrayProperties.indexOfKey(String8("mock-output")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            output = mByteArrayProperties.valueAt(index); +        } +        return OK; +    } + +    status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId, +                                 Vector<uint8_t> const &keyId, +                                 Vector<uint8_t> const &message, +                                 Vector<uint8_t> &signature) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)", +              vectorToString(sessionId).string(), +              vectorToString(keyId).string(), +              vectorToString(message).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] keyId              -> mock-keyid +        //   byte[] message            -> mock-message +        mByteArrayProperties.add(String8("mock-keyid"), keyId); +        mByteArrayProperties.add(String8("mock-message"), message); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-signature        -> signature +        index = mByteArrayProperties.indexOfKey(String8("mock-signature")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            signature = mByteArrayProperties.valueAt(index); +        } +        return OK; +    } + +    status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId, +                                   Vector<uint8_t> const &keyId, +                                   Vector<uint8_t> const &message, +                                   Vector<uint8_t> const &signature, +                                   bool &match) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)", +              vectorToString(sessionId).string(), +              vectorToString(keyId).string(), +              vectorToString(message).string(), +              vectorToString(signature).string()); + +        ssize_t index = findSession(sessionId); +        if (index == kNotFound) { +            ALOGD("Invalid sessionId"); +            return BAD_VALUE; +        } + +        // Properties used in mock test, set by mock plugin and verifed cts test app +        //   byte[] keyId              -> mock-keyid +        //   byte[] message            -> mock-message +        //   byte[] signature          -> mock-signature +        mByteArrayProperties.add(String8("mock-keyid"), keyId); +        mByteArrayProperties.add(String8("mock-message"), message); +        mByteArrayProperties.add(String8("mock-signature"), signature); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   String mock-match "1" or "0"         -> match +        index = mStringProperties.indexOfKey(String8("mock-match")); +        if (index < 0) { +            ALOGD("Missing 'mock-request' parameter for mock"); +            return BAD_VALUE; +        } else { +            match = atol(mStringProperties.valueAt(index).string()); +        } +        return OK; +    } + +    ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const +    { +        ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size()); +        for (size_t i = 0; i < mSessions.size(); ++i) { +            if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) { +                return i; +            } +        } +        return kNotFound; +    } + +    ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const +    { +        ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size()); +        for (size_t i = 0; i < mKeySets.size(); ++i) { +            if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) { +                return i; +            } +        } +        return kNotFound; +    } + + +    // Conversion utilities +    String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const +    { +        return arrayToString(vector.array(), vector.size()); +    } + +    String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const +    { +        String8 result("{ "); +        for (size_t i = 0; i < len; i++) { +            result.appendFormat("0x%02x ", array[i]); +        } +        result += "}"; +        return result; +    } + +    String8 MockDrmPlugin::stringMapToString(KeyedVector<String8, String8> map) const +    { +        String8 result("{ "); +        for (size_t i = 0; i < map.size(); i++) { +            result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "", +                                map.keyAt(i).string(), map.valueAt(i).string()); +        } +        return result + " }"; +    } + +    bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) { +        return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0); +    } + +    // +    // Crypto Plugin +    // + +    bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const +    { +        ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime); +        return false; +    } + +    ssize_t +    MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16], +                              Mode mode, const void *srcPtr, const SubSample *subSamples, +                              size_t numSubSamples, void *dstPtr, AString *errorDetailMsg) +    { +        ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, " +              "subSamples=%s, dst=%p)", +              (int)secure, +              arrayToString(key, sizeof(key)).string(), +              arrayToString(iv, sizeof(iv)).string(), +              (int)mode, srcPtr, +              subSamplesToString(subSamples, numSubSamples).string(), +              dstPtr); +        return OK; +    } + +    // Conversion utilities +    String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const +    { +        String8 result("{ "); +        for (size_t i = 0; i < len; i++) { +            result.appendFormat("0x%02x ", array[i]); +        } +        result += "}"; +        return result; +    } + +    String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples, +                                                 size_t numSubSamples) const +    { +        String8 result; +        for (size_t i = 0; i < numSubSamples; i++) { +            result.appendFormat("[%d] {clear:%d, encrypted:%d} ", i, +                                subSamples[i].mNumBytesOfClearData, +                                subSamples[i].mNumBytesOfEncryptedData); +        } +        return result; +    } + +}; diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h new file mode 100644 index 0000000..2297f9b --- /dev/null +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <utils/Mutex.h> + +#include "drm/DrmAPI.h" +#include "hardware/CryptoAPI.h" + +extern "C" { +      android::DrmFactory *createDrmFactory(); +      android::CryptoFactory *createCryptoFactory(); +} + +namespace android { + +    class MockDrmFactory : public DrmFactory { +    public: +        MockDrmFactory() {} +        virtual ~MockDrmFactory() {} + +        bool isCryptoSchemeSupported(const uint8_t uuid[16]); +        bool isContentTypeSupported(const String8 &mimeType); +        status_t createDrmPlugin(const uint8_t uuid[16], DrmPlugin **plugin); +    }; + +    class MockCryptoFactory : public CryptoFactory { +    public: +        MockCryptoFactory() {} +        virtual ~MockCryptoFactory() {} + +        bool isCryptoSchemeSupported(const uint8_t uuid[16]) const; +        status_t createPlugin( +            const uint8_t uuid[16], const void *data, size_t size, +            CryptoPlugin **plugin); +    }; + + + +    class MockDrmPlugin : public DrmPlugin { +    public: +        MockDrmPlugin() {} +        virtual ~MockDrmPlugin() {} + +        // from DrmPlugin +        status_t openSession(Vector<uint8_t> &sessionId); +        status_t closeSession(Vector<uint8_t> const &sessionId); + +        status_t getKeyRequest(Vector<uint8_t> const &sessionId, +                               Vector<uint8_t> const &initData, +                               String8 const &mimeType, KeyType keyType, +                               KeyedVector<String8, String8> const &optionalParameters, +                               Vector<uint8_t> &request, String8 &defaultUrl); + +        status_t provideKeyResponse(Vector<uint8_t> const &sessionId, +                                    Vector<uint8_t> const &response, +                                    Vector<uint8_t> &keySetId); + +        status_t removeKeys(Vector<uint8_t> const &keySetId); + +        status_t restoreKeys(Vector<uint8_t> const &sessionId, +                             Vector<uint8_t> const &keySetId); + +        status_t queryKeyStatus(Vector<uint8_t> const &sessionId, +                                KeyedVector<String8, String8> &infoMap) const; + +        status_t getProvisionRequest(Vector<uint8_t> &request, +                                             String8 &defaultUrl); + +        status_t provideProvisionResponse(Vector<uint8_t> const &response); + +        status_t getSecureStops(List<Vector<uint8_t> > &secureStops); +        status_t releaseSecureStops(Vector<uint8_t> const &ssRelease); + +        status_t getPropertyString(String8 const &name, String8 &value ) const; +        status_t getPropertyByteArray(String8 const &name, +                                              Vector<uint8_t> &value ) const; + +        status_t setPropertyString(String8 const &name, +                                   String8 const &value ); +        status_t setPropertyByteArray(String8 const &name, +                                      Vector<uint8_t> const &value ); + +        status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, +                                    String8 const &algorithm); + +        status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, +                                 String8 const &algorithm); + +        status_t encrypt(Vector<uint8_t> const &sessionId, +                         Vector<uint8_t> const &keyId, +                         Vector<uint8_t> const &input, +                         Vector<uint8_t> const &iv, +                         Vector<uint8_t> &output); + +        status_t decrypt(Vector<uint8_t> const &sessionId, +                         Vector<uint8_t> const &keyId, +                         Vector<uint8_t> const &input, +                         Vector<uint8_t> const &iv, +                         Vector<uint8_t> &output); + +        status_t sign(Vector<uint8_t> const &sessionId, +                      Vector<uint8_t> const &keyId, +                      Vector<uint8_t> const &message, +                      Vector<uint8_t> &signature); + +        status_t verify(Vector<uint8_t> const &sessionId, +                        Vector<uint8_t> const &keyId, +                        Vector<uint8_t> const &message, +                        Vector<uint8_t> const &signature, +                        bool &match); + +    private: +        String8 vectorToString(Vector<uint8_t> const &vector) const; +        String8 arrayToString(uint8_t const *array, size_t len) const; +        String8 stringMapToString(KeyedVector<String8, String8> map) const; + +        SortedVector<Vector<uint8_t> > mSessions; +        SortedVector<Vector<uint8_t> > mKeySets; + +        static const ssize_t kNotFound = -1; +        ssize_t findSession(Vector<uint8_t> const &sessionId) const; +        ssize_t findKeySet(Vector<uint8_t> const &keySetId) const; + +        Mutex mLock; +        KeyedVector<String8, String8> mStringProperties; +        KeyedVector<String8, Vector<uint8_t> > mByteArrayProperties; +    }; + + +    class MockCryptoPlugin : public CryptoPlugin { + +        bool requiresSecureDecoderComponent(const char *mime) const; + +        ssize_t decrypt(bool secure, +            const uint8_t key[16], const uint8_t iv[16], +            Mode mode, const void *srcPtr, +            const SubSample *subSamples, size_t numSubSamples, +            void *dstPtr, AString *errorDetailMsg); +    private: +        String8 subSamplesToString(CryptoPlugin::SubSample const *subSamples, size_t numSubSamples) const; +        String8 arrayToString(uint8_t const *array, size_t len) const; +    }; +};  | 
