From 86b6020cc999ad2b31c4944f206bff123f85d791 Mon Sep 17 00:00:00 2001 From: shubang Date: Tue, 7 Dec 2021 18:23:12 -0800 Subject: [PATCH] TIAF: app link info Bug: 209701966 Test: mmm Change-Id: Ibd3100f66358fe441bad2a8bba2fb88980d6716f --- .../media/tv/interactive/ITvIAppManager.aidl | 2 + .../media/tv/interactive/ITvIAppService.aidl | 2 + .../media/tv/interactive/TvIAppManager.java | 58 ++++++++++++++++++ .../media/tv/interactive/TvIAppService.java | 14 +++++ .../tv/interactive/TvIAppManagerService.java | 60 +++++++++++++++++++ 5 files changed, 136 insertions(+) diff --git a/media/java/android/media/tv/interactive/ITvIAppManager.aidl b/media/java/android/media/tv/interactive/ITvIAppManager.aidl index cd87a09b91e07..9859a5fbdc4bb 100644 --- a/media/java/android/media/tv/interactive/ITvIAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppManager.aidl @@ -22,6 +22,7 @@ import android.media.tv.interactive.ITvIAppClient; import android.media.tv.interactive.ITvIAppManagerCallback; import android.media.tv.interactive.TvIAppInfo; import android.net.Uri; +import android.os.Bundle; import android.view.Surface; /** @@ -31,6 +32,7 @@ import android.view.Surface; interface ITvIAppManager { List getTvIAppServiceList(int userId); void prepare(String tiasId, int type, int userId); + void notifyAppLinkInfo(String tiasId, in Bundle info, int userId); void startIApp(in IBinder sessionToken, int userId); void createSession( in ITvIAppClient client, in String iAppServiceId, int type, int seq, int userId); diff --git a/media/java/android/media/tv/interactive/ITvIAppService.aidl b/media/java/android/media/tv/interactive/ITvIAppService.aidl index af15dd8f5a3f3..72db3fa8f3fe7 100644 --- a/media/java/android/media/tv/interactive/ITvIAppService.aidl +++ b/media/java/android/media/tv/interactive/ITvIAppService.aidl @@ -18,6 +18,7 @@ package android.media.tv.interactive; import android.media.tv.interactive.ITvIAppServiceCallback; import android.media.tv.interactive.ITvIAppSessionCallback; +import android.os.Bundle; import android.view.InputChannel; /** @@ -31,4 +32,5 @@ oneway interface ITvIAppService { void createSession(in InputChannel channel, in ITvIAppSessionCallback callback, in String iAppServiceId, int type); void prepare(int type); + void notifyAppLinkInfo(in Bundle info); } \ 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 2272084a4017c..87660559cff5c 100644 --- a/media/java/android/media/tv/interactive/TvIAppManager.java +++ b/media/java/android/media/tv/interactive/TvIAppManager.java @@ -26,6 +26,7 @@ import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; import android.media.tv.TvInputManager; import android.net.Uri; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -87,6 +88,51 @@ public final class TvIAppManager { */ public static final int TV_IAPP_RTE_STATE_ERROR = 4; + /** + * Key for package name in app link. + *

Type: String + * + * @see #notifyAppLinkInfo(String, Bundle) + * @hide + */ + public static final String KEY_PACKAGE_NAME = "package_name"; + + /** + * Key for class name in app link. + *

Type: String + * + * @see #notifyAppLinkInfo(String, Bundle) + * @hide + */ + public static final String KEY_CLASS_NAME = "class_name"; + + /** + * Key for URI scheme in app link. + *

Type: String + * + * @see #notifyAppLinkInfo(String, Bundle) + * @hide + */ + public static final String KEY_URI_SCHEME = "uri_scheme"; + + /** + * Key for URI host in app link. + *

Type: String + * + * @see #notifyAppLinkInfo(String, Bundle) + * @hide + */ + public static final String KEY_URI_HOST = "uri_host"; + + /** + * Key for URI prefix in app link. + *

Type: String + * + * @see #notifyAppLinkInfo(String, Bundle) + * @hide + */ + public static final String KEY_URI_PREFIX = "uri_prefix"; + private final ITvIAppManager mService; private final int mUserId; @@ -417,6 +463,18 @@ public final class TvIAppManager { } } + /** + * Notifies app link info. + * @hide + */ + public void notifyAppLinkInfo(String tvIAppServiceId, Bundle appLinkInfo) { + try { + mService.notifyAppLinkInfo(tvIAppServiceId, appLinkInfo, mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Registers a {@link TvIAppManager.TvIAppCallback}. * diff --git a/media/java/android/media/tv/interactive/TvIAppService.java b/media/java/android/media/tv/interactive/TvIAppService.java index f93b59784c7ef..6bf80284aaf53 100644 --- a/media/java/android/media/tv/interactive/TvIAppService.java +++ b/media/java/android/media/tv/interactive/TvIAppService.java @@ -30,6 +30,7 @@ import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; import android.net.Uri; import android.os.AsyncTask; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -123,6 +124,11 @@ public abstract class TvIAppService extends Service { public void prepare(int type) { onPrepare(type); } + + @Override + public void notifyAppLinkInfo(Bundle appLinkInfo) { + onAppLinkInfo(appLinkInfo); + } }; return tvIAppServiceBinder; } @@ -135,6 +141,14 @@ public abstract class TvIAppService extends Service { // TODO: make it abstract when unhide } + /** + * Registers App link info. + * @hide + */ + public void onAppLinkInfo(Bundle appLinkInfo) { + // TODO: make it abstract when unhide + } + /** * Returns a concrete implementation of {@link Session}. 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 122b3f35d8d1c..1aa75985e4bc7 100644 --- a/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvIAppManagerService.java @@ -42,6 +42,7 @@ import android.media.tv.interactive.TvIAppInfo; import android.media.tv.interactive.TvIAppService; import android.net.Uri; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteCallbackList; @@ -652,6 +653,9 @@ public class TvIAppManagerService extends SystemService { userState.mServiceStateMap.put(componentName, serviceState); } else if (serviceState.mService != null) { serviceState.mService.prepare(type); + } else { + serviceState.mPendingPrepare = true; + serviceState.mPendingPrepareType = type; } } } catch (RemoteException e) { @@ -661,6 +665,40 @@ public class TvIAppManagerService extends SystemService { } } + @Override + public void notifyAppLinkInfo(String tiasId, Bundle appLinkInfo, int userId) { + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), + Binder.getCallingUid(), userId, "notifyAppLinkInfo"); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + UserState userState = getOrCreateUserStateLocked(resolvedUserId); + TvIAppState iAppState = userState.mIAppMap.get(tiasId); + if (iAppState == null) { + Slogf.e(TAG, "failed to notifyAppLinkInfo - unknown TIAS id " + + tiasId); + return; + } + ComponentName componentName = iAppState.mInfo.getComponent(); + ServiceState serviceState = userState.mServiceStateMap.get(componentName); + if (serviceState == null) { + serviceState = new ServiceState( + componentName, tiasId, resolvedUserId); + serviceState.addPendingAppLink(appLinkInfo); + userState.mServiceStateMap.put(componentName, serviceState); + } else if (serviceState.mService != null) { + serviceState.mService.notifyAppLinkInfo(appLinkInfo); + } else { + serviceState.addPendingAppLink(appLinkInfo); + } + } + } catch (RemoteException e) { + Slogf.e(TAG, "error in notifyAppLinkInfo", e); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Override public void createSession(final ITvIAppClient client, final String iAppServiceId, int type, int seq, int userId) { @@ -1237,6 +1275,7 @@ public class TvIAppManagerService extends SystemService { private final ServiceConnection mConnection; private final ComponentName mComponent; private final String mIAppSeriviceId; + private final List mPendingAppLinkInfo = new ArrayList<>(); private boolean mPendingPrepare = false; private Integer mPendingPrepareType = null; @@ -1257,6 +1296,10 @@ public class TvIAppManagerService extends SystemService { mConnection = new IAppServiceConnection(component, userId); mIAppSeriviceId = tias; } + + private void addPendingAppLink(Bundle info) { + mPendingAppLinkInfo.add(info); + } } private final class IAppServiceConnection implements ServiceConnection { @@ -1296,6 +1339,23 @@ public class TvIAppManagerService extends SystemService { } } + if (!serviceState.mPendingAppLinkInfo.isEmpty()) { + for (Iterator it = serviceState.mPendingAppLinkInfo.iterator(); + it.hasNext(); ) { + Bundle appLinkInfo = it.next(); + final long identity = Binder.clearCallingIdentity(); + try { + serviceState.mService.notifyAppLinkInfo(appLinkInfo); + it.remove(); + } catch (RemoteException e) { + Slogf.e(TAG, "error in notifyAppLinkInfo(" + appLinkInfo + + ") when onServiceConnected", e); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + } + List tokensToBeRemoved = new ArrayList<>(); // And create sessions, if any.