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

Commit 9fb60eae authored by Robert Shih's avatar Robert Shih Committed by Android (Google) Code Review
Browse files

Merge "IDrmClient: remove Parcel from interface"

parents 517734d6 61e1c76c
Loading
Loading
Loading
Loading
+13 −36
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@
#include <mediadrm/DrmSessionClientInterface.h>
#include <mediadrm/DrmSessionManager.h>

#include <vector>

using drm::V1_0::KeyedVector;
using drm::V1_0::KeyRequestType;
using drm::V1_0::KeyType;
@@ -496,10 +498,6 @@ Return<void> DrmHal::sendEvent(EventType hEventType,
    mEventLock.unlock();

    if (listener != NULL) {
        Parcel obj;
        writeByteArray(obj, sessionId);
        writeByteArray(obj, data);

        Mutex::Autolock lock(mNotifyLock);
        DrmPlugin::EventType eventType;
        switch(hEventType) {
@@ -521,7 +519,7 @@ Return<void> DrmHal::sendEvent(EventType hEventType,
        default:
            return Void();
        }
        listener->notify(eventType, 0, &obj);
        listener->sendEvent(eventType, sessionId, data);
    }
    return Void();
}
@@ -534,12 +532,8 @@ Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
    mEventLock.unlock();

    if (listener != NULL) {
        Parcel obj;
        writeByteArray(obj, sessionId);
        obj.writeInt64(expiryTimeInMS);

        Mutex::Autolock lock(mNotifyLock);
        listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
        listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
    }
    return Void();
}
@@ -556,21 +550,17 @@ Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
}

Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
        const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
        const hidl_vec<KeyStatus>& hKeyStatusList, bool hasNewUsableKey) {

    mEventLock.lock();
    sp<IDrmClient> listener = mListener;
    mEventLock.unlock();

    if (listener != NULL) {
        Parcel obj;
        writeByteArray(obj, sessionId);

        size_t nKeys = keyStatusList.size();
        obj.writeInt32(nKeys);
        std::vector<DrmKeyStatus> keyStatusList;
        size_t nKeys = hKeyStatusList.size();
        for (size_t i = 0; i < nKeys; ++i) {
            const KeyStatus &keyStatus = keyStatusList[i];
            writeByteArray(obj, keyStatus.keyId);
            const KeyStatus &keyStatus = hKeyStatusList[i];
            uint32_t type;
            switch(keyStatus.type) {
            case KeyStatusType::USABLE:
@@ -593,19 +583,18 @@ Return<void> DrmHal::sendKeysChange_1_2(const hidl_vec<uint8_t>& sessionId,
                type = DrmPlugin::kKeyStatusType_InternalError;
                break;
            }
            obj.writeInt32(type);
            keyStatusList.push_back({type, keyStatus.keyId});
            mMetrics.mKeyStatusChangeCounter.Increment(keyStatus.type);
        }
        obj.writeInt32(hasNewUsableKey);

        Mutex::Autolock lock(mNotifyLock);
        listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
        listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
    } else {
        // There's no listener. But we still want to count the key change
        // events.
        size_t nKeys = keyStatusList.size();
        size_t nKeys = hKeyStatusList.size();
        for (size_t i = 0; i < nKeys; i++) {
            mMetrics.mKeyStatusChangeCounter.Increment(keyStatusList[i].type);
            mMetrics.mKeyStatusChangeCounter.Increment(hKeyStatusList[i].type);
        }
    }

@@ -620,10 +609,8 @@ Return<void> DrmHal::sendSessionLostState(
    mEventLock.unlock();

    if (listener != NULL) {
        Parcel obj;
        writeByteArray(obj, sessionId);
        Mutex::Autolock lock(mNotifyLock);
        listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
        listener->sendSessionLostState(sessionId);
    }
    return Void();
}
@@ -1585,16 +1572,6 @@ void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
    cleanup();
}

void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
{
    if (vec.size()) {
        obj.writeInt32(vec.size());
        obj.write(vec.data(), vec.size());
    } else {
        obj.writeInt32(0);
    }
}

void DrmHal::reportFrameworkMetrics() const
{
    std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
+122 −22
Original line number Diff line number Diff line
@@ -17,39 +17,104 @@

//#define LOG_NDEBUG 0
#define LOG_TAG "IDrmClient"
#include <utils/Log.h>

#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <hidl/HidlSupport.h>

#include <media/IMediaPlayerClient.h>
#include <mediadrm/DrmUtils.h>
#include <mediadrm/IDrmClient.h>

#include <cstddef>
#include <cstdint>
#include <vector>

namespace android {

enum {
    NOTIFY = IBinder::FIRST_CALL_TRANSACTION,
    SEND_EVENT = IBinder::FIRST_CALL_TRANSACTION,
    SEND_EXPIRATION_UPDATE,
    SEND_KEYS_CHANGE,
    SEND_SESSION_LOST_STATE,
};

namespace {

hardware::hidl_vec<uint8_t> ReadByteArray(const Parcel &obj, status_t *err)
{
    int32_t len = obj.readInt32();
    hardware::hidl_vec<uint8_t> ret;
    if (len < 0) {
        ALOGE("Invalid array len");
        *err = BAD_VALUE;
        return ret;
    }
    ret.resize(static_cast<size_t>(len));
    *err = obj.read(ret.data(), ret.size());
    return ret;
}

}

class BpDrmClient: public BpInterface<IDrmClient>
{
    template <typename F>
    void notify(uint32_t code, F fillParcel) {
        Parcel obj, reply;
        obj.writeInterfaceToken(IDrmClient::getInterfaceDescriptor());
        fillParcel(obj);
        remote()->transact(code, obj, &reply, IBinder::FLAG_ONEWAY);
    }

public:
    explicit BpDrmClient(const sp<IBinder>& impl)
        : BpInterface<IDrmClient>(impl)
    {
    }

    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj)
    virtual void sendEvent(
            DrmPlugin::EventType eventType,
            const hardware::hidl_vec<uint8_t> &sessionId,
            const hardware::hidl_vec<uint8_t> &data)
    {
        auto fillParcel = [&] (Parcel &p) {
            DrmUtils::WriteEventToParcel(p, eventType, sessionId, data);
        };
        notify(SEND_EVENT, fillParcel);
    }

    virtual void sendExpirationUpdate(
            const hardware::hidl_vec<uint8_t> &sessionId,
            int64_t expiryTimeInMS)
    {
        auto fillParcel = [&] (Parcel &p) {
            DrmUtils::WriteExpirationUpdateToParcel(p, sessionId, expiryTimeInMS);
        };
        notify(SEND_EXPIRATION_UPDATE, fillParcel);
    }

    virtual void sendKeysChange(
            const hardware::hidl_vec<uint8_t> &sessionId,
            const std::vector<DrmKeyStatus> &keyStatusList,
            bool hasNewUsableKey)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IDrmClient::getInterfaceDescriptor());
        data.writeInt32((int)eventType);
        data.writeInt32(extra);
        if (obj && obj->dataSize() > 0) {
            data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize());
        auto fillParcel = [&] (Parcel &p) {
            DrmUtils::WriteKeysChange(p, sessionId, keyStatusList, hasNewUsableKey);
        };
        notify(SEND_KEYS_CHANGE, fillParcel);
    }
        remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);

    virtual void sendSessionLostState(
            const hardware::hidl_vec<uint8_t> &sessionId)
    {
        auto fillParcel = [&] (Parcel &p) {
            DrmUtils::WriteByteArray(p, sessionId);
        };
        notify(SEND_SESSION_LOST_STATE, fillParcel);
    }
};

@@ -58,23 +123,58 @@ IMPLEMENT_META_INTERFACE(DrmClient, "android.media.IDrmClient");
// ----------------------------------------------------------------------

status_t BnDrmClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    uint32_t code, const Parcel& obj, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case NOTIFY: {
            CHECK_INTERFACE(IDrmClient, data, reply);
            int eventType = data.readInt32();
            int extra = data.readInt32();
            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
    CHECK_INTERFACE(IDrmClient, obj, reply);
    status_t err = NO_ERROR;
    hardware::hidl_vec<uint8_t> sessionId(ReadByteArray(obj, &err));
    if (err != NO_ERROR) {
        ALOGE("Failed to read session id, error=%d", err);
        return err;
    }

            notify((DrmPlugin::EventType)eventType, extra, &obj);
    switch (code) {
        case SEND_EVENT: {
            hardware::hidl_vec<uint8_t> data(ReadByteArray(obj, &err));
            int eventType = obj.readInt32();
            if (err == NO_ERROR) {
                sendEvent(static_cast<DrmPlugin::EventType>(eventType), sessionId, data);
            }
            return err;
        } break;
        case SEND_EXPIRATION_UPDATE: {
            int64_t expiryTimeInMS = obj.readInt64();
            sendExpirationUpdate(sessionId, expiryTimeInMS);
            return NO_ERROR;
        } break;
        case SEND_KEYS_CHANGE: {
            // ...
            int32_t n = obj.readInt32();
            if (n < 0) {
                return BAD_VALUE;
            }
            std::vector<DrmKeyStatus> keyStatusList;
            for (int32_t i = 0; i < n; ++i) {
                hardware::hidl_vec<uint8_t> keyId(ReadByteArray(obj, &err));
                if (err != NO_ERROR) {
                    return err;
                }
                int32_t type = obj.readInt32();
                if (type < 0) {
                    return BAD_VALUE;
                }
                keyStatusList.push_back({static_cast<uint32_t>(type), keyId});
            }
            int32_t hasNewUsableKey = obj.readInt32();
            sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
            return NO_ERROR;
        } break;
        case SEND_SESSION_LOST_STATE: {
            sendSessionLostState(sessionId);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
            return BBinder::onTransact(code, obj, reply, flags);
    }
}

+28 −1
Original line number Diff line number Diff line
@@ -22,14 +22,41 @@
#include <binder/Parcel.h>
#include <media/drm/DrmAPI.h>

#include <android/hardware/drm/1.2/types.h>
#include <hidl/HidlSupport.h>

#include <cstdint>
#include <vector>

namespace android {

struct DrmKeyStatus {
    const uint32_t type;
    const hardware::hidl_vec<uint8_t> keyId;
};

class IDrmClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(DrmClient);

    virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) = 0;
    virtual void sendEvent(
            DrmPlugin::EventType eventType,
            const hardware::hidl_vec<uint8_t> &sessionId,
            const hardware::hidl_vec<uint8_t> &data) = 0;

    virtual void sendExpirationUpdate(
            const hardware::hidl_vec<uint8_t> &sessionId,
            int64_t expiryTimeInMS) = 0;

    virtual void sendKeysChange(
            const hardware::hidl_vec<uint8_t> &sessionId,
            const std::vector<DrmKeyStatus> &keyStatusList,
            bool hasNewUsableKey) = 0;

    virtual void sendSessionLostState(
            const hardware::hidl_vec<uint8_t> &sessionId) = 0;

};

// ----------------------------------------------------------------------------
+44 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <utils/Errors.h>  // for status_t
#include <utils/StrongPointer.h>
#include <binder/Parcel.h>

namespace android {

@@ -33,6 +34,49 @@ sp<IDrm> MakeDrm(status_t *pstatus = nullptr);

sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);

template<typename BA>
void WriteByteArray(Parcel &obj, const BA &vec) {
    obj.writeInt32(vec.size());
    if (vec.size()) {
        obj.write(vec.data(), vec.size());
    }
}

template<typename ET, typename BA>
void WriteEventToParcel(
        Parcel &obj,
        ET eventType,
        const BA &sessionId,
        const BA &data) {
    WriteByteArray(obj, sessionId);
    WriteByteArray(obj, data);
    obj.writeInt32(eventType);
}

template<typename BA>
void WriteExpirationUpdateToParcel(
        Parcel &obj,
        const BA &sessionId,
        int64_t expiryTimeInMS) {
    WriteByteArray(obj, sessionId);
    obj.writeInt64(expiryTimeInMS);
}

template<typename BA, typename KSL>
void WriteKeysChange(
        Parcel &obj,
        const BA &sessionId,
        const KSL &keyStatusList,
        bool hasNewUsableKey) {
    WriteByteArray(obj, sessionId);
    obj.writeInt32(keyStatusList.size());
    for (const auto &keyStatus : keyStatusList) {
        WriteByteArray(obj, keyStatus.keyId);
        obj.writeInt32(keyStatus.type);
    }
    obj.writeInt32(hasNewUsableKey);
}

} // namespace DrmUtils

} // namespace android
+58 −68
Original line number Diff line number Diff line
@@ -72,12 +72,27 @@ public:
        mKeysChangeListener = listener;
    }

    void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj);
    void sendEvent(
            DrmPlugin::EventType eventType,
            const hardware::hidl_vec<uint8_t> &sessionId,
            const hardware::hidl_vec<uint8_t> &data) override;

    void sendExpirationUpdate(
            const hardware::hidl_vec<uint8_t> &sessionId,
            int64_t expiryTimeInMS) override;

    void sendKeysChange(
            const hardware::hidl_vec<uint8_t> &sessionId,
            const std::vector<DrmKeyStatus> &keyStatusList,
            bool hasNewUsableKey) override;

    void sendSessionLostState(
            const hardware::hidl_vec<uint8_t> &) override {}

};

struct AMediaDrm {
    sp<IDrm> mDrm;
    sp<IDrmClient> mDrmClient;
    List<idvec_t> mIds;
    KeyedVector<String8, String8> mQueryResults;
    Vector<uint8_t> mKeyRequest;
@@ -89,71 +104,52 @@ struct AMediaDrm {
    sp<DrmListener> mListener;
};

void DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) {
    if (!mEventListener || !mExpirationUpdateListener || !mKeysChangeListener) {
        ALOGE("No listeners are specified");
        return;
    }

    obj->setDataPosition(0);

    AMediaDrmSessionId sessionId = {NULL, 0};
    int32_t sessionIdSize = obj->readInt32();
    if (sessionIdSize <= 0) {
        ALOGE("Invalid session id size");
        return;
    }

    std::unique_ptr<uint8_t[]> sessionIdData(new uint8_t[sessionIdSize]);
    sessionId.ptr = sessionIdData.get();
    sessionId.length = sessionIdSize;
    status_t err = obj->read(sessionIdData.get(), sessionId.length);
    if (err != OK) {
        ALOGE("Failed to read session id, error=%d", err);
void DrmListener::sendExpirationUpdate(
        const hardware::hidl_vec<uint8_t> &sessionId,
        int64_t expiryTimeInMS) {
    if (!mExpirationUpdateListener) {
        ALOGE("No ExpirationUpdateListener specified");
        return;
    }

    if (DrmPlugin::kDrmPluginEventExpirationUpdate == eventType) {
        int64_t expiryTimeInMS = obj->readInt64();
    if (expiryTimeInMS >= 0) {
            (*mExpirationUpdateListener)(mObj, &sessionId, expiryTimeInMS);
        AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
        (*mExpirationUpdateListener)(mObj, &asid, expiryTimeInMS);
    } else {
            ALOGE("Failed to read expiry time, status=%" PRId64 "", expiryTimeInMS);
        ALOGE("expiry time negative, status=%" PRId64 "", expiryTimeInMS);
    }
        return;
    } else if (DrmPlugin::kDrmPluginEventKeysChange == eventType) {
        int32_t numKeys = 0;
        err = obj->readInt32(&numKeys);
        if (err != OK) {
            ALOGE("Failed to read number of keys status, error=%d", err);
}

void DrmListener::sendKeysChange(
        const hardware::hidl_vec<uint8_t> &sessionId,
        const std::vector<DrmKeyStatus> &keyStatusList,
        bool hasNewUsableKey) {
    if (!mKeysChangeListener) {
        ALOGE("No KeysChangeListener specified");
        return;
    }

    Vector<AMediaDrmKeyStatus> keysStatus;
        std::vector<std::unique_ptr<uint8_t[]> > dataPointers;
    for (const auto &drmKeyStatus : keyStatusList) {
        AMediaDrmKeyStatus keyStatus;
        keyStatus.keyId.ptr = drmKeyStatus.keyId.data();
        keyStatus.keyId.length = drmKeyStatus.keyId.size();
        keyStatus.keyType = static_cast<AMediaDrmKeyStatusType>(drmKeyStatus.type);
        keysStatus.push(keyStatus);
    }

        for (size_t i = 0; i < numKeys; ++i) {
            keyStatus.keyId.ptr = nullptr;
            keyStatus.keyId.length = 0;
            int32_t idSize = obj->readInt32();
            if (idSize > 0) {
                std::unique_ptr<uint8_t[]> data(new uint8_t[idSize]);
                err = obj->read(data.get(), idSize);
                if (err != OK) {
                    ALOGE("Failed to read key data, error=%d", err);
    AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
    int32_t numKeys = keyStatusList.size();
    (*mKeysChangeListener)(mObj, &asid, keysStatus.array(), numKeys, hasNewUsableKey);
    return;
}
                keyStatus.keyId.ptr = data.get();
                keyStatus.keyId.length = idSize;
                dataPointers.push_back(std::move(data));
            }
            keyStatus.keyType = static_cast<AMediaDrmKeyStatusType>(obj->readInt32());
            keysStatus.push(keyStatus);
        }

        bool hasNewUsableKey = obj->readInt32();
        (*mKeysChangeListener)(mObj, &sessionId, keysStatus.array(), numKeys, hasNewUsableKey);
void DrmListener::sendEvent(
        DrmPlugin::EventType eventType,
        const hardware::hidl_vec<uint8_t> &sessionId,
        const hardware::hidl_vec<uint8_t> &data) {
    if (!mEventListener) {
        ALOGE("No EventListener specified");
        return;
    }

@@ -177,23 +173,17 @@ void DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel
            ndkEventType = EVENT_SESSION_RECLAIMED;
            break;
        default:
            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", eventType);
            return;
    }

    int32_t dataSize = obj->readInt32();
    uint8_t *data = NULL;
    AMediaDrmSessionId asid = {sessionId.data(), sessionId.size()};
    int32_t dataSize = data.size();
    const uint8_t *dataPtr = data.data();
    if (dataSize > 0) {
        data = new uint8_t[dataSize];
        err = obj->read(data, dataSize);
        if (err == OK) {
            (*mEventListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
        } else {
            ALOGE("Failed to read event data, error=%d", err);
        }
        delete [] data;
        (*mEventListener)(mObj, &asid, ndkEventType, 0, dataPtr, dataSize);
    } else {
        ALOGE("Error reading parcel: invalid event data size=%d", dataSize);
        ALOGE("invalid event data size=%d", dataSize);
    }
}