Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 994023af authored by Kyle Zhang's avatar Kyle Zhang
Browse files

Drm framework change based on new aidl interface cleanup

Test: atest CtsMediaDrmTestCases
Bug: 214410088
Change-Id: Ib80d8f86b069cd9569d71efc2eee94093581e845
parent 74e29ad4
Loading
Loading
Loading
Loading
+73 −74
Original line number Diff line number Diff line
@@ -28,8 +28,7 @@
#include <mediadrm/CryptoHalAidl.h>
#include <mediadrm/DrmUtils.h>

using ::aidl::android::hardware::drm::BufferType;
using ::aidl::android::hardware::drm::DecryptResult;
using ::aidl::android::hardware::drm::CryptoSchemes;
using DestinationBufferAidl = ::aidl::android::hardware::drm::DestinationBuffer;
using ::aidl::android::hardware::drm::Mode;
using ::aidl::android::hardware::drm::Pattern;
@@ -37,8 +36,9 @@ using SharedBufferAidl = ::aidl::android::hardware::drm::SharedBuffer;
using ::aidl::android::hardware::drm::Status;
using ::aidl::android::hardware::drm::SubSample;
using ::aidl::android::hardware::drm::Uuid;

using ::aidl::android::hardware::common::Ashmem;
using ::aidl::android::hardware::drm::SecurityLevel;
using NativeHandleAidlCommon = ::aidl::android::hardware::common::NativeHandle;
using ::aidl::android::hardware::drm::DecryptArgs;

using ::android::sp;
using ::android::DrmUtils::statusAidlToStatusT;
@@ -63,12 +63,6 @@ using DestinationBufferHidl = ::android::hardware::drm::V1_0::DestinationBuffer;

namespace android {

static Uuid toAidlUuid(const uint8_t* uuid) {
    Uuid uuidAidl;
    uuidAidl.uuid = std::vector<uint8_t>(uuid, uuid + 16);
    return uuidAidl;
}

template <typename Byte = uint8_t>
static std::vector<Byte> toStdVec(const Vector<uint8_t>& vector) {
    auto v = reinterpret_cast<const Byte*>(vector.array());
@@ -107,14 +101,24 @@ static DestinationBufferAidl hidlDestinationBufferToAidlDestinationBuffer(
        const DestinationBufferHidl& buffer) {
    DestinationBufferAidl aidldb;
    // skip negative convert check as count of enum elements are 2
    aidldb.type = static_cast<BufferType>((int32_t)buffer.type);
    aidldb.nonsecureMemory = hidlSharedBufferToAidlSharedBuffer(buffer.nonsecureMemory);
    switch(buffer.type) {
        case BufferTypeHidl::SHARED_MEMORY:
            aidldb.set<DestinationBufferAidl::Tag::nonsecureMemory>(
                hidlSharedBufferToAidlSharedBuffer(buffer.nonsecureMemory));
            break;
        default:
            auto handle = buffer.secureMemory.getNativeHandle();
            if (handle) {
        aidldb.secureMemory = ::android::makeToAidl(handle);
                aidldb.set<DestinationBufferAidl::Tag::secureMemory>(
                    ::android::makeToAidl(handle));
            } else {
        aidldb.secureMemory = {.fds = {}, .ints = {}};
                NativeHandleAidlCommon emptyhandle;
                aidldb.set<DestinationBufferAidl::Tag::secureMemory>(
                    std::move(emptyhandle));
            }
            break;
    }

    return aidldb;
}

@@ -144,34 +148,28 @@ static std::vector<uint8_t> toStdVec(const uint8_t* ptr, size_t n) {

// -------Hidl interface related end--------------

bool CryptoHalAidl::isCryptoSchemeSupportedInternal(const uint8_t uuid[16], int* factoryIdx) {
    Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
    for (size_t i = 0; i < mFactories.size(); i++) {
        CryptoSchemes schemes{};
        if (mFactories[i]->getSupportedCryptoSchemes(&schemes).isOk()) {
            if (std::count(schemes.uuids.begin(), schemes.uuids.end(), uuidAidl)) {
                if (factoryIdx != NULL) *factoryIdx = i;
                return true;
            }
        }
    }

    return false;
}

CryptoHalAidl::CryptoHalAidl()
    : mFactories(makeCryptoFactories()),
    : mFactories(DrmUtils::makeDrmFactoriesAidl()),
      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
      mHeapSeqNum(0) {}

CryptoHalAidl::~CryptoHalAidl() {}

std::vector<std::shared_ptr<ICryptoFactoryAidl>> CryptoHalAidl::makeCryptoFactories() {
    std::vector<std::shared_ptr<ICryptoFactoryAidl>> factories;
    AServiceManager_forEachDeclaredInstance(
            ICryptoFactoryAidl::descriptor, static_cast<void*>(&factories),
            [](const char* instance, void* context) {
                auto fullName = std::string(ICryptoFactoryAidl::descriptor) + "/" + std::string(instance);
                auto factory = ICryptoFactoryAidl::fromBinder(
                        ::ndk::SpAIBinder(AServiceManager_getService(fullName.c_str())));
                if (factory == nullptr) {
                    ALOGE("not found ICryptoFactoryAidl. Instance name:[%s]", fullName.c_str());
                    return;
                }

                ALOGI("found ICryptoFactoryAidl. Instance name:[%s]", fullName.c_str());
                static_cast<std::vector<std::shared_ptr<ICryptoFactoryAidl>>*>(context)
                        ->emplace_back(factory);
            });

    return factories;
}

status_t CryptoHalAidl::initCheck() const {
    return mInitCheck;
}
@@ -179,29 +177,17 @@ status_t CryptoHalAidl::initCheck() const {
bool CryptoHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16]) {
    Mutex::Autolock autoLock(mLock);

    bool isSupported = false;
    Uuid uuidAidl = toAidlUuid(uuid);
    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuidAidl, &isSupported).isOk()) {
            if (isSupported) break;
        }
    }
    return isSupported;
    return isCryptoSchemeSupportedInternal(uuid, NULL);
}

status_t CryptoHalAidl::createPlugin(const uint8_t uuid[16], const void* data, size_t size) {
    Mutex::Autolock autoLock(mLock);

    bool isSupported = false;
    Uuid uuidAidl = toAidlUuid(uuid);
    Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
    std::vector<uint8_t> dataAidl = toStdVec(toVector(toHidlVec(data, size)));
    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuidAidl, &isSupported).isOk() && isSupported) {
    int i = 0;
    if (isCryptoSchemeSupportedInternal(uuid, &i)) {
        mPlugin = makeCryptoPlugin(mFactories[i], uuidAidl, dataAidl);
            // Reserve place for future plugins with new versions

            break;
        }
    }

    if (mInitCheck == NO_INIT) {
@@ -212,10 +198,10 @@ status_t CryptoHalAidl::createPlugin(const uint8_t uuid[16], const void* data, s
}

std::shared_ptr<ICryptoPluginAidl> CryptoHalAidl::makeCryptoPlugin(
        const std::shared_ptr<ICryptoFactoryAidl>& factory, const Uuid& uuidAidl,
        const std::shared_ptr<IDrmFactoryAidl>& factory, const Uuid& uuidAidl,
        const std::vector<uint8_t> initData) {
    std::shared_ptr<ICryptoPluginAidl> pluginAidl;
    if (factory->createPlugin(uuidAidl, initData, &pluginAidl).isOk()) {
    if (factory->createCryptoPlugin(uuidAidl, initData, &pluginAidl).isOk()) {
        ALOGI("Create ICryptoPluginAidl. UUID:[%s]", uuidAidl.toString().c_str());
    } else {
        mInitCheck = DEAD_OBJECT;
@@ -349,21 +335,32 @@ ssize_t CryptoHalAidl::decrypt(const uint8_t keyId[16], const uint8_t iv[16],

    std::vector<uint8_t> keyIdAidl(toStdVec(keyId, 16));
    std::vector<uint8_t> ivAidl(toStdVec(iv, 16));
    DecryptResult result;
    ::ndk::ScopedAStatus statusAidl = mPlugin->decrypt(secure,
                           keyIdAidl, ivAidl, aMode, aPattern, stdSubSamples,
                           hidlSharedBufferToAidlSharedBuffer(hSource), offset,
                           hidlDestinationBufferToAidlDestinationBuffer(hDestination), &result);

    DecryptArgs args;
    args.secure = secure;
    args.keyId = keyIdAidl;
    args.iv = ivAidl;
    args.mode = aMode;
    args.pattern = aPattern;
    args.subSamples = std::move(stdSubSamples);
    args.source = hidlSharedBufferToAidlSharedBuffer(hSource);
    args.offset = offset;
    args.destination = hidlDestinationBufferToAidlDestinationBuffer(hDestination);


    int32_t result = 0;
    ::ndk::ScopedAStatus statusAidl = mPlugin->decrypt(args, &result);

    err = statusAidlToStatusT(statusAidl);
    *errorDetailMsg = toString8(result.detailedError);
    std::string msgStr(statusAidl.getMessage());
    *errorDetailMsg = toString8(msgStr);
    if (err != OK) {
        ALOGE("Failed on decrypt, error message:%s, bytes written:%d", result.detailedError.c_str(),
              result.bytesWritten);
        ALOGE("Failed on decrypt, error message:%s, bytes written:%d", statusAidl.getMessage(),
              result);
        return err;
    }

    return result.bytesWritten;
    return result;
}

int32_t CryptoHalAidl::setHeap(const sp<HidlMemory>& heap) {
@@ -378,11 +375,13 @@ int32_t CryptoHalAidl::setHeap(const sp<HidlMemory>& heap) {
    uint32_t bufferId = static_cast<uint32_t>(seqNum);
    mHeapSizes.add(seqNum, heap->size());

    Ashmem memAidl;
    memAidl.fd.set(heap->handle()->data[0]);
    SharedBufferAidl memAidl;
    memAidl.handle = ::android::makeToAidl(heap->handle());
    memAidl.size = heap->size();
    memAidl.bufferId = bufferId;

    ALOGE_IF(!mPlugin->setSharedBufferBase(memAidl, bufferId).isOk(),
    auto status = mPlugin->setSharedBufferBase(memAidl);
       ALOGE_IF(!status.isOk(),
             "setSharedBufferBase(): remote call failed");
    return seqNum;
}
@@ -401,10 +400,10 @@ void CryptoHalAidl::unsetHeap(int32_t seqNum) {
    if (index >= 0) {
        if (mPlugin != NULL) {
            uint32_t bufferId = static_cast<uint32_t>(seqNum);
            Ashmem memAidl;
            memAidl.fd.set(-1);
            memAidl.size = 0;
            ALOGE_IF(!mPlugin->setSharedBufferBase(memAidl, bufferId).isOk(),
            SharedBufferAidl memAidl{};
            memAidl.bufferId = bufferId;
            auto status = mPlugin->setSharedBufferBase(memAidl);
            ALOGE_IF(!status.isOk(),
                     "setSharedBufferBase(): remote call failed");
        }
        mHeapSizes.removeItem(seqNum);
+28 −37
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DrmHalAidl"

#include <array>
#include <algorithm>
#include <android/binder_auto_utils.h>
#include <android/binder_manager.h>
#include <media/PluginMetricsReporting.h>
@@ -29,7 +31,7 @@
#include <mediadrm/DrmUtils.h>

using ::android::DrmUtils::statusAidlToStatusT;

using ::aidl::android::hardware::drm::CryptoSchemes;
using ::aidl::android::hardware::drm::DrmMetricNamedValue;
using ::aidl::android::hardware::drm::DrmMetricValue;
using ::aidl::android::hardware::drm::HdcpLevel;
@@ -94,12 +96,6 @@ namespace android {
        if (mInitCheck != OK) return mInitCheck; \
    }

static Uuid toAidlUuid(const uint8_t* uuid) {
    Uuid uuidAidl;
    uuidAidl.uuid = std::vector<uint8_t>(uuid, uuid + 16);
    return uuidAidl;
}

template <typename Byte = uint8_t>
static std::vector<Byte> toStdVec(const Vector<uint8_t>& vector) {
    auto v = reinterpret_cast<const Byte*>(vector.array());
@@ -395,7 +391,7 @@ DrmHalAidl::DrmSessionClient::~DrmSessionClient() {
// DrmHalAidl methods
DrmHalAidl::DrmHalAidl()
    : mListener(::ndk::SharedRefBase::make<DrmHalListener>(&mMetrics)),
      mFactories(makeDrmFactories()),
      mFactories(DrmUtils::makeDrmFactoriesAidl()),
      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {}

status_t DrmHalAidl::initCheck() const {
@@ -404,27 +400,6 @@ status_t DrmHalAidl::initCheck() const {

DrmHalAidl::~DrmHalAidl() {}

std::vector<std::shared_ptr<IDrmFactoryAidl>> DrmHalAidl::makeDrmFactories() {
    std::vector<std::shared_ptr<IDrmFactoryAidl>> factories;
    AServiceManager_forEachDeclaredInstance(
            IDrmFactoryAidl::descriptor, static_cast<void*>(&factories),
            [](const char* instance, void* context) {
                auto fullName = std::string(IDrmFactoryAidl::descriptor) + "/" + std::string(instance);
                auto factory = IDrmFactoryAidl::fromBinder(
                        ::ndk::SpAIBinder(AServiceManager_getService(fullName.c_str())));
                if (factory == nullptr) {
                    ALOGE("not found IDrmFactory. Instance name:[%s]", fullName.c_str());
                    return;
                }

                ALOGI("found IDrmFactory. Instance name:[%s]", fullName.c_str());
                static_cast<std::vector<std::shared_ptr<IDrmFactoryAidl>>*>(context)->emplace_back(
                        factory);
            });

    return factories;
}

status_t DrmHalAidl::setListener(const sp<IDrmClient>& listener) {
    mListener->setListener(listener);
    return NO_ERROR;
@@ -434,32 +409,47 @@ status_t DrmHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16], const Strin
                                             DrmPlugin::SecurityLevel level, bool* isSupported) {
    Mutex::Autolock autoLock(mLock);
    *isSupported = false;
    Uuid uuidAidl = toAidlUuid(uuid);
    Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
    SecurityLevel levelAidl = toAidlSecurityLevel(level);
    std::string mimeTypeStr = mimeType.string();

    for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
        if (mFactories[i]
                    ->isCryptoSchemeSupported(uuidAidl, mimeTypeStr, levelAidl, isSupported)
                    .isOk()) {
            if (*isSupported) break;
        CryptoSchemes schemes{};
        auto err = mFactories[i]->getSupportedCryptoSchemes(&schemes);
        if (!err.isOk() || !std::count(schemes.uuids.begin(), schemes.uuids.end(), uuidAidl)) {
            continue;
        }

        if (levelAidl != SecurityLevel::DEFAULT && levelAidl != SecurityLevel::UNKNOWN) {
            if (levelAidl > schemes.maxLevel || levelAidl < schemes.minLevel) {
                continue;
            }
        }

        if (!mimeTypeStr.empty()) {
            if (!std::count(schemes.mimeTypes.begin(), schemes.mimeTypes.end(), mimeTypeStr)) {
                continue;
            }
        }

        *isSupported = true;
        break;
    }

    return OK;
}

status_t DrmHalAidl::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
    Mutex::Autolock autoLock(mLock);

    Uuid uuidAidl = toAidlUuid(uuid);
    Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
    std::string appPackageNameAidl = toStdString(appPackageName);
    std::shared_ptr<IDrmPluginAidl> pluginAidl;
    mMetrics.SetAppPackageName(appPackageName);
    mMetrics.SetAppUid(AIBinder_getCallingUid());
    for (ssize_t i = mFactories.size() - 1; i >= 0; i--) {
        ::ndk::ScopedAStatus status =
                mFactories[i]->createPlugin(uuidAidl, appPackageNameAidl, &pluginAidl);
                mFactories[i]->createDrmPlugin(uuidAidl, appPackageNameAidl, &pluginAidl);
        if (status.isOk()) {
            if (pluginAidl != NULL) {
                mPlugin = pluginAidl;
@@ -1076,7 +1066,8 @@ status_t DrmHalAidl::requiresSecureDecoder(const char* mime, bool* required) con
    INIT_CHECK();

    std::string mimeAidl(mime);
    ::ndk::ScopedAStatus status = mPlugin->requiresSecureDecoderDefault(mimeAidl, required);
    ::ndk::ScopedAStatus status =
        mPlugin->requiresSecureDecoder(mimeAidl, SecurityLevel::DEFAULT, required);
    if (!status.isOk()) {
        DrmUtils::LOG2BE("requiresSecureDecoder txn failed: %d", status.getServiceSpecificError());
        return DEAD_OBJECT;
+4 −4
Original line number Diff line number Diff line
@@ -119,16 +119,16 @@ void DrmHalListener::setListener(sp<IDrmClient> listener) {
                case KeyStatusType::EXPIRED:
                    type = DrmPlugin::kKeyStatusType_Expired;
                    break;
                case KeyStatusType::OUTPUTNOTALLOWED:
                case KeyStatusType::OUTPUT_NOT_ALLOWED:
                    type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
                    break;
                case KeyStatusType::STATUSPENDING:
                case KeyStatusType::STATUS_PENDING:
                    type = DrmPlugin::kKeyStatusType_StatusPending;
                    break;
                case KeyStatusType::USABLEINFUTURE:
                case KeyStatusType::USABLE_IN_FUTURE:
                    type = DrmPlugin::kKeyStatusType_UsableInFuture;
                    break;
                case KeyStatusType::INTERNALERROR:
                case KeyStatusType::INTERNAL_ERROR:
                default:
                    type = DrmPlugin::kKeyStatusType_InternalError;
                    break;
+22 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DrmUtils"

#include <android/binder_manager.h>
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <android/hardware/drm/1.0/IDrmFactory.h>
@@ -169,6 +170,27 @@ bool UseDrmService() {
    return property_get_bool("mediadrm.use_mediadrmserver", true);
}

std::vector<std::shared_ptr<IDrmFactoryAidl>> makeDrmFactoriesAidl() {
    std::vector<std::shared_ptr<IDrmFactoryAidl>> factories;
    AServiceManager_forEachDeclaredInstance(
        IDrmFactoryAidl::descriptor, static_cast<void*>(&factories),
        [](const char* instance, void* context) {
            auto fullName = std::string(IDrmFactoryAidl::descriptor) + "/" + std::string(instance);
            auto factory = IDrmFactoryAidl::fromBinder(
                    ::ndk::SpAIBinder(AServiceManager_getService(fullName.c_str())));
            if (factory == nullptr) {
                ALOGE("not found IDrmFactory. Instance name:[%s]", fullName.c_str());
                return;
            }

            ALOGI("found IDrmFactory. Instance name:[%s]", fullName.c_str());
            static_cast<std::vector<std::shared_ptr<IDrmFactoryAidl>>*>(context)->emplace_back(
                    factory);
        });

    return factories;
}

sp<IDrm> MakeDrm(status_t* pstatus) {
    return MakeObject<DrmHal>(pstatus);
}
+5 −6
Original line number Diff line number Diff line
@@ -17,14 +17,13 @@
#ifndef CRYPTO_HAL_AIDL_H_
#define CRYPTO_HAL_AIDL_H_

#include <aidl/android/hardware/drm/ICryptoFactory.h>
#include <aidl/android/hardware/drm/ICryptoPlugin.h>

#include <aidl/android/hardware/drm/IDrmFactory.h>
#include <mediadrm/ICrypto.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>

using ICryptoFactoryAidl = ::aidl::android::hardware::drm::ICryptoFactory;
using IDrmFactoryAidl = ::aidl::android::hardware::drm::IDrmFactory;
using ICryptoPluginAidl = ::aidl::android::hardware::drm::ICryptoPlugin;
using ::aidl::android::hardware::drm::Uuid;

@@ -63,7 +62,7 @@ struct CryptoHalAidl : public ICrypto {
  private:
    mutable Mutex mLock;

    const std::vector<std::shared_ptr<ICryptoFactoryAidl>> mFactories;
    const std::vector<std::shared_ptr<IDrmFactoryAidl>> mFactories;
    std::shared_ptr<ICryptoPluginAidl> mPlugin;

    /**
@@ -77,12 +76,12 @@ struct CryptoHalAidl : public ICrypto {
    KeyedVector<int32_t, size_t> mHeapSizes;
    int32_t mHeapSeqNum;

    std::vector<std::shared_ptr<ICryptoFactoryAidl>> makeCryptoFactories();
    std::shared_ptr<ICryptoPluginAidl> makeCryptoPlugin(
            const std::shared_ptr<ICryptoFactoryAidl>& factory, const Uuid& uuidAidl,
            const std::shared_ptr<IDrmFactoryAidl>& factory, const Uuid& uuidAidl,
            const std::vector<uint8_t> initData);

    status_t checkSharedBuffer(const ::SharedBuffer& buffer);
    bool isCryptoSchemeSupportedInternal(const uint8_t uuid[16], int* factoryIdx);

    DISALLOW_EVIL_CONSTRUCTORS(CryptoHalAidl);
};
Loading