IDrmClient: remove Parcel from interface
This is part of the effort to remove binder-related classes from libmediadrm.
This change replaces a generic listener for Parcel data with separate
listeners for each event type.
Bug: 134787536
Test: MediaDrmClearkeyTest
Test: NativeMediaDrmClearkeyTest
Test: MediaDrmMockTest
Change-Id: I90cbb75b21cc63737994a01a2171caee5cfb84ad
diff --git a/drm/libmediadrm/IDrmClient.cpp b/drm/libmediadrm/IDrmClient.cpp
index 357de9d..2e05093 100644
--- a/drm/libmediadrm/IDrmClient.cpp
+++ b/drm/libmediadrm/IDrmClient.cpp
@@ -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)
{
- 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());
- }
- remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
+ 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)
+ {
+ auto fillParcel = [&] (Parcel &p) {
+ DrmUtils::WriteKeysChange(p, sessionId, keyStatusList, hasNewUsableKey);
+ };
+ notify(SEND_KEYS_CHANGE, fillParcel);
+ }
+
+ 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 @@
// ----------------------------------------------------------------------
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);
}
}