summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hongguang <hgchen@google.com> 2022-08-10 13:17:41 -0700
committer Hongguang <hgchen@google.com> 2022-08-24 19:52:10 -0700
commit00ef56d886ae379518bd4a44f20973fa26db0eb0 (patch)
tree97c1ab5c7a21b1249e47dd17859ccbe1ad9310fa
parent8ce2b6ed0d0c005bdd7615c46ad212758c30c233 (diff)
Support lazy tuner HAL
The tuner server will register its resources to TunerResourceManager every time when it's started. The TunerResourceManager will update its resources accordingly. The TunerResourceManager is only be started when the device has tuner feature. All tuner functions should return error immediately if the devcie does't have TunerResourceManager. Release TunerClient if no one uses it. Stop using staitc TunerService to release tunerserver the because TunerClient is ready signleton. Disable lazy tunerserver if the device is running normal tuner HAL. Bug: 236002754 Test: atest android.media.tv.tuner.cts on both lazy and normal HALs Change-Id: I1fc3ca8413434701742cbe363b0ffd2d6dbf5f9c
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java13
-rw-r--r--media/jni/Android.bp2
-rw-r--r--media/jni/android_media_tv_Tuner.cpp64
-rw-r--r--media/jni/android_media_tv_Tuner.h3
-rw-r--r--media/jni/tuner/TunerClient.cpp7
-rw-r--r--media/jni/tuner/TunerClient.h7
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java10
7 files changed, 69 insertions, 37 deletions
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index bbb4d1fa76bc..b1c97300d08a 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -344,6 +344,16 @@ public class Tuner implements AutoCloseable {
@RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
public Tuner(@NonNull Context context, @Nullable String tvInputSessionId,
@TvInputService.PriorityHintUseCaseType int useCase) {
+ mContext = context;
+ mTunerResourceManager = mContext.getSystemService(TunerResourceManager.class);
+
+ // The Tuner Resource Manager is only started when the device has the tuner feature.
+ if (mTunerResourceManager == null) {
+ throw new IllegalStateException(
+ "Tuner instance is created, but the device doesn't have tuner feature");
+ }
+
+ // This code will start tuner server if the device is running on the lazy tuner HAL.
nativeSetup();
sTunerVersion = nativeGetTunerVersion();
if (sTunerVersion == TunerVersionChecker.TUNER_VERSION_UNKNOWN) {
@@ -353,9 +363,6 @@ public class Tuner implements AutoCloseable {
+ TunerVersionChecker.getMajorVersion(sTunerVersion) + "."
+ TunerVersionChecker.getMinorVersion(sTunerVersion) + ".");
}
- mContext = context;
- mTunerResourceManager = (TunerResourceManager)
- context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
if (mHandler == null) {
mHandler = createEventHandler();
}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index e3e200fcd754..96a3781af3a8 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -160,7 +160,7 @@ cc_library_shared {
cc_library_shared {
name: "libmedia_tv_tuner",
-
+ min_sdk_version: "",
srcs: [
"android_media_tv_Tuner.cpp",
"tuner/DemuxClient.cpp",
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 397c70485d5b..244730b76df2 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1238,7 +1238,8 @@ FrontendClientCallbackImpl::~FrontendClientCallbackImpl() {
}
/////////////// Tuner ///////////////////////
-sp<TunerClient> JTuner::mTunerClient;
+sp<TunerClient> JTuner::sTunerClient = nullptr;
+std::mutex JTuner::sTunerClientMutex;
JTuner::JTuner(JNIEnv *env, jobject thiz) : mClass(nullptr) {
jclass clazz = env->GetObjectClass(thiz);
@@ -1246,10 +1247,15 @@ JTuner::JTuner(JNIEnv *env, jobject thiz) : mClass(nullptr) {
mClass = (jclass)env->NewGlobalRef(clazz);
mObject = env->NewWeakGlobalRef(thiz);
- if (mTunerClient == nullptr) {
- mTunerClient = new TunerClient();
+ {
+ std::scoped_lock<std::mutex> lock(sTunerClientMutex);
+ if (sTunerClient == nullptr) {
+ sTunerClient = new TunerClient();
+ } else {
+ sTunerClient->incStrong(this);
+ }
+ ALOGV("JTuner refs count: %d", sTunerClient->getStrongCount());
}
-
mSharedFeId = (int)Constant::INVALID_FRONTEND_ID;
}
@@ -1271,18 +1277,28 @@ JTuner::~JTuner() {
mFeClient = nullptr;
mFeClientCb = nullptr;
mDemuxClient = nullptr;
+ {
+ std::scoped_lock<std::mutex> lock(sTunerClientMutex);
+ int32_t refCnt = sTunerClient->getStrongCount();
+ ALOGV("~JTuner refs count: %d", refCnt);
+ if (refCnt == 1) {
+ sTunerClient = nullptr;
+ } else {
+ sTunerClient->decStrong(this);
+ }
+ }
mClass = nullptr;
mObject = nullptr;
}
jint JTuner::getTunerVersion() {
ALOGV("JTuner::getTunerVersion()");
- return (jint)mTunerClient->getHalTunerVersion();
+ return (jint)sTunerClient->getHalTunerVersion();
}
jobject JTuner::getFrontendIds() {
ALOGV("JTuner::getFrontendIds()");
- vector<int32_t> ids = mTunerClient->getFrontendIds();
+ vector<int32_t> ids = sTunerClient->getFrontendIds();
if (ids.size() == 0) {
ALOGW("Frontend isn't available");
return nullptr;
@@ -1305,7 +1321,7 @@ jobject JTuner::getFrontendIds() {
jobject JTuner::openFrontendByHandle(int feHandle) {
// TODO: Handle reopening frontend with different handle
- sp<FrontendClient> feClient = mTunerClient->openFrontend(feHandle);
+ sp<FrontendClient> feClient = sTunerClient->openFrontend(feHandle);
if (feClient == nullptr) {
ALOGE("Failed to open frontend");
return nullptr;
@@ -1511,7 +1527,7 @@ jobject JTuner::getDtmbFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) {
jobject JTuner::getFrontendInfo(int id) {
shared_ptr<FrontendInfo> feInfo;
- feInfo = mTunerClient->getFrontendInfo(id);
+ feInfo = sTunerClient->getFrontendInfo(id);
if (feInfo == nullptr) {
return nullptr;
}
@@ -1605,21 +1621,21 @@ Result JTuner::getFrontendHardwareInfo(string &info) {
}
jint JTuner::setMaxNumberOfFrontends(int32_t type, int32_t maxNumber) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
ALOGE("tuner is not initialized");
return (jint)Result::INVALID_STATE;
}
- return (jint)mTunerClient->setMaxNumberOfFrontends(static_cast<FrontendType>(type), maxNumber);
+ return (jint)sTunerClient->setMaxNumberOfFrontends(static_cast<FrontendType>(type), maxNumber);
}
int32_t JTuner::getMaxNumberOfFrontends(int32_t type) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
ALOGE("tuner is not initialized");
return -1;
}
- return mTunerClient->getMaxNumberOfFrontends(static_cast<FrontendType>(type));
+ return sTunerClient->getMaxNumberOfFrontends(static_cast<FrontendType>(type));
}
jint JTuner::removeOutputPid(int32_t pid) {
@@ -1662,13 +1678,13 @@ jobjectArray JTuner::getFrontendStatusReadiness(jintArray types) {
}
jobject JTuner::openLnbByHandle(int handle) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
return nullptr;
}
sp<LnbClient> lnbClient;
sp<LnbClientCallbackImpl> callback = new LnbClientCallbackImpl();
- lnbClient = mTunerClient->openLnb(handle);
+ lnbClient = sTunerClient->openLnb(handle);
if (lnbClient == nullptr) {
ALOGD("Failed to open lnb, handle = %d", handle);
return nullptr;
@@ -1692,7 +1708,7 @@ jobject JTuner::openLnbByHandle(int handle) {
}
jobject JTuner::openLnbByName(jstring name) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
return nullptr;
}
@@ -1700,7 +1716,7 @@ jobject JTuner::openLnbByName(jstring name) {
std::string lnbName(env->GetStringUTFChars(name, nullptr));
sp<LnbClient> lnbClient;
sp<LnbClientCallbackImpl> callback = new LnbClientCallbackImpl();
- lnbClient = mTunerClient->openLnbByName(lnbName);
+ lnbClient = sTunerClient->openLnbByName(lnbName);
if (lnbClient == nullptr) {
ALOGD("Failed to open lnb by name, name = %s", lnbName.c_str());
return nullptr;
@@ -1770,20 +1786,20 @@ int JTuner::setLnb(sp<LnbClient> lnbClient) {
}
int JTuner::setLna(bool enable) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
return (int)Result::NOT_INITIALIZED;
}
- Result result = mTunerClient->setLna(enable);
+ Result result = sTunerClient->setLna(enable);
return (int)result;
}
Result JTuner::openDemux(int handle) {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
return Result::NOT_INITIALIZED;
}
if (mDemuxClient == nullptr) {
- mDemuxClient = mTunerClient->openDemux(handle);
+ mDemuxClient = sTunerClient->openDemux(handle);
if (mDemuxClient == nullptr) {
ALOGE("Failed to open demux");
return Result::UNKNOWN_ERROR;
@@ -1881,10 +1897,10 @@ int JTuner::unlinkCiCam(int id) {
jobject JTuner::openDescrambler() {
ALOGV("JTuner::openDescrambler");
- if (mTunerClient == nullptr || mDemuxClient == nullptr) {
+ if (sTunerClient == nullptr || mDemuxClient == nullptr) {
return nullptr;
}
- sp<DescramblerClient> descramblerClient = mTunerClient->openDescrambler(0/*unused*/);
+ sp<DescramblerClient> descramblerClient = sTunerClient->openDescrambler(0 /*unused*/);
if (descramblerClient == nullptr) {
ALOGD("Failed to open descrambler");
@@ -1995,12 +2011,12 @@ jobject JTuner::openDvr(DvrType type, jlong bufferSize) {
}
jobject JTuner::getDemuxCaps() {
- if (mTunerClient == nullptr) {
+ if (sTunerClient == nullptr) {
return nullptr;
}
shared_ptr<DemuxCapabilities> caps;
- caps = mTunerClient->getDemuxCaps();
+ caps = sTunerClient->getDemuxCaps();
if (caps == nullptr) {
return nullptr;
}
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 03e7fa91653d..c74b2df6c178 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -216,7 +216,8 @@ protected:
private:
jclass mClass;
jweak mObject;
- static sp<TunerClient> mTunerClient;
+ static sp<TunerClient> sTunerClient;
+ static std::mutex sTunerClientMutex;
sp<FrontendClient> mFeClient;
sp<FrontendClientCallbackImpl> mFeClientCb;
int mFeId;
diff --git a/media/jni/tuner/TunerClient.cpp b/media/jni/tuner/TunerClient.cpp
index 3c8fdfe682af..8515874c022f 100644
--- a/media/jni/tuner/TunerClient.cpp
+++ b/media/jni/tuner/TunerClient.cpp
@@ -27,16 +27,13 @@ using ::aidl::android::hardware::tv::tuner::FrontendType;
namespace android {
-shared_ptr<ITunerService> TunerClient::mTunerService;
int32_t TunerClient::mTunerVersion;
/////////////// TunerClient ///////////////////////
TunerClient::TunerClient() {
- if (mTunerService == nullptr) {
- ::ndk::SpAIBinder binder(AServiceManager_getService("media.tuner"));
- mTunerService = ITunerService::fromBinder(binder);
- }
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.tuner"));
+ mTunerService = ITunerService::fromBinder(binder);
if (mTunerService == nullptr) {
ALOGE("Failed to get tuner service");
} else {
diff --git a/media/jni/tuner/TunerClient.h b/media/jni/tuner/TunerClient.h
index a9f37e6df3aa..5410c1b185f5 100644
--- a/media/jni/tuner/TunerClient.h
+++ b/media/jni/tuner/TunerClient.h
@@ -150,10 +150,11 @@ public:
private:
/**
- * An AIDL Tuner Service Singleton assigned at the first time the Tuner Client
- * connects with the Tuner Service. Default null when the service does not exist.
+ * An AIDL Tuner Service assigned at the first time the Tuner Client connects with
+ * the Tuner Service. null when the service does not exist. The tuner client in JNI
+ * will be singleton, so this Tuner Service client will be singleton too.
*/
- static shared_ptr<ITunerService> mTunerService;
+ shared_ptr<ITunerService> mTunerService;
// An integer that carries the Tuner version. The high 16 bits are the major version number
// while the low 16 bits are the minor version. Default value is unknown version 0.
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 6162d716b85e..edd1ef36deda 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -39,6 +39,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
@@ -141,6 +142,15 @@ public class TunerResourceManagerService extends SystemService implements IBinde
(ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
mPriorityCongfig.parse();
+ // Call SystemProperties.set() in mock app will throw exception because of permission.
+ if (!isForTesting) {
+ final boolean lazyHal = SystemProperties.getBoolean("ro.tuner.lazyhal", false);
+ if (!lazyHal) {
+ // The HAL is not a lazy HAL, enable the tuner server.
+ SystemProperties.set("tuner.server.enable", "true");
+ }
+ }
+
if (mMediaResourceManager == null) {
IBinder mediaResourceManagerBinder = getBinderService("media.resource_manager");
if (mediaResourceManagerBinder == null) {