diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index c1b66c7b446ed..ad09a48cf4c39 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1645,7 +1645,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* Called to receive data from the application that the user was currently viewing when
- * an assist session is started. If the original show request did not specify
+- * an assist session is started. If the original show request did not specify
* {@link #SHOW_WITH_ASSIST}, this method will not be called.
*
* @param data Arbitrary data supplied by the app through
@@ -1670,8 +1670,9 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* Called to receive data from the application that the user was currently viewing when
- * an assist session is started. If the original show request did not specify
- * {@link #SHOW_WITH_ASSIST}, this method will not be called.
+ * an assist session is started. If the original show request did not specify
+ * {@link #SHOW_WITH_ASSIST}, {@link AssistState} parameter will only provide
+ * {@link ActivityId}.
*
*
This method is called for all activities along with an index and count that indicates
* which activity the data is for. {@code index} will be between 0 and {@code count}-1 and
@@ -1685,7 +1686,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* @param state The state object capturing the state of an activity.
*/
public void onHandleAssist(@NonNull AssistState state) {
- if (state.getIndex() == 0) {
+ if (state.getAssistData() == null && state.getAssistStructure() == null
+ && state.getAssistContent() == null) {
+ return;
+ } else if (state.getIndex() == 0) {
onHandleAssist(state.getAssistData(), state.getAssistStructure(),
state.getAssistContent());
} else {
@@ -2028,7 +2032,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* @return Arbitrary data supplied by the app through
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
- * May be null if assist data has been disabled by the user or device policy.
+ * May be null if assist data has been disabled by the user or device policy; will be null
+ * if the original show request did not specify {@link #SHOW_WITH_ASSIST}.
*/
public @Nullable Bundle getAssistData() {
return mData;
@@ -2037,7 +2042,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* @return If available, the structure definition of all windows currently
* displayed by the app. May be null if assist data has been disabled by the user
- * or device policy; will be an empty stub if the application has disabled assist
+ * or device policy; will be null if the original show request did not specify
+ * {@link #SHOW_WITH_ASSIST}; will be an empty stub if the application has disabled assist
* by marking its window as secure.
*/
public @Nullable AssistStructure getAssistStructure() {
@@ -2047,9 +2053,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* @return Additional content data supplied by the app through
* {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
- * May be null if assist data has been disabled by the user or device policy; will
- * not be automatically filled in with data from the app if the app has marked its
- * window as secure.
+ * May be null if assist data has been disabled by the user or device policy; will be null
+ * if the original show request did not specify {@link #SHOW_WITH_ASSIST}. Will not be
+ * automatically filled in with data from the app if the app has marked its window as
+ * secure.
*/
public @Nullable AssistContent getAssistContent() {
return mContent;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index e858fe1034b1b..060323c34b40e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -32,6 +32,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.service.voice.IVoiceInteractionSession;
+import android.util.Pair;
import android.util.proto.ProtoOutputStream;
import android.window.TaskSnapshot;
@@ -162,10 +163,10 @@ public abstract class ActivityTaskManagerInternal {
IVoiceInteractor mInteractor);
/**
- * Returns the top activity from each of the currently visible root tasks. The first entry
- * will be the focused activity.
+ * Returns the top activity from each of the currently visible root tasks, and the related task
+ * id. The first entry will be the focused activity.
*/
- public abstract List getTopVisibleActivities();
+ public abstract List> getTopVisibleActivities();
/**
* Returns whether {@code uid} has any resumed activity.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 52d110c95e36a..09f5c937928c2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -215,6 +215,7 @@ import android.text.format.TimeMigrationUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -5074,7 +5075,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public List getTopVisibleActivities() {
+ public List> getTopVisibleActivities() {
synchronized (mGlobalLock) {
return mRootWindowContainer.getTopVisibleActivities();
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 422d4e79e259e..857217fb19e2a 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1814,11 +1814,11 @@ class RootWindowContainer extends WindowContainer
}
/**
- * @return a list of activities which are the top ones in each visible root task. The first
- * entry will be the focused activity.
+ * @return a list of pairs, containing activities and their task id which are the top ones in
+ * each visible root task. The first entry will be the focused activity.
*/
- List getTopVisibleActivities() {
- final ArrayList topActivityTokens = new ArrayList<>();
+ List> getTopVisibleActivities() {
+ final ArrayList> topVisibleActivities = new ArrayList<>();
final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
// Traverse all displays.
forAllRootTasks(rootTask -> {
@@ -1826,15 +1826,17 @@ class RootWindowContainer extends WindowContainer
if (rootTask.shouldBeVisible(null /* starting */)) {
final ActivityRecord top = rootTask.getTopNonFinishingActivity();
if (top != null) {
+ Pair visibleActivity = new Pair<>(top.appToken,
+ top.getTask().mTaskId);
if (rootTask == topFocusedRootTask) {
- topActivityTokens.add(0, top.appToken);
+ topVisibleActivities.add(0, visibleActivity);
} else {
- topActivityTokens.add(top.appToken);
+ topVisibleActivities.add(visibleActivity);
}
}
}
});
- return topActivityTokens;
+ return topVisibleActivities;
}
@Nullable
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 58616104755d1..05573f1d7d607 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -50,6 +50,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
import android.system.OsConstants;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.IWindowManager;
@@ -186,17 +187,27 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mSessionComponentName, mUser, mContext, this,
mInfo.getServiceInfo().applicationInfo.uid, mHandler);
}
- List activityTokens = null;
+ List> allVisibleActivities =
+ LocalServices.getService(ActivityTaskManagerInternal.class)
+ .getTopVisibleActivities();
+
+ List> visibleActivities = null;
if (activityToken != null) {
- activityTokens = new ArrayList<>();
- activityTokens.add(activityToken);
+ visibleActivities = new ArrayList();
+ int activitiesCount = allVisibleActivities.size();
+ for (int i = 0; i < activitiesCount; i++) {
+ if (allVisibleActivities.get(i).first == activityToken) {
+ visibleActivities.add(
+ new Pair<>(activityToken, allVisibleActivities.get(i).second));
+ break;
+ }
+ }
} else {
- // Let's get top activities from all visible stacks
- activityTokens = LocalServices.getService(ActivityTaskManagerInternal.class)
+ visibleActivities = LocalServices.getService(ActivityTaskManagerInternal.class)
.getTopVisibleActivities();
}
return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback,
- activityTokens);
+ visibleActivities);
}
public void getActiveServiceSupportedActions(List commands,
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 84f4f6a017d1e..428d342a80c95 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -56,6 +56,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.service.voice.IVoiceInteractionSessionService;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionSession;
+import android.util.Pair;
import android.util.Slog;
import android.view.IWindowManager;
@@ -190,7 +191,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
}
public boolean showLocked(Bundle args, int flags, int disabledContext,
- IVoiceInteractionSessionShowCallback showCallback, List topActivities) {
+ IVoiceInteractionSessionShowCallback showCallback,
+ List> topActivities) {
if (mBound) {
if (!mFullyBound) {
mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
@@ -205,17 +207,29 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
mShowFlags = flags;
disabledContext |= getUserDisabledShowContextLocked();
- mAssistDataRequester.requestAssistData(topActivities,
- (flags & VoiceInteractionSession.SHOW_WITH_ASSIST) != 0,
- (flags & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0,
- (disabledContext & VoiceInteractionSession.SHOW_WITH_ASSIST) == 0,
- (disabledContext & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0,
- mCallingUid, mSessionComponentName.getPackageName());
- boolean needDisclosure = mAssistDataRequester.getPendingDataCount() > 0
- || mAssistDataRequester.getPendingScreenshotCount() > 0;
- if (needDisclosure && AssistUtils.shouldDisclose(mContext, mSessionComponentName)) {
- mHandler.post(mShowAssistDisclosureRunnable);
+ boolean fetchData = (flags & VoiceInteractionSession.SHOW_WITH_ASSIST) != 0;
+ boolean fetchScreenshot = (flags & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0;
+ boolean assistDataRequestNeeded = fetchData || fetchScreenshot;
+
+ if (assistDataRequestNeeded) {
+ int topActivitiesCount = topActivities.size();
+ final ArrayList topActivitiesToken = new ArrayList<>(topActivitiesCount);
+ for (int i = 0; i < topActivitiesCount; i++) {
+ topActivitiesToken.add(topActivities.get(i).first);
+ }
+ mAssistDataRequester.requestAssistData(topActivitiesToken,
+ fetchData,
+ fetchScreenshot,
+ (disabledContext & VoiceInteractionSession.SHOW_WITH_ASSIST) == 0,
+ (disabledContext & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0,
+ mCallingUid, mSessionComponentName.getPackageName());
+
+ boolean needDisclosure = mAssistDataRequester.getPendingDataCount() > 0
+ || mAssistDataRequester.getPendingScreenshotCount() > 0;
+ if (needDisclosure && AssistUtils.shouldDisclose(mContext, mSessionComponentName)) {
+ mHandler.post(mShowAssistDisclosureRunnable);
+ }
}
if (mSession != null) {
try {
@@ -224,7 +238,11 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
mShowFlags = 0;
} catch (RemoteException e) {
}
- mAssistDataRequester.processPendingAssistData();
+ if (assistDataRequestNeeded) {
+ mAssistDataRequester.processPendingAssistData();
+ } else {
+ doHandleAssistWithoutData(topActivities);
+ }
} else if (showCallback != null) {
mPendingShowCallbacks.add(showCallback);
}
@@ -240,6 +258,28 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
return false;
}
+ private void doHandleAssistWithoutData(List> topActivities) {
+ final int activityCount = topActivities.size();
+ for (int i = 0; i < activityCount; i++) {
+ final Pair topActivity = topActivities.get(i);
+ final IBinder activityId = topActivity.first;
+ final int taskId = topActivity.second;
+ final int activityIndex = i;
+ try {
+ mSession.handleAssist(
+ taskId,
+ activityId,
+ /* assistData = */ null,
+ /* assistStructure = */ null,
+ /* assistContent = */ null,
+ activityIndex,
+ activityCount);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+ }
+
@Override
public boolean canHandleReceivedAssistDataLocked() {
return mSession != null;