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
Merged-in: I5d7f4bd22842b12bcbf08dbc0188eea3f0b262ff
(cherry picked from commit 0804b6e293)
This commit is contained in:
Joanne Chung
2023-02-15 10:00:01 +08:00
parent dd76f4b3fc
commit a846aee933
5 changed files with 38 additions and 9 deletions

View File

@@ -41246,6 +41246,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";

View File

@@ -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
* <p>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)}.</p>
*
* 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());
}
/**
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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)}.</p>
*
* @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) {
}

View File

@@ -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);

View File

@@ -1049,7 +1049,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");
@@ -1060,7 +1061,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);
}

View File

@@ -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);
}