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

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

Add new offline management APIs to MediaDrm

bug:110838441
bug:117570956
bug:116252891

test:cts android.media.cts.MediaDrmClearkeyTest#testOfflineKeyManagement

Change-Id: I2ee86afbd1a0ae793454c2e81f3267aaf10bade7
parent 71fb1a8c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ cc_library {
        "libutils",
        "android.hardware.drm@1.0",
        "android.hardware.drm@1.1",
        "android.hardware.drm@1.2",
        "libhidlallocatorutils",
        "libhidlbase",
        "libhidltransport",
+105 −4
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>

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

@@ -43,12 +43,13 @@ using drm::V1_0::KeyedVector;
using drm::V1_0::KeyStatusType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
using drm::V1_1::HdcpLevel;;
using drm::V1_0::SecureStop;
using drm::V1_1::SecureStopRelease;
using drm::V1_0::SecureStopId;
using drm::V1_1::SecurityLevel;
using drm::V1_0::Status;
using drm::V1_1::HdcpLevel;
using drm::V1_1::SecureStopRelease;
using drm::V1_1::SecurityLevel;
using drm::V1_2::KeySetId;
using ::android::hardware::drm::V1_1::DrmMetricGroup;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
@@ -139,6 +140,18 @@ static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
    }
}

static DrmPlugin::OfflineLicenseState toOfflineLicenseState(
        OfflineLicenseState licenseState) {
    switch(licenseState) {
    case OfflineLicenseState::USABLE:
        return DrmPlugin::kOfflineLicenseStateUsable;
    case OfflineLicenseState::INACTIVE:
        return DrmPlugin::kOfflineLicenseStateInactive;
    default:
        return DrmPlugin::kOfflineLicenseStateUnknown;
    }
}

static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
    switch(level) {
    case HdcpLevel::HDCP_NONE:
@@ -199,6 +212,15 @@ static List<Vector<uint8_t>> toSecureStopIds(const hidl_vec<SecureStopId>&
    return secureStopIds;
}

static List<Vector<uint8_t>> toKeySetIds(const hidl_vec<KeySetId>&
        hKeySetIds) {
    List<Vector<uint8_t>> keySetIds;
    for (size_t i = 0; i < hKeySetIds.size(); i++) {
        keySetIds.push_back(toVector(hKeySetIds[i]));
    }
    return keySetIds;
}

static status_t toStatusT(Status status) {
    switch (status) {
    case Status::OK:
@@ -305,6 +327,7 @@ void DrmHal::cleanup() {
    }
    mPlugin.clear();
    mPluginV1_1.clear();
    mPluginV1_2.clear();
}

Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
@@ -333,6 +356,16 @@ Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
                    }
                }
            );
        manager->listByInterface(drm::V1_2::IDrmFactory::descriptor,
                [&factories](const hidl_vec<hidl_string> &registered) {
                    for (const auto &instance : registered) {
                        auto factory = drm::V1_2::IDrmFactory::getService(instance);
                        if (factory != NULL) {
                            factories.push_back(factory);
                        }
                    }
                }
            );
    }

    if (factories.size() == 0) {
@@ -525,6 +558,7 @@ status_t DrmHal::createPlugin(const uint8_t uuid[16],
            mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
            if (mPlugin != NULL) {
                mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
                mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
            }
        }
    }
@@ -1063,6 +1097,73 @@ status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
    return hResult.isOk() ? err : DEAD_OBJECT;
}

status_t DrmHal::getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const {
    Mutex::Autolock autoLock(mLock);

    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mPluginV1_2 == NULL) {
        return ERROR_DRM_CANNOT_HANDLE;
    }

    status_t err = UNKNOWN_ERROR;

    Return<void> hResult = mPluginV1_2->getOfflineLicenseKeySetIds(
            [&](Status status, const hidl_vec<KeySetId>& hKeySetIds) {
                if (status == Status::OK) {
                    keySetIds = toKeySetIds(hKeySetIds);
                }
                err = toStatusT(status);
            }
    );

    return hResult.isOk() ? err : DEAD_OBJECT;
}

status_t DrmHal::removeOfflineLicense(Vector<uint8_t> const &keySetId) {
    Mutex::Autolock autoLock(mLock);

    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mPluginV1_2 == NULL) {
        return ERROR_DRM_CANNOT_HANDLE;
    }

    Return<Status> status = mPluginV1_2->removeOfflineLicense(toHidlVec(keySetId));
    return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
}

status_t DrmHal::getOfflineLicenseState(Vector<uint8_t> const &keySetId,
        DrmPlugin::OfflineLicenseState *licenseState) const {
    Mutex::Autolock autoLock(mLock);

    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mPluginV1_2 == NULL) {
        return ERROR_DRM_CANNOT_HANDLE;
    }
    *licenseState = DrmPlugin::kOfflineLicenseStateUnknown;

    status_t err = UNKNOWN_ERROR;

    Return<void> hResult = mPluginV1_2->getOfflineLicenseState(toHidlVec(keySetId),
            [&](Status status, OfflineLicenseState hLicenseState) {
                if (status == Status::OK) {
                    *licenseState = toOfflineLicenseState(hLicenseState);
                }
                err = toStatusT(status);
            }
    );

    return hResult.isOk() ? err : DEAD_OBJECT;
}

status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
    Mutex::Autolock autoLock(mLock);
    return getPropertyStringInternal(name, value);
+89 −1
Original line number Diff line number Diff line
@@ -61,7 +61,10 @@ enum {
    GET_NUMBER_OF_SESSIONS,
    GET_SECURITY_LEVEL,
    REMOVE_SECURE_STOP,
    GET_SECURE_STOP_IDS
    GET_SECURE_STOP_IDS,
    GET_OFFLINE_LICENSE_KEYSET_IDS,
    REMOVE_OFFLINE_LICENSE,
    GET_OFFLINE_LICENSE_STATE
};

struct BpDrm : public BpInterface<IDrm> {
@@ -376,6 +379,52 @@ struct BpDrm : public BpInterface<IDrm> {
        return reply.readInt32();
    }

    virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t> > &keySetIds) const {
        Parcel data, reply;
        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());

        status_t status = remote()->transact(GET_OFFLINE_LICENSE_KEYSET_IDS, data, &reply);
        if (status != OK) {
            return status;
        }

        keySetIds.clear();
        uint32_t count = reply.readInt32();
        for (size_t i = 0; i < count; i++) {
            Vector<uint8_t> keySetId;
            readVector(reply, keySetId);
            keySetIds.push_back(keySetId);
        }
        return reply.readInt32();
    }

    virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId) {
        Parcel data, reply;
        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());

        writeVector(data, keySetId);
        status_t status = remote()->transact(REMOVE_OFFLINE_LICENSE, data, &reply);
        if (status != OK) {
            return status;
        }
        return reply.readInt32();
    }

    virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
            DrmPlugin::OfflineLicenseState *licenseState) const {
        Parcel data, reply;
        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());

        writeVector(data, keySetId);
        status_t status = remote()->transact(GET_OFFLINE_LICENSE_STATE, data, &reply);
        if (status != OK) {
            *licenseState = DrmPlugin::OfflineLicenseState::kOfflineLicenseStateUnknown;
            return status;
        }
        *licenseState = static_cast<DrmPlugin::OfflineLicenseState>(reply.readInt32());
        return reply.readInt32();
    }

    virtual status_t getPropertyString(String8 const &name, String8 &value) const {
        Parcel data, reply;
        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -980,6 +1029,45 @@ status_t BnDrm::onTransact(
            return OK;
        }

        case GET_OFFLINE_LICENSE_KEYSET_IDS:
        {
            CHECK_INTERFACE(IDrm, data, reply);
            List<Vector<uint8_t> > keySetIds;
            status_t result = getOfflineLicenseKeySetIds(keySetIds);
            size_t count = keySetIds.size();
            reply->writeInt32(count);
            List<Vector<uint8_t> >::iterator iter = keySetIds.begin();
            while(iter != keySetIds.end()) {
                size_t size = iter->size();
                reply->writeInt32(size);
                reply->write(iter->array(), iter->size());
                iter++;
            }
            reply->writeInt32(result);
            return OK;
        }

        case REMOVE_OFFLINE_LICENSE:
        {
            CHECK_INTERFACE(IDrm, data, reply);
            Vector<uint8_t> keySetId;
            readVector(data, keySetId);
            reply->writeInt32(removeOfflineLicense(keySetId));
            return OK;
        }

        case GET_OFFLINE_LICENSE_STATE:
        {
            CHECK_INTERFACE(IDrm, data, reply);
            Vector<uint8_t> keySetId;
            readVector(data, keySetId);
            DrmPlugin::OfflineLicenseState state;
            status_t result = getOfflineLicenseState(keySetId, &state);
            reply->writeInt32(static_cast<DrmPlugin::OfflineLicenseState>(state));
            reply->writeInt32(result);
            return OK;
        }

        case GET_PROPERTY_STRING:
        {
            CHECK_INTERFACE(IDrm, data, reply);
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ cc_test {
    shared_libs: [
      "android.hardware.drm@1.0",
      "android.hardware.drm@1.1",
      "android.hardware.drm@1.2",
      "libbinder",
      "libhidlbase",
      "liblog",
+9 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>

#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@@ -36,6 +38,7 @@ using drm::V1_0::IDrmFactory;
using drm::V1_0::IDrmPlugin;
using drm::V1_0::IDrmPluginListener;
using drm::V1_0::KeyStatus;
using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
@@ -113,6 +116,11 @@ struct DrmHal : public BnDrm,
    virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
            DrmPlugin::SecurityLevel *level) const;

    virtual status_t getOfflineLicenseKeySetIds(List<Vector<uint8_t>> &keySetIds) const;
    virtual status_t removeOfflineLicense(Vector<uint8_t> const &keySetId);
    virtual status_t getOfflineLicenseState(Vector<uint8_t> const &keySetId,
            DrmPlugin::OfflineLicenseState *licenseState) const;

    virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
    virtual status_t getPropertyByteArray(String8 const &name,
                                          Vector<uint8_t> &value ) const;
@@ -182,6 +190,7 @@ private:
    const Vector<sp<IDrmFactory>> mFactories;
    sp<IDrmPlugin> mPlugin;
    sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
    sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
    String8 mAppPackageName;

    // Mutable to allow modification within GetPropertyByteArray.
Loading