Merge changes from topic "tuner_cts_scanning" into rvc-dev

* changes:
  Complete Frontend release implementation in TRM
  Tuner FW: handle release frontend
This commit is contained in:
TreeHugger Robot
2020-04-16 23:15:06 +00:00
committed by Android (Google) Code Review
7 changed files with 178 additions and 29 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

@@ -131,7 +131,7 @@ public final class ClientProfile {
mUsingFrontendIds.add(frontendId);
}
public Iterable<Integer> getInUseFrontendIds() {
public Set<Integer> getInUseFrontendIds() {
return mUsingFrontendIds;
}

View File

@@ -243,15 +243,20 @@ public class TunerResourceManagerService extends SystemService {
if (DEBUG) {
Slog.d(TAG, "requestLnb(request=" + request + ")");
}
return true;
}
@Override
public void releaseFrontend(int frontendId) {
public void releaseFrontend(int frontendHandle) throws RemoteException {
enforceTunerAccessPermission("releaseFrontend");
enforceTrmAccessPermission("releaseFrontend");
if (DEBUG) {
Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND,
frontendHandle)) {
throw new RemoteException("frontendHandle can't be invalid");
}
synchronized (mLock) {
releaseFrontendInternal(getResourceIdFromHandle(frontendHandle));
}
}
@@ -393,7 +398,6 @@ public class TunerResourceManagerService extends SystemService {
}
}
// TODO check if the removing resource is in use or not. Handle the conflict.
for (int removingId : updatingFrontendIds) {
// update the exclusive group id member list
removeFrontendResource(removingId);
@@ -463,6 +467,14 @@ public class TunerResourceManagerService extends SystemService {
return false;
}
@VisibleForTesting
void releaseFrontendInternal(int frontendId) {
if (DEBUG) {
Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
}
updateFrontendClientMappingOnRelease(frontendId);
}
@VisibleForTesting
boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) {
if (DEBUG) {
@@ -568,6 +580,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(exclusiveGroupMember);
}
}
/**
* Get the owner client's priority from the frontend id.
*
@@ -609,6 +632,9 @@ public class TunerResourceManagerService extends SystemService {
private void removeFrontendResource(int removingId) {
FrontendResource fe = getFrontendResource(removingId);
if (fe.isInUse()) {
releaseFrontendInternal(removingId);
}
for (int excGroupmemberFeId : fe.getExclusiveGroupMemberFeIds()) {
getFrontendResource(excGroupmemberFeId)
.removeExclusiveGroupMemberFeId(fe.getId());
@@ -651,6 +677,22 @@ public class TunerResourceManagerService extends SystemService {
| (mResourceRequestCount++ & 0xffff);
}
@VisibleForTesting
protected int getResourceIdFromHandle(int resourceHandle) {
if (resourceHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE) {
return resourceHandle;
}
return (resourceHandle & 0x00ff0000) >> 16;
}
private boolean validateResourceHandle(int resourceType, int resourceHandle) {
if (resourceHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE
|| ((resourceHandle & 0xff000000) >> 24) != resourceType) {
return false;
}
return true;
}
private void enforceTrmAccessPermission(String apiName) {
getContext().enforceCallingPermission("android.permission.TUNER_RESOURCE_ACCESS",
TAG + ": " + apiName);

View File

@@ -96,13 +96,6 @@ public class TunerResourceManagerServiceTest {
}
};
private static int getResourceIdFromHandle(int resourceHandle) {
if (resourceHandle == TunerResourceManager.INVALID_RESOURCE_HANDLE) {
return resourceHandle;
}
return (resourceHandle & 0x00ff0000) >> 16;
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -247,7 +240,7 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0]))
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
}
@@ -275,7 +268,7 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0]))
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
}
@@ -307,7 +300,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(0);
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(0);
}
@Test
@@ -344,7 +338,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId());
request =
new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
@@ -354,7 +349,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
.isInUse()).isTrue();
assertThat(mTunerResourceManagerService.getFrontendResource(infos[2].getId())
@@ -464,7 +460,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId());
request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
@@ -474,7 +471,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
.isInUse()).isTrue();
assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
@@ -486,6 +484,49 @@ public class TunerResourceManagerServiceTest {
assertThat(listener.isRelaimed()).isTrue();
}
@Test
public void releaseFrontendTest_UnderTheSameExclusiveGroup() {
// Register clients
ResourceClientProfile[] profiles = new ResourceClientProfile[1];
profiles[0] = new ResourceClientProfile("0" /*sessionId*/,
TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
int[] clientId = new int[1];
TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
mTunerResourceManagerService.registerClientProfileInternal(profiles[0], listener, clientId);
assertThat(clientId[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
// Init frontend resources.
TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
infos[0] =
new TunerFrontendInfo(0 /*id*/, FrontendSettings.TYPE_DVBT, 1 /*exclusiveGroupId*/);
infos[1] =
new TunerFrontendInfo(1 /*id*/, FrontendSettings.TYPE_DVBS, 1 /*exclusiveGroupId*/);
mTunerResourceManagerService.setFrontendInfoListInternal(infos);
TunerFrontendRequest request =
new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int frontendId = mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]);
assertThat(frontendId).isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService
.getFrontendResource(infos[1].getId()).isInUse()).isTrue();
// Release frontend
mTunerResourceManagerService.releaseFrontendInternal(frontendId);
assertThat(mTunerResourceManagerService
.getFrontendResource(frontendId).isInUse()).isFalse();
assertThat(mTunerResourceManagerService
.getFrontendResource(infos[1].getId()).isInUse()).isFalse();
assertThat(mTunerResourceManagerService
.getClientProfile(clientId[0]).getInUseFrontendIds().size()).isEqualTo(0);
}
@Test
public void unregisterClientTest_usingFrontend() {
// Register client
@@ -513,7 +554,8 @@ public class TunerResourceManagerServiceTest {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(getResourceIdFromHandle(frontendHandle[0])).isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
.isInUse()).isTrue();
assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
@@ -543,7 +585,8 @@ public class TunerResourceManagerServiceTest {
TunerDemuxRequest request = new TunerDemuxRequest(clientId[0]);
assertThat(mTunerResourceManagerService.requestDemuxInternal(request, demuxHandle))
.isTrue();
assertThat(getResourceIdFromHandle(demuxHandle[0])).isEqualTo(0);
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(demuxHandle[0]))
.isEqualTo(0);
}
@Test
@@ -560,6 +603,6 @@ public class TunerResourceManagerServiceTest {
TunerDescramblerRequest request = new TunerDescramblerRequest(clientId[0]);
assertThat(mTunerResourceManagerService.requestDescramblerInternal(request, desHandle))
.isTrue();
assertThat(getResourceIdFromHandle(desHandle[0])).isEqualTo(0);
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(desHandle[0])).isEqualTo(0);
}
}