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/TunerService.cpp b/services/tuner/TunerService.cpp
index fe5d4ca..36e4cd1 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -25,8 +25,12 @@
#include <aidl/android/hardware/tv/tuner/ILnb.h>
#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 <string>
+
#include "TunerDemux.h"
#include "TunerDescrambler.h"
#include "TunerFrontend.h"
@@ -37,6 +41,8 @@
using ::aidl::android::hardware::tv::tuner::IDescrambler;
using ::aidl::android::hardware::tv::tuner::IFrontend;
using ::aidl::android::hardware::tv::tuner::Result;
+using ::android::IPCThreadState;
+using ::android::PermissionCache;
using ::android::sp;
namespace aidl {
@@ -45,6 +51,8 @@
namespace tv {
namespace tuner {
+shared_ptr<TunerService> TunerService::sTunerService = nullptr;
+
TunerService::TunerService() {
if (!TunerHelper::checkTunerFeature()) {
ALOGD("Device doesn't have tuner hardware.");
@@ -57,9 +65,12 @@
TunerService::~TunerService() {}
binder_status_t TunerService::instantiate() {
- shared_ptr<TunerService> service =
- ::ndk::SharedRefBase::make<TunerService>();
- return AServiceManager_addService(service->asBinder().get(), getServiceName());
+ sTunerService = ::ndk::SharedRefBase::make<TunerService>();
+ return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
+}
+
+shared_ptr<TunerService> TunerService::getTunerService() {
+ return sTunerService;
}
bool TunerService::hasITuner() {
@@ -210,6 +221,61 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus TunerService::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<TunerFilter> 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 TunerService::addFilterToShared(const shared_ptr<TunerFilter>& 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 TunerService::removeSharedFilter(const shared_ptr<TunerFilter>& sharedFilter) {
+ Mutex::Autolock _l(mSharedFiltersLock);
+
+ // Use sharedFilter address as token.
+ mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
+}
+
void TunerService::updateTunerResources() {
if (!hasITuner()) {
ALOGE("Failed to updateTunerResources");