From b488c1baf4790aa4d1877e5ad4ee86886955f8be Mon Sep 17 00:00:00 2001 From: Yixiao Luo Date: Mon, 22 Nov 2021 11:09:29 -0800 Subject: [PATCH] TIAF-TIF broadcastinfo flow Change-Id: Ie1a8e0b8f9b88e3a521dd9876f98665e7ece21ad Bug: 207417265 --- .../media/tv/BroadcastInfoResponse.java | 4 ++ .../java/android/media/tv/TvInputManager.java | 9 +--- .../media/tv/interactive/ITvIAppClient.aidl | 2 + .../media/tv/interactive/ITvIAppManager.aidl | 3 ++ .../media/tv/interactive/ITvIAppSession.aidl | 2 + .../interactive/ITvIAppSessionCallback.aidl | 2 + .../media/tv/interactive/TvIAppManager.java | 40 ++++++++++++++++ .../media/tv/interactive/TvIAppService.java | 47 +++++++++++++++++++ .../tv/interactive/TvIAppManagerService.java | 43 +++++++++++++++++ 9 files changed, 144 insertions(+), 8 deletions(-) diff --git a/media/java/android/media/tv/BroadcastInfoResponse.java b/media/java/android/media/tv/BroadcastInfoResponse.java index 64c884ec4b7fb..fe4e8b7f1d0a5 100644 --- a/media/java/android/media/tv/BroadcastInfoResponse.java +++ b/media/java/android/media/tv/BroadcastInfoResponse.java @@ -46,6 +46,10 @@ public final class BroadcastInfoResponse implements Parcelable { requestId = source.readInt(); } + public int getRequestId() { + return requestId; + } + @Override public int describeContents() { return 0; diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 0461f0a6f61cd..bafb03bc53ebc 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -657,13 +657,6 @@ public final class TvInputManager { */ void onError(Session session, @TvInputManager.RecordingError int error) { } - - /** - * @param session - * @param response - */ - public void onBroadcastInfoResponse(Session session, BroadcastInfoResponse response) { - } } private static final class SessionCallbackRecord { @@ -848,7 +841,7 @@ public final class TvInputManager { mHandler.post(new Runnable() { @Override public void run() { - mSessionCallback.onBroadcastInfoResponse(mSession, response); + mSession.getIAppSession().notifyBroadcastInfoResponse(response); } }); } diff --git a/media/java/android/media/tv/interactive/ITvIAppClient.aidl b/media/java/android/media/tv/interactive/ITvIAppClient.aidl index dabea304591b2..39c438a093119 100644 --- a/media/java/android/media/tv/interactive/ITvIAppClient.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppClient.aidl @@ -15,6 +15,7 @@ */ package android.media.tv.interactive; +import android.media.tv.BroadcastInfoRequest; import android.view.InputChannel; @@ -27,4 +28,5 @@ oneway interface ITvIAppClient { void onSessionCreated(in String iAppServiceId, IBinder token, in InputChannel channel, int seq); void onSessionReleased(int seq); void onLayoutSurface(int left, int top, int right, int bottom, int seq); + void onBroadcastInfoRequest(in BroadcastInfoRequest request, int seq); } \ No newline at end of file diff --git a/media/java/android/media/tv/interactive/ITvIAppManager.aidl b/media/java/android/media/tv/interactive/ITvIAppManager.aidl index 104efe6d18814..25e1acea226dc 100644 --- a/media/java/android/media/tv/interactive/ITvIAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppManager.aidl @@ -19,6 +19,7 @@ package android.media.tv.interactive; import android.media.tv.interactive.ITvIAppClient; import android.media.tv.interactive.ITvIAppManagerCallback; import android.media.tv.interactive.TvIAppInfo; +import android.media.tv.BroadcastInfoResponse; import android.view.Surface; /** @@ -34,6 +35,8 @@ interface ITvIAppManager { void setSurface(in IBinder sessionToken, in Surface surface, int userId); void dispatchSurfaceChanged(in IBinder sessionToken, int format, int width, int height, int userId); + void notifyBroadcastInfoResponse(in IBinder sessionToken, in BroadcastInfoResponse response, + int UserId); void registerCallback(in ITvIAppManagerCallback callback, int userId); void unregisterCallback(in ITvIAppManagerCallback callback, int userId); diff --git a/media/java/android/media/tv/interactive/ITvIAppSession.aidl b/media/java/android/media/tv/interactive/ITvIAppSession.aidl index 0afa9716a783f..440b3d30c0680 100644 --- a/media/java/android/media/tv/interactive/ITvIAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppSession.aidl @@ -17,6 +17,7 @@ package android.media.tv.interactive; import android.view.Surface; +import android.media.tv.BroadcastInfoResponse; /** * Sub-interface of ITvIAppService.aidl which is created per session and has its own context. @@ -27,4 +28,5 @@ oneway interface ITvIAppSession { void release(); void setSurface(in Surface surface); void dispatchSurfaceChanged(int format, int width, int height); + void notifyBroadcastInfoResponse(in BroadcastInfoResponse response); } \ No newline at end of file diff --git a/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl index 0873aad8f5c61..d308463cda4d9 100644 --- a/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppSessionCallback.aidl @@ -17,6 +17,7 @@ package android.media.tv.interactive; import android.media.tv.interactive.ITvIAppSession; +import android.media.tv.BroadcastInfoRequest; /** * Helper interface for ITvIAppSession to allow TvIAppService to notify the system service when @@ -26,4 +27,5 @@ import android.media.tv.interactive.ITvIAppSession; oneway interface ITvIAppSessionCallback { void onSessionCreated(in ITvIAppSession session); void onLayoutSurface(int left, int top, int right, int bottom); + void onBroadcastInfoRequest(in BroadcastInfoRequest request); } \ No newline at end of file diff --git a/media/java/android/media/tv/interactive/TvIAppManager.java b/media/java/android/media/tv/interactive/TvIAppManager.java index 7479b2bd9f205..ae35edc7ef8ab 100644 --- a/media/java/android/media/tv/interactive/TvIAppManager.java +++ b/media/java/android/media/tv/interactive/TvIAppManager.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.content.Context; +import android.media.tv.BroadcastInfoRequest; +import android.media.tv.BroadcastInfoResponse; import android.media.tv.TvInputManager; import android.os.Handler; import android.os.IBinder; @@ -117,6 +119,18 @@ public final class TvIAppManager { record.postLayoutSurface(left, top, right, bottom); } } + + @Override + public void onBroadcastInfoRequest(BroadcastInfoRequest request, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postBroadcastInfoRequest(request); + } + } }; ITvIAppManagerCallback managerCallback = new ITvIAppManagerCallback.Stub() { // TODO: handle IApp service state changes @@ -485,6 +499,23 @@ public final class TvIAppManager { } } + /** + * Notifies of any broadcast info response passed in from TIS. + * + * @param response response passed in from TIS. + */ + public void notifyBroadcastInfoResponse(BroadcastInfoResponse response) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.notifyBroadcastInfoResponse(mToken, response, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Releases this session. */ @@ -744,6 +775,15 @@ public final class TvIAppManager { } }); } + + void postBroadcastInfoRequest(final BroadcastInfoRequest request) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSession.getInputSession().requestBroadcastInfo(request); + } + }); + } } /** diff --git a/media/java/android/media/tv/interactive/TvIAppService.java b/media/java/android/media/tv/interactive/TvIAppService.java index 25dec62a2a2e1..fe087ca564d01 100644 --- a/media/java/android/media/tv/interactive/TvIAppService.java +++ b/media/java/android/media/tv/interactive/TvIAppService.java @@ -23,6 +23,8 @@ import android.annotation.SuppressLint; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.media.tv.BroadcastInfoRequest; +import android.media.tv.BroadcastInfoResponse; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -184,6 +186,14 @@ public abstract class TvIAppService extends Service { public void onSurfaceChanged(int format, int width, int height) { } + /** + * Called when a broadcast info response is received from TIS. + * + * @param response response received from TIS. + */ + public void onNotifyBroadcastInfoResponse(BroadcastInfoResponse response) { + } + /** * Releases TvIAppService session. * @hide @@ -278,6 +288,26 @@ public abstract class TvIAppService extends Service { }); } + public void requestBroadcastInfo(@NonNull final BroadcastInfoRequest request) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestBroadcastInfo (requestId=" + + request.getRequestId() + ")"); + } + if (mSessionCallback != null) { + mSessionCallback.onBroadcastInfoRequest(request); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestBroadcastInfo", e); + } + } + }); + } + void startIApp() { onStartIApp(); } @@ -356,6 +386,18 @@ public abstract class TvIAppService extends Service { onSurfaceChanged(format, width, height); } + /** + * + * Calls {@link #notifyBroadcastInfoResponse}. + */ + void notifyBroadcastInfoResponse(BroadcastInfoResponse response) { + if (DEBUG) { + Log.d(TAG, "notifyBroadcastInfoResponse (requestId=" + + response.getRequestId() + ")"); + } + onNotifyBroadcastInfoResponse(response); + } + private void executeOrPostRunnableOnMainThread(Runnable action) { synchronized (mLock) { if (mSessionCallback == null) { @@ -411,6 +453,11 @@ public abstract class TvIAppService extends Service { mSessionImpl.dispatchSurfaceChanged(format, width, height); } + @Override + public void notifyBroadcastInfoResponse(BroadcastInfoResponse response) { + mSessionImpl.notifyBroadcastInfoResponse(response); + } + private final class TvIAppEventReceiver extends InputEventReceiver { TvIAppEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); 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 d0c6d137f5ef8..c7b6421cd0c9e 100644 --- a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java @@ -28,6 +28,8 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; +import android.media.tv.BroadcastInfoRequest; +import android.media.tv.BroadcastInfoResponse; import android.media.tv.interactive.ITvIAppClient; import android.media.tv.interactive.ITvIAppManager; import android.media.tv.interactive.ITvIAppManagerCallback; @@ -744,6 +746,29 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void notifyBroadcastInfoResponse(IBinder sessionToken, + BroadcastInfoResponse response, int userId) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId, + "notifyBroadcastInfoResponse"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).notifyBroadcastInfoResponse(response); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in notifyBroadcastInfoResponse", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void registerCallback(final ITvIAppManagerCallback callback, int userId) { int callingPid = Binder.getCallingPid(); @@ -1190,6 +1215,24 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void onBroadcastInfoRequest(BroadcastInfoRequest request) { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onBroadcastInfoRequest (requestId=" + + request.getRequestId() + ")"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onBroadcastInfoRequest(request, mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onBroadcastInfoRequest", e); + } + } + } + @GuardedBy("mLock") private boolean addSessionTokenToClientStateLocked(ITvIAppSession session) { try {