blob: cfcf4750e25c52744d0d45940c176ea354f96a2e [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "DrmHalListener"
#include <mediadrm/DrmHalListener.h>
using ::aidl::android::hardware::drm::KeyStatusType;
using ::android::hardware::hidl_vec;
namespace android {
static const Vector<uint8_t> toVector(const std::vector<uint8_t>& vec) {
Vector<uint8_t> vector;
vector.appendArray(vec.data(), vec.size());
return *const_cast<const Vector<uint8_t>*>(&vector);
}
template <typename T = uint8_t>
static hidl_vec<T> toHidlVec(const Vector<T>& vector) {
hidl_vec<T> vec;
vec.setToExternal(const_cast<T*>(vector.array()), vector.size());
return vec;
}
DrmHalListener::DrmHalListener(MediaDrmMetrics* metrics)
: mMetrics(metrics) {}
DrmHalListener::~DrmHalListener() {}
void DrmHalListener::setListener(sp<IDrmClient> listener) {
Mutex::Autolock lock(mEventLock);
mListener = listener;
}
::ndk::ScopedAStatus DrmHalListener::onEvent(EventTypeAidl eventTypeAidl,
const std::vector<uint8_t>& sessionId,
const std::vector<uint8_t>& data) {
mMetrics->mEventCounter.Increment((uint32_t)eventTypeAidl);
mEventLock.lock();
sp<IDrmClient> listener = mListener;
mEventLock.unlock();
if (listener != NULL) {
Mutex::Autolock lock(mNotifyLock);
DrmPlugin::EventType eventType;
switch (eventTypeAidl) {
case EventTypeAidl::PROVISION_REQUIRED:
eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
break;
case EventTypeAidl::KEY_NEEDED:
eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
break;
case EventTypeAidl::KEY_EXPIRED:
eventType = DrmPlugin::kDrmPluginEventKeyExpired;
break;
case EventTypeAidl::VENDOR_DEFINED:
eventType = DrmPlugin::kDrmPluginEventVendorDefined;
break;
case EventTypeAidl::SESSION_RECLAIMED:
eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
break;
default:
return ::ndk::ScopedAStatus::ok();
}
listener->sendEvent(eventType, toHidlVec(toVector(sessionId)), toHidlVec(toVector(data)));
}
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus DrmHalListener::onExpirationUpdate(const std::vector<uint8_t>& sessionId,
int64_t expiryTimeInMS) {
mEventLock.lock();
sp<IDrmClient> listener = mListener;
mEventLock.unlock();
if (listener != NULL) {
Mutex::Autolock lock(mNotifyLock);
listener->sendExpirationUpdate(toHidlVec(toVector(sessionId)), expiryTimeInMS);
}
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus DrmHalListener::onKeysChange(const std::vector<uint8_t>& sessionId,
const std::vector<KeyStatusAidl>& keyStatusListAidl,
bool hasNewUsableKey) {
mEventLock.lock();
sp<IDrmClient> listener = mListener;
mEventLock.unlock();
if (listener != NULL) {
std::vector<DrmKeyStatus> keyStatusList;
size_t nKeys = keyStatusListAidl.size();
for (size_t i = 0; i < nKeys; ++i) {
const KeyStatusAidl keyStatus = keyStatusListAidl[i];
uint32_t type;
switch (keyStatus.type) {
case KeyStatusType::USABLE:
type = DrmPlugin::kKeyStatusType_Usable;
break;
case KeyStatusType::EXPIRED:
type = DrmPlugin::kKeyStatusType_Expired;
break;
case KeyStatusType::OUTPUT_NOT_ALLOWED:
type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
break;
case KeyStatusType::STATUS_PENDING:
type = DrmPlugin::kKeyStatusType_StatusPending;
break;
case KeyStatusType::USABLE_IN_FUTURE:
type = DrmPlugin::kKeyStatusType_UsableInFuture;
break;
case KeyStatusType::INTERNAL_ERROR:
default:
type = DrmPlugin::kKeyStatusType_InternalError;
break;
}
keyStatusList.push_back({type, toHidlVec(toVector(keyStatus.keyId))});
mMetrics->mKeyStatusChangeCounter.Increment((uint32_t)keyStatus.type);
}
Mutex::Autolock lock(mNotifyLock);
listener->sendKeysChange(toHidlVec(toVector(sessionId)), keyStatusList, hasNewUsableKey);
}
else {
// There's no listener. But we still want to count the key change
// events.
size_t nKeys = keyStatusListAidl.size();
for (size_t i = 0; i < nKeys; i++) {
mMetrics->mKeyStatusChangeCounter.Increment((uint32_t)keyStatusListAidl[i].type);
}
}
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus DrmHalListener::onSessionLostState(const std::vector<uint8_t>& sessionId) {
::ndk::ScopedAStatus _aidl_status;
mEventLock.lock();
sp<IDrmClient> listener = mListener;
mEventLock.unlock();
if (listener != NULL) {
Mutex::Autolock lock(mNotifyLock);
listener->sendSessionLostState(toHidlVec(toVector(sessionId)));
}
return ::ndk::ScopedAStatus::ok();
}
} // namespace android