From 86eabbb350b039a93479997808593591fd08cc59 Mon Sep 17 00:00:00 2001 From: shubang Date: Wed, 12 Jan 2022 01:11:07 -0800 Subject: [PATCH] TIAF: cleanup APIs of setup session use case Sequence diagram of the use case: https://screenshot.googleplex.com/4qAsMgdCD6itwWj.png Bug: 208651889 Test: mmm Change-Id: Idcf30b15f6321181117e7c1ef83eed2870140c0b --- media/java/android/media/tv/AitInfo.java | 8 +- .../java/android/media/tv/TvInputManager.java | 2 +- .../java/android/media/tv/TvInputService.java | 17 +- media/java/android/media/tv/TvView.java | 15 +- .../interactive/ITvInteractiveAppClient.aidl | 2 +- .../ITvInteractiveAppManagerCallback.aidl | 2 +- .../ITvInteractiveAppServiceCallback.aidl | 2 +- .../ITvInteractiveAppSessionCallback.aidl | 2 +- .../tv/interactive/TvInteractiveAppInfo.java | 2 +- .../interactive/TvInteractiveAppManager.java | 174 ++++++++++++++---- .../interactive/TvInteractiveAppService.java | 70 ++++--- .../tv/interactive/TvInteractiveAppView.java | 30 ++- .../TvInteractiveAppManagerService.java | 27 ++- 13 files changed, 267 insertions(+), 86 deletions(-) diff --git a/media/java/android/media/tv/AitInfo.java b/media/java/android/media/tv/AitInfo.java index ff4c6253b599c..71b1634cef926 100644 --- a/media/java/android/media/tv/AitInfo.java +++ b/media/java/android/media/tv/AitInfo.java @@ -17,11 +17,12 @@ package android.media.tv; import android.annotation.NonNull; +import android.media.tv.interactive.TvInteractiveAppInfo; import android.os.Parcel; import android.os.Parcelable; /** - * AIT info. + * AIT (Application Information Table) info. * @hide */ public final class AitInfo implements Parcelable { @@ -50,14 +51,15 @@ public final class AitInfo implements Parcelable { /** * Constructs AIT info. */ - public AitInfo(int type, int version) { + public AitInfo(@TvInteractiveAppInfo.InteractiveAppType int type, int version) { mType = type; mVersion = version; } /** - * Gets type. + * Gets interactive app type. */ + @TvInteractiveAppInfo.InteractiveAppType public int getType() { return mType; } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 02167806df325..f438d293ac8e4 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -2593,9 +2593,9 @@ public final class TvInputManager { /** * Enables interactive app notification. + * * @param enabled {@code true} if you want to enable interactive app notifications. * {@code false} otherwise. - * @hide */ public void setInteractiveAppNotificationEnabled(boolean enabled) { if (mToken == null) { diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 524ba34685b5a..9bc736743ecc9 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -945,7 +945,13 @@ public abstract class TvInputService extends Service { } /** - * Notifies AIT info updated. + * Informs the app that the AIT (Application Information Table) is updated. + * + *

This method should also be call when + * {@link #onSetInteractiveAppNotificationEnabled(boolean)} is called to send the first AIT + * info. + * + * @see #onSetInteractiveAppNotificationEnabled(boolean) * @hide */ public void notifyAitInfoUpdated(@NonNull final AitInfo aitInfo) { @@ -1198,7 +1204,16 @@ public abstract class TvInputService extends Service { /** * Enables or disables interactive app notification. + * + *

This method enables or disables the event detection from the corresponding TV input. + * When it's enabled, the TV input service detects events related to interactive app, such + * as AIT (Application Information Table) and sends to TvView or the linked TV interactive + * app service. + * * @param enabled {@code true} to enable, {@code false} to disable. + * + * @see TvView#setInteractiveAppNotificationEnabled(boolean) + * @see Session#notifyAitInfoUpdated(android.media.tv.AitInfo) * @hide */ public void onSetInteractiveAppNotificationEnabled(boolean enabled) { diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 71f6ad6dd0346..d2086c502a5cf 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -481,9 +481,18 @@ public class TvView extends ViewGroup { } /** - * Enables interactive app notification. + * Enables or disables interactive app notification. + * + *

This method enables or disables the event detection from the corresponding TV input. When + * it's enabled, the TV input service detects events related to interactive app, such as + * AIT (Application Information Table) and sends to TvView or the linked TV interactive app + * service. + * * @param enabled {@code true} if you want to enable interactive app notifications. * {@code false} otherwise. + * + * @see TvInputService.Session#notifyAitInfoUpdated(android.media.tv.AitInfo) + * @see android.media.tv.interactive.TvInteractiveAppView#setTvView(TvView) * @hide */ public void setInteractiveAppNotificationEnabled(boolean enabled) { @@ -1062,12 +1071,12 @@ public class TvView extends ViewGroup { } /** - * This is called when the AIT info has been updated. + * This is called when the AIT (Application Information Table) info has been updated. * * @param aitInfo The current AIT info. * @hide */ - public void onAitInfoUpdated(String inputId, AitInfo aitInfo) { + public void onAitInfoUpdated(@NonNull String inputId, @NonNull AitInfo aitInfo) { } /** diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl index 1a8fc4671ec3e..a3e58d16f655a 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl @@ -34,7 +34,7 @@ oneway interface ITvInteractiveAppClient { 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 onSessionStateChanged(int state, int err, int seq); void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId, int seq); void onTeletextAppStateChanged(int state, int seq); void onCommandRequest(in String cmdType, in Bundle parameters, int seq); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl index f4510f6c60a35..23be4c64fcc46 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManagerCallback.aidl @@ -27,5 +27,5 @@ interface ITvInteractiveAppManagerCallback { void onInteractiveAppServiceRemoved(in String iAppServiceId); void onInteractiveAppServiceUpdated(in String iAppServiceId); void onTvInteractiveAppInfoUpdated(in TvInteractiveAppInfo tvIAppInfo); - void onStateChanged(in String iAppServiceId, int type, int state); + void onStateChanged(in String iAppServiceId, int type, int state, int err); } \ No newline at end of file diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppServiceCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppServiceCallback.aidl index 7420e18daac1c..970b943275728 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppServiceCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppServiceCallback.aidl @@ -22,5 +22,5 @@ package android.media.tv.interactive; * @hide */ oneway interface ITvInteractiveAppServiceCallback { - void onStateChanged(int type, int state); + void onStateChanged(int type, int state, int error); } \ No newline at end of file diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl index 6a359a265e2f1..385f0d4f766ad 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl @@ -33,7 +33,7 @@ oneway interface ITvInteractiveAppSessionCallback { void onLayoutSurface(int left, int top, int right, int bottom); void onBroadcastInfoRequest(in BroadcastInfoRequest request); void onRemoveBroadcastInfo(int id); - void onSessionStateChanged(int state); + void onSessionStateChanged(int state, int err); void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId); void onTeletextAppStateChanged(int state); void onCommandRequest(in String cmdType, in Bundle parameters); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java b/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java index e0d641d06ca74..e1f535c93d198 100644 --- a/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppInfo.java @@ -58,7 +58,7 @@ public final class TvInteractiveAppInfo implements Parcelable { INTERACTIVE_APP_TYPE_ATSC, INTERACTIVE_APP_TYPE_GINGA, }) - @interface InteractiveAppType {} + public @interface InteractiveAppType {} /** HbbTV interactive app type */ public static final int INTERACTIVE_APP_TYPE_HBBTV = 0x1; diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java index ddc4a9948096e..15a5f823e144f 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java @@ -16,6 +16,7 @@ package android.media.tv.interactive; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -52,6 +53,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.concurrent.Executor; /** * Central system API to the overall TV interactive application framework (TIAF) architecture, which @@ -64,33 +66,115 @@ public final class TvInteractiveAppManager { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = false, prefix = "TV_INTERACTIVE_APP_RTE_STATE_", value = { - TV_INTERACTIVE_APP_RTE_STATE_UNREALIZED, - TV_INTERACTIVE_APP_RTE_STATE_PREPARING, - TV_INTERACTIVE_APP_RTE_STATE_READY, - TV_INTERACTIVE_APP_RTE_STATE_ERROR}) - public @interface TvInteractiveAppRteState {} + @IntDef(flag = false, prefix = "SERVICE_STATE_", value = { + SERVICE_STATE_UNREALIZED, + SERVICE_STATE_PREPARING, + SERVICE_STATE_READY, + SERVICE_STATE_ERROR}) + public @interface ServiceState {} /** - * Unrealized state of interactive app RTE. + * Unrealized state of interactive app service. * @hide */ - public static final int TV_INTERACTIVE_APP_RTE_STATE_UNREALIZED = 1; + public static final int SERVICE_STATE_UNREALIZED = 1; /** - * Preparing state of interactive app RTE. + * Preparing state of interactive app service. * @hide */ - public static final int TV_INTERACTIVE_APP_RTE_STATE_PREPARING = 2; + public static final int SERVICE_STATE_PREPARING = 2; /** - * Ready state of interactive app RTE. + * Ready state of interactive app service. * @hide */ - public static final int TV_INTERACTIVE_APP_RTE_STATE_READY = 3; + public static final int SERVICE_STATE_READY = 3; /** - * Error state of interactive app RTE. + * Error state of interactive app service. * @hide */ - public static final int TV_INTERACTIVE_APP_RTE_STATE_ERROR = 4; + public static final int SERVICE_STATE_ERROR = 4; + + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, prefix = "INTERACTIVE_APP_STATE_", value = { + INTERACTIVE_APP_STATE_STOPPED, + INTERACTIVE_APP_STATE_RUNNING, + INTERACTIVE_APP_STATE_ERROR}) + public @interface InteractiveAppState {} + + /** + * Stopped (or not started) state of interactive application. + * @hide + */ + public static final int INTERACTIVE_APP_STATE_STOPPED = 1; + /** + * Running state of interactive application. + * @hide + */ + public static final int INTERACTIVE_APP_STATE_RUNNING = 2; + /** + * Error state of interactive application. + * @hide + */ + public static final int INTERACTIVE_APP_STATE_ERROR = 3; + + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, prefix = "ERROR_", value = { + ERROR_NONE, + ERROR_UNKNOWN, + ERROR_NOT_SUPPORTED, + ERROR_WEAK_SIGNAL, + ERROR_RESOURCE_UNAVAILABLE, + ERROR_BLOCKED, + ERROR_ENCRYPTED, + ERROR_UNKNOWN_CHANNEL, + }) + public @interface ErrorCode {} + + /** + * No error. + * @hide + */ + public static final int ERROR_NONE = 0; + /** + * Unknown error code. + * @hide + */ + public static final int ERROR_UNKNOWN = 1; + /** + * Error code for an unsupported channel. + * @hide + */ + public static final int ERROR_NOT_SUPPORTED = 2; + /** + * Error code for weak signal. + * @hide + */ + public static final int ERROR_WEAK_SIGNAL = 3; + /** + * Error code when resource (e.g. tuner) is unavailable. + * @hide + */ + public static final int ERROR_RESOURCE_UNAVAILABLE = 4; + /** + * Error code for blocked contents. + * @hide + */ + public static final int ERROR_BLOCKED = 5; + /** + * Error code when the key or module is missing for the encrypted channel. + * @hide + */ + public static final int ERROR_ENCRYPTED = 6; + /** + * Error code when the current channel is an unknown channel. + * @hide + */ + public static final int ERROR_UNKNOWN_CHANNEL = 7; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -383,14 +467,14 @@ public final class TvInteractiveAppManager { } @Override - public void onSessionStateChanged(int state, int seq) { + public void onSessionStateChanged(int state, int err, int seq) { synchronized (mSessionCallbackRecordMap) { SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); if (record == null) { Log.e(TAG, "Callback not found for seq " + seq); return; } - record.postSessionStateChanged(state); + record.postSessionStateChanged(state, err); } } @@ -458,10 +542,10 @@ public final class TvInteractiveAppManager { } @Override - public void onStateChanged(String iAppServiceId, int type, int state) { + public void onStateChanged(String iAppServiceId, int type, int state, int err) { synchronized (mLock) { for (TvInteractiveAppCallbackRecord record : mCallbackRecords) { - record.postStateChanged(iAppServiceId, type, state); + record.postStateChanged(iAppServiceId, type, state, err); } } } @@ -487,6 +571,7 @@ public final class TvInteractiveAppManager { * that implements {@link TvInteractiveAppService} interface. * * @param iAppServiceId The ID of the TV Interactive App service. + * @hide */ public void onInteractiveAppServiceAdded(@NonNull String iAppServiceId) { } @@ -498,6 +583,7 @@ public final class TvInteractiveAppManager { * App service package. * * @param iAppServiceId The ID of the TV Interactive App service. + * @hide */ public void onInteractiveAppServiceRemoved(@NonNull String iAppServiceId) { } @@ -509,6 +595,7 @@ public final class TvInteractiveAppManager { * re-installed or a newer version of the package exists becomes available/unavailable. * * @param iAppServiceId The ID of the TV Interactive App service. + * @hide */ public void onInteractiveAppServiceUpdated(@NonNull String iAppServiceId) { } @@ -524,26 +611,34 @@ public final class TvInteractiveAppManager { * * @param iAppInfo The TvInteractiveAppInfo object that contains new * information. + * @hide */ public void onTvInteractiveAppInfoUpdated(@NonNull TvInteractiveAppInfo iAppInfo) { } /** * This is called when the state of the interactive app service is changed. - * @hide + * + * @param type the interactive app type + * @param state the current state of the service of the given type + * @param err the error code for error state. {@link #ERROR_NONE} is used when the state is + * not {@link #SERVICE_STATE_ERROR}. */ public void onTvInteractiveAppServiceStateChanged( - @NonNull String iAppServiceId, int type, @TvInteractiveAppRteState int state) { + @NonNull String iAppServiceId, + @TvInteractiveAppInfo.InteractiveAppType int type, + @ServiceState int state, + @ErrorCode int err) { } } private static final class TvInteractiveAppCallbackRecord { private final TvInteractiveAppCallback mCallback; - private final Handler mHandler; + private final Executor mExecutor; - TvInteractiveAppCallbackRecord(TvInteractiveAppCallback callback, Handler handler) { + TvInteractiveAppCallbackRecord(TvInteractiveAppCallback callback, Executor executor) { mCallback = callback; - mHandler = handler; + mExecutor = executor; } public TvInteractiveAppCallback getCallback() { @@ -551,7 +646,7 @@ public final class TvInteractiveAppManager { } public void postInteractiveAppServiceAdded(final String iAppServiceId) { - mHandler.post(new Runnable() { + mExecutor.execute(new Runnable() { @Override public void run() { mCallback.onInteractiveAppServiceAdded(iAppServiceId); @@ -560,7 +655,7 @@ public final class TvInteractiveAppManager { } public void postInteractiveAppServiceRemoved(final String iAppServiceId) { - mHandler.post(new Runnable() { + mExecutor.execute(new Runnable() { @Override public void run() { mCallback.onInteractiveAppServiceRemoved(iAppServiceId); @@ -569,7 +664,7 @@ public final class TvInteractiveAppManager { } public void postInteractiveAppServiceUpdated(final String iAppServiceId) { - mHandler.post(new Runnable() { + mExecutor.execute(new Runnable() { @Override public void run() { mCallback.onInteractiveAppServiceUpdated(iAppServiceId); @@ -578,7 +673,7 @@ public final class TvInteractiveAppManager { } public void postTvInteractiveAppInfoUpdated(final TvInteractiveAppInfo iAppInfo) { - mHandler.post(new Runnable() { + mExecutor.execute(new Runnable() { @Override public void run() { mCallback.onTvInteractiveAppInfoUpdated(iAppInfo); @@ -586,11 +681,12 @@ public final class TvInteractiveAppManager { }); } - public void postStateChanged(String iAppServiceId, int type, int state) { - mHandler.post(new Runnable() { + public void postStateChanged(String iAppServiceId, int type, int state, int err) { + mExecutor.execute(new Runnable() { @Override public void run() { - mCallback.onTvInteractiveAppServiceStateChanged(iAppServiceId, type, state); + mCallback.onTvInteractiveAppServiceStateChanged( + iAppServiceId, type, state, err); } }); } @@ -698,15 +794,16 @@ public final class TvInteractiveAppManager { * Registers a {@link TvInteractiveAppCallback}. * * @param callback A callback used to monitor status of the TV Interactive App services. - * @param handler A {@link Handler} that the status change will be delivered to. + * @param executor A {@link Executor} that the status change will be delivered to. * @hide */ public void registerCallback( - @NonNull TvInteractiveAppCallback callback, @NonNull Handler handler) { + @NonNull TvInteractiveAppCallback callback, + @CallbackExecutor @NonNull Executor executor) { Preconditions.checkNotNull(callback); - Preconditions.checkNotNull(handler); + Preconditions.checkNotNull(executor); synchronized (mLock) { - mCallbackRecords.add(new TvInteractiveAppCallbackRecord(callback, handler)); + mCallbackRecords.add(new TvInteractiveAppCallbackRecord(callback, executor)); } } @@ -1552,11 +1649,11 @@ public final class TvInteractiveAppManager { }); } - void postSessionStateChanged(int state) { + void postSessionStateChanged(int state, int err) { mHandler.post(new Runnable() { @Override public void run() { - mSessionCallback.onSessionStateChanged(mSession, state); + mSessionCallback.onSessionStateChanged(mSession, state, err); } }); } @@ -1690,7 +1787,10 @@ public final class TvInteractiveAppManager { * @param session A {@link TvInteractiveAppManager.Session} associated with this callback. * @param state the current state. */ - public void onSessionStateChanged(Session session, int state) { + public void onSessionStateChanged( + Session session, + @InteractiveAppState int state, + @ErrorCode int err) { } /** diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index a69bb6470e404..094aabdb5e68f 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -196,8 +196,7 @@ public abstract class TvInteractiveAppService extends Service { * Prepares TV Interactive App service for the given type. * @hide */ - public void onPrepare(int type) { - // TODO: make it abstract when unhide + public void onPrepare(@TvInteractiveAppInfo.InteractiveAppType int type) { } /** @@ -236,20 +235,32 @@ public abstract class TvInteractiveAppService extends Service { * @hide */ @Nullable - public Session onCreateSession(@NonNull String iAppServiceId, int type) { - // TODO: make it abstract when unhide + public Session onCreateSession( + @NonNull String iAppServiceId, + @TvInteractiveAppInfo.InteractiveAppType int type) { return null; } /** - * Notifies the system when the state of the interactive app has been changed. - * @param state the current state + * Notifies the system when the state of the interactive app RTE has been changed. + * + * @param type the interactive app type + * @param state the current state of the service of the given type + * @param error the error code for error state. {@link TvInteractiveAppManager#ERROR_NONE} is + * used when the state is not + * {@link TvInteractiveAppManager#SERVICE_STATE_ERROR}. * @hide */ public final void notifyStateChanged( - int type, @TvInteractiveAppManager.TvInteractiveAppRteState int state) { - mServiceHandler.obtainMessage(ServiceHandler.DO_NOTIFY_RTE_STATE_CHANGED, - type, state).sendToTarget(); + @TvInteractiveAppInfo.InteractiveAppType int type, + @TvInteractiveAppManager.ServiceState int state, + @TvInteractiveAppManager.ErrorCode int error) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = type; + args.arg2 = state; + args.arg3 = error; + mServiceHandler + .obtainMessage(ServiceHandler.DO_NOTIFY_RTE_STATE_CHANGED, args).sendToTarget(); } /** @@ -298,6 +309,7 @@ public abstract class TvInteractiveAppService extends Service { * * @param enable {@code true} if you want to enable the media view. {@code false} * otherwise. + * @hide */ public void setMediaViewEnabled(final boolean enable) { mHandler.post(new Runnable() { @@ -320,14 +332,12 @@ public abstract class TvInteractiveAppService extends Service { /** * Starts TvInteractiveAppService session. - * @hide */ public void onStartInteractiveApp() { } /** * Stops TvInteractiveAppService session. - * @hide */ public void onStopInteractiveApp() { } @@ -439,6 +449,7 @@ public abstract class TvInteractiveAppService extends Service { * * @param width The width of the media view. * @param height The height of the media view. + * @hide */ public void onMediaViewSizeChanged(int width, int height) { } @@ -448,6 +459,7 @@ public abstract class TvInteractiveAppService extends Service { * implementation can override this method and return its own view. * * @return a view attached to the media window + * @hide */ @Nullable public View onCreateMediaView() { @@ -621,6 +633,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Requests broadcast related information from the related TV input. * @param request the request for broadcast info + * @hide */ public void requestBroadcastInfo(@NonNull final BroadcastInfoRequest request) { executeOrPostRunnableOnMainThread(new Runnable() { @@ -645,6 +658,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Remove broadcast information request from the related TV input. * @param requestId the ID of the request + * @hide */ public void removeBroadcastInfo(final int requestId) { executeOrPostRunnableOnMainThread(new Runnable() { @@ -670,6 +684,7 @@ public abstract class TvInteractiveAppService extends Service { * requests a specific command to be processed by the related TV input. * @param cmdType type of the specific command * @param parameters parameters of the specific command + * @hide */ public void requestCommand( @InteractiveAppServiceCommandType String cmdType, Bundle parameters) { @@ -694,6 +709,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Sets broadcast video bounds. + * @hide */ public void setVideoBounds(Rect rect) { executeOrPostRunnableOnMainThread(new Runnable() { @@ -716,6 +732,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Requests the URI of the current channel. + * @hide */ public void requestCurrentChannelUri() { executeOrPostRunnableOnMainThread(new Runnable() { @@ -738,6 +755,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Requests the logic channel number (LCN) of the current channel. + * @hide */ public void requestCurrentChannelLcn() { executeOrPostRunnableOnMainThread(new Runnable() { @@ -760,6 +778,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Requests stream volume. + * @hide */ public void requestStreamVolume() { executeOrPostRunnableOnMainThread(new Runnable() { @@ -782,6 +801,7 @@ public abstract class TvInteractiveAppService extends Service { /** * Requests the list of {@link TvTrackInfo}. + * @hide */ public void requestTrackInfoList() { executeOrPostRunnableOnMainThread(new Runnable() { @@ -830,6 +850,7 @@ public abstract class TvInteractiveAppService extends Service { /** * requests an advertisement request to be processed by the related TV input. * @param request advertisement request + * @hide */ public void requestAd(@NonNull final AdRequest request) { executeOrPostRunnableOnMainThread(new Runnable() { @@ -988,10 +1009,15 @@ public abstract class TvInteractiveAppService extends Service { /** * Notifies when the session state is changed. - * @param state the current state. + * + * @param state the current session state. + * @param err the error code for error state. {@link TvInteractiveAppManager#ERROR_NONE} is + * used when the state is not + * {@link TvInteractiveAppManager#INTERACTIVE_APP_STATE_ERROR}. */ - public final void notifySessionStateChanged( - @TvInteractiveAppManager.TvInteractiveAppRteState int state) { + public void notifySessionStateChanged( + @TvInteractiveAppManager.InteractiveAppState int state, + @TvInteractiveAppManager.ErrorCode int err) { executeOrPostRunnableOnMainThread(new Runnable() { @MainThread @Override @@ -999,10 +1025,10 @@ public abstract class TvInteractiveAppService extends Service { try { if (DEBUG) { Log.d(TAG, "notifySessionStateChanged (state=" - + state + ")"); + + state + "; err=" + err + ")"); } if (mSessionCallback != null) { - mSessionCallback.onSessionStateChanged(state); + mSessionCallback.onSessionStateChanged(state, err); } } catch (RemoteException e) { Log.w(TAG, "error in notifySessionStateChanged", e); @@ -1460,11 +1486,11 @@ public abstract class TvInteractiveAppService extends Service { private static final int DO_NOTIFY_SESSION_CREATED = 2; private static final int DO_NOTIFY_RTE_STATE_CHANGED = 3; - private void broadcastRteStateChanged(int type, int state) { + private void broadcastRteStateChanged(int type, int state, int error) { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; ++i) { try { - mCallbacks.getBroadcastItem(i).onStateChanged(type, state); + mCallbacks.getBroadcastItem(i).onStateChanged(type, state, error); } catch (RemoteException e) { Log.e(TAG, "error in broadcastRteStateChanged", e); } @@ -1522,9 +1548,11 @@ public abstract class TvInteractiveAppService extends Service { return; } case DO_NOTIFY_RTE_STATE_CHANGED: { - int type = msg.arg1; - int state = msg.arg2; - broadcastRteStateChanged(type, state); + SomeArgs args = (SomeArgs) msg.obj; + int type = (int) args.arg1; + int state = (int) args.arg2; + int error = (int) args.arg3; + broadcastRteStateChanged(type, state, error); return; } default: { diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java index 0ecd035625eea..9590d5d901761 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java @@ -380,9 +380,16 @@ public class TvInteractiveAppView extends ViewGroup { /** * Prepares the interactive application. + * + * @param iAppServiceId the interactive app service ID, which can be found in + * {@link TvInteractiveAppInfo#getId()}. + * + * @see android.media.tv.interactive.TvInteractiveAppManager#getTvInteractiveAppServiceList() * @hide */ - public void prepareInteractiveApp(@NonNull String iAppServiceId, int type) { + public void prepareInteractiveApp( + @NonNull String iAppServiceId, + @TvInteractiveAppInfo.InteractiveAppType int type) { // TODO: document and handle the cases that this method is called multiple times. if (DEBUG) { Log.d(TAG, "prepareInteractiveApp"); @@ -554,7 +561,7 @@ public class TvInteractiveAppView extends ViewGroup { * TvInteractiveAppManager to TvInputManager session, so the TIAS can get the TIS events. * * @param tvView the TvView to be linked to this TvInteractiveAppView via linking of Sessions. - * @return to be added + * @return The result of the operation. * @hide */ public int setTvView(@Nullable TvView tvView) { @@ -617,10 +624,16 @@ public class TvInteractiveAppView extends ViewGroup { * This is called when the session state is changed. * * @param iAppServiceId The ID of the TV interactive app service bound to this view. - * @param state current session state. + * @param state the current state. + * @param err the error code for error state. {@link TvInteractiveAppManager#ERROR_NONE} + * is used when the state is not + * {@link TvInteractiveAppManager#INTERACTIVE_APP_STATE_ERROR}. * @hide */ - public void onSessionStateChanged(@NonNull String iAppServiceId, int state) { + public void onStateChanged( + @NonNull String iAppServiceId, + @TvInteractiveAppManager.InteractiveAppState int state, + @TvInteractiveAppManager.ErrorCode int err) { } /** @@ -828,9 +841,12 @@ public class TvInteractiveAppView extends ViewGroup { } @Override - public void onSessionStateChanged(Session session, int state) { + public void onSessionStateChanged( + Session session, + @TvInteractiveAppManager.InteractiveAppState int state, + @TvInteractiveAppManager.ErrorCode int err) { if (DEBUG) { - Log.d(TAG, "onSessionStateChanged (state=" + state + ")"); + Log.d(TAG, "onSessionStateChanged (state=" + state + "; err=" + err + ")"); } if (this != mSessionCallback) { Log.w(TAG, "onSessionStateChanged - session not created"); @@ -841,7 +857,7 @@ public class TvInteractiveAppView extends ViewGroup { mCallbackExecutor.execute(() -> { synchronized (mCallbackLock) { if (mCallback != null) { - mCallback.onSessionStateChanged(mIAppServiceId, state); + mCallback.onStateChanged(mIAppServiceId, state, err); } } }); diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java index b6772031f497b..35cc43faa4e9e 100644 --- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java @@ -256,15 +256,16 @@ public class TvInteractiveAppManagerService extends SystemService { @GuardedBy("mLock") private void notifyStateChangedLocked( - UserState userState, String iAppServiceId, int type, int state) { + UserState userState, String iAppServiceId, int type, int state, int err) { if (DEBUG) { Slog.d(TAG, "notifyRteStateChanged(iAppServiceId=" - + iAppServiceId + ", type=" + type + ", state=" + state + ")"); + + iAppServiceId + ", type=" + type + ", state=" + state + ", err=" + err + ")"); } int n = userState.mCallbacks.beginBroadcast(); for (int i = 0; i < n; ++i) { try { - userState.mCallbacks.getBroadcastItem(i).onStateChanged(iAppServiceId, type, state); + userState.mCallbacks.getBroadcastItem(i) + .onStateChanged(iAppServiceId, type, state, err); } catch (RemoteException e) { Slog.e(TAG, "failed to report RTE state changed", e); } @@ -1866,6 +1867,16 @@ public class TvInteractiveAppManagerService extends SystemService { ServiceState serviceState = userState.mServiceStateMap.get(mComponent); serviceState.mService = ITvInteractiveAppService.Stub.asInterface(service); + // Register a callback, if we need to. + if (serviceState.mCallback == null) { + serviceState.mCallback = new ServiceCallback(mComponent, mUserId); + try { + serviceState.mService.registerCallback(serviceState.mCallback); + } catch (RemoteException e) { + Slog.e(TAG, "error in registerCallback", e); + } + } + if (serviceState.mPendingPrepare) { final long identity = Binder.clearCallingIdentity(); try { @@ -1968,14 +1979,14 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override - public void onStateChanged(int type, int state) { + public void onStateChanged(int type, int state, int error) { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { ServiceState serviceState = getServiceStateLocked(mComponent, mUserId); String iAppServiceId = serviceState.mIAppServiceId; UserState userState = getUserStateLocked(mUserId); - notifyStateChangedLocked(userState, iAppServiceId, type, state); + notifyStateChangedLocked(userState, iAppServiceId, type, state, error); } } finally { Binder.restoreCallingIdentity(identity); @@ -2210,16 +2221,16 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override - public void onSessionStateChanged(int state) { + public void onSessionStateChanged(int state, int err) { synchronized (mLock) { if (DEBUG) { - Slogf.d(TAG, "onSessionStateChanged (state=" + state + ")"); + Slogf.d(TAG, "onSessionStateChanged (state=" + state + ", err=" + err + ")"); } if (mSessionState.mSession == null || mSessionState.mClient == null) { return; } try { - mSessionState.mClient.onSessionStateChanged(state, mSessionState.mSeq); + mSessionState.mClient.onSessionStateChanged(state, err, mSessionState.mSeq); } catch (RemoteException e) { Slogf.e(TAG, "error in onSessionStateChanged", e); }