diff options
| author | 2024-01-17 17:15:22 -0800 | |
|---|---|---|
| committer | 2024-01-19 00:13:56 +0000 | |
| commit | feaa4b573522a248055f922cf28ea80a76310da2 (patch) | |
| tree | b1841e42d20b836c349e845a8551f43e44e15f04 | |
| parent | 794391f72cdbe3982d3455f3e112d61f279807df (diff) | |
Add notifyVideoFreezeUpdated
Bug: 309553570
Test: mmm
Change-Id: I63fbeaf985546793b80161cc6a6645a4f7e5b2b7
12 files changed, 164 insertions, 1 deletions
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index 0f8a00a3c7d9..897827750d4e 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -44,6 +44,7 @@ oneway interface ITvInputClient { void onTrackSelected(int type, in String trackId, int seq); void onVideoAvailable(int seq); void onVideoUnavailable(int reason, int seq); + void onVideoFreezeUpdated(boolean isFrozen, int seq); void onContentAllowed(int seq); void onContentBlocked(in String rating, int seq); void onLayoutSurface(int left, int top, int right, int bottom, int seq); diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl index a52e9a572dca..8e2702a50662 100644 --- a/media/java/android/media/tv/ITvInputSessionCallback.aidl +++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl @@ -41,6 +41,7 @@ oneway interface ITvInputSessionCallback { void onTrackSelected(int type, in String trackId); void onVideoAvailable(); void onVideoUnavailable(int reason); + void onVideoFreezeUpdated(boolean isFrozen); void onContentAllowed(); void onContentBlocked(in String rating); void onLayoutSurface(int left, int top, int right, int bottom); diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index c685a5adb08b..6d488bb1bd21 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -740,6 +740,15 @@ public final class TvInputManager { } /** + * This is called when the video freeze state has been updated. + * If {@code true}, the video is frozen on the last frame while audio playback continues. + * @param session A {@link TvInputManager.Session} associated with this callback. + * @param isFrozen Whether the video is frozen + */ + public void onVideoFreezeUpdated(Session session, boolean isFrozen) { + } + + /** * This is called when the current program content turns out to be allowed to watch since * its content rating is not blocked by parental controls. * @@ -1030,6 +1039,19 @@ public final class TvInputManager { }); } + void postVideoFreezeUpdated(boolean isFrozen) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onVideoFreezeUpdated(mSession, isFrozen); + if (mSession.mIAppNotificationEnabled + && mSession.getInteractiveAppSession() != null) { + mSession.getInteractiveAppSession().notifyVideoFreezeUpdated(isFrozen); + } + } + }); + } + void postContentAllowed() { mHandler.post(new Runnable() { @Override @@ -1546,6 +1568,18 @@ public final class TvInputManager { } @Override + public void onVideoFreezeUpdated(boolean isFrozen, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postVideoFreezeUpdated(isFrozen); + } + } + + @Override public void onContentAllowed(int seq) { synchronized (mSessionCallbackRecordMap) { SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 55fa51755177..a12518d6f2f6 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -763,6 +763,34 @@ public abstract class TvInputService extends Service { } /** + * Informs the application that the video freeze state has been updated. + * + * When {@code true}, the video is frozen on the last frame but audio playback remains + * active. + * + * @param isFrozen Whether or not the video is frozen + * @hide + */ + public void notifyVideoFreezeUpdated(boolean isFrozen) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "notifyVideoFreezeUpdated"); + } + if (mSessionCallback != null) { + mSessionCallback.onVideoFreezeUpdated(isFrozen); + } + } catch (RemoteException e) { + Log.e(TAG, "error in notifyVideoFreezeUpdated", e); + } + } + }); + } + + /** * Sends an updated list of all audio presentations available from a Next Generation Audio * service. This is used by the framework to maintain the audio presentation information for * a given track of {@link TvTrackInfo#TYPE_AUDIO}, which in turn is used by diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl index 4316d053a275..0f58b29247bb 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl @@ -88,6 +88,7 @@ interface ITvInteractiveAppManager { void notifyTracksChanged(in IBinder sessionToken, in List<TvTrackInfo> tracks, int userId); void notifyVideoAvailable(in IBinder sessionToken, int userId); void notifyVideoUnavailable(in IBinder sessionToken, int reason, int userId); + void notifyVideoFreezeUpdated(in IBinder sessionToken, boolean isFrozen, int userId); void notifyContentAllowed(in IBinder sessionToken, int userId); void notifyContentBlocked(in IBinder sessionToken, in String rating, int userId); void notifySignalStrength(in IBinder sessionToken, int stength, int userId); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl index ba7cf13a7a1d..06808c9ff915 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl @@ -67,6 +67,7 @@ oneway interface ITvInteractiveAppSession { void notifyTracksChanged(in List<TvTrackInfo> tracks); void notifyVideoAvailable(); void notifyVideoUnavailable(int reason); + void notifyVideoFreezeUpdated(boolean isFrozen); void notifyContentAllowed(); void notifyContentBlocked(in String rating); void notifySignalStrength(int strength); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java index 518b08a93f95..77730aa46d0a 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java @@ -103,6 +103,7 @@ public class ITvInteractiveAppSessionWrapper private static final int DO_SEND_TIME_SHIFT_MODE = 46; private static final int DO_SEND_AVAILABLE_SPEEDS = 47; private static final int DO_SEND_SELECTED_TRACK_INFO = 48; + private static final int DO_NOTIFY_VIDEO_FREEZE_UPDATED = 49; private final HandlerCaller mCaller; private Session mSessionImpl; @@ -364,6 +365,10 @@ public class ITvInteractiveAppSessionWrapper args.recycle(); break; } + case DO_NOTIFY_VIDEO_FREEZE_UPDATED: { + mSessionImpl.notifyVideoFreezeUpdated((Boolean) msg.obj); + break; + } default: { Log.w(TAG, "Unhandled message code: " + msg.what); break; @@ -552,6 +557,12 @@ public class ITvInteractiveAppSessionWrapper } @Override + public void notifyVideoFreezeUpdated(boolean isFrozen) { + mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_NOTIFY_VIDEO_FREEZE_UPDATED, + isFrozen)); + } + + @Override public void notifyContentAllowed() { mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_CONTENT_ALLOWED)); } diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java index bf4379f470d8..8a340f6862bb 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java @@ -1731,6 +1731,22 @@ public final class TvInteractiveAppManager { } /** + * Notifies Interactive app session when the video freeze state is updated + * @param isFrozen Whether or not the video is frozen + */ + public void notifyVideoFreezeUpdated(boolean isFrozen) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.notifyVideoFreezeUpdated(mToken, isFrozen, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Notifies Interactive APP session when content is allowed. */ public void notifyContentAllowed() { diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index 5cc86bacf54f..0ea33901ec94 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -878,6 +878,15 @@ public abstract class TvInteractiveAppService extends Service { } /** + * Called when video becomes frozen or unfrozen. Audio playback will continue while + * video will be frozen to the last frame if {@code true}. + * @param isFrozen Whether or not the video is frozen. + * @hide + */ + public void onVideoFreezeUpdated(boolean isFrozen) { + } + + /** * Called when content is allowed. */ public void onContentAllowed() { @@ -1766,6 +1775,13 @@ public abstract class TvInteractiveAppService extends Service { onVideoUnavailable(reason); } + void notifyVideoFreezeUpdated(boolean isFrozen) { + if (DEBUG) { + Log.d(TAG, "notifyVideoFreezeUpdated (isFrozen=" + isFrozen + ")"); + } + onVideoFreezeUpdated(isFrozen); + } + void notifyContentAllowed() { if (DEBUG) { Log.d(TAG, "notifyContentAllowed"); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java index 40a12e4db4cc..5bb61c261ae2 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java @@ -719,6 +719,22 @@ public class TvInteractiveAppView extends ViewGroup { } /** + * Alerts the TV Interactive app that the video freeze state has been updated. + * If {@code true}, the video is frozen on the last frame while audio playback continues. + * + * @param isFrozen Whether the video is frozen. + * @hide + */ + public void notifyVideoFreezeUpdated(boolean isFrozen) { + if (DEBUG) { + Log.d(TAG, "notifyVideoFreezeUpdated"); + } + if (mSession != null) { + mSession.notifyVideoFreezeUpdated(isFrozen); + } + } + + /** * Sends signing result to related TV interactive app. * * <p>This is used when the corresponding server of the broadcast-independent interactive diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index d903ad4d9f0d..8d30685910c9 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -3840,6 +3840,23 @@ public final class TvInputManagerService extends SystemService { } @Override + public void onVideoFreezeUpdated(boolean isFrozen) { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onVideoFreezeUpdated(" + isFrozen + ")"); + } + if (mSessionState.session == null || mSessionState.client == null) { + return; + } + try { + mSessionState.client.onVideoFreezeUpdated(isFrozen, mSessionState.seq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onVideoFreezeUpdated", e); + } + } + } + + @Override public void onContentAllowed() { synchronized (mLock) { if (DEBUG) { 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 7ab075e2f3a7..9c60fbb6bb9a 100644 --- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java @@ -1470,6 +1470,28 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override + public void notifyVideoFreezeUpdated(IBinder sessionToken, boolean isFrozen, int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, + "notifyVideoFreezeUpdated"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).notifyVideoFreezeUpdated(isFrozen); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in notifyVideoFreezeUpdated", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void notifyContentAllowed(IBinder sessionToken, int userId) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); @@ -1557,7 +1579,6 @@ public class TvInteractiveAppManagerService extends SystemService { } } - @Override public void notifyRecordingStarted(IBinder sessionToken, String recordingId, String requestId, int userId) { |