Merge "Complete Lnb update/request/release implementation in TRM" into rvc-dev
This commit is contained in:
@@ -132,11 +132,11 @@ interface ITunerResourceManager {
|
|||||||
* before this request.
|
* before this request.
|
||||||
*
|
*
|
||||||
* @param request {@link TunerFrontendRequest} information of the current 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.
|
* @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.
|
* Requests to share frontend with an existing client.
|
||||||
@@ -240,11 +240,11 @@ interface ITunerResourceManager {
|
|||||||
* <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this request.
|
* <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this request.
|
||||||
*
|
*
|
||||||
* @param request {@link TunerLnbRequest} information of the current 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.
|
* @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.
|
* Notifies the TRM that the given frontend has been released.
|
||||||
@@ -254,9 +254,9 @@ interface ITunerResourceManager {
|
|||||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||||
* before this release.
|
* 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.
|
* Notifies the TRM that the Demux with the given handle was released.
|
||||||
@@ -288,15 +288,15 @@ interface ITunerResourceManager {
|
|||||||
void releaseCasSession(in int sessionResourceId);
|
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>Client must call this whenever it releases an Lnb.
|
||||||
*
|
*
|
||||||
* <p><strong>Note:</strong> {@link #setLnbInfos(int[])} must be called before this release.
|
* <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.
|
* Compare two clients' priority.
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class TunerResourceManager {
|
|||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
public static final int INVALID_RESOURCE_HANDLE = -1;
|
public static final int INVALID_RESOURCE_HANDLE = -1;
|
||||||
|
public static final int INVALID_OWNER_ID = -1;
|
||||||
/**
|
/**
|
||||||
* Tuner resource type to help generate resource handle
|
* Tuner resource type to help generate resource handle
|
||||||
*/
|
*/
|
||||||
@@ -73,6 +74,7 @@ public class TunerResourceManager {
|
|||||||
TUNER_RESOURCE_TYPE_DESCRAMBLER,
|
TUNER_RESOURCE_TYPE_DESCRAMBLER,
|
||||||
TUNER_RESOURCE_TYPE_LNB,
|
TUNER_RESOURCE_TYPE_LNB,
|
||||||
TUNER_RESOURCE_TYPE_CAS_SESSION,
|
TUNER_RESOURCE_TYPE_CAS_SESSION,
|
||||||
|
TUNER_RESOURCE_TYPE_MAX,
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface TunerResourceType {}
|
public @interface TunerResourceType {}
|
||||||
@@ -82,6 +84,7 @@ public class TunerResourceManager {
|
|||||||
public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
|
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_LNB = 3;
|
||||||
public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
|
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 ITunerResourceManager mService;
|
||||||
private final int mUserId;
|
private final int mUserId;
|
||||||
@@ -243,16 +246,16 @@ public class TunerResourceManager {
|
|||||||
* before this request.
|
* before this request.
|
||||||
*
|
*
|
||||||
* @param request {@link TunerFrontendRequest} information of the current request.
|
* @param request {@link TunerFrontendRequest} information of the current request.
|
||||||
* @param frontendId a one-element array to return the granted frontendId. If
|
* @param frontendHandle a one-element array to return the granted frontendHandle. If
|
||||||
* no frontend granted, this will return {@link #INVALID_FRONTEND_ID}.
|
* no frontend granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
|
||||||
*
|
*
|
||||||
* @return true if there is frontend granted.
|
* @return true if there is frontend granted.
|
||||||
*/
|
*/
|
||||||
public boolean requestFrontend(@NonNull TunerFrontendRequest request,
|
public boolean requestFrontend(@NonNull TunerFrontendRequest request,
|
||||||
@Nullable int[] frontendId) {
|
@Nullable int[] frontendHandle) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
try {
|
try {
|
||||||
result = mService.requestFrontend(request, frontendId);
|
result = mService.requestFrontend(request, frontendHandle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -393,15 +396,15 @@ public class TunerResourceManager {
|
|||||||
* <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request.
|
* <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request.
|
||||||
*
|
*
|
||||||
* @param request {@link TunerLnbRequest} information of the current 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.
|
||||||
* If no Lnb granted, this will return {@link #INVALID_LNB_ID}.
|
* If no Lnb granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
|
||||||
*
|
*
|
||||||
* @return true if there is Lnb granted.
|
* @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;
|
boolean result = false;
|
||||||
try {
|
try {
|
||||||
result = mService.requestLnb(request, lnbId);
|
result = mService.requestLnb(request, lnbHandle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
@@ -481,11 +484,11 @@ public class TunerResourceManager {
|
|||||||
*
|
*
|
||||||
* <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this release.
|
* <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 {
|
try {
|
||||||
mService.releaseLnb(lnbId);
|
mService.releaseLnb(lnbHandle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ public final class ClientProfile {
|
|||||||
*/
|
*/
|
||||||
private Set<Integer> mUsingFrontendIds = new HashSet<>();
|
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.
|
* Optional arbitrary priority value given by the client.
|
||||||
*
|
*
|
||||||
@@ -146,6 +151,30 @@ public final class ClientProfile {
|
|||||||
mUsingFrontendIds.remove(frontendId);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ClientProfile[id=" + this.mId + ", tvInputSessionId=" + this.mTvInputSessionId
|
return "ClientProfile[id=" + this.mId + ", tvInputSessionId=" + this.mTvInputSessionId
|
||||||
|
|||||||
@@ -27,14 +27,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class FrontendResource {
|
public final class FrontendResource extends TunerResourceBasic {
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see {@link android.media.tv.tuner.frontend.FrontendSettings.Type}
|
* see {@link android.media.tv.tuner.frontend.FrontendSettings.Type}
|
||||||
@@ -51,28 +44,12 @@ public final class FrontendResource {
|
|||||||
*/
|
*/
|
||||||
private Set<Integer> mExclusiveGroupMemberFeIds = new HashSet<>();
|
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) {
|
private FrontendResource(Builder builder) {
|
||||||
this.mId = builder.mId;
|
super(builder);
|
||||||
this.mType = builder.mType;
|
this.mType = builder.mType;
|
||||||
this.mExclusiveGroupId = builder.mExclusiveGroupId;
|
this.mExclusiveGroupId = builder.mExclusiveGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return mId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() {
|
public int getType() {
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
@@ -112,32 +89,6 @@ public final class FrontendResource {
|
|||||||
mExclusiveGroupMemberFeIds.remove(id);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "FrontendResource[id=" + this.mId + ", type=" + this.mType
|
return "FrontendResource[id=" + this.mId + ", type=" + this.mType
|
||||||
@@ -149,13 +100,12 @@ public final class FrontendResource {
|
|||||||
/**
|
/**
|
||||||
* Builder class for {@link FrontendResource}.
|
* Builder class for {@link FrontendResource}.
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder extends TunerResourceBasic.Builder {
|
||||||
private final int mId;
|
|
||||||
@Type private int mType;
|
@Type private int mType;
|
||||||
private int mExclusiveGroupId;
|
private int mExclusiveGroupId;
|
||||||
|
|
||||||
Builder(int id) {
|
Builder(int id) {
|
||||||
this.mId = id;
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,6 +133,7 @@ public final class FrontendResource {
|
|||||||
*
|
*
|
||||||
* @return {@link FrontendResource}.
|
* @return {@link FrontendResource}.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public FrontendResource build() {
|
public FrontendResource build() {
|
||||||
FrontendResource frontendResource = new FrontendResource(this);
|
FrontendResource frontendResource = new FrontendResource(this);
|
||||||
return frontendResource;
|
return frontendResource;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,6 +63,8 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
|
|
||||||
// Map of the current available frontend resources
|
// Map of the current available frontend resources
|
||||||
private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();
|
private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();
|
||||||
|
// Map of the current available lnb resources
|
||||||
|
private Map<Integer, LnbResource> mLnbResources = new HashMap<>();
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>();
|
private Map<Integer, ResourcesReclaimListenerRecord> mListeners = new HashMap<>();
|
||||||
@@ -164,12 +166,13 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLnbInfoList(int[] lnbIds) {
|
public void setLnbInfoList(int[] lnbIds) throws RemoteException {
|
||||||
enforceTrmAccessPermission("setLnbInfoList");
|
enforceTrmAccessPermission("setLnbInfoList");
|
||||||
if (DEBUG) {
|
if (lnbIds == null) {
|
||||||
for (int i = 0; i < lnbIds.length; i++) {
|
throw new RemoteException("Lnb id list can't be null");
|
||||||
Slog.d(TAG, "updateLnbInfo(lnbId=" + lnbIds[i] + ")");
|
}
|
||||||
}
|
synchronized (mLock) {
|
||||||
|
setLnbInfoListInternal(lnbIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,14 +240,20 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) {
|
public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle)
|
||||||
|
throws RemoteException {
|
||||||
enforceTunerAccessPermission("requestLnb");
|
enforceTunerAccessPermission("requestLnb");
|
||||||
enforceTrmAccessPermission("requestLnb");
|
enforceTrmAccessPermission("requestLnb");
|
||||||
if (DEBUG) {
|
if (lnbHandle == null) {
|
||||||
Slog.d(TAG, "requestLnb(request=" + request + ")");
|
throw new RemoteException("lnbHandle can't be null");
|
||||||
|
}
|
||||||
|
synchronized (mLock) {
|
||||||
|
try {
|
||||||
|
return requestLnbInternal(request, lnbHandle);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -287,11 +296,14 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseLnb(int lnbId) {
|
public void releaseLnb(int lnbHandle) throws RemoteException {
|
||||||
enforceTunerAccessPermission("releaseLnb");
|
enforceTunerAccessPermission("releaseLnb");
|
||||||
enforceTrmAccessPermission("releaseLnb");
|
enforceTrmAccessPermission("releaseLnb");
|
||||||
if (DEBUG) {
|
if (!validateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB, lnbHandle)) {
|
||||||
Slog.d(TAG, "releaseLnb(lnbId=" + lnbId + ")");
|
throw new RemoteException("lnbHandle can't be invalid");
|
||||||
|
}
|
||||||
|
synchronized (mLock) {
|
||||||
|
releaseLnbInternal(getResourceIdFromHandle(lnbHandle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +416,38 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@VisibleForTesting
|
||||||
protected boolean requestFrontendInternal(TunerFrontendRequest request, int[] frontendHandle)
|
protected boolean requestFrontendInternal(TunerFrontendRequest request, int[] frontendHandle)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
@@ -458,8 +502,8 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
if (inUseLowestPriorityFrId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
|
if (inUseLowestPriorityFrId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
|
||||||
frontendHandle[0] = generateResourceHandle(
|
frontendHandle[0] = generateResourceHandle(
|
||||||
TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
|
TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
|
||||||
reclaimFrontendResource(getFrontendResource(
|
reclaimResource(getFrontendResource(inUseLowestPriorityFrId).getOwnerClientId(),
|
||||||
inUseLowestPriorityFrId).getOwnerClientId());
|
TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
|
||||||
updateFrontendClientMappingOnNewGrant(inUseLowestPriorityFrId, request.getClientId());
|
updateFrontendClientMappingOnNewGrant(inUseLowestPriorityFrId, request.getClientId());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -467,6 +511,62 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@VisibleForTesting
|
||||||
void releaseFrontendInternal(int frontendId) {
|
void releaseFrontendInternal(int frontendId) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -475,6 +575,14 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
updateFrontendClientMappingOnRelease(frontendId);
|
updateFrontendClientMappingOnRelease(frontendId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void releaseLnbInternal(int lnbId) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "releaseLnb(lnbId=" + lnbId + ")");
|
||||||
|
}
|
||||||
|
updateLnbClientMappingOnRelease(lnbId);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) {
|
boolean requestDemuxInternal(TunerDemuxRequest request, int[] demuxHandle) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -542,12 +650,18 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@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 {
|
try {
|
||||||
mListeners.get(reclaimingId).getListener().onReclaimResources();
|
mListeners.get(reclaimingId).getListener().onReclaimResources();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingId, e);
|
Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingId, e);
|
||||||
}
|
}
|
||||||
|
// TODO clean all the client and resources mapping/ownership
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -591,14 +705,28 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
* @param resource a in use tuner resource.
|
||||||
* @return the priority of the owner client of the frontend.
|
* @return the priority of the owner client of the resource.
|
||||||
*/
|
*/
|
||||||
private int getOwnerClientPriority(FrontendResource frontend) {
|
private int getOwnerClientPriority(TunerResourceBasic resource) {
|
||||||
return getClientProfile(frontend.getOwnerClientId()).getPriority();
|
return getClientProfile(resource.getOwnerClientId()).getPriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -642,6 +770,30 @@ public class TunerResourceManagerService extends SystemService {
|
|||||||
mFrontendResources.remove(removingId);
|
mFrontendResources.remove(removingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
protected ClientProfile getClientProfile(int clientId) {
|
protected ClientProfile getClientProfile(int clientId) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
|
|||||||
import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
|
import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
|
||||||
import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
|
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.TunerResourceManager;
|
import android.media.tv.tunerresourcemanager.TunerResourceManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
@@ -527,6 +528,94 @@ public class TunerResourceManagerServiceTest {
|
|||||||
.getClientProfile(clientId[0]).getInUseFrontendIds().size()).isEqualTo(0);
|
.getClientProfile(clientId[0]).getInUseFrontendIds().size()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void unregisterClientTest_usingFrontend() {
|
public void unregisterClientTest_usingFrontend() {
|
||||||
// Register client
|
// Register client
|
||||||
|
|||||||
Reference in New Issue
Block a user