diff options
| author | 2023-01-09 22:45:39 +0000 | |
|---|---|---|
| committer | 2023-01-09 22:45:39 +0000 | |
| commit | b90d3264adb6a5c56ce43c4fd54c49c969902925 (patch) | |
| tree | 390b5dabdd18ece265db55a877735f5ead521d74 | |
| parent | f3075fb3b65e3e11c0910d56321d2bd49f821d75 (diff) | |
| parent | eea0deea4b1d2d21eb411b65eb26477eb44635a7 (diff) | |
Merge "Add TIAF watermarking APIs"
12 files changed, 199 insertions, 2 deletions
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index ed2fd20659ed..d55d2871311f 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -49,6 +49,7 @@ oneway interface ITvInputClient { void onTimeShiftCurrentPositionChanged(long timeMs, int seq); void onAitInfoUpdated(in AitInfo aitInfo, int seq); void onSignalStrength(int stength, int seq); + void onTvMessage(in String type, in Bundle data, int seq); void onTuned(in Uri channelUri, int seq); // For the recording session diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl index b2a8d1c35d01..82166223608f 100644 --- a/media/java/android/media/tv/ITvInputSessionCallback.aidl +++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl @@ -58,4 +58,7 @@ oneway interface ITvInputSessionCallback { // For ad response void onAdResponse(in AdResponse response); void onAdBufferConsumed(in AdBuffer buffer); + + // For messages sent from the TV input + void onTvMessage(in String type, in Bundle data); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 690fcb1db574..e6da1a382f4f 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -22,6 +22,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.StringDef; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -130,6 +131,20 @@ public final class TvInputManager { VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING, VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN}) public @interface VideoUnavailableReason {} + /** + * @hide + */ + public static final String TV_MESSAGE_TYPE_WATERMARK = "Watermark"; + /** + * @hide + */ + public static final String TV_MESSAGE_TYPE_ATSC_CC = "ATSC_CC"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @StringDef({TV_MESSAGE_TYPE_WATERMARK, TV_MESSAGE_TYPE_ATSC_CC}) + public @interface TvMessageType {} + static final int VIDEO_UNAVAILABLE_REASON_START = 0; static final int VIDEO_UNAVAILABLE_REASON_END = 18; @@ -690,6 +705,17 @@ public final class TvInputManager { public void onTuned(Session session, Uri channelUri) { } + /** + * This is called when the session receives a new Tv Message + * + * @param type the type of {@link TvMessageType} + * @param data the raw data of the message + * @hide + */ + public void onTvMessage(Session session, @TvInputManager.TvMessageType String type, + Bundle data) { + } + // For the recording session only /** * This is called when the current recording session has stopped recording and created a @@ -919,6 +945,19 @@ public final class TvInputManager { }); } + void postTvMessage(String type, Bundle data) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onTvMessage(mSession, type, data); + if (mSession.mIAppNotificationEnabled + && mSession.getInteractiveAppSession() != null) { + mSession.getInteractiveAppSession().notifyTvMessage(type, data); + } + } + }); + } + // For the recording session only void postRecordingStopped(final Uri recordedProgramUri) { mHandler.post(new Runnable() { @@ -1379,6 +1418,18 @@ public final class TvInputManager { } @Override + public void onTvMessage(String type, Bundle data, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postTvMessage(type, data); + } + } + + @Override public void onRecordingStopped(Uri recordedProgramUri, 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 c46cdbc78b90..15f511b960e5 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -2063,6 +2063,27 @@ public abstract class TvInputService extends Service { } /** + * Informs the application of the raw data from the TV message. + * @param type The {@link TvInputManager.TvMessageType} of message that was sent. + * @param data The data sent with the message. + * @hide + */ + public void notifyTvMessage(@TvInputManager.TvMessageType String type, Bundle data) { + } + + /** + * Called when the application enables or disables the detection of the specified message + * type. + * @param type The {@link TvInputManager.TvMessageType} of message that was sent. + * @param enabled {@code true} if you want to enable TV message detecting + * {@code false} otherwise. + * @hide + */ + public void onSetTvMessageEnabled(@TvInputManager.TvMessageType String type, + boolean enabled) { + } + + /** * Called when the application requests to tune to a given channel for TV program recording. * * <p>The application may call this method before starting or after stopping recording, but diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index ff3d06c5bd69..2fdbc3b29a65 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -653,6 +653,17 @@ public class TvView extends ViewGroup { mOnUnhandledInputEventListener = listener; } + /** + * Enables or disables TV message detecting in the streams of bound TV input. + * + * @param type The type of {@link android.media.tv.TvInputManager.TvMessageType} + * @param enabled {@code true} if you want to enable TV message detecting + * {@code false} otherwise. + * @hide + */ + public void setTvMessageEnabled(@TvInputManager.TvMessageType String type, boolean enabled) { + } + @Override public boolean dispatchKeyEvent(KeyEvent event) { if (super.dispatchKeyEvent(event)) { @@ -1094,6 +1105,17 @@ public class TvView extends ViewGroup { */ public void onTuned(@NonNull String inputId, @NonNull Uri channelUri) { } + + /** + * This is called when the session has been tuned to the given channel. + * + * @param type The type of {@link android.media.tv.TvInputManager.TvMessageType} + * @param data The raw data of the message + * @hide + */ + public void onTvMessage(@NonNull String inputId, @TvInputManager.TvMessageType String type, + Bundle data) { + } } /** @@ -1432,5 +1454,19 @@ public class TvView extends ViewGroup { mCallback.onTuned(mInputId, channelUri); } } + + @Override + public void onTvMessage(Session session, String type, Bundle data) { + if (DEBUG) { + Log.d(TAG, "onTvMessage(type=" + type + ", data=" + data + ")"); + } + if (this != mSessionCallback) { + Log.w(TAG, "onTvMessage - session not created"); + return; + } + if (mCallback != null) { + mCallback.onTvMessage(mInputId, type, data); + } + } } } diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl index 3b272daa35ae..5a0ac84e5c5e 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl @@ -70,6 +70,7 @@ interface ITvInteractiveAppManager { void notifySignalStrength(in IBinder sessionToken, int stength, int userId); void notifyRecordingStarted(in IBinder sessionToken, in String recordingId, int userId); void notifyRecordingStopped(in IBinder sessionToken, in String recordingId, int userId); + void notifyTvMessage(in IBinder sessionToken, in String type, in Bundle data, int userId); void setSurface(in IBinder sessionToken, in Surface surface, int userId); void dispatchSurfaceChanged(in IBinder sessionToken, int format, int width, int height, int userId); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl index bc09cea1f24a..20ba57b11b11 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl @@ -59,6 +59,7 @@ oneway interface ITvInteractiveAppSession { void notifySignalStrength(int strength); void notifyRecordingStarted(in String recordingId); void notifyRecordingStopped(in String recordingId); + void notifyTvMessage(in String type, in Bundle data); void setSurface(in Surface surface); void dispatchSurfaceChanged(int format, int width, int height); void notifyBroadcastInfoResponse(in BroadcastInfoResponse response); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java index af031dc21f92..a55e1acf7837 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java @@ -86,8 +86,9 @@ public class ITvInteractiveAppSessionWrapper private static final int DO_NOTIFY_RECORDING_STARTED = 30; private static final int DO_NOTIFY_RECORDING_STOPPED = 31; private static final int DO_NOTIFY_AD_BUFFER_CONSUMED = 32; - private static final int DO_SEND_RECORDING_INFO = 33; - private static final int DO_SEND_RECORDING_INFO_LIST = 34; + private static final int DO_NOTIFY_TV_MESSAGE = 33; + private static final int DO_SEND_RECORDING_INFO = 34; + private static final int DO_SEND_RECORDING_INFO_LIST = 35; private final HandlerCaller mCaller; private Session mSessionImpl; @@ -213,6 +214,12 @@ public class ITvInteractiveAppSessionWrapper mSessionImpl.notifyTracksChanged((List<TvTrackInfo>) msg.obj); break; } + case DO_NOTIFY_TV_MESSAGE: { + SomeArgs args = (SomeArgs) msg.obj; + mSessionImpl.notifyTvMessage((String) args.arg1, (Bundle) args.arg2); + args.recycle(); + break; + } case DO_NOTIFY_VIDEO_AVAILABLE: { mSessionImpl.notifyVideoAvailable(); break; @@ -390,6 +397,12 @@ public class ITvInteractiveAppSessionWrapper } @Override + public void notifyTvMessage(String type, Bundle data) { + mCaller.executeOrSendMessage( + mCaller.obtainMessageOO(DO_NOTIFY_TRACK_SELECTED, type, data)); + } + + @Override public void notifyTracksChanged(List<TvTrackInfo> tracks) { mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_NOTIFY_TRACKS_CHANGED, tracks)); } diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java index fa60b66b1348..f4847f70fcee 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java @@ -1504,6 +1504,21 @@ public final class TvInteractiveAppManager { } } + /** + * Notifies Interactive APP session when a new TV message is received. + */ + public void notifyTvMessage(String type, Bundle data) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.notifyTvMessage(mToken, type, data, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private void flushPendingEventsLocked() { mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index 1fa0aaa82a86..3ca9f2fa2986 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -641,6 +641,14 @@ public abstract class TvInteractiveAppService extends Service { * @hide */ public void onAdBufferConsumed(AdBuffer buffer) { + + } + + /** + * Called when a tv message is received + * @hide + */ + public void onTvMessage(@NonNull String type, @NonNull Bundle data) { } @Override @@ -1289,6 +1297,13 @@ public abstract class TvInteractiveAppService extends Service { onAdResponse(response); } + void notifyTvMessage(String type, Bundle data) { + if (DEBUG) { + Log.d(TAG, "notifyTvMessage (type=" + type + ", data= " + data + ")"); + } + onTvMessage(type, data); + } + /** * Calls {@link #onAdBufferConsumed}. */ diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 863ee756af8d..73b22383f541 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -3610,6 +3610,23 @@ public final class TvInputManagerService extends SystemService { } } + @Override + public void onTvMessage(String type, Bundle data) { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onTvMessage(type=" + type + ", data=" + data + ")"); + } + if (mSessionState.session == null || mSessionState.client == null) { + return; + } + try { + mSessionState.client.onTvMessage(type, data, mSessionState.seq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onTvMessage", e); + } + } + } + // For the recording session only @Override public void onRecordingStopped(Uri recordedProgramUri) { 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 966e88354b91..ebee99553309 100644 --- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java @@ -1049,6 +1049,29 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override + public void notifyTvMessage(IBinder sessionToken, String type, Bundle data, int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, + "notifyTvMessage"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).notifyTvMessage(type, data); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in notifyTvMessage", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + + @Override public void notifyRecordingStarted(IBinder sessionToken, String recordingId, int userId) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); |