Merge "Complete the Cas System request/release/update implementation in TRM" into rvc-dev am: aaa8e866d3

Change-Id: I7a4b3140d9278b57f675355a7be1a4eb4cbb984f
This commit is contained in:
Amy Zhang
2020-04-21 19:06:51 +00:00
committed by Automerger Merge Worker
7 changed files with 552 additions and 177 deletions

View File

@@ -388,7 +388,7 @@ public final class MediaCas implements AutoCloseable {
@Override @Override
public void onReclaimResources() { public void onReclaimResources() {
synchronized (mSessionMap) { synchronized (mSessionMap) {
mSessionMap.forEach((casSession, sessionResourceId) -> casSession.close()); mSessionMap.forEach((casSession, sessionResourceHandle) -> casSession.close());
} }
mEventHandler.sendMessage(mEventHandler.obtainMessage( mEventHandler.sendMessage(mEventHandler.obtainMessage(
EventHandler.MSG_CAS_RESOURCE_LOST)); EventHandler.MSG_CAS_RESOURCE_LOST));
@@ -868,7 +868,7 @@ public final class MediaCas implements AutoCloseable {
} }
} }
private int getSessionResourceId() throws MediaCasException { private int getSessionResourceHandle() throws MediaCasException {
validateInternalStates(); validateInternalStates();
int[] sessionResourceHandle = new int[1]; int[] sessionResourceHandle = new int[1];
@@ -884,11 +884,11 @@ public final class MediaCas implements AutoCloseable {
return sessionResourceHandle[0]; return sessionResourceHandle[0];
} }
private void addSessionToResourceMap(Session session, int sessionResourceId) { private void addSessionToResourceMap(Session session, int sessionResourceHandle) {
if (sessionResourceId != -1) { if (sessionResourceHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE) {
synchronized (mSessionMap) { synchronized (mSessionMap) {
mSessionMap.put(session, sessionResourceId); mSessionMap.put(session, sessionResourceHandle);
} }
} }
} }
@@ -918,13 +918,13 @@ public final class MediaCas implements AutoCloseable {
* @throws MediaCasStateException for CAS-specific state exceptions. * @throws MediaCasStateException for CAS-specific state exceptions.
*/ */
public Session openSession() throws MediaCasException { public Session openSession() throws MediaCasException {
int sessionResourceId = getSessionResourceId(); int sessionResourceHandle = getSessionResourceHandle();
try { try {
OpenSessionCallback cb = new OpenSessionCallback(); OpenSessionCallback cb = new OpenSessionCallback();
mICas.openSession(cb); mICas.openSession(cb);
MediaCasException.throwExceptionIfNeeded(cb.mStatus); MediaCasException.throwExceptionIfNeeded(cb.mStatus);
addSessionToResourceMap(cb.mSession, sessionResourceId); addSessionToResourceMap(cb.mSession, sessionResourceHandle);
return cb.mSession; return cb.mSession;
} catch (RemoteException e) { } catch (RemoteException e) {
cleanupAndRethrowIllegalState(); cleanupAndRethrowIllegalState();
@@ -952,7 +952,7 @@ public final class MediaCas implements AutoCloseable {
@Nullable @Nullable
public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode) public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode)
throws MediaCasException { throws MediaCasException {
int sessionResourceId = getSessionResourceId(); int sessionResourceHandle = getSessionResourceHandle();
if (mICasV12 == null) { if (mICasV12 == null) {
Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface"); Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface");
@@ -963,7 +963,7 @@ public final class MediaCas implements AutoCloseable {
OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback(); OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback();
mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb); mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb);
MediaCasException.throwExceptionIfNeeded(cb.mStatus); MediaCasException.throwExceptionIfNeeded(cb.mStatus);
addSessionToResourceMap(cb.mSession, sessionResourceId); addSessionToResourceMap(cb.mSession, sessionResourceHandle);
return cb.mSession; return cb.mSession;
} catch (RemoteException e) { } catch (RemoteException e) {
cleanupAndRethrowIllegalState(); cleanupAndRethrowIllegalState();

View File

@@ -218,11 +218,11 @@ interface ITunerResourceManager {
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request. * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request.
* *
* @param request {@link CasSessionRequest} information of the current request. * @param request {@link CasSessionRequest} information of the current request.
* @param sessionResourceId a one-element array to return the granted cas session id. * @param casSessionHandle a one-element array to return the granted cas session handle.
* *
* @return true if there is CAS session granted. * @return true if there is CAS session granted.
*/ */
boolean requestCasSession(in CasSessionRequest request, out int[] sessionResourceId); boolean requestCasSession(in CasSessionRequest request, out int[] casSessionHandle);
/* /*
* This API is used by the Tuner framework to request an available Lnb from the TunerHAL. * This API is used by the Tuner framework to request an available Lnb from the TunerHAL.
@@ -276,7 +276,7 @@ interface ITunerResourceManager {
* *
* <p>Client must call this whenever it releases a descrambler. * <p>Client must call this whenever it releases a descrambler.
* *
* @param demuxHandle the handle of the released Tuner Descrambler. * @param descramblerHandle the handle of the released Tuner Descrambler.
* @param clientId the id of the client that is releasing the descrambler. * @param clientId the id of the client that is releasing the descrambler.
*/ */
void releaseDescrambler(in int descramblerHandle, int clientId); void releaseDescrambler(in int descramblerHandle, int clientId);
@@ -288,10 +288,10 @@ interface ITunerResourceManager {
* *
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this release. * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this release.
* *
* @param sessionResourceId the id of the released CAS session. * @param casSessionHandle the handle of the released CAS session.
* @param clientId the id of the client that is releasing the cas session. * @param clientId the id of the client that is releasing the cas session.
*/ */
void releaseCasSession(in int sessionResourceId, int clientId); void releaseCasSession(in int casSessionHandle, int clientId);
/* /*
* Notifies the TRM that the Lnb with the given handle was released. * Notifies the TRM that the Lnb with the given handle was released.

View File

@@ -362,17 +362,16 @@ public class TunerResourceManager {
* request. * request.
* *
* @param request {@link CasSessionRequest} information of the current request. * @param request {@link CasSessionRequest} information of the current request.
* @param sessionResourceId a one-element array to return the granted cas session id. * @param casSessionHandle a one-element array to return the granted cas session handel.
* If no CAS granted, this will return * If no CAS granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
* {@link #INVALID_CAS_SESSION_RESOURCE_ID}.
* *
* @return true if there is CAS session granted. * @return true if there is CAS session granted.
*/ */
public boolean requestCasSession(@NonNull CasSessionRequest request, public boolean requestCasSession(@NonNull CasSessionRequest request,
@NonNull int[] sessionResourceId) { @NonNull int[] casSessionHandle) {
boolean result = false; boolean result = false;
try { try {
result = mService.requestCasSession(request, sessionResourceId); result = mService.requestCasSession(request, casSessionHandle);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
@@ -471,12 +470,12 @@ public class TunerResourceManager {
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
* release. * release.
* *
* @param sessionResourceId the id of the released CAS session. * @param casSessionHandle the handle of the released CAS session.
* @param clientId the id of the client that is releasing the cas session. * @param clientId the id of the client that is releasing the cas session.
*/ */
public void releaseCasSession(int sessionResourceId, int clientId) { public void releaseCasSession(int casSessionHandle, int clientId) {
try { try {
mService.releaseCasSession(sessionResourceId, clientId); mService.releaseCasSession(casSessionHandle, clientId);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.tv.tunerresourcemanager;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* A Cas resource object used by the Tuner Resource Manager to record the cas
* information.
*
* @hide
*/
public final class CasResource {
private final int mSystemId;
private int mMaxSessionNum;
private int mAvailableSessionNum;
/**
* The owner clients' ids when part of the Cas is occupied.
*/
private Map<Integer, Integer> mOwnerClientIdsToSessionNum = new HashMap<>();
private CasResource(Builder builder) {
this.mSystemId = builder.mSystemId;
this.mMaxSessionNum = builder.mMaxSessionNum;
this.mAvailableSessionNum = builder.mMaxSessionNum;
}
public int getSystemId() {
return mSystemId;
}
public int getMaxSessionNum() {
return mMaxSessionNum;
}
public int getUsedSessionNum() {
return (mMaxSessionNum - mAvailableSessionNum);
}
public boolean isFullyUsed() {
return mAvailableSessionNum == 0;
}
/**
* Update max session number.
*
* @param maxSessionNum the new max session num.
*/
public void updateMaxSessionNum(int maxSessionNum) {
mAvailableSessionNum = Math.max(
0, mAvailableSessionNum + (maxSessionNum - mMaxSessionNum));
mMaxSessionNum = maxSessionNum;
}
/**
* Set an owner for the cas
*
* @param ownerId the client id of the owner.
*/
public void setOwner(int ownerId) {
int sessionNum = mOwnerClientIdsToSessionNum.get(ownerId) == null
? 1 : (mOwnerClientIdsToSessionNum.get(ownerId) + 1);
mOwnerClientIdsToSessionNum.put(ownerId, sessionNum);
mAvailableSessionNum--;
}
/**
* Remove an owner of the Cas.
*
* @param ownerId the removing client id of the owner.
*/
public void removeOwner(int ownerId) {
mAvailableSessionNum += mOwnerClientIdsToSessionNum.get(ownerId);
mOwnerClientIdsToSessionNum.remove(ownerId);
}
public Set<Integer> getOwnerClientIds() {
return mOwnerClientIdsToSessionNum.keySet();
}
@Override
public String toString() {
return "CasResource[systemId=" + this.mSystemId
+ ", isFullyUsed=" + (this.mAvailableSessionNum == 0)
+ ", maxSessionNum=" + this.mMaxSessionNum
+ ", ownerClients=" + ownersMapToString() + "]";
}
/**
* Builder class for {@link CasResource}.
*/
public static class Builder {
private int mSystemId;
private int mMaxSessionNum;
Builder(int systemId) {
this.mSystemId = systemId;
}
/**
* Builder for {@link CasResource}.
*
* @param maxSessionNum the max session num the current Cas has.
*/
public Builder maxSessionNum(int maxSessionNum) {
this.mMaxSessionNum = maxSessionNum;
return this;
}
/**
* Build a {@link CasResource}.
*
* @return {@link CasResource}.
*/
public CasResource build() {
CasResource cas = new CasResource(this);
return cas;
}
}
private String ownersMapToString() {
StringBuilder string = new StringBuilder("{");
for (int clienId : mOwnerClientIdsToSessionNum.keySet()) {
string.append(" clientId=")
.append(clienId)
.append(", owns session num=")
.append(mOwnerClientIdsToSessionNum.get(clienId))
.append(",");
}
return string.append("}").toString();
}
}

View File

@@ -27,6 +27,7 @@ import java.util.Set;
public final class ClientProfile { public final class ClientProfile {
public static final int INVALID_GROUP_ID = -1; public static final int INVALID_GROUP_ID = -1;
public static final int INVALID_RESOURCE_ID = -1;
/** /**
* Client id sent to the client when registering with * Client id sent to the client when registering with
@@ -56,7 +57,6 @@ public final class ClientProfile {
* also lose their resources. * also lose their resources.
*/ */
private int mGroupId = INVALID_GROUP_ID; private int mGroupId = INVALID_GROUP_ID;
/** /**
* Optional nice value for TRM to reduce client’s priority. * Optional nice value for TRM to reduce client’s priority.
*/ */
@@ -72,6 +72,11 @@ public final class ClientProfile {
*/ */
private Set<Integer> mUsingLnbIds = new HashSet<>(); private Set<Integer> mUsingLnbIds = new HashSet<>();
/**
* List of the Cas system ids that are used by the current client.
*/
private int mUsingCasSystemId = INVALID_RESOURCE_ID;
/** /**
* Optional arbitrary priority value given by the client. * Optional arbitrary priority value given by the client.
* *
@@ -171,12 +176,33 @@ public final class ClientProfile {
mUsingLnbIds.remove(lnbId); mUsingLnbIds.remove(lnbId);
} }
/**
* Set when the client starts to use a Cas system.
*
* @param casSystemId cas being used.
*/
public void useCas(int casSystemId) {
mUsingCasSystemId = casSystemId;
}
public int getInUseCasSystemId() {
return mUsingCasSystemId;
}
/**
* Called when the client released a Cas System.
*/
public void releaseCas() {
mUsingCasSystemId = INVALID_RESOURCE_ID;
}
/** /**
* Called to reclaim all the resources being used by the current client. * Called to reclaim all the resources being used by the current client.
*/ */
public void reclaimAllResources() { public void reclaimAllResources() {
mUsingFrontendIds.clear(); mUsingFrontendIds.clear();
mUsingLnbIds.clear(); mUsingLnbIds.clear();
mUsingCasSystemId = INVALID_RESOURCE_ID;
} }
@Override @Override

View File

@@ -65,6 +65,8 @@ public class TunerResourceManagerService extends SystemService {
private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>(); private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();
// Map of the current available lnb resources // Map of the current available lnb resources
private Map<Integer, LnbResource> mLnbResources = new HashMap<>(); private Map<Integer, LnbResource> mLnbResources = new HashMap<>();
// Map of the current available Cas resources
private Map<Integer, CasResource> mCasResources = new HashMap<>();
@GuardedBy("mLock") @GuardedBy("mLock")
private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>(); private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>();
@@ -158,10 +160,8 @@ public class TunerResourceManagerService extends SystemService {
@Override @Override
public void updateCasInfo(int casSystemId, int maxSessionNum) { public void updateCasInfo(int casSystemId, int maxSessionNum) {
enforceTrmAccessPermission("updateCasInfo"); enforceTrmAccessPermission("updateCasInfo");
if (DEBUG) { synchronized (mLock) {
Slog.d(TAG, updateCasInfoInternal(casSystemId, maxSessionNum);
"updateCasInfo(casSystemId=" + casSystemId
+ ", maxSessionNum=" + maxSessionNum + ")");
} }
} }
@@ -185,11 +185,11 @@ public class TunerResourceManagerService extends SystemService {
throw new RemoteException("frontendHandle can't be null"); throw new RemoteException("frontendHandle can't be null");
} }
synchronized (mLock) { synchronized (mLock) {
try { if (!checkClientExists(request.getClientId())) {
return requestFrontendInternal(request, frontendHandle); throw new RemoteException("Request frontend from unregistered client:"
} catch (RemoteException e) { + request.getClientId());
throw e.rethrowFromSystemServer();
} }
return requestFrontendInternal(request, frontendHandle);
} }
} }
@@ -211,32 +211,45 @@ public class TunerResourceManagerService extends SystemService {
throw new RemoteException("demuxHandle can't be null"); throw new RemoteException("demuxHandle can't be null");
} }
synchronized (mLock) { synchronized (mLock) {
if (!checkClientExists(request.getClientId())) {
throw new RemoteException("Request demux from unregistered client:"
+ request.getClientId());
}
return requestDemuxInternal(request, demuxHandle); return requestDemuxInternal(request, demuxHandle);
} }
} }
@Override @Override
public boolean requestDescrambler(@NonNull TunerDescramblerRequest request, public boolean requestDescrambler(@NonNull TunerDescramblerRequest request,
@NonNull int[] descrambleHandle) throws RemoteException { @NonNull int[] descramblerHandle) throws RemoteException {
enforceDescramblerAccessPermission("requestDescrambler"); enforceDescramblerAccessPermission("requestDescrambler");
enforceTrmAccessPermission("requestDescrambler"); enforceTrmAccessPermission("requestDescrambler");
if (descrambleHandle == null) { if (descramblerHandle == null) {
throw new RemoteException("descrambleHandle can't be null"); throw new RemoteException("descramblerHandle can't be null");
} }
synchronized (mLock) { synchronized (mLock) {
return requestDescramblerInternal(request, descrambleHandle); if (!checkClientExists(request.getClientId())) {
throw new RemoteException("Request descrambler from unregistered client:"
+ request.getClientId());
}
return requestDescramblerInternal(request, descramblerHandle);
} }
} }
@Override @Override
public boolean requestCasSession( public boolean requestCasSession(@NonNull CasSessionRequest request,
@NonNull CasSessionRequest request, @NonNull int[] sessionResourceHandle) { @NonNull int[] casSessionHandle) throws RemoteException {
enforceTrmAccessPermission("requestCasSession"); enforceTrmAccessPermission("requestCasSession");
if (DEBUG) { if (casSessionHandle == null) {
Slog.d(TAG, "requestCasSession(request=" + request + ")"); throw new RemoteException("casSessionHandle can't be null");
}
synchronized (mLock) {
if (!checkClientExists(request.getClientId())) {
throw new RemoteException("Request cas from unregistered client:"
+ request.getClientId());
}
return requestCasSessionInternal(request, casSessionHandle);
} }
return true;
} }
@Override @Override
@@ -248,11 +261,11 @@ public class TunerResourceManagerService extends SystemService {
throw new RemoteException("lnbHandle can't be null"); throw new RemoteException("lnbHandle can't be null");
} }
synchronized (mLock) { synchronized (mLock) {
try { if (!checkClientExists(request.getClientId())) {
return requestLnbInternal(request, lnbHandle); throw new RemoteException("Request lnb from unregistered client:"
} catch (RemoteException e) { + request.getClientId());
throw e.rethrowFromSystemServer();
} }
return requestLnbInternal(request, lnbHandle);
} }
} }
@@ -264,15 +277,20 @@ public class TunerResourceManagerService extends SystemService {
frontendHandle)) { frontendHandle)) {
throw new RemoteException("frontendHandle can't be invalid"); throw new RemoteException("frontendHandle can't be invalid");
} }
synchronized (mLock) {
if (!checkClientExists(clientId)) {
throw new RemoteException("Release frontend from unregistered client:"
+ clientId);
}
int frontendId = getResourceIdFromHandle(frontendHandle); int frontendId = getResourceIdFromHandle(frontendHandle);
FrontendResource fe = getFrontendResource(frontendId); FrontendResource fe = getFrontendResource(frontendId);
if (fe == null) { if (fe == null) {
throw new RemoteException("Releasing frontend does not exist."); throw new RemoteException("Releasing frontend does not exist.");
} }
if (fe.getOwnerClientId() != clientId) { if (fe.getOwnerClientId() != clientId) {
throw new RemoteException("Client is not the current owner of the releasing fe."); throw new RemoteException(
"Client is not the current owner of the releasing fe.");
} }
synchronized (mLock) {
releaseFrontendInternal(fe); releaseFrontendInternal(fe);
} }
} }
@@ -296,10 +314,26 @@ public class TunerResourceManagerService extends SystemService {
} }
@Override @Override
public void releaseCasSession(int sessionResourceId, int clientId) { public void releaseCasSession(int casSessionHandle, int clientId) throws RemoteException {
enforceTrmAccessPermission("releaseCasSession"); enforceTrmAccessPermission("releaseCasSession");
if (DEBUG) { if (!validateResourceHandle(
Slog.d(TAG, "releaseCasSession(sessionResourceId=" + sessionResourceId + ")"); TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, casSessionHandle)) {
throw new RemoteException("casSessionHandle can't be invalid");
}
synchronized (mLock) {
if (!checkClientExists(clientId)) {
throw new RemoteException("Release cas from unregistered client:" + clientId);
}
int casSystemId = getClientProfile(clientId).getInUseCasSystemId();
CasResource cas = getCasResource(casSystemId);
if (cas == null) {
throw new RemoteException("Releasing cas does not exist.");
}
if (!cas.getOwnerClientIds().contains(clientId)) {
throw new RemoteException(
"Client is not the current owner of the releasing cas.");
}
releaseCasSessionInternal(cas, clientId);
} }
} }
@@ -310,6 +344,9 @@ public class TunerResourceManagerService extends SystemService {
if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, lnbHandle)) { if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, lnbHandle)) {
throw new RemoteException("lnbHandle can't be invalid"); throw new RemoteException("lnbHandle can't be invalid");
} }
if (!checkClientExists(clientId)) {
throw new RemoteException("Release lnb from unregistered client:" + clientId);
}
int lnbId = getResourceIdFromHandle(lnbHandle); int lnbId = getResourceIdFromHandle(lnbHandle);
LnbResource lnb = getLnbResource(lnbId); LnbResource lnb = getLnbResource(lnbId);
if (lnb == null) { if (lnb == null) {
@@ -465,17 +502,42 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
protected boolean requestFrontendInternal(TunerFrontendRequest request, int[] frontendHandle) protected void updateCasInfoInternal(int casSystemId, int maxSessionNum) {
throws RemoteException { if (DEBUG) {
Slog.d(TAG,
"updateCasInfo(casSystemId=" + casSystemId
+ ", maxSessionNum=" + maxSessionNum + ")");
}
// If maxSessionNum is 0, removing the Cas Resource.
if (maxSessionNum == 0) {
removeCasResource(casSystemId);
return;
}
// If the Cas exists, updates the Cas Resource accordingly.
CasResource cas = getCasResource(casSystemId);
if (cas != null) {
if (cas.getUsedSessionNum() > maxSessionNum) {
// Sort and release the short number of Cas resources.
int releasingCasResourceNum = cas.getUsedSessionNum() - maxSessionNum;
releaseLowerPriorityClientCasResources(releasingCasResourceNum);
}
cas.updateMaxSessionNum(maxSessionNum);
return;
}
// Add the new Cas Resource.
cas = new CasResource.Builder(casSystemId)
.maxSessionNum(maxSessionNum)
.build();
addCasResource(cas);
}
@VisibleForTesting
protected boolean requestFrontendInternal(TunerFrontendRequest request, int[] frontendHandle) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "requestFrontend(request=" + request + ")"); Slog.d(TAG, "requestFrontend(request=" + request + ")");
} }
frontendHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; frontendHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE;
if (!checkClientExists(request.getClientId())) {
Slog.e(TAG, "Request frontend from unregistered client:" + request.getClientId());
return false;
}
ClientProfile requestClient = getClientProfile(request.getClientId()); ClientProfile requestClient = getClientProfile(request.getClientId());
int grantingFrontendId = -1; int grantingFrontendId = -1;
int inUseLowestPriorityFrId = -1; int inUseLowestPriorityFrId = -1;
@@ -496,7 +558,7 @@ public class TunerResourceManagerService extends SystemService {
} else if (grantingFrontendId < 0) { } else if (grantingFrontendId < 0) {
// Record the frontend id with the lowest client priority among all the // Record the frontend id with the lowest client priority among all the
// in use frontends when no available frontend has been found. // in use frontends when no available frontend has been found.
int priority = getOwnerClientPriority(fr); int priority = getOwnerClientPriority(fr.getOwnerClientId());
if (currentLowestPriority > priority) { if (currentLowestPriority > priority) {
inUseLowestPriorityFrId = fr.getId(); inUseLowestPriorityFrId = fr.getId();
currentLowestPriority = priority; currentLowestPriority = priority;
@@ -530,17 +592,12 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) {
throws RemoteException {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "requestLnb(request=" + request + ")"); Slog.d(TAG, "requestLnb(request=" + request + ")");
} }
lnbHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE; lnbHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE;
if (!checkClientExists(request.getClientId())) {
Slog.e(TAG, "Request lnb from unregistered client:" + request.getClientId());
return false;
}
ClientProfile requestClient = getClientProfile(request.getClientId()); ClientProfile requestClient = getClientProfile(request.getClientId());
int grantingLnbId = -1; int grantingLnbId = -1;
int inUseLowestPriorityLnbId = -1; int inUseLowestPriorityLnbId = -1;
@@ -554,7 +611,7 @@ public class TunerResourceManagerService extends SystemService {
} else { } else {
// Record the lnb id with the lowest client priority among all the // Record the lnb id with the lowest client priority among all the
// in use lnb when no available lnb has been found. // in use lnb when no available lnb has been found.
int priority = getOwnerClientPriority(lnb); int priority = getOwnerClientPriority(lnb.getOwnerClientId());
if (currentLowestPriority > priority) { if (currentLowestPriority > priority) {
inUseLowestPriorityLnbId = lnb.getId(); inUseLowestPriorityLnbId = lnb.getId();
currentLowestPriority = priority; currentLowestPriority = priority;
@@ -588,7 +645,55 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
void releaseFrontendInternal(FrontendResource fe) { protected boolean requestCasSessionInternal(CasSessionRequest request, int[] casSessionHandle) {
if (DEBUG) {
Slog.d(TAG, "requestCasSession(request=" + request + ")");
}
CasResource cas = getCasResource(request.getCasSystemId());
// Unregistered Cas System is treated as having unlimited sessions.
if (cas == null) {
cas = new CasResource.Builder(request.getCasSystemId())
.maxSessionNum(Integer.MAX_VALUE)
.build();
addCasResource(cas);
}
casSessionHandle[0] = TunerResourceManager.INVALID_RESOURCE_HANDLE;
ClientProfile requestClient = getClientProfile(request.getClientId());
int lowestPriorityOwnerId = -1;
// Priority max value is 1000
int currentLowestPriority = MAX_CLIENT_PRIORITY + 1;
if (!cas.isFullyUsed()) {
casSessionHandle[0] = generateResourceHandle(
TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, cas.getSystemId());
updateCasClientMappingOnNewGrant(request.getCasSystemId(), request.getClientId());
return true;
}
for (int ownerId : cas.getOwnerClientIds()) {
// Record the client id with lowest priority that is using the current Cas system.
int priority = getOwnerClientPriority(ownerId);
if (currentLowestPriority > priority) {
lowestPriorityOwnerId = ownerId;
currentLowestPriority = priority;
}
}
// When all the Cas sessions are occupied, reclaim the lowest priority client if the
// request client has higher priority.
if (lowestPriorityOwnerId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
if (!reclaimResource(lowestPriorityOwnerId,
TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION)) {
return false;
}
casSessionHandle[0] = generateResourceHandle(
TunerResourceManager.TUNER_RESOURCE_TYPE_CAS_SESSION, cas.getSystemId());
updateCasClientMappingOnNewGrant(request.getCasSystemId(), request.getClientId());
return true;
}
return false;
}
@VisibleForTesting
protected void releaseFrontendInternal(FrontendResource fe) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ")"); Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ")");
} }
@@ -596,7 +701,7 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
void releaseLnbInternal(LnbResource lnb) { protected void releaseLnbInternal(LnbResource lnb) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "releaseLnb(lnbId=" + lnb.getId() + ")"); Slog.d(TAG, "releaseLnb(lnbId=" + lnb.getId() + ")");
} }
@@ -604,7 +709,15 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) { protected void releaseCasSessionInternal(CasResource cas, int ownerClientId) {
if (DEBUG) {
Slog.d(TAG, "releaseCasSession(sessionResourceId=" + cas.getSystemId() + ")");
}
updateCasClientMappingOnRelease(cas, ownerClientId);
}
@VisibleForTesting
protected boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "requestDemux(request=" + request + ")"); Slog.d(TAG, "requestDemux(request=" + request + ")");
} }
@@ -614,7 +727,8 @@ public class TunerResourceManagerService extends SystemService {
} }
@VisibleForTesting @VisibleForTesting
boolean requestDescramblerInternal(TunerDescramblerRequest request, int[] descramblerHandle) { protected boolean requestDescramblerInternal(
TunerDescramblerRequest request, int[] descramblerHandle) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "requestDescrambler(request=" + request + ")"); Slog.d(TAG, "requestDescrambler(request=" + request + ")");
} }
@@ -742,14 +856,28 @@ public class TunerResourceManagerService extends SystemService {
ownerProfile.releaseLnb(releasingLnb.getId()); ownerProfile.releaseLnb(releasingLnb.getId());
} }
private void updateCasClientMappingOnNewGrant(int grantingId, int ownerClientId) {
CasResource grantingCas = getCasResource(grantingId);
ClientProfile ownerProfile = getClientProfile(ownerClientId);
grantingCas.setOwner(ownerClientId);
ownerProfile.useCas(grantingId);
}
private void updateCasClientMappingOnRelease(
@NonNull CasResource releasingCas, int ownerClientId) {
ClientProfile ownerProfile = getClientProfile(ownerClientId);
releasingCas.removeOwner(ownerClientId);
ownerProfile.releaseCas();
}
/** /**
* Get the owner client's priority from the resource id. * Get the owner client's priority from the resource id.
* *
* @param resource a in use tuner resource. * @param clientId the owner client id.
* @return the priority of the owner client of the resource. * @return the priority of the owner client of the resource.
*/ */
private int getOwnerClientPriority(TunerResourceBasic resource) { private int getOwnerClientPriority(int clientId) {
return getClientProfile(resource.getOwnerClientId()).getPriority(); return getClientProfile(clientId).getPriority();
} }
@VisibleForTesting @VisibleForTesting
@@ -783,6 +911,9 @@ public class TunerResourceManagerService extends SystemService {
private void removeFrontendResource(int removingId) { private void removeFrontendResource(int removingId) {
FrontendResource fe = getFrontendResource(removingId); FrontendResource fe = getFrontendResource(removingId);
if (fe == null) {
return;
}
if (fe.isInUse()) { if (fe.isInUse()) {
releaseFrontendInternal(fe); releaseFrontendInternal(fe);
} }
@@ -811,12 +942,48 @@ public class TunerResourceManagerService extends SystemService {
private void removeLnbResource(int removingId) { private void removeLnbResource(int removingId) {
LnbResource lnb = getLnbResource(removingId); LnbResource lnb = getLnbResource(removingId);
if (lnb == null) {
return;
}
if (lnb.isInUse()) { if (lnb.isInUse()) {
releaseLnbInternal(lnb); releaseLnbInternal(lnb);
} }
mLnbResources.remove(removingId); mLnbResources.remove(removingId);
} }
@VisibleForTesting
@Nullable
protected CasResource getCasResource(int systemId) {
return mCasResources.get(systemId);
}
@VisibleForTesting
protected Map<Integer, CasResource> getCasResources() {
return mCasResources;
}
private void addCasResource(CasResource newCas) {
// Update resource list and available id list
mCasResources.put(newCas.getSystemId(), newCas);
}
private void removeCasResource(int removingId) {
CasResource cas = getCasResource(removingId);
if (cas == null) {
return;
}
for (int ownerId : cas.getOwnerClientIds()) {
getClientProfile(ownerId).releaseCas();
}
mCasResources.remove(removingId);
}
private void releaseLowerPriorityClientCasResources(int releasingCasResourceNum) {
// TODO: Sort with a treemap
// select the first num client to release
}
@VisibleForTesting @VisibleForTesting
@Nullable @Nullable
protected ClientProfile getClientProfile(int clientId) { protected ClientProfile getClientProfile(int clientId) {
@@ -830,12 +997,7 @@ public class TunerResourceManagerService extends SystemService {
} }
private void removeClientProfile(int clientId) { private void removeClientProfile(int clientId) {
for (int id : getClientProfile(clientId).getInUseFrontendIds()) { reclaimingResourcesFromClient(getClientProfile(clientId));
getFrontendResource(id).removeOwner();
for (int groupMemberId : getFrontendResource(id).getExclusiveGroupMemberFeIds()) {
getFrontendResource(groupMemberId).removeOwner();
}
}
mClientProfiles.remove(clientId); mClientProfiles.remove(clientId);
mListeners.remove(clientId); mListeners.remove(clientId);
} }
@@ -847,6 +1009,9 @@ public class TunerResourceManagerService extends SystemService {
for (Integer lnbId : profile.getInUseLnbIds()) { for (Integer lnbId : profile.getInUseLnbIds()) {
getLnbResource(lnbId).removeOwner(); getLnbResource(lnbId).removeOwner();
} }
if (profile.getInUseCasSystemId() != ClientProfile.INVALID_RESOURCE_ID) {
getCasResource(profile.getInUseCasSystemId()).removeOwner(profile.getId());
}
profile.reclaimAllResources(); profile.reclaimAllResources();
} }

View File

@@ -26,6 +26,7 @@ import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager; import android.media.tv.TvInputManager;
import android.media.tv.TvInputService; import android.media.tv.TvInputService;
import android.media.tv.tuner.frontend.FrontendSettings; import android.media.tv.tuner.frontend.FrontendSettings;
import android.media.tv.tunerresourcemanager.CasSessionRequest;
import android.media.tv.tunerresourcemanager.IResourcesReclaimListener; import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
import android.media.tv.tunerresourcemanager.ResourceClientProfile; import android.media.tv.tunerresourcemanager.ResourceClientProfile;
import android.media.tv.tunerresourcemanager.TunerDemuxRequest; import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
@@ -34,7 +35,6 @@ import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
import android.media.tv.tunerresourcemanager.TunerFrontendRequest; import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
import android.media.tv.tunerresourcemanager.TunerLnbRequest; import android.media.tv.tunerresourcemanager.TunerLnbRequest;
import android.media.tv.tunerresourcemanager.TunerResourceManager; import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry;
@@ -236,12 +236,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(0 /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(0 /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse(); .requestFrontendInternal(request, frontendHandle)).isFalse();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE); .isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
} }
@@ -264,12 +260,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse(); .requestFrontendInternal(request, frontendHandle)).isFalse();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE); .isEqualTo(TunerResourceManager.INVALID_RESOURCE_HANDLE);
} }
@@ -296,12 +288,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(0); .isEqualTo(0);
} }
@@ -334,23 +322,15 @@ public class TunerResourceManagerServiceTest {
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId()); .isEqualTo(infos[0].getId());
request = request =
new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[1].getId()); .isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId()) assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
@@ -394,32 +374,20 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
request = request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse(); .requestFrontendInternal(request, frontendHandle)).isFalse();
assertThat(listener.isRelaimed()).isFalse(); assertThat(listener.isRelaimed()).isFalse();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
request = request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS); new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse(); .requestFrontendInternal(request, frontendHandle)).isFalse();
assertThat(listener.isRelaimed()).isFalse(); assertThat(listener.isRelaimed()).isFalse();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} }
@Test @Test
@@ -456,12 +424,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId0[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId()); .isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
@@ -470,12 +434,8 @@ public class TunerResourceManagerServiceTest {
request = request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS); new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[1].getId()); .isEqualTo(infos[1].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId()) assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
@@ -511,12 +471,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int frontendId = mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]); int frontendId = mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]);
assertThat(frontendId).isEqualTo(infos[0].getId()); assertThat(frontendId).isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
@@ -533,6 +489,99 @@ public class TunerResourceManagerServiceTest {
.getClientProfile(clientId[0]).getInUseFrontendIds().size()).isEqualTo(0); .getClientProfile(clientId[0]).getInUseFrontendIds().size()).isEqualTo(0);
} }
@Test
public void requestCasTest_NoCasAvailable_RequestWithHigherPriority() {
// Register clients
ResourceClientProfile[] profiles = new ResourceClientProfile[2];
profiles[0] = new ResourceClientProfile("0" /*sessionId*/,
TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
profiles[1] = new ResourceClientProfile("1" /*sessionId*/,
TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK);
int[] clientPriorities = {100, 500};
int[] clientId0 = new int[1];
int[] clientId1 = new int[1];
TestResourcesReclaimListener listener = new TestResourcesReclaimListener();
mTunerResourceManagerService.registerClientProfileInternal(
profiles[0], listener, clientId0);
assertThat(clientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
mTunerResourceManagerService.getClientProfile(clientId0[0])
.setPriority(clientPriorities[0]);
mTunerResourceManagerService.registerClientProfileInternal(
profiles[1], new TestResourcesReclaimListener(), clientId1);
assertThat(clientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
mTunerResourceManagerService.getClientProfile(clientId1[0])
.setPriority(clientPriorities[1]);
// Init cas resources.
mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
CasSessionRequest request = new CasSessionRequest(clientId0[0], 1 /*casSystemId*/);
int[] casSessionHandle = new int[1];
// Request for 2 cas sessions.
assertThat(mTunerResourceManagerService
.requestCasSessionInternal(request, casSessionHandle)).isTrue();
assertThat(mTunerResourceManagerService
.requestCasSessionInternal(request, casSessionHandle)).isTrue();
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
.isEqualTo(1);
assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
.getInUseCasSystemId()).isEqualTo(1);
assertThat(mTunerResourceManagerService.getCasResource(1)
.getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId0[0])));
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isTrue();
request = new CasSessionRequest(clientId1[0], 1);
assertThat(mTunerResourceManagerService
.requestCasSessionInternal(request, casSessionHandle)).isTrue();
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
.isEqualTo(1);
assertThat(mTunerResourceManagerService.getClientProfile(clientId1[0])
.getInUseCasSystemId()).isEqualTo(1);
assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
.getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
assertThat(mTunerResourceManagerService.getCasResource(1)
.getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0])));
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
assertThat(listener.isRelaimed()).isTrue();
}
@Test
public void releaseCasTest() {
// 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 cas resources.
mTunerResourceManagerService.updateCasInfoInternal(1 /*casSystemId*/, 2 /*maxSessionNum*/);
CasSessionRequest request = new CasSessionRequest(clientId[0], 1 /*casSystemId*/);
int[] casSessionHandle = new int[1];
// Request for 1 cas sessions.
assertThat(mTunerResourceManagerService
.requestCasSessionInternal(request, casSessionHandle)).isTrue();
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(casSessionHandle[0]))
.isEqualTo(1);
assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
.getInUseCasSystemId()).isEqualTo(1);
assertThat(mTunerResourceManagerService.getCasResource(1)
.getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId[0])));
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
// Release cas
mTunerResourceManagerService.releaseCasSessionInternal(mTunerResourceManagerService
.getCasResource(1), clientId[0]);
assertThat(mTunerResourceManagerService.getClientProfile(clientId[0])
.getInUseCasSystemId()).isEqualTo(ClientProfile.INVALID_RESOURCE_ID);
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
assertThat(mTunerResourceManagerService.getCasResource(1)
.getOwnerClientIds()).isEmpty();
}
@Test @Test
public void requestLnbTest_NoLnbAvailable_RequestWithHigherPriority() { public void requestLnbTest_NoLnbAvailable_RequestWithHigherPriority() {
// Register clients // Register clients
@@ -562,24 +611,16 @@ public class TunerResourceManagerServiceTest {
TunerLnbRequest request = new TunerLnbRequest(clientId0[0]); TunerLnbRequest request = new TunerLnbRequest(clientId0[0]);
int[] lnbHandle = new int[1]; int[] lnbHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestLnbInternal(request, lnbHandle)).isTrue(); .requestLnbInternal(request, lnbHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]))
.isEqualTo(lnbIds[0]); .isEqualTo(lnbIds[0]);
assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0]) assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
.getInUseLnbIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(lnbIds[0]))); .getInUseLnbIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(lnbIds[0])));
request = new TunerLnbRequest(clientId1[0]); request = new TunerLnbRequest(clientId1[0]);
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestLnbInternal(request, lnbHandle)).isTrue(); .requestLnbInternal(request, lnbHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]))
.isEqualTo(lnbIds[0]); .isEqualTo(lnbIds[0]);
assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0]) assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0])
@@ -608,12 +649,8 @@ public class TunerResourceManagerServiceTest {
TunerLnbRequest request = new TunerLnbRequest(clientId[0]); TunerLnbRequest request = new TunerLnbRequest(clientId[0]);
int[] lnbHandle = new int[1]; int[] lnbHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestLnbInternal(request, lnbHandle)).isTrue(); .requestLnbInternal(request, lnbHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
int lnbId = mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]); int lnbId = mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]);
assertThat(lnbId).isEqualTo(lnbIds[0]); assertThat(lnbId).isEqualTo(lnbIds[0]);
@@ -647,12 +684,8 @@ public class TunerResourceManagerServiceTest {
TunerFrontendRequest request = TunerFrontendRequest request =
new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT); new TunerFrontendRequest(clientId[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
int[] frontendHandle = new int[1]; int[] frontendHandle = new int[1];
try {
assertThat(mTunerResourceManagerService assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isTrue(); .requestFrontendInternal(request, frontendHandle)).isTrue();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0])) assertThat(mTunerResourceManagerService.getResourceIdFromHandle(frontendHandle[0]))
.isEqualTo(infos[0].getId()); .isEqualTo(infos[0].getId());
assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId()) assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())