From e861efdc57e6b4ceae4b48a95c4302ce46172426 Mon Sep 17 00:00:00 2001 From: shubang Date: Thu, 23 Dec 2021 10:35:30 -0800 Subject: [PATCH] TIAF cleanup: add missing APIs for main use cases Bug: 211931006 Test: mmm Change-Id: I48fb11278aae463c6eda81dbcd1b3bc6a175b031 --- .../java/android/media/tv/ITvInputClient.aidl | 2 +- .../android/media/tv/ITvInputManager.aidl | 1 + .../android/media/tv/ITvInputSession.aidl | 1 + .../media/tv/ITvInputSessionWrapper.java | 12 +- .../java/android/media/tv/TvInputManager.java | 28 +- .../java/android/media/tv/TvInputService.java | 10 + .../media/tv/interactive/ITvIAppClient.aidl | 7 + .../media/tv/interactive/ITvIAppManager.aidl | 8 + .../media/tv/interactive/ITvIAppSession.aidl | 9 + .../interactive/ITvIAppSessionCallback.aidl | 7 + .../media/tv/interactive/TvIAppManager.java | 259 +++++++++++++++- .../media/tv/interactive/TvIAppService.java | 276 ++++++++++++++++- .../media/tv/interactive/TvIAppView.java | 185 +++++++++++- .../server/tv/TvInputManagerService.java | 24 +- .../tv/interactive/TvIAppManagerService.java | 282 ++++++++++++++++++ 15 files changed, 1086 insertions(+), 25 deletions(-) diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index 6f7db4a7b192c..de13fc1b91490 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -20,8 +20,8 @@ import android.content.ComponentName; import android.media.tv.AitInfo; import android.media.tv.BroadcastInfoResponse; import android.media.tv.ITvInputSession; -import android.net.Uri; import android.media.tv.TvTrackInfo; +import android.net.Uri; import android.os.Bundle; import android.view.InputChannel; diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index 28b7b45100208..a6e02174e6fd8 100644 --- a/media/java/android/media/tv/ITvInputManager.aidl +++ b/media/java/android/media/tv/ITvInputManager.aidl @@ -104,6 +104,7 @@ interface ITvInputManager { // For broadcast info void requestBroadcastInfo(in IBinder sessionToken, in BroadcastInfoRequest request, int userId); + void removeBroadcastInfo(in IBinder sessionToken, int id, int userId); // For TV input hardware binding List getHardwareList(); diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl index 984a551086ac3..025e6f1c2df80 100644 --- a/media/java/android/media/tv/ITvInputSession.aidl +++ b/media/java/android/media/tv/ITvInputSession.aidl @@ -66,4 +66,5 @@ oneway interface ITvInputSession { // For broadcast info void requestBroadcastInfo(in BroadcastInfoRequest request); + void removeBroadcastInfo(int id); } diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java index 6539472d203c0..ef6ef91e66101 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -71,7 +71,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand private static final int DO_PAUSE_RECORDING = 22; private static final int DO_RESUME_RECORDING = 23; private static final int DO_REQUEST_BROADCAST_INFO = 24; - private static final int DO_SET_IAPP_NOTIFICATION_ENABLED = 25; + private static final int DO_REMOVE_BROADCAST_INFO = 25; + private static final int DO_SET_IAPP_NOTIFICATION_ENABLED = 26; private final boolean mIsRecordingSession; private final HandlerCaller mCaller; @@ -240,6 +241,10 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand mTvInputSessionImpl.requestBroadcastInfo((BroadcastInfoRequest) msg.obj); break; } + case DO_REMOVE_BROADCAST_INFO: { + mTvInputSessionImpl.removeBroadcastInfo(msg.arg1); + break; + } case DO_SET_IAPP_NOTIFICATION_ENABLED: { mTvInputSessionImpl.setIAppNotificationEnabled((Boolean) msg.obj); break; @@ -404,6 +409,11 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REQUEST_BROADCAST_INFO, request)); } + @Override + public void removeBroadcastInfo(int requestId) { + mCaller.executeOrSendMessage(mCaller.obtainMessageI(DO_REMOVE_BROADCAST_INFO, requestId)); + } + private final class TvInputEventReceiver extends InputEventReceiver { public TvInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 7a20c71d76ae8..cde2f5a65df39 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -731,6 +731,9 @@ public final class TvInputManager { @Override public void run() { mSessionCallback.onTracksChanged(mSession, tracks); + if (mSession.mIAppNotificationEnabled && mSession.getIAppSession() != null) { + mSession.getIAppSession().notifyTracksChanged(tracks); + } } }); } @@ -740,6 +743,9 @@ public final class TvInputManager { @Override public void run() { mSessionCallback.onTrackSelected(mSession, type, trackId); + if (mSession.mIAppNotificationEnabled && mSession.getIAppSession() != null) { + mSession.getIAppSession().notifyTrackSelected(type, trackId); + } } }); } @@ -1273,12 +1279,6 @@ public final class TvInputManager { } record.postTuned(channelUri); // TODO: synchronized and wrap the channelUri - if (record.mSession.mIAppNotificationEnabled) { - TvIAppManager.Session iappSession = record.mSession.mIAppSession; - if (iappSession != null) { - iappSession.notifyTuned(channelUri); - } - } } } @@ -3014,7 +3014,23 @@ public final class TvInputManager { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + } + /** + * Removes broadcast info. + * @param requestId the corresponding request ID sent from + * {@link #requestBroadcastInfo(android.media.tv.BroadcastInfoRequest)} + */ + public void removeBroadcastInfo(int requestId) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.removeBroadcastInfo(mToken, requestId, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } private final class InputEventHandler extends Handler { diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index eccd90aa2f642..ee33e5c43dde3 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -1044,6 +1044,12 @@ public abstract class TvInputService extends Service { public void onRequestBroadcastInfo(@NonNull BroadcastInfoRequest request) { } + /** + * @hide + */ + public void onRemoveBroadcastInfo(int requestId) { + } + /** * Tunes to a given channel. * @@ -1653,6 +1659,10 @@ public abstract class TvInputService extends Service { onRequestBroadcastInfo(request); } + void removeBroadcastInfo(int requestId) { + onRemoveBroadcastInfo(requestId); + } + /** * Takes care of dispatching incoming input events and tells whether the event was handled. */ diff --git a/media/java/android/media/tv/interactive/ITvIAppClient.aidl b/media/java/android/media/tv/interactive/ITvIAppClient.aidl index d6e37a653a294..00c464f5e0adb 100644 --- a/media/java/android/media/tv/interactive/ITvIAppClient.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppClient.aidl @@ -16,6 +16,7 @@ package android.media.tv.interactive; +import android.graphics.Rect; import android.media.tv.BroadcastInfoRequest; import android.net.Uri; import android.os.Bundle; @@ -31,7 +32,13 @@ oneway interface ITvIAppClient { void onSessionReleased(int seq); void onLayoutSurface(int left, int top, int right, int bottom, int seq); void onBroadcastInfoRequest(in BroadcastInfoRequest request, int seq); + void onRemoveBroadcastInfo(int id, int seq); void onSessionStateChanged(int state, int seq); void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId, int seq); void onCommandRequest(in String cmdType, in Bundle parameters, int seq); + void onSetVideoBounds(in Rect rect, int seq); + void onRequestCurrentChannelUri(int seq); + void onRequestCurrentChannelLcn(int seq); + void onRequestStreamVolume(int seq); + void onRequestTrackInfoList(int seq); } diff --git a/media/java/android/media/tv/interactive/ITvIAppManager.aidl b/media/java/android/media/tv/interactive/ITvIAppManager.aidl index e26c2abf949b0..15a2eacee2a27 100644 --- a/media/java/android/media/tv/interactive/ITvIAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppManager.aidl @@ -18,6 +18,7 @@ package android.media.tv.interactive; import android.graphics.Rect; import android.media.tv.BroadcastInfoResponse; +import android.media.tv.TvTrackInfo; import android.media.tv.interactive.ITvIAppClient; import android.media.tv.interactive.ITvIAppManagerCallback; import android.media.tv.interactive.TvIAppInfo; @@ -35,13 +36,20 @@ interface ITvIAppManager { void notifyAppLinkInfo(String tiasId, in Bundle info, int userId); void sendAppLinkCommand(String tiasId, in Bundle command, int userId); void startIApp(in IBinder sessionToken, int userId); + void stopIApp(in IBinder sessionToken, int userId); void createBiInteractiveApp( in IBinder sessionToken, in Uri biIAppUri, in Bundle params, int userId); void destroyBiInteractiveApp(in IBinder sessionToken, in String biIAppId, int userId); + void sendCurrentChannelUri(in IBinder sessionToken, in Uri channelUri, int userId); + void sendCurrentChannelLcn(in IBinder sessionToken, int lcn, int userId); + void sendStreamVolume(in IBinder sessionToken, float volume, int userId); + void sendTrackInfoList(in IBinder sessionToken, in List tracks, int userId); void createSession( in ITvIAppClient client, in String iAppServiceId, int type, int seq, int userId); void releaseSession(in IBinder sessionToken, int userId); void notifyTuned(in IBinder sessionToken, in Uri channelUri, int userId); + void notifyTrackSelected(in IBinder sessionToken, int type, in String trackId, int userId); + void notifyTracksChanged(in IBinder sessionToken, in List tracks, int userId); void setSurface(in IBinder sessionToken, in Surface surface, int userId); void dispatchSurfaceChanged(in IBinder sessionToken, int format, int width, int height, int userId); diff --git a/media/java/android/media/tv/interactive/ITvIAppSession.aidl b/media/java/android/media/tv/interactive/ITvIAppSession.aidl index 78930c0d02fb5..4a85feff159a6 100644 --- a/media/java/android/media/tv/interactive/ITvIAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppSession.aidl @@ -19,6 +19,8 @@ package android.media.tv.interactive; import android.graphics.Rect; import android.media.tv.BroadcastInfoResponse; import android.net.Uri; +import android.media.tv.BroadcastInfoResponse; +import android.media.tv.TvTrackInfo; import android.os.Bundle; import android.view.Surface; @@ -28,10 +30,17 @@ import android.view.Surface; */ oneway interface ITvIAppSession { void startIApp(); + void stopIApp(); void createBiInteractiveApp(in Uri biIAppUri, in Bundle params); void destroyBiInteractiveApp(in String biIAppId); + void sendCurrentChannelUri(in Uri channelUri); + void sendCurrentChannelLcn(int lcn); + void sendStreamVolume(float volume); + void sendTrackInfoList(in List tracks); void release(); void notifyTuned(in Uri channelUri); + void notifyTrackSelected(int type, in String trackId); + void notifyTracksChanged(in List tracks); void setSurface(in Surface surface); void dispatchSurfaceChanged(int format, int width, int height); void notifyBroadcastInfoResponse(in BroadcastInfoResponse response); diff --git a/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl index c754c8c170a65..b09f787ef6808 100644 --- a/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl @@ -16,6 +16,7 @@ package android.media.tv.interactive; +import android.graphics.Rect; import android.media.tv.BroadcastInfoRequest; import android.media.tv.interactive.ITvIAppSession; import android.media.tv.BroadcastInfoRequest; @@ -31,7 +32,13 @@ oneway interface ITvIAppSessionCallback { void onSessionCreated(in ITvIAppSession session); void onLayoutSurface(int left, int top, int right, int bottom); void onBroadcastInfoRequest(in BroadcastInfoRequest request); + void onRemoveBroadcastInfo(int id); void onSessionStateChanged(int state); void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId); void onCommandRequest(in String cmdType, in Bundle parameters); + void onSetVideoBounds(in Rect rect); + void onRequestCurrentChannelUri(); + void onRequestCurrentChannelLcn(); + void onRequestStreamVolume(); + void onRequestTrackInfoList(); } diff --git a/media/java/android/media/tv/interactive/TvIAppManager.java b/media/java/android/media/tv/interactive/TvIAppManager.java index 8694cc5d6aad5..4c4dffb794048 100644 --- a/media/java/android/media/tv/interactive/TvIAppManager.java +++ b/media/java/android/media/tv/interactive/TvIAppManager.java @@ -25,6 +25,7 @@ import android.graphics.Rect; import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; import android.media.tv.TvInputManager; +import android.media.tv.TvTrackInfo; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -243,6 +244,18 @@ public final class TvIAppManager { } } + @Override + public void onRemoveBroadcastInfo(int requestId, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRemoveBroadcastInfo(requestId); + } + } + @Override public void onCommandRequest(@TvIAppService.IAppServiceCommandType String cmdType, Bundle parameters, int seq) { @@ -256,6 +269,66 @@ public final class TvIAppManager { } } + @Override + public void onSetVideoBounds(Rect rect, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postSetVideoBounds(rect); + } + } + + @Override + public void onRequestCurrentChannelUri(int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRequestCurrentChannelUri(); + } + } + + @Override + public void onRequestCurrentChannelLcn(int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRequestCurrentChannelLcn(); + } + } + + @Override + public void onRequestStreamVolume(int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRequestStreamVolume(); + } + } + + @Override + public void onRequestTrackInfoList(int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRequestTrackInfoList(); + } + } + @Override public void onSessionStateChanged(int state, int seq) { synchronized (mSessionCallbackRecordMap) { @@ -634,6 +707,18 @@ public final class TvIAppManager { } } + void stopIApp() { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.stopIApp(mToken, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + void createBiInteractiveApp(Uri biIAppUri, Bundle params) { if (mToken == null) { Log.w(TAG, "The session has been already released"); @@ -658,6 +743,54 @@ public final class TvIAppManager { } } + void sendCurrentChannelUri(@Nullable Uri channelUri) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.sendCurrentChannelUri(mToken, channelUri, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void sendCurrentChannelLcn(int lcn) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.sendCurrentChannelLcn(mToken, lcn, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void sendStreamVolume(float volume) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.sendStreamVolume(mToken, volume, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void sendTrackInfoList(@NonNull List tracks) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.sendTrackInfoList(mToken, tracks, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Sets the {@link android.view.Surface} for this session. * @@ -829,7 +962,7 @@ public final class TvIAppManager { } /** - * Notifies IAPP session when a channels is tuned. + * Notifies IAPP session when a channel is tuned. */ public void notifyTuned(Uri channelUri) { if (mToken == null) { @@ -843,6 +976,36 @@ public final class TvIAppManager { } } + /** + * Notifies IAPP session when a track is selected. + */ + public void notifyTrackSelected(int type, String trackId) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.notifyTrackSelected(mToken, type, trackId, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Notifies IAPP session when tracks are changed. + */ + public void notifyTracksChanged(List tracks) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.notifyTracksChanged(mToken, tracks, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private void flushPendingEventsLocked() { mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT); @@ -1095,6 +1258,15 @@ public final class TvIAppManager { }); } + void postRemoveBroadcastInfo(final int requestId) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSession.getInputSession().removeBroadcastInfo(requestId); + } + }); + } + void postCommandRequest(final @TvIAppService.IAppServiceCommandType String cmdType, final Bundle parameters) { mHandler.post(new Runnable() { @@ -1105,6 +1277,51 @@ public final class TvIAppManager { }); } + void postSetVideoBounds(Rect rect) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onSetVideoBounds(mSession, rect); + } + }); + } + + void postRequestCurrentChannelUri() { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onRequestCurrentChannelUri(mSession); + } + }); + } + + void postRequestCurrentChannelLcn() { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onRequestCurrentChannelLcn(mSession); + } + }); + } + + void postRequestStreamVolume() { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onRequestStreamVolume(mSession); + } + }); + } + + void postRequestTrackInfoList() { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onRequestTrackInfoList(mSession); + } + }); + } + void postSessionStateChanged(int state) { mHandler.post(new Runnable() { @Override @@ -1171,6 +1388,46 @@ public final class TvIAppManager { @TvIAppService.IAppServiceCommandType String cmdType, Bundle parameters) { } + /** + * This is called when {@link TvIAppService.Session#SetVideoBounds} is called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + */ + public void onSetVideoBounds(Session session, Rect rect) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestCurrentChannelUri} is called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + */ + public void onRequestCurrentChannelUri(Session session) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestCurrentChannelLcn} is called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + */ + public void onRequestCurrentChannelLcn(Session session) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestStreamVolume} is called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + */ + public void onRequestStreamVolume(Session session) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestTrackInfoList} is called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + */ + public void onRequestTrackInfoList(Session session) { + } + /** * This is called when {@link TvIAppService.Session#notifySessionStateChanged} is called. * diff --git a/media/java/android/media/tv/interactive/TvIAppService.java b/media/java/android/media/tv/interactive/TvIAppService.java index 93a7e576d0ef6..a0f8413ac29d7 100644 --- a/media/java/android/media/tv/interactive/TvIAppService.java +++ b/media/java/android/media/tv/interactive/TvIAppService.java @@ -29,6 +29,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; +import android.media.tv.TvTrackInfo; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; @@ -90,23 +91,26 @@ public abstract class TvIAppService extends Service { @Retention(RetentionPolicy.SOURCE) @StringDef(prefix = "IAPP_SERVICE_COMMAND_TYPE_", value = { IAPP_SERVICE_COMMAND_TYPE_TUNE, - IAPP_SERVICE_COMMAND_TYPE_TUNENEXT, - IAPP_SERVICE_COMMAND_TYPE_TUNEPREV, + IAPP_SERVICE_COMMAND_TYPE_TUNE_NEXT, + IAPP_SERVICE_COMMAND_TYPE_TUNE_PREV, IAPP_SERVICE_COMMAND_TYPE_STOP, - IAPP_SERVICE_COMMAND_TYPE_SETSTREAMVOLUME + IAPP_SERVICE_COMMAND_TYPE_SET_STREAM_VOLUME, + IAPP_SERVICE_COMMAND_TYPE_SELECT_TRACK }) public @interface IAppServiceCommandType {} /** @hide */ - public static final String IAPP_SERVICE_COMMAND_TYPE_TUNE = "Tune"; + public static final String IAPP_SERVICE_COMMAND_TYPE_TUNE = "tune"; /** @hide */ - public static final String IAPP_SERVICE_COMMAND_TYPE_TUNENEXT = "TuneNext"; + public static final String IAPP_SERVICE_COMMAND_TYPE_TUNE_NEXT = "tune_next"; /** @hide */ - public static final String IAPP_SERVICE_COMMAND_TYPE_TUNEPREV = "TunePrevious"; + public static final String IAPP_SERVICE_COMMAND_TYPE_TUNE_PREV = "tune_previous"; /** @hide */ - public static final String IAPP_SERVICE_COMMAND_TYPE_STOP = "Stop"; + public static final String IAPP_SERVICE_COMMAND_TYPE_STOP = "stop"; /** @hide */ - public static final String IAPP_SERVICE_COMMAND_TYPE_SETSTREAMVOLUME = "setStreamVolume"; + public static final String IAPP_SERVICE_COMMAND_TYPE_SET_STREAM_VOLUME = "set_stream_volume"; + /** @hide */ + public static final String IAPP_SERVICE_COMMAND_TYPE_SELECT_TRACK = "select_track"; private final Handler mServiceHandler = new ServiceHandler(); private final RemoteCallbackList mCallbacks = @@ -287,6 +291,13 @@ public abstract class TvIAppService extends Service { public void onStartIApp() { } + /** + * Stops TvIAppService session. + * @hide + */ + public void onStopIApp() { + } + /** * Creates broadcast-independent(BI) interactive application. * @@ -309,6 +320,34 @@ public abstract class TvIAppService extends Service { public void onDestroyBiInteractiveApp(@NonNull String biIAppId) { } + /** + * Receives current channel URI. + * @hide + */ + public void onCurrentChannelUri(@Nullable Uri channelUri) { + } + + /** + * Receives logical channel number (LCN) of current channel. + * @hide + */ + public void onCurrentChannelLcn(int lcn) { + } + + /** + * Receives stream volume. + * @hide + */ + public void onStreamVolume(float volume) { + } + + /** + * Receives track list. + * @hide + */ + public void onTrackInfoList(@NonNull List tracks) { + } + /** * Called when the application sets the surface. * @@ -373,6 +412,20 @@ public abstract class TvIAppService extends Service { public void onTuned(@NonNull Uri channelUri) { } + /** + * Called when the corresponding TV input selected to a track. + * @hide + */ + public void onTrackSelected(int type, String trackId) { + } + + /** + * Called when the tracks are changed. + * @hide + */ + public void onTracksChanged(List tracks) { + } + /** * Called when a broadcast info response is received. * @hide @@ -491,6 +544,30 @@ public abstract class TvIAppService extends Service { }); } + /** + * Remove broadcast information request from the related TV input. + * @param requestId the ID of the request + */ + public void removeBroadcastInfo(final int requestId) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "removeBroadcastInfo (requestId=" + + requestId + ")"); + } + if (mSessionCallback != null) { + mSessionCallback.onRemoveBroadcastInfo(requestId); + } + } catch (RemoteException e) { + Log.w(TAG, "error in removeBroadcastInfo", e); + } + } + }); + } + /** * requests a specific command to be processed by the related TV input. * @param cmdType type of the specific command @@ -516,10 +593,124 @@ public abstract class TvIAppService extends Service { }); } + /** + * Sets broadcast video bounds. + */ + public void setVideoBounds(Rect rect) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "setVideoBounds (rect=" + rect + ")"); + } + if (mSessionCallback != null) { + mSessionCallback.onSetVideoBounds(rect); + } + } catch (RemoteException e) { + Log.w(TAG, "error in setVideoBounds", e); + } + } + }); + } + + /** + * Requests the URI of the current channel. + */ + public void requestCurrentChannelUri() { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestCurrentChannelUri"); + } + if (mSessionCallback != null) { + mSessionCallback.onRequestCurrentChannelUri(); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestCurrentChannelUri", e); + } + } + }); + } + + /** + * Requests the logic channel number (LCN) of the current channel. + */ + public void requestCurrentChannelLcn() { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestCurrentChannelLcn"); + } + if (mSessionCallback != null) { + mSessionCallback.onRequestCurrentChannelLcn(); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestCurrentChannelLcn", e); + } + } + }); + } + + /** + * Requests stream volume. + */ + public void requestStreamVolume() { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestStreamVolume"); + } + if (mSessionCallback != null) { + mSessionCallback.onRequestStreamVolume(); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestStreamVolume", e); + } + } + }); + } + + /** + * Requests the list of {@link TvTrackInfo}. + */ + public void requestTrackInfoList() { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestTrackInfoList"); + } + if (mSessionCallback != null) { + mSessionCallback.onRequestTrackInfoList(); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestTrackInfoList", e); + } + } + }); + } + void startIApp() { onStartIApp(); } + void stopIApp() { + onStopIApp(); + } + void createBiInteractiveApp(@NonNull Uri biIAppUri, @Nullable Bundle params) { onCreateBiInteractiveApp(biIAppUri, params); } @@ -528,6 +719,22 @@ public abstract class TvIAppService extends Service { onDestroyBiInteractiveApp(biIAppId); } + void sendCurrentChannelUri(@Nullable Uri channelUri) { + onCurrentChannelUri(channelUri); + } + + void sendCurrentChannelLcn(int lcn) { + onCurrentChannelLcn(lcn); + } + + void sendStreamVolume(float volume) { + onStreamVolume(volume); + } + + void sendTrackInfoList(@NonNull List tracks) { + onTrackInfoList(tracks); + } + void release() { onRelease(); if (mSurface != null) { @@ -550,6 +757,20 @@ public abstract class TvIAppService extends Service { onTuned(channelUri); } + void notifyTrackSelected(int type, String trackId) { + if (DEBUG) { + Log.d(TAG, "notifyTrackSelected (type=" + type + "trackId=" + trackId + ")"); + } + onTrackSelected(type, trackId); + } + + void notifyTracksChanged(List tracks) { + if (DEBUG) { + Log.d(TAG, "notifyTracksChanged (tracks=" + tracks + ")"); + } + onTracksChanged(tracks); + } + /** * Calls {@link #onBroadcastInfoResponse}. @@ -850,15 +1071,40 @@ public abstract class TvIAppService extends Service { } @Override - public void createBiInteractiveApp(Uri biIAppUri, Bundle params) { + public void stopIApp() { + mSessionImpl.stopIApp(); + } + + @Override + public void createBiInteractiveApp(@NonNull Uri biIAppUri, @Nullable Bundle params) { mSessionImpl.createBiInteractiveApp(biIAppUri, params); } @Override - public void destroyBiInteractiveApp(String biIAppId) { + public void destroyBiInteractiveApp(@NonNull String biIAppId) { mSessionImpl.destroyBiInteractiveApp(biIAppId); } + @Override + public void sendCurrentChannelUri(@Nullable Uri channelUri) { + mSessionImpl.sendCurrentChannelUri(channelUri); + } + + @Override + public void sendCurrentChannelLcn(int lcn) { + mSessionImpl.sendCurrentChannelLcn(lcn); + } + + @Override + public void sendStreamVolume(float volume) { + mSessionImpl.sendStreamVolume(volume); + } + + @Override + public void sendTrackInfoList(@NonNull List tracks) { + mSessionImpl.sendTrackInfoList(tracks); + } + @Override public void release() { mSessionImpl.scheduleMediaViewCleanup(); @@ -870,6 +1116,16 @@ public abstract class TvIAppService extends Service { mSessionImpl.notifyTuned(channelUri); } + @Override + public void notifyTrackSelected(int type, final String trackId) { + mSessionImpl.notifyTrackSelected(type, trackId); + } + + @Override + public void notifyTracksChanged(List tracks) { + mSessionImpl.notifyTracksChanged(tracks); + } + @Override public void setSurface(Surface surface) { mSessionImpl.setSurface(surface); diff --git a/media/java/android/media/tv/interactive/TvIAppView.java b/media/java/android/media/tv/interactive/TvIAppView.java index 77be645289b69..62ec4e31931f2 100644 --- a/media/java/android/media/tv/interactive/TvIAppView.java +++ b/media/java/android/media/tv/interactive/TvIAppView.java @@ -24,6 +24,7 @@ import android.content.res.XmlResourceParser; import android.graphics.Rect; import android.graphics.RectF; import android.media.tv.TvInputManager; +import android.media.tv.TvTrackInfo; import android.media.tv.TvView; import android.media.tv.interactive.TvIAppManager.Session; import android.media.tv.interactive.TvIAppManager.SessionCallback; @@ -39,6 +40,8 @@ import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; +import java.util.List; + /** * Displays contents of interactive TV applications. * @hide @@ -291,6 +294,66 @@ public class TvIAppView extends ViewGroup { } } + /** + * Stops the interactive application. + */ + public void stopIApp() { + if (DEBUG) { + Log.d(TAG, "stopIApp"); + } + if (mSession != null) { + mSession.stopIApp(); + } + } + + /** + * Sends current channel URI to related TV interactive app. + */ + public void sendCurrentChannelUri(Uri channelUri) { + if (DEBUG) { + Log.d(TAG, "sendCurrentChannelUri"); + } + if (mSession != null) { + mSession.sendCurrentChannelUri(channelUri); + } + } + + /** + * Sends current channel logical channel number (LCN) to related TV interactive app. + */ + public void sendCurrentChannelLcn(int lcn) { + if (DEBUG) { + Log.d(TAG, "sendCurrentChannelLcn"); + } + if (mSession != null) { + mSession.sendCurrentChannelLcn(lcn); + } + } + + /** + * Sends stream volume to related TV interactive app. + */ + public void sendStreamVolume(float volume) { + if (DEBUG) { + Log.d(TAG, "sendStreamVolume"); + } + if (mSession != null) { + mSession.sendStreamVolume(volume); + } + } + + /** + * Sends track info list to related TV interactive app. + */ + public void sendTrackInfoList(List tracks) { + if (DEBUG) { + Log.d(TAG, "sendTrackInfoList"); + } + if (mSession != null) { + mSession.sendTrackInfoList(tracks); + } + } + private void resetInternal() { mSessionCallback = null; if (mSession != null) { @@ -380,8 +443,10 @@ public class TvIAppView extends ViewGroup { * @param cmdType type of the command * @param parameters parameters of the command */ - public void onCommandRequest(String iAppServiceId, - @TvIAppService.IAppServiceCommandType String cmdType, Bundle parameters) { + public void onCommandRequest( + @NonNull String iAppServiceId, + @NonNull @TvIAppService.IAppServiceCommandType String cmdType, + @Nullable Bundle parameters) { } /** @@ -390,7 +455,7 @@ public class TvIAppView extends ViewGroup { * @param iAppServiceId The ID of the TV interactive app service bound to this view. * @param state current session state. */ - public void onSessionStateChanged(String iAppServiceId, int state) { + public void onSessionStateChanged(@NonNull String iAppServiceId, int state) { } /** @@ -402,8 +467,48 @@ public class TvIAppView extends ViewGroup { * @param biIAppId BI interactive app ID, which can be used to destroy the BI interactive * app. */ - public void onBiInteractiveAppCreated(String iAppServiceId, Uri biIAppUri, - String biIAppId) { + public void onBiInteractiveAppCreated(@NonNull String iAppServiceId, @NonNull Uri biIAppUri, + @Nullable String biIAppId) { + } + + /** + * This is called when {@link TvIAppService.Session#SetVideoBounds} is called. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + */ + public void onSetVideoBounds(@NonNull String iAppServiceId, @NonNull Rect rect) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestCurrentChannelUri} is called. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + */ + public void onRequestCurrentChannelUri(@NonNull String iAppServiceId) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestCurrentChannelLcn} is called. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + */ + public void onRequestCurrentChannelLcn(@NonNull String iAppServiceId) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestStreamVolume} is called. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + */ + public void onRequestStreamVolume(@NonNull String iAppServiceId) { + } + + /** + * This is called when {@link TvIAppService.Session#RequestTrackInfoList} is called. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + */ + public void onRequestTrackInfoList(@NonNull String iAppServiceId) { } } @@ -525,5 +630,75 @@ public class TvIAppView extends ViewGroup { mCallback.onBiInteractiveAppCreated(mIAppServiceId, biIAppUri, biIAppId); } } + + @Override + public void onSetVideoBounds(Session session, Rect rect) { + if (DEBUG) { + Log.d(TAG, "onSetVideoBounds (rect=" + rect + ")"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onSetVideoBounds - session not created"); + return; + } + if (mCallback != null) { + mCallback.onSetVideoBounds(mIAppServiceId, rect); + } + } + + @Override + public void onRequestCurrentChannelUri(Session session) { + if (DEBUG) { + Log.d(TAG, "onRequestCurrentChannelUri"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onRequestCurrentChannelUri - session not created"); + return; + } + if (mCallback != null) { + mCallback.onRequestCurrentChannelUri(mIAppServiceId); + } + } + + @Override + public void onRequestCurrentChannelLcn(Session session) { + if (DEBUG) { + Log.d(TAG, "onRequestCurrentChannelLcn"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onRequestCurrentChannelLcn - session not created"); + return; + } + if (mCallback != null) { + mCallback.onRequestCurrentChannelLcn(mIAppServiceId); + } + } + + @Override + public void onRequestStreamVolume(Session session) { + if (DEBUG) { + Log.d(TAG, "onRequestStreamVolume"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onRequestStreamVolume - session not created"); + return; + } + if (mCallback != null) { + mCallback.onRequestStreamVolume(mIAppServiceId); + } + } + + @Override + public void onRequestTrackInfoList(Session session) { + if (DEBUG) { + Log.d(TAG, "onRequestTrackInfoList"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onRequestTrackInfoList - session not created"); + return; + } + if (mCallback != null) { + mCallback.onRequestTrackInfoList(mIAppServiceId); + } + } } } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 4bc728a515c4d..332fed7c1695b 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -2468,7 +2468,29 @@ public final class TvInputManagerService extends SystemService { } } finally { Binder.restoreCallingIdentity(identity); - }; + } + } + + @Override + public void removeBroadcastInfo(IBinder sessionToken, int requestId, int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, + userId, "removeBroadcastInfo"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).removeBroadcastInfo(requestId); + } catch (RemoteException | SessionNotFoundException e) { + Slog.e(TAG, "error in removeBroadcastInfo", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } } @Override diff --git a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java index 7aa2dbd513898..02a56ec8d9510 100644 --- a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java @@ -31,6 +31,7 @@ import android.content.pm.UserInfo; import android.graphics.Rect; import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; +import android.media.tv.TvTrackInfo; import android.media.tv.interactive.ITvIAppClient; import android.media.tv.interactive.ITvIAppManager; import android.media.tv.interactive.ITvIAppManagerCallback; @@ -847,6 +848,60 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void notifyTrackSelected(IBinder sessionToken, int type, String trackId, + int userId) { + if (DEBUG) { + Slogf.d(TAG, "notifyTrackSelected(sessionToken=" + sessionToken + + ", type=" + type + ", trackId=" + trackId + ")"); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "notifyTrackSelected"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).notifyTrackSelected(type, trackId); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in notifyTrackSelected", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void notifyTracksChanged(IBinder sessionToken, List tracks, + int userId) { + if (DEBUG) { + Slogf.d(TAG, "notifyTracksChanged(sessionToken=" + sessionToken + + ", tracks=" + tracks + ")"); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "notifyTracksChanged"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).notifyTracksChanged(tracks); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in notifyTracksChanged", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void startIApp(IBinder sessionToken, int userId) { if (DEBUG) { @@ -872,6 +927,31 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void stopIApp(IBinder sessionToken, int userId) { + if (DEBUG) { + Slogf.d(TAG, "BinderService#stop(userId=%d)", userId); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "stopIApp"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).stopIApp(); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in stop", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void createBiInteractiveApp( IBinder sessionToken, Uri biIAppUri, Bundle params, int userId) { @@ -924,6 +1004,106 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void sendCurrentChannelUri(IBinder sessionToken, Uri channelUri, int userId) { + if (DEBUG) { + Slogf.d(TAG, "sendCurrentChannelUri(channelUri=%s)", channelUri.toString()); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "sendCurrentChannelUri"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).sendCurrentChannelUri(channelUri); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in sendCurrentChannelUri", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void sendCurrentChannelLcn(IBinder sessionToken, int lcn, int userId) { + if (DEBUG) { + Slogf.d(TAG, "sendCurrentChannelLcn(lcn=%d)", lcn); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "sendCurrentChannelLcn"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).sendCurrentChannelLcn(lcn); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in sendCurrentChannelLcn", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void sendStreamVolume(IBinder sessionToken, float volume, int userId) { + if (DEBUG) { + Slogf.d(TAG, "sendStreamVolume(volume=%f)", volume); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "sendStreamVolume"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).sendStreamVolume(volume); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in sendStreamVolume", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void sendTrackInfoList(IBinder sessionToken, List tracks, int userId) { + if (DEBUG) { + Slogf.d(TAG, "sendTrackInfoList(tracks=%s)", tracks.toString()); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "sendTrackInfoList"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).sendTrackInfoList(tracks); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in sendTrackInfoList", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void setSurface(IBinder sessionToken, Surface surface, int userId) { final int callingUid = Binder.getCallingUid(); @@ -1605,6 +1785,23 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void onRemoveBroadcastInfo(int requestId) { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRemoveBroadcastInfo (requestId=" + requestId + ")"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRemoveBroadcastInfo(requestId, mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRemoveBroadcastInfo", e); + } + } + } + @Override public void onCommandRequest(@TvIAppService.IAppServiceCommandType String cmdType, Bundle parameters) { @@ -1624,6 +1821,91 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void onSetVideoBounds(Rect rect) { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onSetVideoBounds(rect=" + rect + ")"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onSetVideoBounds(rect, mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onSetVideoBounds", e); + } + } + } + + @Override + public void onRequestCurrentChannelUri() { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRequestCurrentChannelUri"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRequestCurrentChannelUri(mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRequestCurrentChannelUri", e); + } + } + } + + @Override + public void onRequestCurrentChannelLcn() { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRequestCurrentChannelLcn"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRequestCurrentChannelLcn(mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRequestCurrentChannelLcn", e); + } + } + } + + @Override + public void onRequestStreamVolume() { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRequestStreamVolume"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRequestStreamVolume(mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRequestStreamVolume", e); + } + } + } + + @Override + public void onRequestTrackInfoList() { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRequestTrackInfoList"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRequestTrackInfoList(mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRequestTrackInfoList", e); + } + } + } + @Override public void onSessionStateChanged(int state) { synchronized (mLock) {