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

Commit d386d7da authored by Andy Wickham's avatar Andy Wickham
Browse files

Forces OveriewInputConsumer to be used when Assistant is running on top of Launcher.

Previously it was using OtherActivityInputConsumer, which got things in a
pretty weird state (e.g. most recent app would appear in the center as if
it was the active app when you started Quick Switching, etc.).

By default (toggleable by a feature flag), OverviewWithoutFocusInputConsumer
is used because Assistant doesn't seem to respect the CLOSE_SYSTEM_DIALOGS
broadcast, at least in half-shelf mode. In this case, the Home intent is
sent on swipe up, or you can dismiss it with the back gesture or by tapping
above the half shelf.

The new feature flag ASSISTANT_GIVES_LAUNCHER_FOCUS routes touches through
OverviewInputConsumer. As opposed to OverviewWithoutFocusInputConsumer,
this allows Quick Step to work while Assistant is running. Additional logic
is added to dismiss the Assistant when appropriate. Note that the dismissal
happens atomically, so it's not completely fluid with the other animations.
As mentioned above, this is disabled by default because Assistant doesn't
currently respect CLOSE_SYSTEM_DIALOGS.

Demo with the flag enabled (and Assistant respecting CLOSE_SYSTEM_DIALOGS):
https://drive.google.com/open?id=1W5jGpn_TEC-KjrYwQtaBT3pzxG_5tC4W

Bug: 139661510
Change-Id: I261653118aff289b329ec2a7ca6e52f100f7835a
Tested: Manually used quick switch after invoking Assistant from home screen.
parent 632bcf76
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.touch.AbstractStateChangeTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;

import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -43,11 +44,14 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.util.AssistantUtilities;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;

/**
 * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps.
@@ -104,6 +108,10 @@ public class NavBarToHomeTouchController implements TouchController,
        if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
            return true;
        }
        if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
                && AssistantUtilities.isExcludedAssistantRunning()) {
            return true;
        }
        return false;
    }

@@ -194,6 +202,8 @@ public class NavBarToHomeTouchController implements TouchController,
                AbstractFloatingView.closeAllOpenViews(mLauncher);
                logStateChange(topOpenView.getLogContainerType(), logAction);
            }
            ActivityManagerWrapper.getInstance()
                    .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
        } else {
            // Quickly return to the state we came from (we didn't move far).
            ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;

import android.view.MotionEvent;
@@ -50,6 +51,7 @@ import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityManagerWrapper;

/**
 * Handles quick switching to a recent task from the home screen.
@@ -94,6 +96,8 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
        super.onDragStart(start);
        mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
        mTaskToLaunch = mLauncher.<RecentsView>getOverviewPanel().getTaskViewAt(0);
        ActivityManagerWrapper.getInstance()
                .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
    }

    @Override
+18 −20
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -57,6 +56,7 @@ import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.provider.RestoreDbTask;
@@ -74,6 +74,7 @@ import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
import com.android.quickstep.inputconsumers.ResetGestureInputConsumer;
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.AssistantUtilities;
import com.android.systemui.plugins.OverscrollPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.recents.IOverviewProxy;
@@ -83,7 +84,6 @@ import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.TaskInfoCompat;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -518,17 +518,16 @@ public class TouchInteractionService extends Service implements PluginListener<O
        }

        boolean forceOverviewInputConsumer = false;
        if (isExcludedAssistant(gestureState.getRunningTask())) {
        if (AssistantUtilities.isExcludedAssistant(gestureState.getRunningTask())) {
            // In the case where we are in the excluded assistant state, ignore it and treat the
            // running activity as the task behind the assistant
            gestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.assistant",
                    () -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT)));
            if (!ActivityManagerWrapper.isHomeTask(gestureState.getRunningTask())) {
                final ComponentName homeComponent =
                        mOverviewComponentObserver.getHomeIntent().getComponent();
                forceOverviewInputConsumer = gestureState.getRunningTask()
                        .baseIntent.getComponent().equals(homeComponent);
            }
                    () -> mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT /* ignoreActivityType */)));
            ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent();
            ComponentName runningComponent =
                    gestureState.getRunningTask().baseIntent.getComponent();
            forceOverviewInputConsumer =
                    runningComponent != null && runningComponent.equals(homeComponent);
        }

        if (previousGestureState.getFinishingRecentsAnimationTaskId() > 0) {
@@ -543,10 +542,12 @@ public class TouchInteractionService extends Service implements PluginListener<O
        } else if (previousGestureState.isRunningAnimationToLauncher()
                || gestureState.getActivityInterface().isResumed()
                || forceOverviewInputConsumer) {
            return createOverviewInputConsumer(previousGestureState, gestureState, event);
            return createOverviewInputConsumer(
                    previousGestureState, gestureState, event, forceOverviewInputConsumer);
        } else if (ENABLE_QUICKSTEP_LIVE_TILE.get()
                && gestureState.getActivityInterface().isInLiveTileMode()) {
            return createOverviewInputConsumer(previousGestureState, gestureState, event);
            return createOverviewInputConsumer(
                    previousGestureState, gestureState, event, forceOverviewInputConsumer);
        } else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) {
            return mResetGestureInputConsumer;
        } else {
@@ -554,12 +555,6 @@ public class TouchInteractionService extends Service implements PluginListener<O
        }
    }

    private boolean isExcludedAssistant(TaskInfo info) {
        return info != null
                && TaskInfoCompat.getActivityType(info) == ACTIVITY_TYPE_ASSISTANT
                && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
    }

    private InputConsumer createOtherActivityInputConsumer(GestureState previousGestureState,
            GestureState gestureState, MotionEvent event) {

@@ -592,14 +587,17 @@ public class TouchInteractionService extends Service implements PluginListener<O
    }

    public InputConsumer createOverviewInputConsumer(GestureState previousGestureState,
            GestureState gestureState, MotionEvent event) {
            GestureState gestureState, MotionEvent event,
            boolean forceOverviewInputConsumer) {
        BaseDraggingActivity activity = gestureState.getActivityInterface().getCreatedActivity();
        if (activity == null) {
            return mResetGestureInputConsumer;
        }

        if (activity.getRootView().hasWindowFocus()
                || previousGestureState.isRunningAnimationToLauncher()) {
                || previousGestureState.isRunningAnimationToLauncher()
                || (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
                    && forceOverviewInputConsumer)) {
            return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
                    false /* startingInActivityBounds */);
        } else {
+5 −6
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;

import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;

import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -35,11 +35,10 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;

public class OverviewWithoutFocusInputConsumer implements InputConsumer {
@@ -152,9 +151,9 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer {
        }

        if (triggerQuickstep) {
            mGestureState.getActivityInterface().closeOverlay();
            ActivityManagerWrapper.getInstance()
                    .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
            mContext.startActivity(new Intent(Intent.ACTION_MAIN)
                    .addCategory(Intent.CATEGORY_HOME)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
            ActiveGestureLog.INSTANCE.addLog("startQuickstep");
            BaseActivity activity = BaseDraggingActivity.fromContext(mContext);
            int pageIndex = -1; // This number doesn't reflect workspace page index.
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.quickstep.util;

import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;

import android.annotation.TargetApi;
import android.app.TaskInfo;
import android.content.Intent;
import android.os.Build;

import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskInfoCompat;

/**
 * Utility class for interacting with the Assistant.
 */
@TargetApi(Build.VERSION_CODES.Q)
public final class AssistantUtilities {

    /** Returns true if an Assistant activity that is excluded from recents is running. */
    public static boolean isExcludedAssistantRunning() {
        return isExcludedAssistant(ActivityManagerWrapper.getInstance().getRunningTask());
    }

    /** Returns true if the given task holds an Assistant activity that is excluded from recents. */
    public static boolean isExcludedAssistant(TaskInfo info) {
        return info != null
            && TaskInfoCompat.getActivityType(info) == ACTIVITY_TYPE_ASSISTANT
            && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
    }

    private AssistantUtilities() {}
}
Loading