Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbc1459c authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Always call onHandleAssist with AssistState containing at least activity id

With this change, even if clients are not requesting any assist
data (e.g. VoiceInteractionSession.showSession is called with 0
as flags), Activity's `onHandleAssist(AssistState)` is always
called with non-null ActivityId. If no other data were requested,
AssistContent, AssistData and AssistStructure inside
VoiceInteractionSession.AssistState are null.

The previous behaviour was that if no assistData were requested,
Activity's `onHandleAssist` would not have been called.

This new behaviour saves time to clients interested only in ActivityIds,
because no activities methods need to be called (to get AssistData and
AssistContent).

We are not adding a new flag "SHOW_WITH_ACTIVITY_ID" because this
ActivityId is always non-null in ActivityState, and it's cheap to get it.

Bug: 178020517
Test: atest CtsAssistTestCases
Test: atest CtsVoiceInteractionTestCases
Change-Id: Icb46a928c8508a4bd355622df78f9371c21fd0e6
parent 24923769
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -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
@@ -1671,7 +1671,8 @@ 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.
     * {@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;
+4 −3
Original line number Diff line number Diff line
@@ -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.
+2 −1
Original line number Diff line number Diff line
@@ -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();
            }
+9 −7
Original line number Diff line number Diff line
@@ -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
+17 −6
Original line number Diff line number Diff line
@@ -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,
Loading