Add SharedFilter to tuner service.
Bug: 196124225
Test: atest android.media.tv.tuner.cts on both AIDL and HIDL HAL.
Change-Id: I91b1f9ef09b0bda868b7817be4d946d11629b16c
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index 9d9bc7e..8d4053a 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -21,6 +21,8 @@
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <android/binder_manager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
#include <utils/Log.h>
#include "TunerHelper.h"
@@ -43,6 +45,8 @@
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::Result;
using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
+using ::android::IPCThreadState;
+using ::android::PermissionCache;
using ::android::hardware::hidl_vec;
using HidlFrontendId = ::android::hardware::tv::tuner::V1_0::FrontendId;
@@ -57,6 +61,8 @@
namespace tv {
namespace tuner {
+shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
+
TunerHidlService::TunerHidlService() {
if (!TunerHelper::checkTunerFeature()) {
ALOGD("Device doesn't have tuner hardware.");
@@ -74,8 +80,12 @@
return STATUS_NAME_NOT_FOUND;
}
- shared_ptr<TunerHidlService> service = ::ndk::SharedRefBase::make<TunerHidlService>();
- return AServiceManager_addService(service->asBinder().get(), getServiceName());
+ sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
+ return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
+}
+
+shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
+ return sTunerService;
}
bool TunerHidlService::hasITuner() {
@@ -304,6 +314,62 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
+ const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
+ shared_ptr<ITunerFilter>* _aidl_return) {
+ if (!hasITuner()) {
+ ALOGE("get ITuner failed");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
+ ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Mutex::Autolock _l(mSharedFiltersLock);
+ if (mSharedFilters.find(in_filterToken) == mSharedFilters.end()) {
+ *_aidl_return = nullptr;
+ ALOGD("fail to find %s", in_filterToken.c_str());
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
+ shared_ptr<TunerHidlFilter> filter = mSharedFilters.at(in_filterToken);
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ if (!filter->isSharedFilterAllowed(pid)) {
+ *_aidl_return = nullptr;
+ ALOGD("shared filter %s is opened in the same process", in_filterToken.c_str());
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
+ filter->attachSharedFilterCallback(in_cb);
+
+ *_aidl_return = filter;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+string TunerHidlService::addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter) {
+ Mutex::Autolock _l(mSharedFiltersLock);
+
+ // Use sharedFilter address as token.
+ string token = to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get()));
+ mSharedFilters[token] = sharedFilter;
+
+ return token;
+}
+
+void TunerHidlService::removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter) {
+ Mutex::Autolock _l(mSharedFiltersLock);
+
+ // Use sharedFilter address as token.
+ mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
+}
+
void TunerHidlService::updateTunerResources() {
if (!hasITuner()) {
ALOGE("Failed to updateTunerResources");