diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | media/java/android/media/tv/ITvInputClient.aidl | 2 | ||||
-rw-r--r-- | media/java/android/media/tv/ITvInputSessionCallback.aidl | 2 | ||||
-rw-r--r-- | media/java/android/media/tv/TvInputManager.java | 31 | ||||
-rw-r--r-- | media/java/android/media/tv/TvInputService.java | 19 | ||||
-rw-r--r-- | media/java/android/media/tv/TvView.java | 20 | ||||
-rw-r--r-- | services/core/java/com/android/server/tv/TvInputManagerService.java | 21 |
7 files changed, 97 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 92dce76..769657b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16098,6 +16098,7 @@ package android.media.tv { public abstract class TvInputService.Session implements android.view.KeyEvent.Callback { ctor public TvInputService.Session(); + method public void dispatchChannelRetuned(android.net.Uri); method public android.view.View onCreateOverlayView(); method public boolean onGenericMotionEvent(android.view.MotionEvent); method public boolean onKeyDown(int, android.view.KeyEvent); @@ -16135,6 +16136,7 @@ package android.media.tv { public static abstract class TvView.TvInputListener { ctor public TvView.TvInputListener(); + method public void onChannelRetuned(java.lang.String, android.net.Uri); method public void onError(java.lang.String, int); } diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index 011da35..2854007 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -18,6 +18,7 @@ package android.media.tv; import android.content.ComponentName; import android.media.tv.ITvInputSession; +import android.net.Uri; import android.os.Bundle; import android.view.InputChannel; @@ -34,4 +35,5 @@ oneway interface ITvInputClient { void onVideoStreamChanged(int width, int height, boolean interlaced, int seq); void onAudioStreamChanged(int channelCount, int seq); void onClosedCaptionStreamChanged(boolean hasClosedCaption, int seq); + void onChannelRetuned(in Uri channelUri, int seq); } diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl index 00f2922..5a57ccd 100644 --- a/media/java/android/media/tv/ITvInputSessionCallback.aidl +++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl @@ -17,6 +17,7 @@ package android.media.tv; import android.media.tv.ITvInputSession; +import android.net.Uri; import android.os.Bundle; /** @@ -30,4 +31,5 @@ oneway interface ITvInputSessionCallback { void onVideoStreamChanged(int width, int height, boolean interlaced); void onAudioStreamChanged(int channelCount); void onClosedCaptionStreamChanged(boolean hasClosedCaption); + void onChannelRetuned(in Uri channelUri); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index daa7009..834ce64 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -125,6 +125,16 @@ public final class TvInputManager { } /** + * This is called when the channel of this session is changed by the underlying TV input + * with out any {@link TvInputManager.Session#tune(Uri)} request. + * + * @param session A {@link TvInputManager.Session} associated with this callback + * @param channelUri The URI of a channel. + */ + public void onChannelRetuned(Session session, Uri channelUri) { + } + + /** * This is called when a custom event has been sent from this session. * * @param session A {@link TvInputManager.Session} associated with this callback @@ -194,6 +204,15 @@ public final class TvInputManager { }); } + public void postChannelRetuned(final Uri channelUri) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onChannelRetuned(mSession, channelUri); + } + }); + } + public void postSessionEvent(final String eventType, final Bundle eventArgs) { mHandler.post(new Runnable() { @Override @@ -318,6 +337,18 @@ public final class TvInputManager { } @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 onSessionEvent(String eventType, Bundle eventArgs, int seq) { synchronized (mSessionCallbackRecordMap) { SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 0f4a930..1e512cd 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -286,6 +286,25 @@ public abstract class TvInputService extends Service { } /** + * Notifies the channel of the session is retuned by TV input. + * + * @param channelUri The URI of a channel. + */ + public void dispatchChannelRetuned(final Uri channelUri) { + mHandler.post(new Runnable() { + @Override + public void run() { + try { + if (DEBUG) Log.d(TAG, "dispatchChannelRetuned"); + mSessionCallback.onChannelRetuned(channelUri); + } catch (RemoteException e) { + Log.w(TAG, "error in dispatchChannelRetuned"); + } + } + }); + } + + /** * Called when the session is released. */ public abstract void onRelease(); diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index a913e59c..664a215 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -456,6 +456,16 @@ public class TvView extends ViewGroup { } /** + * This is invoked when the channel of this TvView is changed by the underlying TV input + * with out any {@link TvView#tune(String, Uri)} request. + * + * @param inputId The ID of the TV input bound to this view. + * @param channelUri The URI of a channel. + */ + public void onChannelRetuned(String inputId, Uri channelUri) { + } + + /** * This is invoked when a custom event from the bound TV input is sent to this view. * * @param eventType The type of the event. @@ -562,6 +572,16 @@ public class TvView extends ViewGroup { } @Override + public void onChannelRetuned(Session session, Uri channelUri) { + if (DEBUG) { + Log.d(TAG, "onChannelChangedByTvInput(" + channelUri + ")"); + } + if (mListener != null) { + mListener.onChannelRetuned(mInputId, channelUri); + } + } + + @Override public void onSessionEvent(TvInputManager.Session session, String eventType, Bundle eventArgs) { if (mListener != null) { diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 02dd1bf..bf767e2 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -485,6 +485,27 @@ public final class TvInputManagerService extends SystemService { } @Override + public void onChannelRetuned(Uri channelUri) { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onChannelRetuned(" + channelUri + ")"); + } + if (sessionState.mSession == null || sessionState.mClient == null) { + return; + } + try { + // TODO: Consider adding this channel change in the watch log. When we do + // that, how we can protect the watch log from malicious tv inputs should + // be addressed. e.g. add a field which represents where the channel change + // originated from. + sessionState.mClient.onChannelRetuned(channelUri, sessionState.mSeq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onChannelRetuned"); + } + } + } + + @Override public void onSessionEvent(String eventType, Bundle eventArgs) { synchronized (mLock) { if (DEBUG) { |