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:
shubang
2020-04-10 18:00:56 -07:00
committed by Amy Zhang
parent 2b40d3c462
commit 2f9cab383b
5 changed files with 91 additions and 8 deletions

View File

@@ -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.
*

View File

@@ -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();
}

View File

@@ -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[] = {

View File

@@ -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();

View File

@@ -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);