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
This commit is contained in:
shubang
2022-01-12 01:11:07 -08:00
parent 07ab2f5275
commit 86eabbb350
13 changed files with 267 additions and 86 deletions

View File

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

View File

@@ -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) {

View File

@@ -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.
*
* <p>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.
*
* <p>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) {

View File

@@ -481,9 +481,18 @@ public class TvView extends ViewGroup {
}
/**
* Enables interactive app notification.
* Enables or disables interactive app notification.
*
* <p>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) {
}
/**

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;

View File

@@ -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 <code>TvInteractiveAppInfo</code> 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) {
}
/**

View File

@@ -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: {

View File

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

View File

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