FileDocCategorySizeDatePackage
TvInputManager.javaAPI DocAndroid 5.1 API72558Thu Mar 12 22:22:30 GMT 2015android.media.tv

TvInputManager

public 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_UNKNOWN
A generic reason. Video is not available due to an unspecified error.
public static final int
VIDEO_UNAVAILABLE_REASON_TUNING
Video 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_SIGNAL
Video is not available due to the weak TV signal.
public static final int
VIDEO_UNAVAILABLE_REASON_BUFFERING
Video is not available because the TV input stopped the playback temporarily to buffer more data.
public static final int
INPUT_STATE_UNKNOWN
The 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_CONNECTED
The TV input is connected.

State for {@link #getInputState} and {@link TvInputManager.TvInputCallback#onInputStateChanged}.

public static final int
INPUT_STATE_CONNECTED_STANDBY
The 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_DISCONNECTED
The TV input is disconnected.

State for {@link #getInputState} and {@link TvInputManager.TvInputCallback#onInputStateChanged}.

public static final String
ACTION_BLOCKED_RATINGS_CHANGED
Broadcast intent action when the user blocked content ratings change. For use with the {@link #isRatingBlocked}.
public static final String
ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
Broadcast intent action when the parental controls enabled state changes. For use with the {@link #isParentalControlsEnabled}.
public static final String
ACTION_QUERY_CONTENT_RATING_SYSTEMS
Broadcast 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_SYSTEMS
Content 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)

hide

        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$HardwareacquireTvInputHardware(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.

hide

        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 voidaddBlockedRating(TvContentRating rating)
Adds a user blocked content rating.

param
rating The content rating to block.
see
#isRatingBlocked
see
#removeBlockedRating
hide

        if (rating == null) {
            throw new IllegalArgumentException("rating cannot be null");
        }
        try {
            mService.addBlockedRating(rating.flattenToString(), mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public booleancaptureFrame(java.lang.String inputId, android.view.Surface surface, TvStreamConfig config)
Take a snapshot of the given TV input into the provided Surface.

param
inputId the id of the TV input.
param
surface the {@link Surface} to which the snapshot is captured.
param
config the {@link TvStreamConfig} which is used for capturing.
return
true when the {@link Surface} is ready to be captured.
hide

        try {
            return mService.captureFrame(inputId, surface, config, mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public voidcreateSession(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.

param
inputId The id of the TV input.
param
callback A callback used to receive the created session.
param
handler A {@link Handler} that the session creation will be delivered to.
throws
IllegalArgumentException if any of the arguments is {@code null}.
hide

        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.ListgetAvailableTvStreamConfigList(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.

param
inputId the id of the TV input.
return
List of {@link TvStreamConfig} which is available for capturing of the given TV input.
hide

        try {
            return mService.getAvailableTvStreamConfigList(inputId, mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public java.util.ListgetBlockedRatings()
Returns the list of blocked content ratings.

return
the list of content ratings blocked by the user.
hide

        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.ListgetHardwareList()
Returns a list of TvInputHardwareInfo objects representing available hardware.

hide

        try {
            return mService.getHardwareList();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public intgetInputState(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}

param
inputId The id of the TV input.
throws
IllegalArgumentException if the argument is {@code null} or if there is no {@link TvInputInfo} corresponding to {@code inputId}.

        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.ListgetTvContentRatingSystemList()
Returns the list of all TV content rating systems defined.

hide

        try {
            return mService.getTvContentRatingSystemList(mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public TvInputInfogetTvInputInfo(java.lang.String inputId)
Returns the {@link TvInputInfo} for a given TV input.

param
inputId The ID of the TV input.
return
the {@link TvInputInfo} for a given TV input. {@code null} if not found.

        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.ListgetTvInputList()
Returns the complete list of TV inputs on the system.

return
List of {@link TvInputInfo} for each TV input that describes its meta information.

        try {
            return mService.getTvInputList(mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public booleanisParentalControlsEnabled()
Returns the user's parental controls enabled state.

return
{@code true} if the user enabled the parental controls, {@code false} otherwise.

        try {
            return mService.isParentalControlsEnabled(mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public booleanisRatingBlocked(TvContentRating rating)
Checks whether a given TV content rating is blocked by the user.

param
rating The TV content rating to check.
return
{@code true} if the given TV content rating is blocked, {@code false} otherwise.

        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 booleanisSingleSessionActive()
Returns true if there is only a single TV input session.

hide

        try {
            return mService.isSingleSessionActive(mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public voidregisterCallback(android.media.tv.TvInputManager$TvInputCallback callback, android.os.Handler handler)
Registers a {@link TvInputCallback}.

param
callback A callback used to monitor status of the TV inputs.
param
handler A {@link Handler} that the status change will be delivered to.
throws
IllegalArgumentException if any of the arguments is {@code null}.

        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 voidreleaseTvInputHardware(int deviceId, android.media.tv.TvInputManager$Hardware hardware)
Releases previously acquired hardware object.

hide

        try {
            mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public voidremoveBlockedRating(TvContentRating rating)
Removes a user blocked content rating.

param
rating The content rating to unblock.
see
#isRatingBlocked
see
#addBlockedRating
hide

        if (rating == null) {
            throw new IllegalArgumentException("rating cannot be null");
        }
        try {
            mService.removeBlockedRating(rating.flattenToString(), mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public voidsetParentalControlsEnabled(boolean enabled)
Sets the user's parental controls enabled state.

param
enabled The user's parental controls enabled state. {@code true} if the user enabled the parental controls, {@code false} otherwise.
see
#isParentalControlsEnabled
hide

        try {
            mService.setParentalControlsEnabled(enabled, mUserId);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    
public voidunregisterCallback(android.media.tv.TvInputManager$TvInputCallback callback)
Unregisters the existing {@link TvInputCallback}.

param
callback The existing callback to remove.
throws
IllegalArgumentException if any of the arguments is {@code null}.

        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;
                }
            }
        }