Merge "Complete Lnb update/request/release implementation in TRM" into rvc-dev
diff --git a/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl b/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
index 77cac6e..f33ad7d 100644
--- a/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
+++ b/media/java/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
@@ -132,11 +132,11 @@
* before this request.
*
* @param request {@link TunerFrontendRequest} information of the current request.
- * @param frontendId a one-element array to return the granted frontendId.
+ * @param frontendHandle a one-element array to return the granted frontendHandle.
*
* @return true if there is frontend granted.
*/
- boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendId);
+ boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendHandle);
/*
* Requests to share frontend with an existing client.
@@ -240,11 +240,11 @@
* <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this request.
*
* @param request {@link TunerLnbRequest} information of the current request.
- * @param lnbId a one-element array to return the granted Lnb id.
+ * @param lnbHandle a one-element array to return the granted Lnb handle.
*
* @return true if there is Lnb granted.
*/
- boolean requestLnb(in TunerLnbRequest request, out int[] lnbId);
+ boolean requestLnb(in TunerLnbRequest request, out int[] lnbHandle);
/*
* Notifies the TRM that the given frontend has been released.
@@ -254,9 +254,9 @@
* <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.
*/
- void releaseFrontend(in int frontendId);
+ void releaseFrontend(in int frontendHandle);
/*
* Notifies the TRM that the Demux with the given handle was released.
@@ -288,15 +288,15 @@
void releaseCasSession(in int sessionResourceId);
/*
- * Notifies the TRM that the Lnb with the given id was released.
+ * Notifies the TRM that the Lnb with the given handle was released.
*
* <p>Client must call this whenever it releases an Lnb.
*
* <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this release.
*
- * @param lnbId the id of the released Tuner Lnb.
+ * @param lnbHandle the handle of the released Tuner Lnb.
*/
- void releaseLnb(in int lnbId);
+ void releaseLnb(in int lnbHandle);
/*
* Compare two clients' priority.
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index a9f3dcf..a9f89be 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -64,6 +64,7 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int INVALID_RESOURCE_HANDLE = -1;
+ public static final int INVALID_OWNER_ID = -1;
/**
* Tuner resource type to help generate resource handle
*/
@@ -73,6 +74,7 @@
TUNER_RESOURCE_TYPE_DESCRAMBLER,
TUNER_RESOURCE_TYPE_LNB,
TUNER_RESOURCE_TYPE_CAS_SESSION,
+ TUNER_RESOURCE_TYPE_MAX,
})
@Retention(RetentionPolicy.SOURCE)
public @interface TunerResourceType {}
@@ -82,6 +84,7 @@
public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
public static final int TUNER_RESOURCE_TYPE_LNB = 3;
public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
+ public static final int TUNER_RESOURCE_TYPE_MAX = 5;
private final ITunerResourceManager mService;
private final int mUserId;
@@ -243,16 +246,16 @@
* before this request.
*
* @param request {@link TunerFrontendRequest} information of the current request.
- * @param frontendId a one-element array to return the granted frontendId. If
- * no frontend granted, this will return {@link #INVALID_FRONTEND_ID}.
+ * @param frontendHandle a one-element array to return the granted frontendHandle. If
+ * no frontend granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
*
* @return true if there is frontend granted.
*/
public boolean requestFrontend(@NonNull TunerFrontendRequest request,
- @Nullable int[] frontendId) {
+ @Nullable int[] frontendHandle) {
boolean result = false;
try {
- result = mService.requestFrontend(request, frontendId);
+ result = mService.requestFrontend(request, frontendHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -393,15 +396,15 @@
* <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request.
*
* @param request {@link TunerLnbRequest} information of the current request.
- * @param lnbId a one-element array to return the granted Lnb id.
- * If no Lnb granted, this will return {@link #INVALID_LNB_ID}.
+ * @param lnbHandle a one-element array to return the granted Lnb handle.
+ * If no Lnb granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
*
* @return true if there is Lnb granted.
*/
- public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbId) {
+ public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) {
boolean result = false;
try {
- result = mService.requestLnb(request, lnbId);
+ result = mService.requestLnb(request, lnbHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -481,11 +484,11 @@
*
* <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this release.
*
- * @param lnbId the id of the released Tuner Lnb.
+ * @param lnbHandle the handle of the released Tuner Lnb.
*/
- public void releaseLnb(int lnbId) {
+ public void releaseLnb(int lnbHandle) {
try {
- mService.releaseLnb(lnbId);
+ mService.releaseLnb(lnbHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index dfd23df..43b4854 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -68,6 +68,11 @@
private Set<Integer> mUsingFrontendIds = new HashSet<>();
/**
+ * List of the Lnb ids that are used by the current client.
+ */
+ private Set<Integer> mUsingLnbIds = new HashSet<>();
+
+ /**
* Optional arbitrary priority value given by the client.
*
* <p>This value can override the default priorotiy calculated from
@@ -146,6 +151,30 @@
mUsingFrontendIds.remove(frontendId);
}
+ /**
+ * Set when the client starts to use an Lnb.
+ *
+ * @param lnbId being used.
+ */
+ public void useLnb(int lnbId) {
+ mUsingLnbIds.add(lnbId);
+ }
+
+ public Set<Integer> getInUseLnbIds() {
+ return mUsingLnbIds;
+ }
+
+ /**
+ * Called when the client released an lnb.
+ *
+ * <p>This could happen when client resource reclaimed.
+ *
+ * @param lnbId being released.
+ */
+ public void releaseLnb(int lnbId) {
+ mUsingLnbIds.remove(lnbId);
+ }
+
@Override
public String toString() {
return "ClientProfile[id=" + this.mId + ", tvInputSessionId=" + this.mTvInputSessionId
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/FrontendResource.java b/services/core/java/com/android/server/tv/tunerresourcemanager/FrontendResource.java
index 56f6159..7ea62b2 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/FrontendResource.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/FrontendResource.java
@@ -27,14 +27,7 @@
*
* @hide
*/
-public final class FrontendResource {
- public static final int INVALID_OWNER_ID = -1;
-
- /**
- * Id of the current frontend. Should not be changed and should be aligned with the driver level
- * implementation.
- */
- private final int mId;
+public final class FrontendResource extends TunerResourceBasic {
/**
* see {@link android.media.tv.tuner.frontend.FrontendSettings.Type}
@@ -51,28 +44,12 @@
*/
private Set<Integer> mExclusiveGroupMemberFeIds = new HashSet<>();
- /**
- * If the current resource is in use. Once resources under the same exclusive group id is in use
- * all other resources in the same group would be considered in use.
- */
- private boolean mIsInUse;
-
- /**
- * The owner client's id if this resource is occupied. Owner of the resource under the same
- * exclusive group id would be considered as the whole group's owner.
- */
- private int mOwnerClientId = INVALID_OWNER_ID;
-
private FrontendResource(Builder builder) {
- this.mId = builder.mId;
+ super(builder);
this.mType = builder.mType;
this.mExclusiveGroupId = builder.mExclusiveGroupId;
}
- public int getId() {
- return mId;
- }
-
public int getType() {
return mType;
}
@@ -112,32 +89,6 @@
mExclusiveGroupMemberFeIds.remove(id);
}
- public boolean isInUse() {
- return mIsInUse;
- }
-
- public int getOwnerClientId() {
- return mOwnerClientId;
- }
-
- /**
- * Set an owner client on the resource.
- *
- * @param ownerClientId the id of the owner client.
- */
- public void setOwner(int ownerClientId) {
- mIsInUse = true;
- mOwnerClientId = ownerClientId;
- }
-
- /**
- * Remove an owner client from the resource.
- */
- public void removeOwner() {
- mIsInUse = false;
- mOwnerClientId = INVALID_OWNER_ID;
- }
-
@Override
public String toString() {
return "FrontendResource[id=" + this.mId + ", type=" + this.mType
@@ -149,13 +100,12 @@
/**
* Builder class for {@link FrontendResource}.
*/
- public static class Builder {
- private final int mId;
+ public static class Builder extends TunerResourceBasic.Builder {
@Type private int mType;
private int mExclusiveGroupId;
Builder(int id) {
- this.mId = id;
+ super(id);
}
/**
@@ -183,6 +133,7 @@
*
* @return {@link FrontendResource}.
*/
+ @Override
public FrontendResource build() {
FrontendResource frontendResource = new FrontendResource(this);
return frontendResource;
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/LnbResource.java b/services/core/java/com/android/server/tv/tunerresourcemanager/LnbResource.java
new file mode 100644
index 0000000..345b4b2
--- /dev/null
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/LnbResource.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+/**
+ * An Lnb resource object used by the Tuner Resource Manager to record the tuner Lnb
+ * information.
+ *
+ * @hide
+ */
+public final class LnbResource extends TunerResourceBasic {
+
+ private LnbResource(Builder builder) {
+ super(builder);
+ }
+
+ @Override
+ public String toString() {
+ return "LnbResource[id=" + this.mId
+ + ", isInUse=" + this.mIsInUse + ", ownerClientId=" + this.mOwnerClientId + "]";
+ }
+
+ /**
+ * Builder class for {@link LnbResource}.
+ */
+ public static class Builder extends TunerResourceBasic.Builder {
+
+ Builder(int id) {
+ super(id);
+ }
+
+ /**
+ * Build a {@link LnbResource}.
+ *
+ * @return {@link LnbResource}.
+ */
+ @Override
+ public LnbResource build() {
+ LnbResource lnb = new LnbResource(this);
+ return lnb;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceBasic.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceBasic.java
new file mode 100644
index 0000000..7f133c3
--- /dev/null
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceBasic.java
@@ -0,0 +1,97 @@
+/*
+ * 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 static android.media.tv.tunerresourcemanager.TunerResourceManager.INVALID_OWNER_ID;
+
+/**
+ * A Tuner resource basic object used by the Tuner Resource Manager to record the resource
+ * information.
+ *
+ * @hide
+ */
+public class TunerResourceBasic {
+ /**
+ * Id of the current resource. Should not be changed and should be aligned with the driver level
+ * implementation.
+ */
+ final int mId;
+
+ /**
+ * If the current resource is in use.
+ */
+ boolean mIsInUse;
+
+ /**
+ * The owner client's id if this resource is occupied.
+ */
+ int mOwnerClientId = INVALID_OWNER_ID;
+
+ TunerResourceBasic(Builder builder) {
+ this.mId = builder.mId;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ public boolean isInUse() {
+ return mIsInUse;
+ }
+
+ public int getOwnerClientId() {
+ return mOwnerClientId;
+ }
+
+ /**
+ * Set an owner client on the resource.
+ *
+ * @param ownerClientId the id of the owner client.
+ */
+ public void setOwner(int ownerClientId) {
+ mIsInUse = true;
+ mOwnerClientId = ownerClientId;
+ }
+
+ /**
+ * Remove an owner client from the resource.
+ */
+ public void removeOwner() {
+ mIsInUse = false;
+ mOwnerClientId = INVALID_OWNER_ID;
+ }
+
+ /**
+ * Builder class for {@link TunerResourceBasic}.
+ */
+ public static class Builder {
+ private final int mId;
+
+ Builder(int id) {
+ this.mId = id;
+ }
+
+ /**
+ * Build a {@link TunerResourceBasic}.
+ *
+ * @return {@link TunerResourceBasic}.
+ */
+ public TunerResourceBasic build() {
+ TunerResourceBasic resource = new TunerResourceBasic(this);
+ return resource;
+ }
+ }
+}
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 fd2445f..acb6f95 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -63,6 +63,8 @@
// Map of the current available frontend resources
private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();
+ // Map of the current available lnb resources
+ private Map<Integer, LnbResource> mLnbResources = new HashMap<>();
@GuardedBy("mLock")
private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>();
@@ -164,12 +166,13 @@
}
@Override
- public void setLnbInfoList(int[] lnbIds) {
+ public void setLnbInfoList(int[] lnbIds) throws RemoteException {
enforceTrmAccessPermission("setLnbInfoList");
- if (DEBUG) {
- for (int i = 0; i < lnbIds.length; i++) {
- Slog.d(TAG, "updateLnbInfo(lnbId=" + lnbIds[i] + ")");
- }
+ if (lnbIds == null) {
+ throw new RemoteException("Lnb id list can't be null");
+ }
+ synchronized (mLock) {
+ setLnbInfoListInternal(lnbIds);
}
}
@@ -237,14 +240,20 @@
}
@Override
- public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) {
+ public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle)
+ throws RemoteException {
enforceTunerAccessPermission("requestLnb");
enforceTrmAccessPermission("requestLnb");
- if (DEBUG) {
- Slog.d(TAG, "requestLnb(request=" + request + ")");
+ if (lnbHandle == null) {
+ throw new RemoteException("lnbHandle can't be null");
}
-
- return true;
+ synchronized (mLock) {
+ try {
+ return requestLnbInternal(request, lnbHandle);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
@Override
@@ -287,11 +296,14 @@
}
@Override
- public void releaseLnb(int lnbId) {
+ public void releaseLnb(int lnbHandle) throws RemoteException {
enforceTunerAccessPermission("releaseLnb");
enforceTrmAccessPermission("releaseLnb");
- if (DEBUG) {
- Slog.d(TAG, "releaseLnb(lnbId=" + lnbId + ")");
+ if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, lnbHandle)) {
+ throw new RemoteException("lnbHandle can't be invalid");
+ }
+ synchronized (mLock) {
+ releaseLnbInternal(getResourceIdFromHandle(lnbHandle));
}
}
@@ -405,6 +417,38 @@
}
@VisibleForTesting
+ protected void setLnbInfoListInternal(int[] lnbIds) {
+ if (DEBUG) {
+ for (int i = 0; i < lnbIds.length; i++) {
+ Slog.d(TAG, "updateLnbInfo(lnbId=" + lnbIds[i] + ")");
+ }
+ }
+
+ // A set to record the Lnbs pending on updating. Ids will be removed
+ // from this set once its updating finished. Any lnb left in this set when all
+ // the updates are done will be removed from mLnbResources.
+ Set<Integer> updatingLnbIds = new HashSet<>(getLnbResources().keySet());
+
+ // Update lnbResources map and other mappings accordingly
+ for (int i = 0; i < lnbIds.length; i++) {
+ if (getLnbResource(lnbIds[i]) != null) {
+ if (DEBUG) {
+ Slog.d(TAG, "Lnb id=" + lnbIds[i] + "exists.");
+ }
+ updatingLnbIds.remove(lnbIds[i]);
+ } else {
+ // Add a new lnb resource
+ LnbResource newLnb = new LnbResource.Builder(lnbIds[i]).build();
+ addLnbResource(newLnb);
+ }
+ }
+
+ for (int removingId : updatingLnbIds) {
+ removeLnbResource(removingId);
+ }
+ }
+
+ @VisibleForTesting
protected boolean requestFrontendInternal(TunerFrontendRequest request, int[] frontendHandle)
throws RemoteException {
if (DEBUG) {
@@ -458,8 +502,8 @@
if (inUseLowestPriorityFrId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
frontendHandle[0] = generateResourceHandle(
TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
- reclaimFrontendResource(getFrontendResource(
- inUseLowestPriorityFrId).getOwnerClientId());
+ reclaimResource(getFrontendResource(inUseLowestPriorityFrId).getOwnerClientId(),
+ TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
updateFrontendClientMappingOnNewGrant(inUseLowestPriorityFrId, request.getClientId());
return true;
}
@@ -468,6 +512,62 @@
}
@VisibleForTesting
+ protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle)
+ throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "requestLnb(request=" + request + ")");
+ }
+
+ 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());
+ int grantingLnbId = -1;
+ int inUseLowestPriorityLnbId = -1;
+ // Priority max value is 1000
+ int currentLowestPriority = MAX_CLIENT_PRIORITY + 1;
+ for (LnbResource lnb : getLnbResources().values()) {
+ if (!lnb.isInUse()) {
+ // Grant the unused lnb with lower id first
+ grantingLnbId = lnb.getId();
+ break;
+ } else {
+ // Record the lnb id with the lowest client priority among all the
+ // in use lnb when no available lnb has been found.
+ int priority = getOwnerClientPriority(lnb);
+ if (currentLowestPriority > priority) {
+ inUseLowestPriorityLnbId = lnb.getId();
+ currentLowestPriority = priority;
+ }
+ }
+ }
+
+ // Grant Lnb when there is unused resource.
+ if (grantingLnbId > -1) {
+ lnbHandle[0] = generateResourceHandle(
+ TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, grantingLnbId);
+ updateLnbClientMappingOnNewGrant(grantingLnbId, request.getClientId());
+ return true;
+ }
+
+ // When all the resources are occupied, grant the lowest priority resource if the
+ // request client has higher priority.
+ if (inUseLowestPriorityLnbId > -1
+ && (requestClient.getPriority() > currentLowestPriority)) {
+ lnbHandle[0] = generateResourceHandle(
+ TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, inUseLowestPriorityLnbId);
+ reclaimResource(getLnbResource(inUseLowestPriorityLnbId).getOwnerClientId(),
+ TunerResourceManager.TUNER_RESOURCE_TYPE_LNB);
+ updateLnbClientMappingOnNewGrant(inUseLowestPriorityLnbId, request.getClientId());
+ return true;
+ }
+
+ return false;
+ }
+
+ @VisibleForTesting
void releaseFrontendInternal(int frontendId) {
if (DEBUG) {
Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
@@ -476,6 +576,14 @@
}
@VisibleForTesting
+ void releaseLnbInternal(int lnbId) {
+ if (DEBUG) {
+ Slog.d(TAG, "releaseLnb(lnbId=" + lnbId + ")");
+ }
+ updateLnbClientMappingOnRelease(lnbId);
+ }
+
+ @VisibleForTesting
boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) {
if (DEBUG) {
Slog.d(TAG, "requestDemux(request=" + request + ")");
@@ -542,12 +650,18 @@
}
@VisibleForTesting
- protected void reclaimFrontendResource(int reclaimingId) {
+ protected void reclaimResource(int reclaimingId,
+ @TunerResourceManager.TunerResourceType int resourceType) {
+ if (DEBUG) {
+ Slog.d(TAG, "Reclaiming resources because higher priority client request resource type "
+ + resourceType);
+ }
try {
mListeners.get(reclaimingId).getListener().onReclaimResources();
} catch (RemoteException e) {
Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingId, e);
}
+ // TODO clean all the client and resources mapping/ownership
}
@VisibleForTesting
@@ -591,14 +705,28 @@
}
}
+ private void updateLnbClientMappingOnNewGrant(int grantingId, int ownerClientId) {
+ LnbResource grantingLnb = getLnbResource(grantingId);
+ ClientProfile ownerProfile = getClientProfile(ownerClientId);
+ grantingLnb.setOwner(ownerClientId);
+ ownerProfile.useLnb(grantingId);
+ }
+
+ private void updateLnbClientMappingOnRelease(int lnbId) {
+ LnbResource releasingLnb = getLnbResource(lnbId);
+ ClientProfile ownerProfile = getClientProfile(releasingLnb.getOwnerClientId());
+ releasingLnb.removeOwner();
+ ownerProfile.releaseLnb(lnbId);
+ }
+
/**
- * Get the owner client's priority from the frontend id.
+ * Get the owner client's priority from the resource id.
*
- * @param frontend an in use frontend.
- * @return the priority of the owner client of the frontend.
+ * @param resource a in use tuner resource.
+ * @return the priority of the owner client of the resource.
*/
- private int getOwnerClientPriority(FrontendResource frontend) {
- return getClientProfile(frontend.getOwnerClientId()).getPriority();
+ private int getOwnerClientPriority(TunerResourceBasic resource) {
+ return getClientProfile(resource.getOwnerClientId()).getPriority();
}
@VisibleForTesting
@@ -644,6 +772,30 @@
@VisibleForTesting
@Nullable
+ protected LnbResource getLnbResource(int lnbId) {
+ return mLnbResources.get(lnbId);
+ }
+
+ @VisibleForTesting
+ protected Map<Integer, LnbResource> getLnbResources() {
+ return mLnbResources;
+ }
+
+ private void addLnbResource(LnbResource newLnb) {
+ // Update resource list and available id list
+ mLnbResources.put(newLnb.getId(), newLnb);
+ }
+
+ private void removeLnbResource(int removingId) {
+ LnbResource lnb = getLnbResource(removingId);
+ if (lnb.isInUse()) {
+ releaseLnbInternal(removingId);
+ }
+ mLnbResources.remove(removingId);
+ }
+
+ @VisibleForTesting
+ @Nullable
protected ClientProfile getClientProfile(int clientId) {
return mClientProfiles.get(clientId);
}
diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
index 13248a0..b9a33df 100644
--- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
@@ -32,6 +32,7 @@
import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
+import android.media.tv.tunerresourcemanager.TunerLnbRequest;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -528,6 +529,94 @@
}
@Test
+ public void requestLnbTest_NoLnbAvailable_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 lnb resources.
+ int[] lnbIds = {0};
+ mTunerResourceManagerService.setLnbInfoListInternal(lnbIds);
+
+ TunerLnbRequest request = new TunerLnbRequest(clientId0[0]);
+ int[] lnbHandle = new int[1];
+ try {
+ assertThat(mTunerResourceManagerService
+ .requestLnbInternal(request, lnbHandle)).isTrue();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]))
+ .isEqualTo(lnbIds[0]);
+
+ request = new TunerLnbRequest(clientId1[0]);
+ try {
+ assertThat(mTunerResourceManagerService
+ .requestLnbInternal(request, lnbHandle)).isTrue();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ assertThat(mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]))
+ .isEqualTo(lnbIds[0]);
+ assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0])
+ .isInUse()).isTrue();
+ assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0])
+ .getOwnerClientId()).isEqualTo(clientId1[0]);
+ assertThat(listener.isRelaimed()).isTrue();
+ }
+
+ @Test
+ public void releaseLnbTest() {
+ // 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 lnb resources.
+ int[] lnbIds = {0};
+ mTunerResourceManagerService.setLnbInfoListInternal(lnbIds);
+
+ TunerLnbRequest request = new TunerLnbRequest(clientId[0]);
+ int[] lnbHandle = new int[1];
+ try {
+ assertThat(mTunerResourceManagerService
+ .requestLnbInternal(request, lnbHandle)).isTrue();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ int lnbId = mTunerResourceManagerService.getResourceIdFromHandle(lnbHandle[0]);
+ assertThat(lnbId).isEqualTo(lnbIds[0]);
+
+ // Release lnb
+ mTunerResourceManagerService.releaseLnbInternal(lnbId);
+ assertThat(mTunerResourceManagerService
+ .getLnbResource(lnbId).isInUse()).isFalse();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(clientId[0]).getInUseLnbIds().size()).isEqualTo(0);
+ }
+
+ @Test
public void unregisterClientTest_usingFrontend() {
// Register client
ResourceClientProfile profile = new ResourceClientProfile("0" /*sessionId*/,