Merge "Always call onHandleAssist with AssistState containing at least activity id" into sc-dev

This commit is contained in:
Nicolò Mazzucato
2021-03-19 13:34:18 +00:00
committed by Android (Google) Code Review
6 changed files with 100 additions and 38 deletions

View File

@@ -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}.
*
* <p>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;

View File

@@ -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<IBinder> getTopVisibleActivities();
public abstract List<Pair<IBinder, Integer>> getTopVisibleActivities();
/**
* Returns whether {@code uid} has any resumed activity.

View File

@@ -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<IBinder> getTopVisibleActivities() {
public List<Pair<IBinder, Integer>> getTopVisibleActivities() {
synchronized (mGlobalLock) {
return mRootWindowContainer.getTopVisibleActivities();
}

View File

@@ -1814,11 +1814,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
/**
* @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<IBinder> getTopVisibleActivities() {
final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
List<Pair<IBinder, Integer>> getTopVisibleActivities() {
final ArrayList<Pair<IBinder, Integer>> topVisibleActivities = new ArrayList<>();
final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
// Traverse all displays.
forAllRootTasks(rootTask -> {
@@ -1826,15 +1826,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
if (rootTask.shouldBeVisible(null /* starting */)) {
final ActivityRecord top = rootTask.getTopNonFinishingActivity();
if (top != null) {
Pair<IBinder, Integer> 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

View File

@@ -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<IBinder> activityTokens = null;
List<Pair<IBinder, Integer>> allVisibleActivities =
LocalServices.getService(ActivityTaskManagerInternal.class)
.getTopVisibleActivities();
List<Pair<IBinder, Integer>> 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<String> commands,

View File

@@ -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<IBinder> topActivities) {
IVoiceInteractionSessionShowCallback showCallback,
List<Pair<IBinder, Integer>> 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<IBinder> 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<Pair<IBinder, Integer>> topActivities) {
final int activityCount = topActivities.size();
for (int i = 0; i < activityCount; i++) {
final Pair<IBinder, Integer> 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;