Merge changes from topic "tuner-rm"
* changes: Add a TunerResourceManagerService as an Android System Serivce. Add Lnb related APIs into the TunerResourceManager interface Add Cas related APIs into the Tuner Resource Manager Adding ITunerResourceManagerService interface into android.media.tv
This commit is contained in:
@@ -109,6 +109,8 @@ import android.media.session.MediaSessionManager;
|
||||
import android.media.soundtrigger.SoundTriggerManager;
|
||||
import android.media.tv.ITvInputManager;
|
||||
import android.media.tv.TvInputManager;
|
||||
import android.media.tv.tuner.ITunerResourceManager;
|
||||
import android.media.tv.tuner.TunerResourceManager;
|
||||
import android.net.ConnectivityDiagnosticsManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.ConnectivityThread;
|
||||
@@ -937,6 +939,17 @@ public final class SystemServiceRegistry {
|
||||
return new TvInputManager(service, ctx.getUserId());
|
||||
}});
|
||||
|
||||
registerService(Context.TV_TUNER_RESOURCE_MGR_SERVICE, TunerResourceManager.class,
|
||||
new CachedServiceFetcher<TunerResourceManager>() {
|
||||
@Override
|
||||
public TunerResourceManager createService(ContextImpl ctx)
|
||||
throws ServiceNotFoundException {
|
||||
IBinder iBinder =
|
||||
ServiceManager.getServiceOrThrow(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
|
||||
ITunerResourceManager service = ITunerResourceManager.Stub.asInterface(iBinder);
|
||||
return new TunerResourceManager(service, ctx.getUserId());
|
||||
}});
|
||||
|
||||
registerService(Context.NETWORK_SCORE_SERVICE, NetworkScoreManager.class,
|
||||
new CachedServiceFetcher<NetworkScoreManager>() {
|
||||
@Override
|
||||
|
||||
@@ -3457,6 +3457,7 @@ public abstract class Context {
|
||||
CONSUMER_IR_SERVICE,
|
||||
//@hide: TRUST_SERVICE,
|
||||
TV_INPUT_SERVICE,
|
||||
//@hide: TV_TUNER_RESOURCE_MGR_SERVICE,
|
||||
//@hide: NETWORK_SCORE_SERVICE,
|
||||
USAGE_STATS_SERVICE,
|
||||
MEDIA_SESSION_SERVICE,
|
||||
@@ -4756,6 +4757,17 @@ public abstract class Context {
|
||||
*/
|
||||
public static final String TV_INPUT_SERVICE = "tv_input";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService(String)} to retrieve a
|
||||
* {@link android.media.tv.TunerResourceManager} for interacting with TV
|
||||
* tuner resources on the device.
|
||||
*
|
||||
* @see #getSystemService(String)
|
||||
* @see android.media.tv.TunerResourceManager
|
||||
* @hide
|
||||
*/
|
||||
public static final String TV_TUNER_RESOURCE_MGR_SERVICE = "tv_tuner_resource_mgr";
|
||||
|
||||
/**
|
||||
* {@link android.net.NetworkScoreManager} for managing network scoring.
|
||||
* @see #getSystemService(String)
|
||||
|
||||
24
media/java/android/media/tv/tuner/CasSessionRequest.aidl
Normal file
24
media/java/android/media/tv/tuner/CasSessionRequest.aidl
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* A wrapper of a cas session requests that contains all the request info of the client.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
parcelable CasSessionRequest;
|
||||
114
media/java/android/media/tv/tuner/CasSessionRequest.java
Normal file
114
media/java/android/media/tv/tuner/CasSessionRequest.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Information required to request a Cas Session.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class CasSessionRequest implements Parcelable {
|
||||
static final String TAG = "CasSessionRequest";
|
||||
|
||||
public static final
|
||||
@NonNull
|
||||
Parcelable.Creator<CasSessionRequest> CREATOR =
|
||||
new Parcelable.Creator<CasSessionRequest>() {
|
||||
@Override
|
||||
public CasSessionRequest createFromParcel(Parcel source) {
|
||||
try {
|
||||
return new CasSessionRequest(source);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating CasSessionRequest from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CasSessionRequest[] newArray(int size) {
|
||||
return new CasSessionRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Client id of the client that sends the request.
|
||||
*/
|
||||
private final int mClientId;
|
||||
|
||||
/**
|
||||
* System id of the requested cas.
|
||||
*/
|
||||
private final int mCasSystemId;
|
||||
|
||||
private CasSessionRequest(@NonNull Parcel source) {
|
||||
mClientId = source.readInt();
|
||||
mCasSystemId = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link CasSessionRequest} with the given parameters.
|
||||
*
|
||||
* @param clientId id of the client.
|
||||
* @param casSystemId the cas system id that the client is requesting.
|
||||
*/
|
||||
public CasSessionRequest(int clientId,
|
||||
int casSystemId) {
|
||||
mClientId = clientId;
|
||||
mCasSystemId = casSystemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the client.
|
||||
*/
|
||||
public int getClientId() {
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cas system id requested.
|
||||
*/
|
||||
public int getCasSystemId() {
|
||||
return mCasSystemId;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder(128);
|
||||
b.append("CasSessionRequest {clientId=").append(mClientId);
|
||||
b.append(", casSystemId=").append(mCasSystemId);
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mClientId);
|
||||
dest.writeInt(mCasSystemId);
|
||||
}
|
||||
}
|
||||
244
media/java/android/media/tv/tuner/ITunerResourceManager.aidl
Normal file
244
media/java/android/media/tv/tuner/ITunerResourceManager.aidl
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.media.tv.tuner.CasSessionRequest;
|
||||
import android.media.tv.tuner.ITunerResourceManagerListener;
|
||||
import android.media.tv.tuner.ResourceClientProfile;
|
||||
import android.media.tv.tuner.TunerFrontendInfo;
|
||||
import android.media.tv.tuner.TunerFrontendRequest;
|
||||
import android.media.tv.tuner.TunerLnbRequest;
|
||||
|
||||
/**
|
||||
* Interface of the Tuner Resource Manager. It manages resources used by TV Tuners.
|
||||
* <p>Resources include:
|
||||
* <ul>
|
||||
* <li>TunerFrontend {@link android.media.tv.tuner.frontend}.
|
||||
* <li>TunerLnb {@link android.media.tv.tuner.Lnb}.
|
||||
* <li>MediaCas {@link android.media.MediaCas}.
|
||||
* <li>TvInputHardware {@link android.media.tv.TvInputHardwareInfo}.
|
||||
* <ul>
|
||||
*
|
||||
* <p>Expected workflow is:
|
||||
* <ul>
|
||||
* <li>Tuner Java/MediaCas/TIF update resources of the current device with TRM.
|
||||
* <li>Client registers its profile through {@link #registerClientProfile(ResourceClientProfile,
|
||||
* ITunerResourceManagerListener, int[])}.
|
||||
* <li>Client requests resources through request APIs.
|
||||
* <li>If the resource needs to be handed to a higher priority client from a lower priority
|
||||
* one, TRM calls ITunerResourceManagerListener registered by the lower priority client to release
|
||||
* the resource.
|
||||
* <ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface ITunerResourceManager {
|
||||
/*
|
||||
* This API is used by the client to register their profile with the Tuner Resource manager.
|
||||
*
|
||||
* <p>The profile contains information that can show the base priority score of the client.
|
||||
*
|
||||
* @param profile {@link ResourceClientProfile} profile of the current client
|
||||
* @param listener {@link ITunerResourceManagerListener} a callback to
|
||||
* reclaim clients' resources when needed.
|
||||
* @param clientId returns a clientId from the resource manager when the
|
||||
* the client registers its profile.
|
||||
*/
|
||||
void registerClientProfile(in ResourceClientProfile profile,
|
||||
ITunerResourceManagerListener listener, out int[] clientId);
|
||||
|
||||
/*
|
||||
* This API is used by the client to unregister their profile with the Tuner Resource manager.
|
||||
*
|
||||
* @param clientId the client id that needs to be unregistered.
|
||||
*/
|
||||
void unregisterClientProfile(in int clientId);
|
||||
|
||||
/*
|
||||
* Updates a registered client's priority and niceValue.
|
||||
*
|
||||
* @param clientId the id of the client that is updating its profile.
|
||||
* @param priority the priority that the client would like to update to.
|
||||
* @param niceValue the nice value that the client would like to update to.
|
||||
*
|
||||
* @return true if the update is successful.
|
||||
*/
|
||||
boolean updateClientPriority(in int clientId, in int priority, in int niceValue);
|
||||
|
||||
/*
|
||||
* Updates the available Frontend resources information on the current device.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestFrontend(TunerFrontendRequest,int[])} and {@link #releaseFrontend(int)} call.
|
||||
*
|
||||
* @param infos an array of the available {@link TunerFrontendInfo} information.
|
||||
*/
|
||||
void setFrontendInfoList(in TunerFrontendInfo[] infos);
|
||||
|
||||
/*
|
||||
* Updates the available Cas resource information on the current device.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int)} call.
|
||||
*
|
||||
* @param casSystemId id of the updating CAS system.
|
||||
* @param maxSessionNum the max session number of the CAS system that is updated.
|
||||
*/
|
||||
void updateCasInfo(in int casSystemId, in int maxSessionNum);
|
||||
|
||||
/*
|
||||
* Updates the available Lnb resource information on the current device.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int)} call.
|
||||
*
|
||||
* @param lnbIds ids of the updating lnbs.
|
||||
*/
|
||||
void setLnbInfoList(in int[] lnbIds);
|
||||
|
||||
/*
|
||||
* This API is used by the Tuner framework to request an available frontend from the TunerHAL.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is frontend available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Frontend is available but the current request info can show higher priority than
|
||||
* other uses of Frontend, the API will send
|
||||
* {@link ITunerResourceManagerListener#onResourcesReclaim()} to the {@link Tuner}. Tuner would
|
||||
* handle the resource reclaim on the holder of lower priority and notify the holder of its
|
||||
* resource loss.
|
||||
*
|
||||
* <li>If no frontend can be granted, the API would return false.
|
||||
* <ul>
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this request.
|
||||
*
|
||||
* @param request {@link TunerFrontendRequest} information of the current request.
|
||||
* @param frontendId a one-element array to return the granted frontendId.
|
||||
*
|
||||
* @return true if there is frontend granted.
|
||||
*/
|
||||
boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendId);
|
||||
|
||||
/*
|
||||
* Requests to share frontend with an existing client.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this request.
|
||||
*
|
||||
* @param selfClientId the id of the client that sends the request.
|
||||
* @param targetClientId the id of the client to share the frontend with.
|
||||
*/
|
||||
void shareFrontend(in int selfClientId, in int targetClientId);
|
||||
|
||||
/*
|
||||
* This API is used by the Tuner framework to request an available Cas session. This session
|
||||
* needs to be under the CAS system with the id indicated in the {@code request}.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is Cas session available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Cas session is available but the current request info can show higher priority than
|
||||
* other uses of the sessions under the requested CAS system, the API will send
|
||||
* {@link ITunerResourceManagerCallback#onResourcesReclaim()} to the {@link Tuner}. Tuner would
|
||||
* handle the resource reclaim on the holder of lower priority and notify the holder of its
|
||||
* resource loss.
|
||||
*
|
||||
* <li>If no Cas session can be granted, the API would return false.
|
||||
* <ul>
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request.
|
||||
*
|
||||
* @param request {@link CasSessionRequest} information of the current request.
|
||||
* @param sessionResourceId a one-element array to return the granted cas session id.
|
||||
*
|
||||
* @return true if there is CAS session granted.
|
||||
*/
|
||||
boolean requestCasSession(in CasSessionRequest request, out int[] sessionResourceId);
|
||||
|
||||
/*
|
||||
* This API is used by the Tuner framework to request an available Lnb from the TunerHAL.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is Lnb available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Lnb is available but the current request has a higher priority than other uses of
|
||||
* lnbs, the API will send {@link ITunerResourceManagerCallback#onResourcesReclaim()} to the
|
||||
* {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
|
||||
* notify the holder of its resource loss.
|
||||
*
|
||||
* <li>If no Lnb system can be granted, the API would return false.
|
||||
* <ul>
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* @return true if there is Lnb granted.
|
||||
*/
|
||||
boolean requestLnb(in TunerLnbRequest request, out int[] lnbId);
|
||||
|
||||
/*
|
||||
* Notifies the TRM that the given frontend has been released.
|
||||
*
|
||||
* <p>Client must call this whenever it releases a Tuner frontend.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this release.
|
||||
*
|
||||
* @param frontendId the id of the released frontend.
|
||||
*/
|
||||
void releaseFrontend(in int frontendId);
|
||||
|
||||
/*
|
||||
* Notifies the TRM that the given Cas session has been released.
|
||||
*
|
||||
* <p>Client must call this whenever it releases a Cas session.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this release.
|
||||
*
|
||||
* @param sessionResourceId the id of the released CAS session.
|
||||
*/
|
||||
void releaseCasSession(in int sessionResourceId);
|
||||
|
||||
/*
|
||||
* Notifies the TRM that the Lnb with the given id 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.
|
||||
*/
|
||||
void releaseLnb(in int lnbId);
|
||||
|
||||
/*
|
||||
* Compare two clients' priority.
|
||||
*
|
||||
* @param challengerProfile the {@link ResourceClientProfile} of the challenger.
|
||||
* @param holderProfile the {@link ResourceClientProfile} of the holder of the resource.
|
||||
*
|
||||
* @return true if the challenger has higher priority than the holder.
|
||||
*/
|
||||
boolean isHigherPriority(in ResourceClientProfile challengerProfile,
|
||||
in ResourceClientProfile holderProfile);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* Interface to receive callbacks from ITunerResourceManager.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ITunerResourceManagerListener {
|
||||
/*
|
||||
* TRM invokes this method when the client's resources need to be reclaimed.
|
||||
*
|
||||
* <p>This method is implemented in Tuner Framework to take the reclaiming
|
||||
* actions. It's a synchonized call. TRM would wait on the call to finish
|
||||
* then grant the resource.
|
||||
*/
|
||||
void onResourcesReclaim();
|
||||
}
|
||||
25
media/java/android/media/tv/tuner/ResourceClientProfile.aidl
Normal file
25
media/java/android/media/tv/tuner/ResourceClientProfile.aidl
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* A profile of a resource client. This profile is used to register the client info
|
||||
* with the Tuner Resource Manager.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
parcelable ResourceClientProfile;
|
||||
129
media/java/android/media/tv/tuner/ResourceClientProfile.java
Normal file
129
media/java/android/media/tv/tuner/ResourceClientProfile.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A profile of a resource client. This profile is used to register the client info
|
||||
* with the Tuner Resource Manager(TRM).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ResourceClientProfile implements Parcelable {
|
||||
static final String TAG = "ResourceClientProfile";
|
||||
|
||||
public static final
|
||||
@NonNull
|
||||
Parcelable.Creator<ResourceClientProfile> CREATOR =
|
||||
new Parcelable.Creator<ResourceClientProfile>() {
|
||||
@Override
|
||||
public ResourceClientProfile createFromParcel(Parcel source) {
|
||||
try {
|
||||
return new ResourceClientProfile(source);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating ResourceClientProfile from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceClientProfile[] newArray(int size) {
|
||||
return new ResourceClientProfile[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is used by TRM to get TV App’s processId from TIF.
|
||||
* The processId will be used to identify foreground applications.
|
||||
*
|
||||
* <p>MediaCas, Tuner and TvInputHardwareManager get tvInputSessionId from TIS.
|
||||
* If mTvInputSessionId is UNKNOWN, the client is always background.
|
||||
*/
|
||||
private final String mTvInputSessionId;
|
||||
|
||||
/**
|
||||
* Usage of the client.
|
||||
*/
|
||||
private final int mUseCase;
|
||||
|
||||
private ResourceClientProfile(@NonNull Parcel source) {
|
||||
mTvInputSessionId = source.readString();
|
||||
mUseCase = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link ResourceClientProfile} with the given parameters.
|
||||
*
|
||||
* @param tvInputSessionId the unique id of the session owned by the client.
|
||||
* @param useCase the usage of the client. Suggested priority hints are
|
||||
* {@link android.media.tv.TvInputService.PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK}
|
||||
* {@link android.media.tv.TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE}
|
||||
* {@link android.media.tv.TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD}.
|
||||
* New [use case : priority value] pair can be defined in the manifest by the
|
||||
* OEM. Any undefined use case would cause IllegalArgumentException.
|
||||
*/
|
||||
public ResourceClientProfile(@NonNull String tvInputSessionId,
|
||||
int useCase) {
|
||||
mTvInputSessionId = tvInputSessionId;
|
||||
mUseCase = useCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tv input session id of the client.
|
||||
*
|
||||
* @return the value of the tv input session id.
|
||||
*/
|
||||
@NonNull
|
||||
public String getTvInputSessionId() {
|
||||
return mTvInputSessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user usage of the client.
|
||||
*
|
||||
* @return the value of use case.
|
||||
*/
|
||||
public int getUseCase() {
|
||||
return mUseCase;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder(128);
|
||||
b.append("ResourceClientProfile {tvInputSessionId=").append(mTvInputSessionId);
|
||||
b.append(", useCase=").append(mUseCase);
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString(mTvInputSessionId);
|
||||
dest.writeInt(mUseCase);
|
||||
}
|
||||
}
|
||||
24
media/java/android/media/tv/tuner/TunerFrontendInfo.aidl
Normal file
24
media/java/android/media/tv/tuner/TunerFrontendInfo.aidl
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* Simple container of the FrontendInfo struct defined in the TunerHAL 1.0 interface.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
parcelable TunerFrontendInfo;
|
||||
141
media/java/android/media/tv/tuner/TunerFrontendInfo.java
Normal file
141
media/java/android/media/tv/tuner/TunerFrontendInfo.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.media.tv.tuner.frontend.FrontendSettings.Type;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Simple container of the FrontendInfo struct defined in the TunerHAL 1.0 interface.
|
||||
*
|
||||
* <p>Note that this object is defined to pass necessary frontend info between the
|
||||
* Tuner Resource Manager and the client. It includes partial information in
|
||||
* {@link FrontendInfo}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class TunerFrontendInfo implements Parcelable {
|
||||
static final String TAG = "TunerFrontendInfo";
|
||||
|
||||
public static final
|
||||
@NonNull
|
||||
Parcelable.Creator<TunerFrontendInfo> CREATOR =
|
||||
new Parcelable.Creator<TunerFrontendInfo>() {
|
||||
@Override
|
||||
public TunerFrontendInfo createFromParcel(Parcel source) {
|
||||
try {
|
||||
return new TunerFrontendInfo(source);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating TunerFrontendInfo from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TunerFrontendInfo[] newArray(int size) {
|
||||
return new TunerFrontendInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final int mId;
|
||||
|
||||
@Type
|
||||
private final int mFrontendType;
|
||||
|
||||
/**
|
||||
* Frontends are assigned with the same exclusiveGroupId if they can't
|
||||
* function at same time. For instance, they share same hardware module.
|
||||
*/
|
||||
private final int mExclusiveGroupId;
|
||||
|
||||
private TunerFrontendInfo(@NonNull Parcel source) {
|
||||
mId = source.readInt();
|
||||
mFrontendType = source.readInt();
|
||||
mExclusiveGroupId = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link TunerFrontendInfo} with the given parameters.
|
||||
*
|
||||
* @param frontendType the type of the frontend.
|
||||
* @param exclusiveGroupId the group id of the frontend. FE with the same
|
||||
group id can't function at the same time.
|
||||
*/
|
||||
public TunerFrontendInfo(int id,
|
||||
@Type int frontendType,
|
||||
int exclusiveGroupId) {
|
||||
mId = id;
|
||||
mFrontendType = frontendType;
|
||||
mExclusiveGroupId = exclusiveGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the frontend id.
|
||||
*
|
||||
* @return the value of the frontend id.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application id that requests the tuner frontend resource.
|
||||
*
|
||||
* @return the value of the frontend type.
|
||||
*/
|
||||
@Type
|
||||
public int getFrontendType() {
|
||||
return mFrontendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exclusiveGroupId. Frontends with the same exclusiveGroupId
|
||||
* can't function at same time.
|
||||
*
|
||||
* @return the value of the exclusive group id.
|
||||
*/
|
||||
public int getExclusiveGroupId() {
|
||||
return mExclusiveGroupId;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder(128);
|
||||
b.append("TunerFrontendInfo {id=").append(mId);
|
||||
b.append(", frontendType=").append(mFrontendType);
|
||||
b.append(", exclusiveGroupId=").append(mExclusiveGroupId);
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mId);
|
||||
dest.writeInt(mFrontendType);
|
||||
dest.writeInt(mExclusiveGroupId);
|
||||
}
|
||||
}
|
||||
24
media/java/android/media/tv/tuner/TunerFrontendRequest.aidl
Normal file
24
media/java/android/media/tv/tuner/TunerFrontendRequest.aidl
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* Information required to request a Tuner Frontend.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
parcelable TunerFrontendRequest;
|
||||
114
media/java/android/media/tv/tuner/TunerFrontendRequest.java
Normal file
114
media/java/android/media/tv/tuner/TunerFrontendRequest.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.media.tv.tuner.frontend.FrontendSettings.Type;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Information required to request a Tuner Frontend.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class TunerFrontendRequest implements Parcelable {
|
||||
static final String TAG = "TunerFrontendRequest";
|
||||
|
||||
public static final
|
||||
@NonNull
|
||||
Parcelable.Creator<TunerFrontendRequest> CREATOR =
|
||||
new Parcelable.Creator<TunerFrontendRequest>() {
|
||||
@Override
|
||||
public TunerFrontendRequest createFromParcel(Parcel source) {
|
||||
try {
|
||||
return new TunerFrontendRequest(source);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating TunerFrontendRequest from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TunerFrontendRequest[] newArray(int size) {
|
||||
return new TunerFrontendRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final int mClientId;
|
||||
@Type
|
||||
private final int mFrontendType;
|
||||
|
||||
private TunerFrontendRequest(@NonNull Parcel source) {
|
||||
mClientId = source.readInt();
|
||||
mFrontendType = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link TunerFrontendRequest} with the given parameters.
|
||||
*
|
||||
* @param clientId the unique id of the client returned when registering profile.
|
||||
* @param frontendType the type of the requested frontend.
|
||||
*/
|
||||
public TunerFrontendRequest(int clientId,
|
||||
@Type int frontendType) {
|
||||
mClientId = clientId;
|
||||
mFrontendType = frontendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the client id that requests the tuner frontend resource.
|
||||
*
|
||||
* @return the value of the client id.
|
||||
*/
|
||||
public int getClientId() {
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the frontend type that the client requests for.
|
||||
*
|
||||
* @return the value of the requested frontend type.
|
||||
*/
|
||||
@Type
|
||||
public int getFrontendType() {
|
||||
return mFrontendType;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder(128);
|
||||
b.append("TunerFrontendRequest {clientId=").append(mClientId);
|
||||
b.append(", frontendType=").append(mFrontendType);
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mClientId);
|
||||
dest.writeInt(mFrontendType);
|
||||
}
|
||||
}
|
||||
24
media/java/android/media/tv/tuner/TunerLnbRequest.aidl
Normal file
24
media/java/android/media/tv/tuner/TunerLnbRequest.aidl
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
/**
|
||||
* Information required to request a Tuner Lnb.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
parcelable TunerLnbRequest;
|
||||
96
media/java/android/media/tv/tuner/TunerLnbRequest.java
Normal file
96
media/java/android/media/tv/tuner/TunerLnbRequest.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Information required to request a Tuner Lnb.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class TunerLnbRequest implements Parcelable {
|
||||
static final String TAG = "TunerLnbRequest";
|
||||
|
||||
public static final
|
||||
@NonNull
|
||||
Parcelable.Creator<TunerLnbRequest> CREATOR =
|
||||
new Parcelable.Creator<TunerLnbRequest>() {
|
||||
@Override
|
||||
public TunerLnbRequest createFromParcel(Parcel source) {
|
||||
try {
|
||||
return new TunerLnbRequest(source);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception creating TunerLnbRequest from parcel", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TunerLnbRequest[] newArray(int size) {
|
||||
return new TunerLnbRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Client id of the client that sends the request.
|
||||
*/
|
||||
private final int mClientId;
|
||||
|
||||
private TunerLnbRequest(@NonNull Parcel source) {
|
||||
mClientId = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link TunerLnbRequest} with the given parameters.
|
||||
*
|
||||
* @param clientId the id of the client.
|
||||
*/
|
||||
public TunerLnbRequest(int clientId) {
|
||||
mClientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the client
|
||||
*/
|
||||
public int getClientId() {
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder(128);
|
||||
b.append("TunerLnbRequest {clientId=").append(mClientId);
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mClientId);
|
||||
}
|
||||
}
|
||||
407
media/java/android/media/tv/tuner/TunerResourceManager.java
Normal file
407
media/java/android/media/tv/tuner/TunerResourceManager.java
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* 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 android.media.tv.tuner;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresFeature;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Interface of the Tuner Resource Manager(TRM). It manages resources used by TV Tuners.
|
||||
* <p>Resources include:
|
||||
* <ul>
|
||||
* <li>TunerFrontend {@link android.media.tv.tuner.frontend}.
|
||||
* <li>TunerLnb {@link android.media.tv.tuner.Lnb}.
|
||||
* <li>MediaCas {@link android.media.MediaCas}.
|
||||
* <ul>
|
||||
*
|
||||
* <p>Expected workflow is:
|
||||
* <ul>
|
||||
* <li>Tuner Java/MediaCas/TIF update resources of the current device with TRM.
|
||||
* <li>Client registers its profile through {@link #registerClientProfile(ResourceClientProfile,
|
||||
* Executor, ResourceListener, int[])}.
|
||||
* <li>Client requests resources through request APIs.
|
||||
* <li>If the resource needs to be handed to a higher priority client from a lower priority
|
||||
* one, TRM calls ITunerResourceManagerListener registered by the lower priority client to release
|
||||
* the resource.
|
||||
* <ul>
|
||||
*
|
||||
* <p>TRM also exposes its priority comparison algorithm as a helping method to other services.
|
||||
* {@see #isHigherPriority(ResourceClientProfile, ResourceClientProfile)}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresFeature(PackageManager.FEATURE_LIVE_TV)
|
||||
@SystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE)
|
||||
public class TunerResourceManager {
|
||||
private static final String TAG = "TunerResourceManager";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
public static final int INVALID_FRONTEND_ID = -1;
|
||||
public static final int INVALID_CAS_SESSION_RESOURCE_ID = -1;
|
||||
public static final int INVALID_LNB_ID = -1;
|
||||
public static final int INVALID_TV_INPUT_DEVICE_ID = -1;
|
||||
public static final int INVALID_TV_INPUT_PORT_ID = -1;
|
||||
|
||||
private final ITunerResourceManager mService;
|
||||
private final int mUserId;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public TunerResourceManager(ITunerResourceManager service, int userId) {
|
||||
mService = service;
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is used by the client to register their profile with the Tuner Resource manager.
|
||||
*
|
||||
* <p>The profile contains information that can show the base priority score of the client.
|
||||
*
|
||||
* @param profile {@link ResourceClientProfile} profile of the current client. Undefined use
|
||||
* case would cause IllegalArgumentException.
|
||||
* @param executor the executor on which the listener would be invoked.
|
||||
* @param listener {@link ResourceListener} callback to reclaim clients' resources when needed.
|
||||
* @param clientId returned a clientId from the resource manager when the
|
||||
* the client registeres.
|
||||
* @throws IllegalArgumentException when {@code profile} contains undefined use case.
|
||||
*/
|
||||
public void registerClientProfile(@NonNull ResourceClientProfile profile,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull ResourceListener listener,
|
||||
@NonNull int[] clientId) {
|
||||
// TODO: throw new IllegalArgumentException("Unknown client use case")
|
||||
// when the use case is not defined.
|
||||
try {
|
||||
mService.registerClientProfile(profile,
|
||||
new ITunerResourceManagerListener.Stub() {
|
||||
@Override
|
||||
public void onResourcesReclaim() {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
executor.execute(() -> listener.onResourcesReclaim());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}, clientId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is used by the client to unregister their profile with the
|
||||
* Tuner Resource manager.
|
||||
*
|
||||
* @param clientId the client id that needs to be unregistered.
|
||||
*/
|
||||
public void unregisterClientProfile(int clientId) {
|
||||
try {
|
||||
mService.unregisterClientProfile(clientId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is used by client to update its registered {@link ResourceClientProfile}.
|
||||
*
|
||||
* <p>We recommend creating a new tuner instance for different use cases instead of using this
|
||||
* API since different use cases may need different resources.
|
||||
*
|
||||
* <p>If TIS updates use case, it needs to ensure underneath resources are exchangeable between
|
||||
* two different use cases.
|
||||
*
|
||||
* <p>Only the arbitrary priority and niceValue are allowed to be updated.
|
||||
*
|
||||
* @param clientId the id of the client that is updating its profile.
|
||||
* @param priority the priority that the client would like to update to.
|
||||
* @param niceValue the nice value that the client would like to update to.
|
||||
*
|
||||
* @return true if the update is successful.
|
||||
*/
|
||||
public boolean updateClientPriority(int clientId, int priority, int niceValue) {
|
||||
boolean result = false;
|
||||
try {
|
||||
result = mService.updateClientPriority(clientId, priority, niceValue);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current TRM of the TunerHAL Frontend information.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestFrontend(TunerFrontendRequest, int[])} and {@link #releaseFrontend(int)} call.
|
||||
*
|
||||
* @param infos an array of the available {@link TunerFrontendInfo} information.
|
||||
*/
|
||||
public void setFrontendInfoList(@NonNull TunerFrontendInfo[] infos) {
|
||||
try {
|
||||
mService.setFrontendInfoList(infos);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the TRM of the current CAS information.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int)}
|
||||
* call.
|
||||
*
|
||||
* @param casSystemId id of the updating CAS system.
|
||||
* @param maxSessionNum the max session number of the CAS system that is updated.
|
||||
*/
|
||||
public void updateCasInfo(int casSystemId, int maxSessionNum) {
|
||||
try {
|
||||
mService.updateCasInfo(casSystemId, maxSessionNum);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the TRM of the current Lnb information.
|
||||
*
|
||||
* <p><strong>Note:</strong> This update must happen before the first
|
||||
* {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int)} call.
|
||||
*
|
||||
* @param lnbIds ids of the updating lnbs.
|
||||
*/
|
||||
public void setLnbInfoList(int[] lnbIds) {
|
||||
try {
|
||||
mService.setLnbInfoList(lnbIds);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a frontend resource.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is frontend available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Frontend is available but the current request info can show higher priority than
|
||||
* other uses of Frontend, the API will send
|
||||
* {@link ITunerResourceManagerListener#onResourcesReclaim()} to the {@link Tuner}. Tuner would
|
||||
* handle the resource reclaim on the holder of lower priority and notify the holder of its
|
||||
* resource loss.
|
||||
*
|
||||
* <li>If no frontend can be granted, the API would return false.
|
||||
* <ul>
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* 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}.
|
||||
*
|
||||
* @return true if there is frontend granted.
|
||||
*/
|
||||
public boolean requestFrontend(@NonNull TunerFrontendRequest request,
|
||||
@Nullable int[] frontendId) {
|
||||
boolean result = false;
|
||||
try {
|
||||
result = mService.requestFrontend(request, frontendId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests from the client to share frontend with an existing client.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this request.
|
||||
*
|
||||
* @param selfClientId the id of the client that sends the request.
|
||||
* @param targetClientId the id of the client to share the frontend with.
|
||||
*/
|
||||
public void shareFrontend(int selfClientId, int targetClientId) {
|
||||
try {
|
||||
mService.shareFrontend(selfClientId, targetClientId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a CAS session resource.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is Cas session available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Cas system is available but the current request info can show higher priority than
|
||||
* other uses of the cas sessions under the requested cas system, the API will send
|
||||
* {@link ITunerResourceManagerListener#onResourcesReclaim()} to the {@link Tuner}. Tuner would
|
||||
* handle the resource reclaim on the holder of lower priority and notify the holder of its
|
||||
* resource loss.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
|
||||
* request.
|
||||
*
|
||||
* @param request {@link CasSessionRequest} information of the current request.
|
||||
* @param sessionResourceId a one-element array to return the granted cas session id.
|
||||
* If no CAS granted, this will return
|
||||
* {@link #INVALID_CAS_SESSION_RESOURCE_ID}.
|
||||
*
|
||||
* @return true if there is CAS session granted.
|
||||
*/
|
||||
public boolean requestCasSession(@NonNull CasSessionRequest request,
|
||||
@NonNull int[] sessionResourceId) {
|
||||
boolean result = false;
|
||||
try {
|
||||
result = mService.requestCasSession(request, sessionResourceId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a Tuner Lnb resource.
|
||||
*
|
||||
* <p>There are three possible scenarios:
|
||||
* <ul>
|
||||
* <li>If there is Lnb available, the API would send the id back.
|
||||
*
|
||||
* <li>If no Lnb is available but the current request has a higher priority than other uses of
|
||||
* lnbs, the API will send {@link ITunerResourceManagerListener#onResourcesReclaim()} to the
|
||||
* {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
|
||||
* notify the holder of its resource loss.
|
||||
*
|
||||
* <li>If no Lnb system can be granted, the API would return false.
|
||||
* <ul>
|
||||
*
|
||||
* <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.
|
||||
* If no Lnb granted, this will return {@link #INVALID_LNB_ID}.
|
||||
*
|
||||
* @return true if there is Lnb granted.
|
||||
*/
|
||||
public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbId) {
|
||||
boolean result = false;
|
||||
try {
|
||||
result = mService.requestLnb(request, lnbId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the TRM that the given frontend has been released.
|
||||
*
|
||||
* <p>Client must call this whenever it releases a Tuner frontend.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
|
||||
* before this release.
|
||||
*
|
||||
* @param frontendId the id of the released frontend.
|
||||
*/
|
||||
public void releaseFrontend(int frontendId) {
|
||||
try {
|
||||
mService.releaseFrontend(frontendId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the TRM that the given Cas session has been released.
|
||||
*
|
||||
* <p>Client must call this whenever it releases a Cas session.
|
||||
*
|
||||
* <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
|
||||
* release.
|
||||
*
|
||||
* @param sessionResourceId the id of the released CAS session.
|
||||
*/
|
||||
public void releaseCasSession(int sessionResourceId) {
|
||||
try {
|
||||
mService.releaseCasSession(sessionResourceId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the TRM that the Lnb with the given id has been 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.
|
||||
*/
|
||||
public void releaseLnb(int lnbId) {
|
||||
try {
|
||||
mService.releaseLnb(lnbId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two clients' priority.
|
||||
*
|
||||
* @param challengerProfile the {@link ResourceClientProfile} of the challenger.
|
||||
* @param holderProfile the {@link ResourceClientProfile} of the holder of the resource.
|
||||
*
|
||||
* @return true if the challenger has higher priority than the holder.
|
||||
*/
|
||||
public boolean isHigherPriority(ResourceClientProfile challengerProfile,
|
||||
ResourceClientProfile holderProfile) {
|
||||
try {
|
||||
return mService.isHigherPriority(challengerProfile, holderProfile);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used to receive events from TunerResourceManager.
|
||||
*/
|
||||
public abstract static class ResourceListener {
|
||||
/*
|
||||
* To reclaim all the resources of the callack owner.
|
||||
*/
|
||||
public abstract void onResourcesReclaim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.tuner;
|
||||
|
||||
/**
|
||||
* A client profile object used by the Tuner Resource Manager to record the registered clients'
|
||||
* information.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ClientProfile {
|
||||
public static final int INVALID_GROUP_ID = -1;
|
||||
/**
|
||||
* Client id sent to the client when registering with
|
||||
* {@link #registerClientProfile(ResourceClientProfile, TunerResourceManagerCallback, int[])}
|
||||
*/
|
||||
private final int mClientId;
|
||||
|
||||
/**
|
||||
* see {@link ResourceClientProfile}
|
||||
*/
|
||||
private final String mTvInputSessionId;
|
||||
|
||||
/**
|
||||
* see {@link ResourceClientProfile}
|
||||
*/
|
||||
private final int mUseCase;
|
||||
|
||||
/**
|
||||
* Process id queried from {@link TvInputManager#}
|
||||
*/
|
||||
private final int mProcessId;
|
||||
|
||||
/**
|
||||
* All the clients that share the same resource would be under the same group id.
|
||||
*
|
||||
* <p>If a client's resource is to be reclaimed, all other clients under the same group id
|
||||
* also lose their resources.
|
||||
*/
|
||||
private int mGroupId = INVALID_GROUP_ID;
|
||||
|
||||
/**
|
||||
* Optional nice value for TRM to reduce client’s priority.
|
||||
*/
|
||||
private int mNiceValue;
|
||||
|
||||
/**
|
||||
* Optional arbitrary priority value given by the client.
|
||||
*
|
||||
* <p>This value can override the default priorotiy calculated from
|
||||
* the client profile.
|
||||
*/
|
||||
private int mPriority;
|
||||
|
||||
private ClientProfile(ClientProfileBuilder builder) {
|
||||
this.mClientId = builder.mClientId;
|
||||
this.mTvInputSessionId = builder.mTvInputSessionId;
|
||||
this.mUseCase = builder.mUseCase;
|
||||
this.mProcessId = builder.mProcessId;
|
||||
this.mGroupId = builder.mGroupId;
|
||||
this.mNiceValue = builder.mNiceValue;
|
||||
this.mPriority = builder.mPriority;
|
||||
}
|
||||
|
||||
public int getClientId() {
|
||||
return mClientId;
|
||||
}
|
||||
|
||||
public String getTvInputSessionId() {
|
||||
return mTvInputSessionId;
|
||||
}
|
||||
|
||||
public int getUseCase() {
|
||||
return mUseCase;
|
||||
}
|
||||
|
||||
public int getProcessId() {
|
||||
return mProcessId;
|
||||
}
|
||||
|
||||
public int getGroupId() {
|
||||
return mGroupId;
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return mPriority;
|
||||
}
|
||||
|
||||
public int getNiceValue() {
|
||||
return mNiceValue;
|
||||
}
|
||||
|
||||
public void setGroupId(int groupId) {
|
||||
mGroupId = groupId;
|
||||
}
|
||||
|
||||
public void setPriority(int priority) {
|
||||
mPriority = priority;
|
||||
}
|
||||
|
||||
public void setNiceValue(int niceValue) {
|
||||
mNiceValue = niceValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClientProfile: " + this.mClientId + ", " + this.mTvInputSessionId + ", "
|
||||
+ this.mUseCase + ", " + this.mProcessId;
|
||||
}
|
||||
|
||||
public static class ClientProfileBuilder {
|
||||
private final int mClientId;
|
||||
private String mTvInputSessionId;
|
||||
private int mUseCase;
|
||||
private int mProcessId;
|
||||
private int mGroupId;
|
||||
private int mNiceValue;
|
||||
private int mPriority;
|
||||
|
||||
ClientProfileBuilder(int clientId) {
|
||||
this.mClientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param useCase the useCase of the client.
|
||||
*/
|
||||
public ClientProfileBuilder useCase(int useCase) {
|
||||
this.mUseCase = useCase;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param tvInputSessionId the id of the tv input session.
|
||||
*/
|
||||
public ClientProfileBuilder tvInputSessionId(String tvInputSessionId) {
|
||||
this.mTvInputSessionId = tvInputSessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param processId the id of process.
|
||||
*/
|
||||
public ClientProfileBuilder processId(int processId) {
|
||||
this.mProcessId = processId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param groupId the id of the group that shares the same resource.
|
||||
*/
|
||||
public ClientProfileBuilder groupId(int groupId) {
|
||||
this.mGroupId = groupId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param niceValue the nice value of the client.
|
||||
*/
|
||||
public ClientProfileBuilder niceValue(int niceValue) {
|
||||
this.mNiceValue = niceValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link ClientProfile}.
|
||||
*
|
||||
* @param priority the priority value of the client.
|
||||
*/
|
||||
public ClientProfileBuilder priority(int priority) {
|
||||
this.mPriority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link ClientProfile}.
|
||||
*
|
||||
* @return {@link ClientProfile}.
|
||||
*/
|
||||
public ClientProfile build() {
|
||||
ClientProfile clientProfile = new ClientProfile(this);
|
||||
return clientProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* 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.tuner;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.media.tv.TvInputManager;
|
||||
import android.media.tv.tuner.CasSessionRequest;
|
||||
import android.media.tv.tuner.ITunerResourceManager;
|
||||
import android.media.tv.tuner.ITunerResourceManagerListener;
|
||||
import android.media.tv.tuner.ResourceClientProfile;
|
||||
import android.media.tv.tuner.TunerFrontendInfo;
|
||||
import android.media.tv.tuner.TunerFrontendRequest;
|
||||
import android.media.tv.tuner.TunerLnbRequest;
|
||||
import android.media.tv.tuner.TunerResourceManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class provides a system service that manages the TV tuner resources.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class TunerResourceManagerService extends SystemService {
|
||||
private static final String TAG = "TunerResourceManagerService";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private SparseArray<ClientProfile> mClientProfiles = new SparseArray<>();
|
||||
private SparseArray<ITunerResourceManagerListener> mListeners = new SparseArray<>();
|
||||
private int mNextUnusedFrontendId = 0;
|
||||
private List<Integer> mReleasedClientId = new ArrayList<Integer>();
|
||||
private List<Integer> mAvailableFrontendIds = new ArrayList<Integer>();
|
||||
|
||||
private TvInputManager mManager;
|
||||
|
||||
public TunerResourceManagerService(@Nullable Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
publishBinderService(Context.TV_TUNER_RESOURCE_MGR_SERVICE, new BinderService());
|
||||
mManager = (TvInputManager) getContext()
|
||||
.getSystemService(Context.TV_INPUT_SERVICE);
|
||||
}
|
||||
|
||||
private final class BinderService extends ITunerResourceManager.Stub {
|
||||
@Override
|
||||
public void registerClientProfile(@NonNull ResourceClientProfile profile,
|
||||
@NonNull ITunerResourceManagerListener listener,
|
||||
@NonNull int[] clientId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "registerClientProfile(clientProfile=" + profile + ")");
|
||||
}
|
||||
|
||||
// TODO tell if the client already exists
|
||||
if (mReleasedClientId.isEmpty()) {
|
||||
clientId[0] = mNextUnusedFrontendId++;
|
||||
} else {
|
||||
clientId[0] = mReleasedClientId.get(0);
|
||||
mReleasedClientId.remove(0);
|
||||
}
|
||||
|
||||
if (mManager == null) {
|
||||
Slog.e(TAG, "TvInputManager is null. Can't register client profile.");
|
||||
return;
|
||||
}
|
||||
|
||||
int callingPid = mManager.getClientPid(profile.getTvInputSessionId());
|
||||
|
||||
ClientProfile clientProfile = new ClientProfile.ClientProfileBuilder(
|
||||
clientId[0])
|
||||
.tvInputSessionId(profile.getTvInputSessionId())
|
||||
.useCase(profile.getUseCase())
|
||||
.processId(callingPid)
|
||||
.build();
|
||||
mClientProfiles.append(clientId[0], clientProfile);
|
||||
mListeners.append(clientId[0], listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterClientProfile(int clientId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "unregisterClientProfile(clientId=" + clientId + ")");
|
||||
}
|
||||
|
||||
mClientProfiles.remove(clientId);
|
||||
mListeners.remove(clientId);
|
||||
mReleasedClientId.add(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateClientPriority(int clientId, int priority, int niceValue) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateClientPriority(clientId=" + clientId
|
||||
+ ", priority=" + priority + ", niceValue=" + niceValue + ")");
|
||||
}
|
||||
|
||||
ClientProfile profile = mClientProfiles.get(clientId);
|
||||
if (profile == null) {
|
||||
Slog.e(TAG, "Can not find client profile with id " + clientId
|
||||
+ " when trying to update the client priority.");
|
||||
return false;
|
||||
}
|
||||
|
||||
profile.setPriority(priority);
|
||||
profile.setNiceValue(niceValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrontendInfoList(@NonNull TunerFrontendInfo[] infos)
|
||||
throws RemoteException {
|
||||
if (infos == null || infos.length == 0) {
|
||||
Slog.d(TAG, "Can't update with empty frontend info");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateFrontendInfo:");
|
||||
for (int i = 0; i < infos.length; i++) {
|
||||
Slog.d(TAG, infos[i].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCasInfo(int casSystemId, int maxSessionNum) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateCasInfo(casSystemId="
|
||||
+ casSystemId + ", maxSessionNum=" + maxSessionNum + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLnbInfoList(int[] lnbIds) {
|
||||
if (DEBUG) {
|
||||
for (int i = 0; i < lnbIds.length; i++) {
|
||||
Slog.d(TAG, "updateLnbInfo(lnbId=" + lnbIds[i] + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestFrontend(@NonNull TunerFrontendRequest request,
|
||||
@NonNull int[] frontendId) throws RemoteException {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "requestFrontend(request=" + request + ")");
|
||||
}
|
||||
|
||||
frontendId[0] = TunerResourceManager.INVALID_FRONTEND_ID;
|
||||
|
||||
if (getContext() == null) {
|
||||
Slog.e(TAG, "Can not find context when requesting frontend");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mClientProfiles.get(request.getClientId()) == null) {
|
||||
Slog.e(TAG, "Request from unregistered client. Id: "
|
||||
+ request.getClientId());
|
||||
return false;
|
||||
}
|
||||
|
||||
String sessionId = mClientProfiles.get(request.getClientId())
|
||||
.getTvInputSessionId();
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "session Id:" + sessionId + ")");
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "No available Frontend found.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shareFrontend(int selfClientId, int targetClientId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "shareFrontend from "
|
||||
+ selfClientId + " with " + targetClientId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestCasSession(@NonNull CasSessionRequest request,
|
||||
@NonNull int[] sessionResourceId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "requestCasSession(request=" + request + ")");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "requestLnb(request=" + request + ")");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseFrontend(int frontendId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseCasSession(int sessionResourceId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "releaseCasSession(sessionResourceId=" + sessionResourceId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseLnb(int lnbId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "releaseLnb(lnbId=" + lnbId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHigherPriority(ResourceClientProfile challengerProfile,
|
||||
ResourceClientProfile holderProfile) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "isHigherPriority(challengerProfile=" + challengerProfile
|
||||
+ ", holderProfile=" + challengerProfile + ")");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,7 @@ import com.android.server.textservices.TextServicesManagerService;
|
||||
import com.android.server.trust.TrustManagerService;
|
||||
import com.android.server.tv.TvInputManagerService;
|
||||
import com.android.server.tv.TvRemoteService;
|
||||
import com.android.server.tv.tuner.TunerResourceManagerService;
|
||||
import com.android.server.twilight.TwilightService;
|
||||
import com.android.server.uri.UriGrantsManagerService;
|
||||
import com.android.server.usage.UsageStatsService;
|
||||
@@ -1854,6 +1855,8 @@ public final class SystemServer {
|
||||
|| mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
|
||||
t.traceBegin("StartTvInputManager");
|
||||
mSystemServiceManager.startService(TvInputManagerService.class);
|
||||
t.traceBegin("StartTunerResourceManager");
|
||||
mSystemServiceManager.startService(TunerResourceManagerService.class);
|
||||
t.traceEnd();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user