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