TvInputManagerpublic final class TvInputManager extends Object Central system API to the overall TV input framework (TIF) architecture, which arbitrates
interaction between applications and the selected TV inputs. |
Fields Summary |
---|
private static final String | TAG | static final int | VIDEO_UNAVAILABLE_REASON_START | static final int | VIDEO_UNAVAILABLE_REASON_END | public static final int | VIDEO_UNAVAILABLE_REASON_UNKNOWNA generic reason. Video is not available due to an unspecified error. | public static final int | VIDEO_UNAVAILABLE_REASON_TUNINGVideo is not available because the TV input is in the middle of tuning to a new channel. | public static final int | VIDEO_UNAVAILABLE_REASON_WEAK_SIGNALVideo is not available due to the weak TV signal. | public static final int | VIDEO_UNAVAILABLE_REASON_BUFFERINGVideo is not available because the TV input stopped the playback temporarily to buffer more
data. | public static final int | INPUT_STATE_UNKNOWNThe TV input is in unknown state.
State for denoting unknown TV input state. The typical use case is when a requested TV
input is removed from the device or it is not registered. Used in
{@code ITvInputManager.getTvInputState()}.
| public static final int | INPUT_STATE_CONNECTEDThe TV input is connected.
State for {@link #getInputState} and {@link
TvInputManager.TvInputCallback#onInputStateChanged}.
| public static final int | INPUT_STATE_CONNECTED_STANDBYThe TV input is connected but in standby mode. It would take a while until it becomes
fully ready.
State for {@link #getInputState} and {@link
TvInputManager.TvInputCallback#onInputStateChanged}.
| public static final int | INPUT_STATE_DISCONNECTEDThe TV input is disconnected.
State for {@link #getInputState} and {@link
TvInputManager.TvInputCallback#onInputStateChanged}.
| public static final String | ACTION_BLOCKED_RATINGS_CHANGEDBroadcast intent action when the user blocked content ratings change. For use with the
{@link #isRatingBlocked}. | public static final String | ACTION_PARENTAL_CONTROLS_ENABLED_CHANGEDBroadcast intent action when the parental controls enabled state changes. For use with the
{@link #isParentalControlsEnabled}. | public static final String | ACTION_QUERY_CONTENT_RATING_SYSTEMSBroadcast intent action used to query available content rating systems.
The TV input manager service locates available content rating systems by querying broadcast
receivers that are registered for this action. An application can offer additional content
rating systems to the user by declaring a suitable broadcast receiver in its manifest.
Here is an example broadcast receiver declaration that an application might include in its
AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a
resource that contains a description of each content rating system that is provided by the
application.
{@literal
}
In the above example, the @xml/tv_content_rating_systems resource refers to an
XML resource whose root element is <rating-system-definitions> that
contains zero or more <rating-system-definition> elements. Each
<rating-system-definition> element specifies the ratings, sub-ratings and rating
orders of a particular content rating system.
| public static final String | META_DATA_CONTENT_RATING_SYSTEMSContent rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}.
Specifies the resource ID of an XML resource that describes the content rating systems that
are provided by the application.
| private final ITvInputManager | mService | private final Object | mLock | private final List | mCallbackRecords | private final Map | mStateMap | private final android.util.SparseArray | mSessionCallbackRecordMap | private int | mNextSeq | private final ITvInputClient | mClient | private final ITvInputManagerCallback | mManagerCallback | private final int | mUserId |
Constructors Summary |
---|
public TvInputManager(ITvInputManager service, int userId)
mService = service;
mUserId = userId;
mClient = new ITvInputClient.Stub() {
@Override
public void onSessionCreated(String inputId, IBinder token, InputChannel channel,
int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for " + token);
return;
}
Session session = null;
if (token != null) {
session = new Session(token, channel, mService, mUserId, seq,
mSessionCallbackRecordMap);
}
record.postSessionCreated(session);
}
}
@Override
public void onSessionReleased(int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
mSessionCallbackRecordMap.delete(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq:" + seq);
return;
}
record.mSession.releaseInternal();
record.postSessionReleased();
}
}
@Override
public void onChannelRetuned(Uri channelUri, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postChannelRetuned(channelUri);
}
}
@Override
public void onTracksChanged(List<TvTrackInfo> tracks, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
if (record.mSession.updateTracks(tracks)) {
record.postTracksChanged(tracks);
postVideoSizeChangedIfNeededLocked(record);
}
}
}
@Override
public void onTrackSelected(int type, String trackId, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
if (record.mSession.updateTrackSelection(type, trackId)) {
record.postTrackSelected(type, trackId);
postVideoSizeChangedIfNeededLocked(record);
}
}
}
private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) {
TvTrackInfo track = record.mSession.getVideoTrackToNotify();
if (track != null) {
record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight());
}
}
@Override
public void onVideoAvailable(int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postVideoAvailable();
}
}
@Override
public void onVideoUnavailable(int reason, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postVideoUnavailable(reason);
}
}
@Override
public void onContentAllowed(int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postContentAllowed();
}
}
@Override
public void onContentBlocked(String rating, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postContentBlocked(TvContentRating.unflattenFromString(rating));
}
}
@Override
public void onLayoutSurface(int left, int top, int right, int bottom, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postLayoutSurface(left, top, right, bottom);
}
}
@Override
public void onSessionEvent(String eventType, Bundle eventArgs, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postSessionEvent(eventType, eventArgs);
}
}
};
mManagerCallback = new ITvInputManagerCallback.Stub() {
@Override
public void onInputStateChanged(String inputId, int state) {
synchronized (mLock) {
mStateMap.put(inputId, state);
for (TvInputCallbackRecord record : mCallbackRecords) {
record.postInputStateChanged(inputId, state);
}
}
}
@Override
public void onInputAdded(String inputId) {
synchronized (mLock) {
mStateMap.put(inputId, INPUT_STATE_CONNECTED);
for (TvInputCallbackRecord record : mCallbackRecords) {
record.postInputAdded(inputId);
}
}
}
@Override
public void onInputRemoved(String inputId) {
synchronized (mLock) {
mStateMap.remove(inputId);
for (TvInputCallbackRecord record : mCallbackRecords) {
record.postInputRemoved(inputId);
}
}
}
@Override
public void onInputUpdated(String inputId) {
synchronized (mLock) {
for (TvInputCallbackRecord record : mCallbackRecords) {
record.postInputUpdated(inputId);
}
}
}
};
try {
if (mService != null) {
mService.registerCallback(mManagerCallback, mUserId);
List<TvInputInfo> infos = mService.getTvInputList(mUserId);
synchronized (mLock) {
for (TvInputInfo info : infos) {
String inputId = info.getId();
int state = mService.getTvInputState(inputId, mUserId);
if (state != INPUT_STATE_UNKNOWN) {
mStateMap.put(inputId, state);
}
}
}
}
} catch (RemoteException e) {
Log.e(TAG, "TvInputManager initialization failed: " + e);
}
|
Methods Summary |
---|
public android.media.tv.TvInputManager$Hardware | acquireTvInputHardware(int deviceId, android.media.tv.TvInputManager$HardwareCallback callback, TvInputInfo info)Returns acquired TvInputManager.Hardware object for given deviceId.
If there are other Hardware object acquired for the same deviceId, calling this method will
preempt the previously acquired object and report {@link HardwareCallback#onReleased} to the
old object.
try {
return new Hardware(
mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() {
@Override
public void onReleased() {
callback.onReleased();
}
@Override
public void onStreamConfigChanged(TvStreamConfig[] configs) {
callback.onStreamConfigChanged(configs);
}
}, info, mUserId));
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | addBlockedRating(TvContentRating rating)Adds a user blocked content rating.
if (rating == null) {
throw new IllegalArgumentException("rating cannot be null");
}
try {
mService.addBlockedRating(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public boolean | captureFrame(java.lang.String inputId, android.view.Surface surface, TvStreamConfig config)Take a snapshot of the given TV input into the provided Surface.
try {
return mService.captureFrame(inputId, surface, config, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | createSession(java.lang.String inputId, android.media.tv.TvInputManager$SessionCallback callback, android.os.Handler handler)Creates a {@link Session} for a given TV input.
The number of sessions that can be created at the same time is limited by the capability of
the given TV input.
if (inputId == null) {
throw new IllegalArgumentException("id cannot be null");
}
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
if (handler == null) {
throw new IllegalArgumentException("handler cannot be null");
}
SessionCallbackRecord record = new SessionCallbackRecord(callback, handler);
synchronized (mSessionCallbackRecordMap) {
int seq = mNextSeq++;
mSessionCallbackRecordMap.put(seq, record);
try {
mService.createSession(mClient, inputId, seq, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
| public java.util.List | getAvailableTvStreamConfigList(java.lang.String inputId)Returns the TvStreamConfig list of the given TV input.
If you are using {@link Hardware} object from {@link
#acquireTvInputHardware}, you should get the list of available streams
from {@link HardwareCallback#onStreamConfigChanged} method, not from
here. This method is designed to be used with {@link #captureFrame} in
capture scenarios specifically and not suitable for any other use.
try {
return mService.getAvailableTvStreamConfigList(inputId, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public java.util.List | getBlockedRatings()Returns the list of blocked content ratings.
try {
List<TvContentRating> ratings = new ArrayList<TvContentRating>();
for (String rating : mService.getBlockedRatings(mUserId)) {
ratings.add(TvContentRating.unflattenFromString(rating));
}
return ratings;
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public java.util.List | getHardwareList()Returns a list of TvInputHardwareInfo objects representing available hardware.
try {
return mService.getHardwareList();
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public int | getInputState(java.lang.String inputId)Returns the state of a given TV input. It returns one of the following:
- {@link #INPUT_STATE_CONNECTED}
- {@link #INPUT_STATE_CONNECTED_STANDBY}
- {@link #INPUT_STATE_DISCONNECTED}
if (inputId == null) {
throw new IllegalArgumentException("inputId cannot be null");
}
synchronized (mLock) {
Integer state = mStateMap.get(inputId);
if (state == null) {
throw new IllegalArgumentException("Unrecognized input ID: " + inputId);
}
return state.intValue();
}
| public java.util.List | getTvContentRatingSystemList()Returns the list of all TV content rating systems defined.
try {
return mService.getTvContentRatingSystemList(mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public TvInputInfo | getTvInputInfo(java.lang.String inputId)Returns the {@link TvInputInfo} for a given TV input.
if (inputId == null) {
throw new IllegalArgumentException("inputId cannot be null");
}
try {
return mService.getTvInputInfo(inputId, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public java.util.List | getTvInputList()Returns the complete list of TV inputs on the system.
try {
return mService.getTvInputList(mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public boolean | isParentalControlsEnabled()Returns the user's parental controls enabled state.
try {
return mService.isParentalControlsEnabled(mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public boolean | isRatingBlocked(TvContentRating rating)Checks whether a given TV content rating is blocked by the user.
if (rating == null) {
throw new IllegalArgumentException("rating cannot be null");
}
try {
return mService.isRatingBlocked(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public boolean | isSingleSessionActive()Returns true if there is only a single TV input session.
try {
return mService.isSingleSessionActive(mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | registerCallback(android.media.tv.TvInputManager$TvInputCallback callback, android.os.Handler handler)Registers a {@link TvInputCallback}.
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
if (handler == null) {
throw new IllegalArgumentException("handler cannot be null");
}
synchronized (mLock) {
mCallbackRecords.add(new TvInputCallbackRecord(callback, handler));
}
| public void | releaseTvInputHardware(int deviceId, android.media.tv.TvInputManager$Hardware hardware)Releases previously acquired hardware object.
try {
mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | removeBlockedRating(TvContentRating rating)Removes a user blocked content rating.
if (rating == null) {
throw new IllegalArgumentException("rating cannot be null");
}
try {
mService.removeBlockedRating(rating.flattenToString(), mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | setParentalControlsEnabled(boolean enabled)Sets the user's parental controls enabled state.
try {
mService.setParentalControlsEnabled(enabled, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
| public void | unregisterCallback(android.media.tv.TvInputManager$TvInputCallback callback)Unregisters the existing {@link TvInputCallback}.
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
synchronized (mLock) {
for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator();
it.hasNext(); ) {
TvInputCallbackRecord record = it.next();
if (record.getCallback() == callback) {
it.remove();
break;
}
}
}
|
|