diff options
| -rw-r--r-- | media/java/android/media/tv/tuner/Tuner.java | 13 | ||||
| -rw-r--r-- | media/jni/Android.bp | 2 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.cpp | 64 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.h | 3 | ||||
| -rw-r--r-- | media/jni/tuner/TunerClient.cpp | 7 | ||||
| -rw-r--r-- | media/jni/tuner/TunerClient.h | 7 | ||||
| -rw-r--r-- | services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java | 10 |
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) { |