From 0804b6e2935191308d8d8b1624847c6d74f960f7 Mon Sep 17 00:00:00 2001 From: Joanne Chung Date: Wed, 15 Feb 2023 10:00:01 +0800 Subject: [PATCH] Allow VISS to start assistant activity with ActivityOptions The assisant app would like to override the Activity start and exit animation. The ActivityOptions is not a parcelable class so we use Bundle to pass to system. The system can use Bundle to create ActivityOptions to start assistant activity. Bug: 241457460 Test: atest CtsVoiceInteractionTestCases API-Coverage-Bug: 269360412 Change-Id: I5d7f4bd22842b12bcbf08dbc0188eea3f0b262ff --- core/api/current.txt | 1 + .../voice/VoiceInteractionSession.java | 29 ++++++++++++++++++- .../app/IVoiceInteractionManagerService.aidl | 2 +- .../VoiceInteractionManagerService.java | 5 ++-- .../VoiceInteractionManagerServiceImpl.java | 10 +++---- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 1b5e020c02ce6..301e69aed7395 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -40974,6 +40974,7 @@ package android.service.voice { method public void setUiEnabled(boolean); method public void show(android.os.Bundle, int); method public void startAssistantActivity(android.content.Intent); + method public void startAssistantActivity(@NonNull android.content.Intent, @NonNull android.os.Bundle); method public void startVoiceActivity(android.content.Intent); method public final void unregisterVisibleActivityCallback(@NonNull android.service.voice.VoiceInteractionSession.VisibleActivityCallback); field public static final String KEY_SHOW_SESSION_ID = "android.service.voice.SHOW_SESSION_ID"; diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 0d513951a4a7c..bcd7835b22be5 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -26,6 +26,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.app.Activity; +import android.app.ActivityOptions; import android.app.Dialog; import android.app.DirectAction; import android.app.Instrumentation; @@ -1527,8 +1528,34 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall *

By default, the system will create a window for the UI for this session. If you are using * an assistant activity instead, then you can disable the window creation by calling * {@link #setUiEnabled} in {@link #onPrepareShow(Bundle, int)}.

+ * + * NOTE: if the app would like to override some options to start the Activity, + * use {@link #startAssistantActivity(Intent, Bundle)} instead. */ public void startAssistantActivity(Intent intent) { + startAssistantActivity(intent, ActivityOptions.makeBasic().toBundle()); + } + + /** + *

Ask that a new assistant activity be started. This will create a new task in the + * in activity manager: this means that + * {@link Intent#FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK} + * will be set for you to make it a new task.

+ * + *

The newly started activity will be displayed on top of other activities in the system + * in a new layer that is not affected by multi-window mode. Tasks started from this activity + * will go into the normal activity layer and not this new layer.

+ * + *

By default, the system will create a window for the UI for this session. If you are using + * an assistant activity instead, then you can disable the window creation by calling + * {@link #setUiEnabled} in {@link #onPrepareShow(Bundle, int)}.

+ * + * @param intent the intent used to start an assistant activity + * @param bundle Additional options for how the Activity should be started. See + * {@link ActivityOptions} for how to build the Bundle supplied here. + */ + public void startAssistantActivity(@NonNull Intent intent, @NonNull Bundle bundle) { + Objects.requireNonNull(bundle); if (mToken == null) { throw new IllegalStateException("Can't call before onCreate()"); } @@ -1537,7 +1564,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall intent.prepareToLeaveProcess(mContext); int res = mSystemService.startAssistantActivity(mToken, intent, intent.resolveType(mContext.getContentResolver()), - mContext.getAttributionTag()); + mContext.getAttributionTag(), bundle); Instrumentation.checkStartActivityResult(res, intent); } catch (RemoteException e) { } diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 619b4208048c3..3d38490da5ae2 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -51,7 +51,7 @@ interface IVoiceInteractionManagerService { int startVoiceActivity(IBinder token, in Intent intent, String resolvedType, String attributionTag); int startAssistantActivity(IBinder token, in Intent intent, String resolvedType, - String attributionTag); + String attributionTag, in Bundle bundle); void setKeepAwake(IBinder token, boolean keepAwake); void closeSystemDialogs(IBinder token); void finish(IBinder token); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 0abed0b27759f..0079170636f78 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -1038,7 +1038,8 @@ public class VoiceInteractionManagerService extends SystemService { @Override public int startAssistantActivity(@NonNull IBinder token, @NonNull Intent intent, - @Nullable String resolvedType, @Nullable String attributionTag) { + @Nullable String resolvedType, @NonNull String attributionTag, + @NonNull Bundle bundle) { synchronized (this) { if (mImpl == null) { Slog.w(TAG, "startAssistantActivity without running voice interaction service"); @@ -1049,7 +1050,7 @@ public class VoiceInteractionManagerService extends SystemService { final long caller = Binder.clearCallingIdentity(); try { return mImpl.startAssistantActivityLocked(attributionTag, callingPid, - callingUid, token, intent, resolvedType); + callingUid, token, intent, resolvedType, bundle); } finally { Binder.restoreCallingIdentity(caller); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 3dbd269a4adc4..5f5539468142f 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -29,7 +29,6 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.app.ApplicationExitInfo; @@ -376,7 +375,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne @GuardedBy("this") public int startAssistantActivityLocked(@Nullable String callingFeatureId, int callingPid, - int callingUid, IBinder token, Intent intent, String resolvedType) { + int callingUid, IBinder token, Intent intent, String resolvedType, + @NonNull Bundle bundle) { try { if (mActiveSession == null || token != mActiveSession.mToken) { Slog.w(TAG, "startAssistantActivity does not match active session"); @@ -388,10 +388,10 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } intent = new Intent(intent); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - final ActivityOptions options = ActivityOptions.makeBasic(); - options.setLaunchActivityType(ACTIVITY_TYPE_ASSISTANT); + // TODO: make the key public hidden + bundle.putInt("android.activity.activityType", ACTIVITY_TYPE_ASSISTANT); return mAtm.startAssistantActivity(mComponent.getPackageName(), callingFeatureId, - callingPid, callingUid, intent, resolvedType, options.toBundle(), mUser); + callingPid, callingUid, intent, resolvedType, bundle, mUser); } catch (RemoteException e) { throw new IllegalStateException("Unexpected remote error", e); }