From 6547f1a937170e52d2802d67c28168ebd3688903 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Thu, 17 Oct 2019 18:21:41 -0700 Subject: [PATCH] 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 Merged-In: I261653118aff289b329ec2a7ca6e52f100f7835a --- .../NavBarToHomeTouchController.java | 10 ++++ .../QuickSwitchTouchController.java | 4 ++ .../quickstep/TouchInteractionService.java | 36 +++++++------- .../OverviewWithoutFocusInputConsumer.java | 11 ++--- .../quickstep/util/AssistantUtilities.java | 47 +++++++++++++++++++ .../android/launcher3/config/BaseFlags.java | 4 ++ .../launcher3/views/BaseDragLayer.java | 4 +- 7 files changed, 86 insertions(+), 30 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/AssistantUtilities.java diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 738436a757..ef50c7b5d4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -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.BaseFlags; 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 (BaseFlags.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(); diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java index 379f41c531..14216ffdfe 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java @@ -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; import com.android.quickstep.SysUINavigationMode.Mode; 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.getOverviewPanel().getTaskViewAt(0); + ActivityManagerWrapper.getInstance() + .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 729287c823..f32182600a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -42,7 +42,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.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -74,6 +73,7 @@ import com.android.launcher3.R; import com.android.launcher3.ResourceUtils; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.config.BaseFlags; import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; @@ -92,6 +92,7 @@ import com.android.quickstep.inputconsumers.OverviewInputConsumer; import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer; import com.android.quickstep.inputconsumers.ResetGestureInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; +import com.android.quickstep.util.AssistantUtilities; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -102,7 +103,6 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; import com.android.systemui.shared.system.RecentsAnimationListener; import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; -import com.android.systemui.shared.system.TaskInfoCompat; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -649,16 +649,14 @@ public class TouchInteractionService extends Service implements mOverviewComponentObserver.getActivityControlHelper(); boolean forceOverviewInputConsumer = false; - if (isExcludedAssistant(runningTaskInfo)) { + if (AssistantUtilities.isExcludedAssistant(runningTaskInfo)) { // In the case where we are in the excluded assistant state, ignore it and treat the // running activity as the task behind the assistant - runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT); - if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) { - final ComponentName homeComponent = - mOverviewComponentObserver.getHomeIntent().getComponent(); - forceOverviewInputConsumer = - runningTaskInfo.baseIntent.getComponent(). equals(homeComponent); - } + runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT /* ignoreActivityType */); + ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); + ComponentName runningComponent = runningTaskInfo.baseIntent.getComponent(); + forceOverviewInputConsumer = + runningComponent != null && runningComponent.equals(homeComponent); } if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher @@ -672,9 +670,9 @@ public class TouchInteractionService extends Service implements return createOtherActivityInputConsumer(event, info); } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed() || forceOverviewInputConsumer) { - return createOverviewInputConsumer(event); + return createOverviewInputConsumer(event, forceOverviewInputConsumer); } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) { - return createOverviewInputConsumer(event); + return createOverviewInputConsumer(event, forceOverviewInputConsumer); } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { return mResetGestureInputConsumer; @@ -683,12 +681,6 @@ public class TouchInteractionService extends Service implements } } - 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 boolean disableHorizontalSwipe(MotionEvent event) { // mExclusionRegion can change on binder thread, use a local instance here. Region exclusionRegion = mExclusionRegion; @@ -726,7 +718,8 @@ public class TouchInteractionService extends Service implements } } - public InputConsumer createOverviewInputConsumer(MotionEvent event) { + public InputConsumer createOverviewInputConsumer(MotionEvent event, + boolean forceOverviewInputConsumer) { final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); BaseDraggingActivity activity = activityControl.getCreatedActivity(); @@ -734,7 +727,10 @@ public class TouchInteractionService extends Service implements return mResetGestureInputConsumer; } - if (activity.getRootView().hasWindowFocus() || sSwipeSharedState.goingToLauncher) { + if (activity.getRootView().hasWindowFocus() + || sSwipeSharedState.goingToLauncher + || (BaseFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get() + && forceOverviewInputConsumer)) { return new OverviewInputConsumer(activity, mInputMonitorCompat, false /* startingInActivityBounds */); } else { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java index 05cbb789d9..f40d55263b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java @@ -22,9 +22,9 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Utilities.squaredHypot; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; -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; @@ -34,12 +34,9 @@ import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogUtils; -import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; -import com.android.quickstep.OverviewCallbacks; import com.android.quickstep.util.NavBarPosition; -import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; public class OverviewWithoutFocusInputConsumer implements InputConsumer { @@ -148,9 +145,9 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer { } if (triggerQuickstep) { - OverviewCallbacks.get(mContext).closeAllWindows(); - 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)); TOUCH_INTERACTION_LOG.addLog("startQuickstep"); BaseActivity activity = BaseDraggingActivity.fromContext(mContext); int pageIndex = -1; // This number doesn't reflect workspace page index. diff --git a/quickstep/src/com/android/quickstep/util/AssistantUtilities.java b/quickstep/src/com/android/quickstep/util/AssistantUtilities.java new file mode 100644 index 0000000000..552db1f4dd --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/AssistantUtilities.java @@ -0,0 +1,47 @@ +/* + * 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() {} +} diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 7c8fe16dfc..99a3604cb0 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -115,6 +115,10 @@ public abstract class BaseFlags { public static final TogglableFlag ENABLE_PREDICTION_DISMISS = new TogglableFlag( "ENABLE_PREDICTION_DISMISS", false, "Allow option to dimiss apps from predicted list"); + public static final TogglableFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = new TogglableFlag( + "ASSISTANT_GIVES_LAUNCHER_FOCUS", false, + "Allow Launcher to handle nav bar gestures while Assistant is running over it"); + public static void initialize(Context context) { // Avoid the disk read for user builds diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 2a4c5a7bfe..e43fc8a01c 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -170,10 +170,8 @@ public abstract class BaseDragLayer // Only look for controllers if we are not dispatching from gesture area and proxy is // not active mActiveController = findControllerToHandleTouch(ev); - - if (mActiveController != null) return true; } - return false; + return mActiveController != null; } @Override