summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt21
-rw-r--r--media/java/android/media/tv/ITvInputClient.aidl4
-rw-r--r--media/java/android/media/tv/ITvInputManager.aidl3
-rw-r--r--media/java/android/media/tv/ITvInputSession.aidl3
-rw-r--r--media/java/android/media/tv/ITvInputSessionCallback.aidl4
-rw-r--r--media/java/android/media/tv/ITvInputSessionWrapper.java28
-rw-r--r--media/java/android/media/tv/TvInputManager.java168
-rw-r--r--media/java/android/media/tv/TvInputService.java93
-rw-r--r--media/java/android/media/tv/TvTrackInfo.java28
-rw-r--r--media/java/android/media/tv/TvView.java93
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java42
11 files changed, 248 insertions, 239 deletions
diff --git a/api/current.txt b/api/current.txt
index d2c4888f12d4..3929a7508180 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -17087,8 +17087,8 @@ package android.media.tv {
method public void notifyChannelRetuned(android.net.Uri);
method public void notifyContentAllowed();
method public void notifyContentBlocked(android.media.tv.TvContentRating);
- method public void notifyTrackInfoChanged(java.util.List<android.media.tv.TvTrackInfo>);
- method public void notifyTrackSelectionChanged(java.util.List<android.media.tv.TvTrackInfo>);
+ method public void notifyTrackSelected(int, java.lang.String);
+ method public void notifyTracksChanged(java.util.List<android.media.tv.TvTrackInfo>);
method public void notifyVideoAvailable();
method public void notifyVideoUnavailable(int);
method public android.view.View onCreateOverlayView();
@@ -17098,7 +17098,7 @@ package android.media.tv {
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
method public boolean onKeyUp(int, android.view.KeyEvent);
method public abstract void onRelease();
- method public boolean onSelectTrack(android.media.tv.TvTrackInfo);
+ method public boolean onSelectTrack(int, java.lang.String);
method public abstract void onSetCaptionEnabled(boolean);
method public abstract void onSetStreamVolume(float);
method public abstract boolean onSetSurface(android.view.Surface);
@@ -17107,7 +17107,6 @@ package android.media.tv {
method public boolean onTrackballEvent(android.view.MotionEvent);
method public abstract boolean onTune(android.net.Uri);
method public void onUnblockContent(android.media.tv.TvContentRating);
- method public boolean onUnselectTrack(android.media.tv.TvTrackInfo);
method public void setOverlayViewEnabled(boolean);
}
@@ -17116,6 +17115,7 @@ package android.media.tv {
method public final int getAudioChannelCount();
method public final int getAudioSampleRate();
method public final android.os.Bundle getExtra();
+ method public final java.lang.String getId();
method public final java.lang.String getLanguage();
method public final int getType();
method public final int getVideoHeight();
@@ -17128,7 +17128,7 @@ package android.media.tv {
}
public static final class TvTrackInfo.Builder {
- ctor public TvTrackInfo.Builder(int);
+ ctor public TvTrackInfo.Builder(int, java.lang.String);
method public android.media.tv.TvTrackInfo build();
method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
@@ -17143,18 +17143,17 @@ package android.media.tv {
ctor public TvView(android.content.Context, android.util.AttributeSet);
ctor public TvView(android.content.Context, android.util.AttributeSet, int);
method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
- method public java.util.List<android.media.tv.TvTrackInfo> getSelectedTracks();
- method public java.util.List<android.media.tv.TvTrackInfo> getTracks();
+ method public java.lang.String getSelectedTrack(int);
+ method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int);
method protected void onLayout(boolean, int, int, int, int);
method public boolean onUnhandledInputEvent(android.view.InputEvent);
method public void reset();
- method public void selectTrack(android.media.tv.TvTrackInfo);
+ method public void selectTrack(int, java.lang.String);
method public void setCaptionEnabled(boolean);
method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
method public void setStreamVolume(float);
method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
method public void tune(java.lang.String, android.net.Uri);
- method public void unselectTrack(android.media.tv.TvTrackInfo);
field public static final int ERROR_INPUT_DISCONNECTED = 1; // 0x1
field public static final int ERROR_INPUT_NOT_CONNECTED = 0; // 0x0
}
@@ -17169,8 +17168,8 @@ package android.media.tv {
method public void onContentAllowed(java.lang.String);
method public void onContentBlocked(java.lang.String, android.media.tv.TvContentRating);
method public void onError(java.lang.String, int);
- method public void onTrackInfoChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
- method public void onTrackSelectionChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
+ method public void onTrackSelected(java.lang.String, int, java.lang.String);
+ method public void onTracksChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
method public void onVideoAvailable(java.lang.String);
method public void onVideoSizeChanged(java.lang.String, int, int);
method public void onVideoUnavailable(java.lang.String, int);
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index 2c39afaefc94..37c75531653f 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -33,8 +33,8 @@ oneway interface ITvInputClient {
void onSessionReleased(int seq);
void onSessionEvent(in String name, in Bundle args, int seq);
void onChannelRetuned(in Uri channelUri, int seq);
- void onTrackInfoChanged(in List<TvTrackInfo> tracks, int seq);
- void onTrackSelectionChanged(in List<TvTrackInfo> selectedTracks, int seq);
+ void onTracksChanged(in List<TvTrackInfo> tracks, int seq);
+ void onTrackSelected(int type, in String trackId, int seq);
void onVideoAvailable(int seq);
void onVideoUnavailable(int reason, int seq);
void onContentAllowed(int seq);
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index a2b7d6b355e2..d5719c82c4e5 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -60,8 +60,7 @@ interface ITvInputManager {
void setVolume(in IBinder sessionToken, float volume, int userId);
void tune(in IBinder sessionToken, in Uri channelUri, in Bundle params, int userId);
void setCaptionEnabled(in IBinder sessionToken, boolean enabled, int userId);
- void selectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
- void unselectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
+ void selectTrack(in IBinder sessionToken, int type, in String trackId, int userId);
void sendAppPrivateCommand(in IBinder sessionToken, in String action, in Bundle data,
int userId);
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 9a0be25da81e..99fb91147707 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -37,8 +37,7 @@ oneway interface ITvInputSession {
void setVolume(float volume);
void tune(in Uri channelUri, in Bundle params);
void setCaptionEnabled(boolean enabled);
- void selectTrack(in TvTrackInfo track);
- void unselectTrack(in TvTrackInfo track);
+ void selectTrack(int type, in String trackId);
void appPrivateCommand(in String action, in Bundle data);
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index 3773987c0763..f8c22fca3774 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -30,8 +30,8 @@ oneway interface ITvInputSessionCallback {
void onSessionCreated(ITvInputSession session);
void onSessionEvent(in String name, in Bundle args);
void onChannelRetuned(in Uri channelUri);
- void onTrackInfoChanged(in List<TvTrackInfo> tracks);
- void onTrackSelectionChanged(in List<TvTrackInfo> selectedTracks);
+ void onTracksChanged(in List<TvTrackInfo> tracks);
+ void onTrackSelected(int type, in String trackId);
void onVideoAvailable();
void onVideoUnavailable(int reason);
void onContentAllowed();
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index a809da9cc11f..5022cc128b35 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -49,12 +49,11 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
private static final int DO_TUNE = 6;
private static final int DO_SET_CAPTION_ENABLED = 7;
private static final int DO_SELECT_TRACK = 8;
- private static final int DO_UNSELECT_TRACK = 9;
- private static final int DO_APP_PRIVATE_COMMAND = 10;
- private static final int DO_CREATE_OVERLAY_VIEW = 11;
- private static final int DO_RELAYOUT_OVERLAY_VIEW = 12;
- private static final int DO_REMOVE_OVERLAY_VIEW = 13;
- private static final int DO_REQUEST_UNBLOCK_CONTENT = 14;
+ private static final int DO_APP_PRIVATE_COMMAND = 9;
+ private static final int DO_CREATE_OVERLAY_VIEW = 10;
+ private static final int DO_RELAYOUT_OVERLAY_VIEW = 11;
+ private static final int DO_REMOVE_OVERLAY_VIEW = 12;
+ private static final int DO_REQUEST_UNBLOCK_CONTENT = 13;
private final HandlerCaller mCaller;
@@ -121,11 +120,9 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
return;
}
case DO_SELECT_TRACK: {
- mTvInputSessionImpl.selectTrack((TvTrackInfo) msg.obj);
- return;
- }
- case DO_UNSELECT_TRACK: {
- mTvInputSessionImpl.unselectTrack((TvTrackInfo) msg.obj);
+ SomeArgs args = (SomeArgs) msg.obj;
+ mTvInputSessionImpl.selectTrack((Integer) args.arg1, (String) args.arg2);
+ args.recycle();
return;
}
case DO_APP_PRIVATE_COMMAND: {
@@ -196,13 +193,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
}
@Override
- public void selectTrack(TvTrackInfo track) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SELECT_TRACK, track));
- }
-
- @Override
- public void unselectTrack(TvTrackInfo track) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_UNSELECT_TRACK, track));
+ public void selectTrack(int type, String trackId) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_SELECT_TRACK, type, trackId));
}
@Override
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index a5554540f10b..9c4f121c519b 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -176,16 +176,20 @@ public final class TvInputManager {
* @param session A {@link TvInputManager.Session} associated with this callback.
* @param tracks A list which includes track information.
*/
- public void onTrackInfoChanged(Session session, List<TvTrackInfo> tracks) {
+ public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
}
/**
- * This is called when there is a change on the selected tracks in this session.
+ * This is called when a track for a given type is selected.
*
* @param session A {@link TvInputManager.Session} associated with this callback
- * @param selectedTracks A list of selected tracks.
+ * @param type The type of the selected track. The type can be
+ * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+ * {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @param trackId The ID of the selected track. When {@code null} the currently selected
+ * track for a given type should be unselected.
*/
- public void onTrackSelectionChanged(Session session, List<TvTrackInfo> selectedTracks) {
+ public void onTrackSelected(Session session, int type, String trackId) {
}
/**
@@ -282,22 +286,44 @@ public final class TvInputManager {
});
}
- public void postTrackInfoChanged(final List<TvTrackInfo> tracks) {
+ public void postTracksChanged(final List<TvTrackInfo> tracks) {
mHandler.post(new Runnable() {
@Override
public void run() {
- mSession.mTracks = tracks;
- mSessionCallback.onTrackInfoChanged(mSession, tracks);
+ mSession.mAudioTracks.clear();
+ mSession.mVideoTracks.clear();
+ mSession.mSubtitleTracks.clear();
+ for (TvTrackInfo track : tracks) {
+ if (track.getType() == TvTrackInfo.TYPE_AUDIO) {
+ mSession.mAudioTracks.add(track);
+ } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) {
+ mSession.mVideoTracks.add(track);
+ } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
+ mSession.mSubtitleTracks.add(track);
+ } else {
+ // Silently ignore.
+ }
+ }
+ mSessionCallback.onTracksChanged(mSession, tracks);
}
});
}
- public void postTrackSelectionChanged(final List<TvTrackInfo> selectedTracks) {
+ public void postTrackSelected(final int type, final String trackId) {
mHandler.post(new Runnable() {
@Override
public void run() {
- mSession.mSelectedTracks = selectedTracks;
- mSessionCallback.onTrackSelectionChanged(mSession, selectedTracks);
+ if (type == TvTrackInfo.TYPE_AUDIO) {
+ mSession.mSelectedAudioTrackId = trackId;
+ } else if (type == TvTrackInfo.TYPE_VIDEO) {
+ mSession.mSelectedVideoTrackId = trackId;
+ } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+ mSession.mSelectedSubtitleTrackId = trackId;
+ } else {
+ // Silently ignore.
+ return;
+ }
+ mSessionCallback.onTrackSelected(mSession, type, trackId);
}
});
}
@@ -476,26 +502,26 @@ public final class TvInputManager {
}
@Override
- public void onTrackInfoChanged(List<TvTrackInfo> tracks, int seq) {
+ 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;
}
- record.postTrackInfoChanged(tracks);
+ record.postTracksChanged(tracks);
}
}
@Override
- public void onTrackSelectionChanged(List<TvTrackInfo> selectedTracks, int seq) {
+ 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;
}
- record.postTrackSelectionChanged(selectedTracks);
+ record.postTrackSelected(type, trackId);
}
}
@@ -911,8 +937,12 @@ public final class TvInputManager {
private IBinder mToken;
private TvInputEventSender mSender;
private InputChannel mChannel;
- private List<TvTrackInfo> mTracks;
- private List<TvTrackInfo> mSelectedTracks;
+ private final List<TvTrackInfo> mAudioTracks = new ArrayList<TvTrackInfo>();
+ private final List<TvTrackInfo> mVideoTracks = new ArrayList<TvTrackInfo>();
+ private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<TvTrackInfo>();
+ private String mSelectedAudioTrackId;
+ private String mSelectedVideoTrackId;
+ private String mSelectedSubtitleTrackId;
private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId,
int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) {
@@ -1045,7 +1075,12 @@ public final class TvInputManager {
Log.w(TAG, "The session has been already released");
return;
}
- mTracks = null;
+ mAudioTracks.clear();
+ mVideoTracks.clear();
+ mSubtitleTracks.clear();
+ mSelectedAudioTrackId = null;
+ mSelectedVideoTrackId = null;
+ mSelectedSubtitleTrackId = null;
try {
mService.tune(mToken, channelUri, params, mUserId);
} catch (RemoteException e) {
@@ -1073,69 +1108,84 @@ public final class TvInputManager {
/**
* Selects a track.
*
- * @param track The track to be selected.
+ * @param type The type of the track to select. The type can be
+ * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+ * {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @param trackId The ID of the track to select. When {@code null}, the currently selected
+ * track of the given type will be unselected.
* @see #getTracks()
*/
- public void selectTrack(TvTrackInfo track) {
- if (track == null) {
- throw new IllegalArgumentException("track cannot be null");
+ public void selectTrack(int type, String trackId) {
+ if (type == TvTrackInfo.TYPE_AUDIO) {
+ if (trackId != null && !mAudioTracks.contains(trackId)) {
+ Log.w(TAG, "Invalid audio trackId: " + trackId);
+ }
+ } else if (type == TvTrackInfo.TYPE_VIDEO) {
+ if (trackId != null && !mVideoTracks.contains(trackId)) {
+ Log.w(TAG, "Invalid video trackId: " + trackId);
+ }
+ } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+ if (trackId != null && !mSubtitleTracks.contains(trackId)) {
+ Log.w(TAG, "Invalid subtitle trackId: " + trackId);
+ }
+ } else {
+ throw new IllegalArgumentException("invalid type: " + type);
}
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
try {
- mService.selectTrack(mToken, track, mUserId);
+ mService.selectTrack(mToken, type, trackId, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
/**
- * Unselects a track.
+ * Returns the list of tracks for a given type. Returns {@code null} if the information is
+ * not available.
*
- * @param track The track to be selected.
- * @see #getTracks()
- */
- public void unselectTrack(TvTrackInfo track) {
- if (track == null) {
- throw new IllegalArgumentException("track cannot be null");
- }
- if (mToken == null) {
- Log.w(TAG, "The session has been already released");
- return;
- }
- try {
- mService.unselectTrack(mToken, track, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns a list which includes track information. May return {@code null} if the
- * information is not available.
- * @see #selectTrack(TvTrackInfo)
- * @see #unselectTrack(TvTrackInfo)
+ * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+ * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @return the list of tracks for the given type.
*/
- public List<TvTrackInfo> getTracks() {
- if (mTracks == null) {
- return null;
+ public List<TvTrackInfo> getTracks(int type) {
+ if (type == TvTrackInfo.TYPE_AUDIO) {
+ if (mAudioTracks == null) {
+ return null;
+ }
+ return mAudioTracks;
+ } else if (type == TvTrackInfo.TYPE_VIDEO) {
+ if (mVideoTracks == null) {
+ return null;
+ }
+ return mVideoTracks;
+ } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+ if (mSubtitleTracks == null) {
+ return null;
+ }
+ return mSubtitleTracks;
}
- return new ArrayList<TvTrackInfo>(mTracks);
+ throw new IllegalArgumentException("invalid type: " + type);
}
/**
- * Returns a list of selected tracks May return {@code null} if the information is not
- * available.
- * @see #selectTrack(TvTrackInfo)
- * @see #unselectTrack(TvTrackInfo)
+ * Returns the selected track for a given type. Returns {@code null} if the information is
+ * not available or any of the tracks for the given type is not selected.
+ *
+ * @return the ID of the selected track.
+ * @see #selectTrack
*/
- public List<TvTrackInfo> getSelectedTracks() {
- if (mSelectedTracks == null) {
- return null;
- }
- return new ArrayList<TvTrackInfo>(mSelectedTracks);
+ public String getSelectedTrack(int type) {
+ if (type == TvTrackInfo.TYPE_AUDIO) {
+ return mSelectedAudioTrackId;
+ } else if (type == TvTrackInfo.TYPE_VIDEO) {
+ return mSelectedVideoTrackId;
+ } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+ return mSelectedSubtitleTrackId;
+ }
+ throw new IllegalArgumentException("invalid type: " + type);
}
/**
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7ce278c93d3e..d084cf70338e 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -47,7 +47,9 @@ import android.view.accessibility.CaptioningManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* The TvInputService class represents a TV input or source such as HDMI or built-in tuner which
@@ -319,42 +321,56 @@ public abstract class TvInputService extends Service {
}
/**
- * Sends the change on the track information. This is expected to be called whenever a
- * track is added/removed and the metadata of a track is modified.
+ * Sends the change on the track information. This is expected to be called whenever a track
+ * is added/removed and the metadata of a track is modified.
*
* @param tracks A list which includes track information.
+ * @throws IllegalArgumentException if {@code tracks} contains redundant tracks.
*/
- public void notifyTrackInfoChanged(final List<TvTrackInfo> tracks) {
+ public void notifyTracksChanged(final List<TvTrackInfo> tracks) {
+ Set<String> trackIdSet = new HashSet<String>();
+ for (TvTrackInfo track : tracks) {
+ String trackId = track.getId();
+ if (trackIdSet.contains(trackId)) {
+ throw new IllegalArgumentException("redundant track ID: " + trackId);
+ }
+ trackIdSet.add(trackId);
+ }
+ trackIdSet.clear();
+
+ // TODO: Validate the track list.
mHandler.post(new Runnable() {
@Override
public void run() {
try {
- if (DEBUG) Log.d(TAG, "notifyTrackInfoChanged");
- mSessionCallback.onTrackInfoChanged(tracks);
+ if (DEBUG) Log.d(TAG, "notifyTracksChanged");
+ mSessionCallback.onTracksChanged(tracks);
} catch (RemoteException e) {
- Log.w(TAG, "error in notifyTrackInfoChanged");
+ Log.w(TAG, "error in notifyTracksChanged");
}
}
});
}
/**
- * Sends the list of selected tracks. This is expected to be called whenever there is a
- * change on track selection.
+ * Sends the ID of the selected track for a given track type. This is expected to be called
+ * whenever there is a change on track selection.
*
- * @param selectedTracks A list of selected tracks.
- * @see #onSelectTrack(TvTrackInfo)
- * @see #onUnselectTrack(TvTrackInfo)
+ * @param type The type of the selected track. The type can be
+ * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+ * {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @param trackId The ID of the selected track.
+ * @see #onSelectTrack
*/
- public void notifyTrackSelectionChanged(final List<TvTrackInfo> selectedTracks) {
+ public void notifyTrackSelected(final int type, final String trackId) {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
- if (DEBUG) Log.d(TAG, "notifyTrackSelectionChanged");
- mSessionCallback.onTrackSelectionChanged(selectedTracks);
+ if (DEBUG) Log.d(TAG, "notifyTrackSelected");
+ mSessionCallback.onTrackSelected(type, trackId);
} catch (RemoteException e) {
- Log.w(TAG, "error in notifyTrackSelectionChanged");
+ Log.w(TAG, "error in notifyTrackSelected");
}
}
});
@@ -598,34 +614,20 @@ public abstract class TvInputService extends Service {
}
/**
- * Selects a given track.
+ * Select a given track.
* <p>
- * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the
- * track selected previously should be unselected in the implementation of this method.
- * Also, if the select operation was successful, the implementation should call
- * {@link #notifyTrackSelectionChanged(List)} to report the selected track list.
+ * If this is done successfully, the implementation should call {@link #notifyTrackSelected}
+ * to help applications maintain the selcted track lists.
* </p>
*
- * @param track The track to be selected.
- * @return {@code true} if the select operation was successful, {@code false} otherwise.
- * @see #notifyTrackSelectionChanged(List)
+ * @param trackId The ID of the track to select. {@code null} means to unselect the current
+ * track for a given type.
+ * @param type The type of the track to select. The type can be
+ * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+ * {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @see #notifyTrackSelected
*/
- public boolean onSelectTrack(TvTrackInfo track) {
- return false;
- }
-
- /**
- * Unselects a given track.
- * <p>
- * If the unselect operation was successful, the implementation should call
- * {@link #notifyTrackSelectionChanged(List)} to report the selected track list.
- * </p>
- *
- * @param track The track to be unselected.
- * @return {@code true} if the unselect operation was successful, {@code false} otherwise.
- * @see #notifyTrackSelectionChanged(List)
- */
- public boolean onUnselectTrack(TvTrackInfo track) {
+ public boolean onSelectTrack(int type, String trackId) {
return false;
}
@@ -837,17 +839,8 @@ public abstract class TvInputService extends Service {
/**
* Calls {@link #onSelectTrack}.
*/
- void selectTrack(TvTrackInfo track) {
- onSelectTrack(track);
- // TODO: Handle failure.
- }
-
- /**
- * Calls {@link #onUnselectTrack}.
- */
- void unselectTrack(TvTrackInfo track) {
- onUnselectTrack(track);
- // TODO: Handle failure.
+ void selectTrack(int type, String trackId) {
+ onSelectTrack(type, trackId);
}
/**
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index f296984fa041..6ddb2a2e0ec8 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -40,6 +40,7 @@ public final class TvTrackInfo implements Parcelable {
public static final int TYPE_SUBTITLE = 2;
private final int mType;
+ private final String mId;
private final String mLanguage;
private final int mAudioChannelCount;
private final int mAudioSampleRate;
@@ -47,9 +48,10 @@ public final class TvTrackInfo implements Parcelable {
private final int mVideoHeight;
private final Bundle mExtra;
- private TvTrackInfo(int type, String language, int audioChannelCount,
+ private TvTrackInfo(int type, String id, String language, int audioChannelCount,
int audioSampleRate, int videoWidth, int videoHeight, Bundle extra) {
mType = type;
+ mId = id;
mLanguage = language;
mAudioChannelCount = audioChannelCount;
mAudioSampleRate = audioSampleRate;
@@ -60,6 +62,7 @@ public final class TvTrackInfo implements Parcelable {
private TvTrackInfo(Parcel in) {
mType = in.readInt();
+ mId = in.readString();
mLanguage = in.readString();
mAudioChannelCount = in.readInt();
mAudioSampleRate = in.readInt();
@@ -77,6 +80,13 @@ public final class TvTrackInfo implements Parcelable {
}
/**
+ * Returns the ID of the track.
+ */
+ public final String getId() {
+ return mId;
+ }
+
+ /**
* Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
* is unknown or could not be determined, the corresponding value will be {@code null}.
*/
@@ -147,6 +157,7 @@ public final class TvTrackInfo implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
+ dest.writeString(mId);
dest.writeString(mLanguage);
dest.writeInt(mAudioChannelCount);
dest.writeInt(mAudioSampleRate);
@@ -172,7 +183,8 @@ public final class TvTrackInfo implements Parcelable {
* A builder class for creating {@link TvTrackInfo} objects.
*/
public static final class Builder {
- private int mType;
+ private final String mId;
+ private final int mType;
private String mLanguage;
private int mAudioChannelCount;
private int mAudioSampleRate;
@@ -185,14 +197,20 @@ public final class TvTrackInfo implements Parcelable {
* must be added.
*
* @param type The type of the track.
+ * @param id The ID of the track that uniquely identifies the current track among all the
+ * other tracks in the same TV program.
*/
- public Builder(int type) {
+ public Builder(int type, String id) {
if (type != TYPE_AUDIO
&& type != TYPE_VIDEO
&& type != TYPE_SUBTITLE) {
throw new IllegalArgumentException("Unknown type: " + type);
}
+ if (id == null) {
+ throw new IllegalArgumentException("id cannot be null");
+ }
mType = type;
+ mId = id;
}
/**
@@ -276,8 +294,8 @@ public final class TvTrackInfo implements Parcelable {
* @return The new {@link TvTrackInfo} instance
*/
public TvTrackInfo build() {
- return new TvTrackInfo(mType, mLanguage, mAudioChannelCount,
- mAudioSampleRate, mVideoWidth, mVideoHeight, mExtra);
+ return new TvTrackInfo(mType, mId, mLanguage, mAudioChannelCount, mAudioSampleRate,
+ mVideoWidth, mVideoHeight, mExtra);
}
}
} \ No newline at end of file
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 78b1754da36a..0959800d4807 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -294,55 +294,49 @@ public class TvView extends ViewGroup {
/**
* Selects a track.
- * <p>
- * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the track
- * selected in previous will be unselected. Note that this method does not take any effect
- * unless the current TvView is tuned.
- * </p>
*
- * @param track the track to be selected.
- * @see #getTracks()
+ * @param type The type of the track to select. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+ * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @param trackId The ID of the track to select. {@code null} means to unselect the current
+ * track for a given type.
+ * @see #getTracks
+ * @see #getSelectedTrack
*/
- public void selectTrack(TvTrackInfo track) {
+ public void selectTrack(int type, String trackId) {
if (mSession != null) {
- mSession.selectTrack(track);
+ mSession.selectTrack(type, trackId);
}
}
/**
- * Unselects a track.
- * <p>
- * Note that this method does not take any effect unless the current TvView is tuned.
+ * Returns the list of tracks. Returns {@code null} if the information is not available.
*
- * @param track the track to be unselected.
- * @see #getTracks()
+ * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+ * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @see #selectTrack
+ * @see #getSelectedTrack
*/
- public void unselectTrack(TvTrackInfo track) {
- if (mSession != null) {
- mSession.unselectTrack(track);
- }
- }
-
- /**
- * Returns a list which includes of track information. May return {@code null} if the
- * information is not available.
- */
- public List<TvTrackInfo> getTracks() {
+ public List<TvTrackInfo> getTracks(int type) {
if (mSession == null) {
return null;
}
- return mSession.getTracks();
+ return mSession.getTracks(type);
}
/**
- * Returns a list of selected tracks. May return {@code null} if the information is not
- * available.
+ * Returns the ID of the selected track for a given type. Returns {@code null} if the
+ * information is not available or the track is not selected.
+ *
+ * @param type The type of the selected tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+ * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @see #selectTrack
+ * @see #getTracks
*/
- public List<TvTrackInfo> getSelectedTracks() {
+ public String getSelectedTrack(int type) {
if (mSession == null) {
return null;
}
- return mSession.getSelectedTracks();
+ return mSession.getSelectedTrack(type);
}
/**
@@ -592,22 +586,6 @@ public class TvView extends ViewGroup {
location[0] + getWidth(), location[1] + getHeight());
}
- private void updateVideoSize(List<TvTrackInfo> tracks) {
- for (TvTrackInfo track : tracks) {
- if (track.getType() == TvTrackInfo.TYPE_VIDEO) {
- int width = track.getVideoWidth();
- int height = track.getVideoHeight();
- if (width != mVideoWidth || height != mVideoHeight) {
- mVideoWidth = width;
- mVideoHeight = height;
- if (mListener != null) {
- mListener.onVideoSizeChanged(mSessionCallback.mInputId, width, height);
- }
- }
- }
- }
- }
-
/**
* Interface used to receive various status updates on the {@link TvView}.
*/
@@ -650,16 +628,19 @@ public class TvView extends ViewGroup {
* @param inputId The ID of the TV input bound to this view.
* @param tracks A list which includes track information.
*/
- public void onTrackInfoChanged(String inputId, List<TvTrackInfo> tracks) {
+ public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
}
/**
* This is called when there is a change on the selected tracks.
*
* @param inputId The ID of the TV input bound to this view.
- * @param selectedTracks A list which includes track information.
+ * @param type The type of the track selected. The type can be
+ * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+ * {@link TvTrackInfo#TYPE_SUBTITLE}.
+ * @param trackId The ID of the track selected.
*/
- public void onTrackSelectionChanged(String inputId, List<TvTrackInfo> selectedTracks) {
+ public void onTrackSelected(String inputId, int type, String trackId) {
}
/**
@@ -807,29 +788,29 @@ public class TvView extends ViewGroup {
}
@Override
- public void onTrackInfoChanged(Session session, List<TvTrackInfo> tracks) {
+ public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
if (this != mSessionCallback) {
return;
}
if (DEBUG) {
- Log.d(TAG, "onTrackInfoChanged()");
+ Log.d(TAG, "onTracksChanged()");
}
if (mListener != null) {
- mListener.onTrackInfoChanged(mInputId, tracks);
+ mListener.onTracksChanged(mInputId, tracks);
}
}
@Override
- public void onTrackSelectionChanged(Session session, List<TvTrackInfo> selectedTracks) {
+ public void onTrackSelected(Session session, int type, String trackId) {
if (this != mSessionCallback) {
return;
}
if (DEBUG) {
- Log.d(TAG, "onTrackInfoChanged()");
+ Log.d(TAG, "onTrackSelected()");
}
- updateVideoSize(selectedTracks);
+ // TODO: Update the video size when the type is TYPE_VIDEO.
if (mListener != null) {
- mListener.onTrackSelectionChanged(mInputId, selectedTracks);
+ mListener.onTrackSelected(mInputId, type, trackId);
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e11b6a70928b..73b4a5464fe2 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -533,37 +533,35 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void onTrackInfoChanged(List<TvTrackInfo> tracks) {
+ public void onTracksChanged(List<TvTrackInfo> tracks) {
synchronized (mLock) {
if (DEBUG) {
- Slog.d(TAG, "onTrackInfoChanged(" + tracks + ")");
+ Slog.d(TAG, "onTracksChanged(" + tracks + ")");
}
if (sessionState.mSession == null || sessionState.mClient == null) {
return;
}
try {
- sessionState.mClient.onTrackInfoChanged(tracks,
- sessionState.mSeq);
+ sessionState.mClient.onTracksChanged(tracks, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onTrackInfoChanged");
+ Slog.e(TAG, "error in onTracksChanged");
}
}
}
@Override
- public void onTrackSelectionChanged(List<TvTrackInfo> selectedTracks) {
+ public void onTrackSelected(int type, String trackId) {
synchronized (mLock) {
if (DEBUG) {
- Slog.d(TAG, "onTrackSelectionChanged(" + selectedTracks + ")");
+ Slog.d(TAG, "onTrackSelected(type=" + type + ", trackId=" + trackId + ")");
}
if (sessionState.mSession == null || sessionState.mClient == null) {
return;
}
try {
- sessionState.mClient.onTrackSelectionChanged(selectedTracks,
- sessionState.mSeq);
+ sessionState.mClient.onTrackSelected(type, trackId, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onTrackSelectionChanged");
+ Slog.e(TAG, "error in onTrackSelected");
}
}
}
@@ -1266,7 +1264,7 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void selectTrack(IBinder sessionToken, TvTrackInfo track, int userId) {
+ public void selectTrack(IBinder sessionToken, int type, String trackId, int userId) {
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "selectTrack");
@@ -1275,7 +1273,7 @@ public final class TvInputManagerService extends SystemService {
synchronized (mLock) {
try {
getSessionLocked(sessionToken, callingUid, resolvedUserId).selectTrack(
- track);
+ type, trackId);
} catch (RemoteException e) {
Slog.e(TAG, "error in selectTrack", e);
}
@@ -1286,26 +1284,6 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void unselectTrack(IBinder sessionToken, TvTrackInfo track, int userId) {
- final int callingUid = Binder.getCallingUid();
- final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
- userId, "unselectTrack");
- final long identity = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- try {
- getSessionLocked(sessionToken, callingUid, resolvedUserId).unselectTrack(
- track);
- } catch (RemoteException e) {
- Slog.e(TAG, "error in unselectTrack", e);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
public void sendAppPrivateCommand(IBinder sessionToken, String command, Bundle data,
int userId) {
final int callingUid = Binder.getCallingUid();