Tuner FW: handle release frontend
This can unblock tune/scan CTS test cases. If a frontend resource is acquired in a test case and not released, it cannot be used by another test case. Bug: 150952758 Test: atest android.media.tv.tuner.cts.TunerTest Change-Id: Ib9bab003fc81fe008091a9d1aaefc43e454c3230
This commit is contained in:
@@ -263,14 +263,14 @@ public class Tuner implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void setFrontendInfoList() {
|
||||
List<Integer> ids = nativeGetFrontendIds();
|
||||
List<Integer> ids = getFrontendIds();
|
||||
if (ids == null) {
|
||||
return;
|
||||
}
|
||||
TunerFrontendInfo[] infos = new TunerFrontendInfo[ids.size()];
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
int id = ids.get(i);
|
||||
FrontendInfo frontendInfo = nativeGetFrontendInfo(id);
|
||||
FrontendInfo frontendInfo = getFrontendInfoById(id);
|
||||
if (frontendInfo == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -281,6 +281,11 @@ public class Tuner implements AutoCloseable {
|
||||
mTunerResourceManager.setFrontendInfoList(infos);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public List<Integer> getFrontendIds() {
|
||||
return nativeGetFrontendIds();
|
||||
}
|
||||
|
||||
private void setLnbIds() {
|
||||
int[] ids = nativeGetLnbIds();
|
||||
if (ids == null) {
|
||||
@@ -345,14 +350,17 @@ public class Tuner implements AutoCloseable {
|
||||
@Override
|
||||
public void close() {
|
||||
if (mFrontendHandle != null) {
|
||||
nativeCloseFrontendByHandle(mFrontendHandle);
|
||||
mTunerResourceManager.releaseFrontend(mFrontendHandle);
|
||||
mFrontendHandle = null;
|
||||
mFrontend = null;
|
||||
}
|
||||
if (mLnb != null) {
|
||||
mTunerResourceManager.releaseLnb(mLnbHandle);
|
||||
mLnb = null;
|
||||
mLnbHandle = null;
|
||||
}
|
||||
nativeClose();
|
||||
TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,6 +382,8 @@ public class Tuner implements AutoCloseable {
|
||||
* Native method to open frontend of the given ID.
|
||||
*/
|
||||
private native Frontend nativeOpenFrontendByHandle(int handle);
|
||||
@Result
|
||||
private native int nativeCloseFrontendByHandle(int handle);
|
||||
private native int nativeTune(int type, FrontendSettings settings);
|
||||
private native int nativeStopTune();
|
||||
private native int nativeScan(int settingsType, FrontendSettings settings, int scanType);
|
||||
@@ -522,6 +532,7 @@ public class Tuner implements AutoCloseable {
|
||||
public int tune(@NonNull FrontendSettings settings) {
|
||||
mFrontendType = settings.getType();
|
||||
checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
|
||||
|
||||
mFrontendInfo = null;
|
||||
return nativeTune(settings.getType(), settings);
|
||||
}
|
||||
@@ -706,11 +717,16 @@ public class Tuner implements AutoCloseable {
|
||||
throw new IllegalStateException("frontend is not initialized");
|
||||
}
|
||||
if (mFrontendInfo == null) {
|
||||
mFrontendInfo = nativeGetFrontendInfo(mFrontend.mId);
|
||||
mFrontendInfo = getFrontendInfoById(mFrontend.mId);
|
||||
}
|
||||
return mFrontendInfo;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public FrontendInfo getFrontendInfoById(int id) {
|
||||
return nativeGetFrontendInfo(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Demux capabilities.
|
||||
*
|
||||
|
||||
@@ -416,11 +416,11 @@ public class TunerResourceManager {
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this release.
|
||||
*
|
||||
* @param frontendId the id of the released frontend.
|
||||
* @param frontendHandle the handle of the released frontend.
|
||||
*/
|
||||
public void releaseFrontend(int frontendId) {
|
||||
public void releaseFrontend(int frontendHandle) {
|
||||
try {
|
||||
mService.releaseFrontend(frontendId);
|
||||
mService.releaseFrontend(frontendHandle);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -833,6 +833,12 @@ JTuner::JTuner(JNIEnv *env, jobject thiz)
|
||||
}
|
||||
|
||||
JTuner::~JTuner() {
|
||||
if (mFe != NULL) {
|
||||
mFe->close();
|
||||
}
|
||||
if (mDemux != NULL) {
|
||||
mDemux->close();
|
||||
}
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
env->DeleteWeakGlobalRef(mObject);
|
||||
@@ -908,6 +914,14 @@ jobject JTuner::openFrontendById(int id) {
|
||||
(jint) jId);
|
||||
}
|
||||
|
||||
jint JTuner::closeFrontendById(int id) {
|
||||
if (mFe != NULL && mFeId == id) {
|
||||
Result r = mFe->close();
|
||||
return (jint) r;
|
||||
}
|
||||
return (jint) Result::SUCCESS;
|
||||
}
|
||||
|
||||
jobject JTuner::getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
|
||||
jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendCapabilities");
|
||||
jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
|
||||
@@ -1271,6 +1285,23 @@ Result JTuner::openDemux() {
|
||||
return res;
|
||||
}
|
||||
|
||||
jint JTuner::close() {
|
||||
Result res = Result::SUCCESS;
|
||||
if (mFe != NULL) {
|
||||
res = mFe->close();
|
||||
if (res != Result::SUCCESS) {
|
||||
return (jint) res;
|
||||
}
|
||||
}
|
||||
if (mDemux != NULL) {
|
||||
res = mDemux->close();
|
||||
if (res != Result::SUCCESS) {
|
||||
return (jint) res;
|
||||
}
|
||||
}
|
||||
return (jint) res;
|
||||
}
|
||||
|
||||
jobject JTuner::getAvSyncHwId(sp<Filter> filter) {
|
||||
if (mDemux == NULL) {
|
||||
return NULL;
|
||||
@@ -2362,6 +2393,13 @@ static jobject android_media_tv_Tuner_open_frontend_by_handle(
|
||||
return tuner->openFrontendById(id);
|
||||
}
|
||||
|
||||
static jint android_media_tv_Tuner_close_frontend_by_handle(
|
||||
JNIEnv *env, jobject thiz, jint handle) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
uint32_t id = getResourceIdFromHandle(handle);
|
||||
return tuner->closeFrontendById(id);
|
||||
}
|
||||
|
||||
static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
return tuner->tune(getFrontendSettings(env, type, settings));
|
||||
@@ -3135,6 +3173,11 @@ static jint android_media_tv_Tuner_open_demux(JNIEnv* env, jobject thiz, jint /*
|
||||
return (jint) tuner->openDemux();
|
||||
}
|
||||
|
||||
static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
return (jint) tuner->close();
|
||||
}
|
||||
|
||||
static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
|
||||
sp<Dvr> dvrSp = getDvr(env, dvr);
|
||||
if (dvrSp == NULL) {
|
||||
@@ -3424,6 +3467,8 @@ static const JNINativeMethod gTunerMethods[] = {
|
||||
(void *)android_media_tv_Tuner_get_frontend_ids },
|
||||
{ "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
|
||||
(void *)android_media_tv_Tuner_open_frontend_by_handle },
|
||||
{ "nativeCloseFrontendByHandle", "(I)I",
|
||||
(void *)android_media_tv_Tuner_close_frontend_by_handle },
|
||||
{ "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
|
||||
(void *)android_media_tv_Tuner_tune },
|
||||
{ "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
|
||||
@@ -3460,6 +3505,7 @@ static const JNINativeMethod gTunerMethods[] = {
|
||||
{ "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
|
||||
(void *)android_media_tv_Tuner_get_demux_caps },
|
||||
{ "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux },
|
||||
{"nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
|
||||
};
|
||||
|
||||
static const JNINativeMethod gFilterMethods[] = {
|
||||
|
||||
@@ -172,6 +172,7 @@ struct JTuner : public RefBase {
|
||||
int disconnectCiCam();
|
||||
jobject getFrontendIds();
|
||||
jobject openFrontendById(int id);
|
||||
jint closeFrontendById(int id);
|
||||
jobject getFrontendInfo(int id);
|
||||
int tune(const FrontendSettings& settings);
|
||||
int stopTune();
|
||||
@@ -189,6 +190,7 @@ struct JTuner : public RefBase {
|
||||
jobject getDemuxCaps();
|
||||
jobject getFrontendStatus(jintArray types);
|
||||
Result openDemux();
|
||||
jint close();
|
||||
|
||||
protected:
|
||||
virtual ~JTuner();
|
||||
|
||||
@@ -247,12 +247,15 @@ public class TunerResourceManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseFrontend(int frontendId) {
|
||||
public void releaseFrontend(int frontendHandle) {
|
||||
enforceTunerAccessPermission("releaseFrontend");
|
||||
enforceTrmAccessPermission("releaseFrontend");
|
||||
int frontendId = getResourceId(
|
||||
TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, frontendHandle);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
|
||||
}
|
||||
updateFrontendClientMappingOnRelease(frontendId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -568,6 +571,17 @@ public class TunerResourceManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrontendClientMappingOnRelease(int frontendId) {
|
||||
FrontendResource releasingFrontend = getFrontendResource(frontendId);
|
||||
ClientProfile ownerProfile = getClientProfile(releasingFrontend.getOwnerClientId());
|
||||
releasingFrontend.removeOwner();
|
||||
ownerProfile.releaseFrontend(frontendId);
|
||||
for (int exclusiveGroupMember : releasingFrontend.getExclusiveGroupMemberFeIds()) {
|
||||
getFrontendResource(exclusiveGroupMember).removeOwner();
|
||||
ownerProfile.releaseFrontend(frontendId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner client's priority from the frontend id.
|
||||
*
|
||||
@@ -651,6 +665,11 @@ public class TunerResourceManagerService extends SystemService {
|
||||
| (mResourceRequestCount++ & 0xffff);
|
||||
}
|
||||
|
||||
private int getResourceId(
|
||||
@TunerResourceManager.TunerResourceType int resourceType, int resourceHandle) {
|
||||
return (resourceHandle & 0x00ff0000) >> 16;
|
||||
}
|
||||
|
||||
private void enforceTrmAccessPermission(String apiName) {
|
||||
getContext().enforceCallingPermission("android.permission.TUNER_RESOURCE_ACCESS",
|
||||
TAG + ": " + apiName);
|
||||
|
||||
Reference in New Issue
Block a user