diff --git a/media/java/android/media/tv/interactive/ITvIAppManager.aidl b/media/java/android/media/tv/interactive/ITvIAppManager.aidl index 7da539ecc3abc..a19a2d2d6135a 100644 --- a/media/java/android/media/tv/interactive/ITvIAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppManager.aidl @@ -43,6 +43,7 @@ interface ITvIAppManager { void createBiInteractiveApp( in IBinder sessionToken, in Uri biIAppUri, in Bundle params, int userId); void destroyBiInteractiveApp(in IBinder sessionToken, in String biIAppId, int userId); + void setTeletextAppEnabled(in IBinder sessionToken, boolean enable, int userId); void sendCurrentChannelUri(in IBinder sessionToken, in Uri channelUri, int userId); void sendCurrentChannelLcn(in IBinder sessionToken, int lcn, int userId); void sendStreamVolume(in IBinder sessionToken, float volume, int userId); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl index f4b58c681313b..1a8fc4671ec3e 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl @@ -36,6 +36,7 @@ oneway interface ITvInteractiveAppClient { void onRemoveBroadcastInfo(int id, int seq); void onSessionStateChanged(int state, 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); void onSetVideoBounds(in Rect rect, int seq); void onRequestCurrentChannelUri(int seq); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl index 0806531df2c40..c449d24754285 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl @@ -36,6 +36,7 @@ oneway interface ITvInteractiveAppSession { void resetInteractiveApp(); void createBiInteractiveApp(in Uri biIAppUri, in Bundle params); void destroyBiInteractiveApp(in String biIAppId); + void setTeletextAppEnabled(boolean enable); void sendCurrentChannelUri(in Uri channelUri); void sendCurrentChannelLcn(int lcn); void sendStreamVolume(float volume); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl index 2350d4442a55e..c270424b40676 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl @@ -35,6 +35,7 @@ oneway interface ITvInteractiveAppSessionCallback { void onRemoveBroadcastInfo(int id); void onSessionStateChanged(int state); void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId); + void onTeletextAppStateChanged(int state); void onCommandRequest(in String cmdType, in Bundle parameters); void onSetVideoBounds(in Rect rect); void onRequestCurrentChannelUri(); diff --git a/media/java/android/media/tv/interactive/TvIAppManager.java b/media/java/android/media/tv/interactive/TvIAppManager.java old mode 100644 new mode 100755 index 2b7eddf2c50d0..f819438944f43 --- a/media/java/android/media/tv/interactive/TvIAppManager.java +++ b/media/java/android/media/tv/interactive/TvIAppManager.java @@ -92,6 +92,30 @@ public final class TvIAppManager { */ public static final int TV_INTERACTIVE_APP_RTE_STATE_ERROR = 4; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, prefix = "TELETEXT_APP_STATE_", value = { + TELETEXT_APP_STATE_SHOW, + TELETEXT_APP_STATE_HIDE, + TELETEXT_APP_STATE_ERROR}) + public @interface TeletextAppState {} + + /** + * Show state of Teletext app. + * @hide + */ + public static final int TELETEXT_APP_STATE_SHOW = 1; + /** + * Hide state of Teletext app. + * @hide + */ + public static final int TELETEXT_APP_STATE_HIDE = 2; + /** + * Error state of Teletext app. + * @hide + */ + public static final int TELETEXT_APP_STATE_ERROR = 3; + /** * Key for package name in app link. *
Type: String @@ -381,6 +405,18 @@ public final class TvIAppManager { record.postBiInteractiveAppCreated(biIAppUri, biIAppId); } } + + @Override + public void onTeletextAppStateChanged(int state, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postTeletextAppStateChanged(state); + } + } }; ITvInteractiveAppManagerCallback managerCallback = new ITvInteractiveAppManagerCallback.Stub() { @@ -801,6 +837,18 @@ public final class TvIAppManager { } } + void setTeletextAppEnabled(boolean enable) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.setTeletextAppEnabled(mToken, enable, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + void sendCurrentChannelUri(@Nullable Uri channelUri) { if (mToken == null) { Log.w(TAG, "The session has been already released"); @@ -1522,6 +1570,15 @@ public final class TvIAppManager { } }); } + + void postTeletextAppStateChanged(int state) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onTeletextAppStateChanged(mSession, state); + } + }); + } } /** @@ -1647,5 +1704,16 @@ public final class TvIAppManager { */ public void onBiInteractiveAppCreated(Session session, Uri biIAppUri, String biIAppId) { } + + /** + * This is called when {@link TvIAppService.Session#notifyTeletextAppStateChanged} is + * called. + * + * @param session A {@link TvIAppManager.Session} associated with this callback. + * @param state the current state. + */ + public void onTeletextAppStateChanged( + Session session, @TvIAppManager.TeletextAppState int state) { + } } } diff --git a/media/java/android/media/tv/interactive/TvIAppService.java b/media/java/android/media/tv/interactive/TvIAppService.java old mode 100644 new mode 100755 index ef848db5730a1..c0ec76b106558 --- a/media/java/android/media/tv/interactive/TvIAppService.java +++ b/media/java/android/media/tv/interactive/TvIAppService.java @@ -361,6 +361,13 @@ public abstract class TvIAppService extends Service { public void onDestroyBiInteractiveApp(@NonNull String biIAppId) { } + /** + * To toggle Digital Teletext Application if there is one in AIT app list. + * @param enable + */ + public void onSetTeletextAppEnabled(boolean enable) { + } + /** * Receives current channel URI. * @hide @@ -862,6 +869,10 @@ public abstract class TvIAppService extends Service { onDestroyBiInteractiveApp(biIAppId); } + void setTeletextAppEnabled(boolean enable) { + onSetTeletextAppEnabled(enable); + } + void sendCurrentChannelUri(@Nullable Uri channelUri) { onCurrentChannelUri(channelUri); } @@ -1025,6 +1036,30 @@ public abstract class TvIAppService extends Service { }); } + /** + * Notifies when the digital teletext app state is changed. + * @param state the current state. + */ + public final void notifyTeletextAppStateChanged(@TvIAppManager.TeletextAppState int state) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "notifyTeletextAppState (state=" + + state + ")"); + } + if (mSessionCallback != null) { + mSessionCallback.onTeletextAppStateChanged(state); + } + } catch (RemoteException e) { + Log.w(TAG, "error in notifyTeletextAppState", e); + } + } + }); + } + /** * Takes care of dispatching incoming input events and tells whether the event was handled. */ @@ -1278,6 +1313,11 @@ public abstract class TvIAppService extends Service { mSessionImpl.createBiInteractiveApp(biIAppUri, params); } + @Override + public void setTeletextAppEnabled(boolean enable) { + mSessionImpl.setTeletextAppEnabled(enable); + } + @Override public void destroyBiInteractiveApp(@NonNull String biIAppId) { mSessionImpl.destroyBiInteractiveApp(biIAppId); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java old mode 100644 new mode 100755 index 6c05687b41776..6f99d515f1e4f --- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java @@ -580,6 +580,19 @@ public class TvInteractiveAppView extends ViewGroup { return UNSET_TVVIEW_SUCCESS; } + /** + * To toggle Digital Teletext Application if there is one in AIT app list. + * @param enable + */ + public void setTeletextAppEnabled(boolean enable) { + if (DEBUG) { + Log.d(TAG, "setTeletextAppEnabled enable=" + enable); + } + if (mSession != null) { + mSession.setTeletextAppEnabled(enable); + } + } + /** * Callback used to receive various status updates on the {@link TvInteractiveAppView}. */ @@ -624,6 +637,16 @@ public class TvInteractiveAppView extends ViewGroup { @Nullable String biIAppId) { } + /** + * This is called when the digital teletext app state is changed. + * + * @param iAppServiceId The ID of the TV interactive app service bound to this view. + * @param state digital teletext app current state. + */ + public void onTeletextAppStateChanged( + @NonNull String iAppServiceId, @TvIAppManager.TeletextAppState int state) { + } + /** * This is called when {@link TvIAppService.Session#SetVideoBounds} is called. * @@ -847,6 +870,20 @@ public class TvInteractiveAppView extends ViewGroup { } } + @Override + public void onTeletextAppStateChanged(Session session, int state) { + if (DEBUG) { + Log.d(TAG, "onTeletextAppStateChanged (state=" + state + ")"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onTeletextAppStateChanged - session not created"); + return; + } + if (mCallback != null) { + mCallback.onTeletextAppStateChanged(mIAppServiceId, state); + } + } + @Override public void onSetVideoBounds(Session session, Rect rect) { if (DEBUG) { diff --git a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java index 512fc4b2412d2..6058d8873e94d 100644 --- a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java @@ -1192,6 +1192,31 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void setTeletextAppEnabled(IBinder sessionToken, boolean enable, int userId) { + if (DEBUG) { + Slogf.d(TAG, "setTeletextAppEnabled(enable=%d)", enable); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "setTeletextAppEnabled"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).setTeletextAppEnabled(enable); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in setTeletextAppEnabled", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void sendCurrentChannelUri(IBinder sessionToken, Uri channelUri, int userId) { if (DEBUG) { @@ -2220,6 +2245,23 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void onTeletextAppStateChanged(int state) { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onTeletextAppStateChanged (state=" + state + ")"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onTeletextAppStateChanged(state, mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onTeletextAppStateChanged", e); + } + } + } + @GuardedBy("mLock") private boolean addSessionTokenToClientStateLocked(ITvInteractiveAppSession session) { try {