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/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 8a08a7b..40077f9 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -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 @@
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 @@
default:
return Void();
}
- listener->notify(eventType, 0, &obj);
+ listener->sendEvent(eventType, sessionId, data);
}
return Void();
}
@@ -534,12 +532,8 @@
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_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 @@
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 @@
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 @@
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"));
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);
}
}
diff --git a/drm/libmediadrm/include/mediadrm/IDrmClient.h b/drm/libmediadrm/include/mediadrm/IDrmClient.h
index 3b2fc7c..f8f2b25 100644
--- a/drm/libmediadrm/include/mediadrm/IDrmClient.h
+++ b/drm/libmediadrm/include/mediadrm/IDrmClient.h
@@ -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;
+
};
// ----------------------------------------------------------------------------
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 2cd3e6d..a5bc09b 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -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<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