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

Commit abeb36a8 authored by Jeff Tinker's avatar Jeff Tinker
Browse files

Load vendor-provided drm hidl hal modules

Prior to this change, the default legacy hal
module was explicitly referenced. This change
uses the service manager to iterate through
any hal instances so vendor-provided hals
can be loaded.

bug:34507158
Change-Id: I23bc4fdb2dc7d5254833c9a977241f1fede726a9
parent e1bd456c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ LOCAL_SHARED_LIBRARIES += \
    android.hidl.base@1.0 \
    android.hardware.drm@1.0 \
    libhidlbase \
    libhidlmemory
    libhidlmemory \
    libhidltransport
endif

LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
+48 −20
Original line number Diff line number Diff line
@@ -17,10 +17,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CryptoHal"
#include <utils/Log.h>
#include <dirent.h>
#include <dlfcn.h>

#include <android/hardware/drm/1.0/types.h>
#include <android/hidl/manager/1.0/IServiceManager.h>

#include <binder/IMemory.h>
#include <cutils/native_handle.h>
@@ -47,6 +46,7 @@ using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::sp;


@@ -101,31 +101,52 @@ static String8 toString8(hidl_string hString) {


CryptoHal::CryptoHal()
    : mFactory(makeCryptoFactory()),
      mInitCheck((mFactory == NULL) ? ERROR_UNSUPPORTED : NO_INIT),
    : mFactories(makeCryptoFactories()),
      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
      mNextBufferId(0) {
}

CryptoHal::~CryptoHal() {
}

Vector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
    Vector<sp<ICryptoFactory>> factories;

sp<ICryptoFactory> CryptoHal::makeCryptoFactory() {
    sp<ICryptoFactory> factory = ICryptoFactory::getService("crypto");
    if (factory == NULL) {
        ALOGE("Failed to make crypto factory");
    auto manager = ::IServiceManager::getService("manager");
    if (manager != NULL) {
        manager->listByInterface(ICryptoFactory::descriptor,
                [&factories](const hidl_vec<hidl_string> &registered) {
                    for (const auto &instance : registered) {
                        auto factory = ICryptoFactory::getService(instance);
                        if (factory != NULL) {
                            factories.push_back(factory);
                            ALOGI("makeCryptoFactories: factory instance %s is %s",
                                    instance.c_str(),
                                    factory->isRemote() ? "Remote" : "Not Remote");
                        }
    return factory;
                    }
                }
            );
    }

sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const uint8_t uuid[16],
        const void *initData, size_t initDataSize) {
    if (mFactory == NULL){
        return NULL;
    if (factories.size() == 0) {
        // must be in passthrough mode, load the default passthrough service
        auto passthrough = ICryptoFactory::getService("crypto");
        if (passthrough != NULL) {
            ALOGI("makeCryptoFactories: using default crypto instance");
            factories.push_back(passthrough);
        } else {
            ALOGE("Failed to find any crypto factories");
        }
    }
    return factories;
}

sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
        const uint8_t uuid[16], const void *initData, size_t initDataSize) {

    sp<ICryptoPlugin> plugin;
    Return<void> hResult = mFactory->createPlugin(toHidlArray16(uuid),
    Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
            toHidlVec(initData, initDataSize),
            [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
                if (status != Status::OK) {
@@ -146,17 +167,24 @@ status_t CryptoHal::initCheck() const {

bool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
    Mutex::Autolock autoLock(mLock);
    if (mFactory != NULL) {
        return mFactory->isCryptoSchemeSupported(uuid);

    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
            return true;
        }
    }
    return false;
}

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

    mPlugin = makeCryptoPlugin(uuid, data, size);
    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
            mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
        }
    }

    if (mPlugin == NULL) {
        mInitCheck = ERROR_UNSUPPORTED;
+62 −36
Original line number Diff line number Diff line
@@ -20,12 +20,11 @@

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <dirent.h>
#include <dlfcn.h>

#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/types.h>
#include <android/hidl/manager/1.0/IServiceManager.h>

#include <media/DrmHal.h>
#include <media/DrmSessionClientInterface.h>
@@ -52,6 +51,7 @@ using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::sp;

namespace android {
@@ -189,38 +189,56 @@ private:

DrmHal::DrmHal()
   : mDrmSessionClient(new DrmSessionClient(this)),
     mFactory(makeDrmFactory()),
     mInitCheck((mFactory == NULL) ? ERROR_UNSUPPORTED : NO_INIT) {
     mFactories(makeDrmFactories()),
     mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
}

DrmHal::~DrmHal() {
    DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
}

sp<IDrmFactory> DrmHal::makeDrmFactory() {
    sp<IDrmFactory> factory = IDrmFactory::getService("drm");
    if (factory == NULL) {
        ALOGE("Failed to make drm factory");
        return NULL;
    }
Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
    Vector<sp<IDrmFactory>> factories;

    ALOGD("makeDrmFactory: service is %s",
            factory->isRemote() ? "Remote" : "Not Remote");
    auto manager = ::IServiceManager::getService("manager");

    return factory;
    if (manager != NULL) {
        manager->listByInterface(IDrmFactory::descriptor,
                [&factories](const hidl_vec<hidl_string> &registered) {
                    for (const auto &instance : registered) {
                        auto factory = IDrmFactory::getService(instance);
                        if (factory != NULL) {
                            factories.push_back(factory);
                            ALOGI("makeDrmFactories: factory instance %s is %s",
                                    instance.c_str(),
                                    factory->isRemote() ? "Remote" : "Not Remote");
                        }
                    }
                }
            );
    }

sp<IDrmPlugin> DrmHal::makeDrmPlugin(const uint8_t uuid[16],
        const String8& appPackageName) {
    if (mFactory == NULL){
        return NULL;
    if (factories.size() == 0) {
        // must be in passthrough mode, load the default passthrough service
        auto passthrough = IDrmFactory::getService("drm");
        if (passthrough != NULL) {
            ALOGI("makeDrmFactories: using default drm instance");
            factories.push_back(passthrough);
        } else {
            ALOGE("Failed to find any drm factories");
        }
    }
    return factories;
}

sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
        const uint8_t uuid[16], const String8& appPackageName) {

    sp<IDrmPlugin> plugin;
    Return<void> hResult = mFactory->createPlugin(uuid, appPackageName.string(),
    Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
            [&](Status status, const sp<IDrmPlugin>& hPlugin) {
                if (status != Status::OK) {
        ALOGD("Failed to make drm plugin");
                    ALOGE("Failed to make drm plugin");
                    return;
                }
                plugin = hPlugin;
@@ -346,22 +364,30 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,

bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
    Mutex::Autolock autoLock(mLock);
    bool result = false;

    if (mFactory != NULL && mFactory->isCryptoSchemeSupported(uuid)) {
        result = true;
    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
            if (mimeType != "") {
            result = mFactory->isContentTypeSupported(mimeType.string());
                if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
                    return true;
                }
            } else {
                return true;
            }
        }
    }
    return result;
    return false;
}

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

    mPlugin = makeDrmPlugin(uuid, appPackageName);
    for (size_t i = 0; i < mFactories.size(); i++) {
        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
        }
    }

    if (mPlugin == NULL) {
        mInitCheck = ERROR_UNSUPPORTED;
+10 −11
Original line number Diff line number Diff line
@@ -20,11 +20,14 @@

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

#include <media/ICrypto.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>

#include "SharedLibrary.h"
using ::android::hardware::drm::V1_0::ICryptoFactory;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::drm::V1_0::SharedBuffer;

class IMemoryHeap;

@@ -60,9 +63,8 @@ struct CryptoHal : public BnCrypto {
private:
    mutable Mutex mLock;

    sp<SharedLibrary> mLibrary;
    sp<::android::hardware::drm::V1_0::ICryptoFactory> mFactory;
    sp<::android::hardware::drm::V1_0::ICryptoPlugin> mPlugin;
    const Vector<sp<ICryptoFactory>> mFactories;
    sp<ICryptoPlugin> mPlugin;

    /**
     * mInitCheck is:
@@ -75,16 +77,13 @@ private:
    KeyedVector<void *, uint32_t> mHeapBases;
    uint32_t mNextBufferId;

    sp<::android::hardware::drm::V1_0::ICryptoFactory>
            makeCryptoFactory();
    sp<::android::hardware::drm::V1_0::ICryptoPlugin>
            makeCryptoPlugin(const uint8_t uuid[16], const void *initData,
                size_t size);
    Vector<sp<ICryptoFactory>> makeCryptoFactories();
    sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory,
            const uint8_t uuid[16], const void *initData, size_t size);

    void setHeapBase(const sp<IMemoryHeap>& heap);

    status_t toSharedBuffer(const sp<IMemory>& memory,
            ::android::hardware::drm::V1_0::SharedBuffer* buffer);
    status_t toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer);

    DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
};
+5 −5
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ private:
    mutable Mutex mEventLock;
    mutable Mutex mNotifyLock;

    sp<IDrmFactory> mFactory;
    const Vector<sp<IDrmFactory>> mFactories;
    sp<IDrmPlugin> mPlugin;

    /**
@@ -169,9 +169,9 @@ private:
     */
    status_t mInitCheck;

    sp<IDrmFactory> makeDrmFactory();
    sp<IDrmPlugin> makeDrmPlugin(const uint8_t uuid[16],
                                 const String8 &appPackageName);
    Vector<sp<IDrmFactory>> makeDrmFactories();
    sp<IDrmPlugin> makeDrmPlugin(const sp<IDrmFactory>& factory,
            const uint8_t uuid[16], const String8& appPackageName);

    void writeByteArray(Parcel &obj, const hidl_vec<uint8_t>& array);