summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Zhao <qingxun@google.com> 2024-01-17 17:15:22 -0800
committer David Zhao <qingxun@google.com> 2024-01-19 00:13:56 +0000
commitfeaa4b573522a248055f922cf28ea80a76310da2 (patch)
treeb1841e42d20b836c349e845a8551f43e44e15f04
parent794391f72cdbe3982d3455f3e112d61f279807df (diff)
Add notifyVideoFreezeUpdated
Bug: 309553570 Test: mmm Change-Id: I63fbeaf985546793b80161cc6a6645a4f7e5b2b7
-rw-r--r--media/java/android/media/tv/ITvInputClient.aidl1
-rw-r--r--media/java/android/media/tv/ITvInputSessionCallback.aidl1
-rw-r--r--media/java/android/media/tv/TvInputManager.java34
-rw-r--r--media/java/android/media/tv/TvInputService.java28
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl1
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl1
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java11
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppManager.java16
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppService.java16
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppView.java16
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java17
-rw-r--r--services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java23
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) {