diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 43cdbdb1e9..4e73a79076 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -18,6 +18,8 @@ package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; +import static com.android.quickstep.util.NavBarPosition.ROTATION_LANDSCAPE; +import static com.android.quickstep.util.NavBarPosition.ROTATION_SEASCAPE; import android.content.Context; import android.content.res.Configuration; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index c94c6d5699..4f50e33b00 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -15,7 +15,6 @@ */ package com.android.quickstep; -import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -32,8 +31,6 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; @@ -51,7 +48,6 @@ import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.util.VibratorWrapper; import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.BaseActivityInterface.HomeAnimationFactory; -import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AppWindowAnimationHelper; @@ -92,9 +88,8 @@ public abstract class BaseSwipeUpHandler mActivityInterface; - protected final RecentsModel mRecentsModel; + protected final InputConsumerController mInputConsumer; protected final AppWindowAnimationHelper mAppWindowAnimationHelper; protected final TransformParams mTransformParams = new TransformParams(); @@ -106,7 +101,6 @@ public abstract class BaseSwipeUpHandler mAM.getRunningTask(0))); @@ -607,7 +604,7 @@ public class TouchInteractionService extends Service implements PluginListener public WindowTransformSwipeHandler(Context context, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, - long touchTimeMs, OverviewComponentObserver overviewComponentObserver, - boolean continuingLastGesture, InputConsumerController inputConsumer, - RecentsModel recentsModel) { - super(context, deviceState, gestureState, overviewComponentObserver, recentsModel, - inputConsumer); + long touchTimeMs, boolean continuingLastGesture, + InputConsumerController inputConsumer) { + super(context, deviceState, gestureState, inputConsumer); mTaskAnimationManager = taskAnimationManager; mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; @@ -379,7 +377,7 @@ public class WindowTransformSwipeHandler private void onDeferredActivityLaunch() { if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mOverviewComponentObserver.getActivityInterface().switchRunningTaskViewToScreenshot( + mActivityInterface.switchRunningTaskViewToScreenshot( null, () -> { mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); }); @@ -521,7 +519,7 @@ public class WindowTransformSwipeHandler @Override public Intent getLaunchIntent() { - return mOverviewComponentObserver.getOverviewIntent(); + return mGestureState.getOverviewIntent(); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index 5ffb975923..b6cd45679b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -46,11 +46,9 @@ import com.android.quickstep.GestureState; import com.android.quickstep.GestureState.GestureEndTarget; import com.android.quickstep.InputConsumer; import com.android.quickstep.MultiStateCallback; -import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.RecentsActivity; import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationDeviceState; -import com.android.quickstep.RecentsModel; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.RecentsAnimationTargets; @@ -111,11 +109,9 @@ public class FallbackNoButtonInputConsumer extends private RunningWindowAnim mFinishAnimation; public FallbackNoButtonInputConsumer(Context context, RecentsAnimationDeviceState deviceState, - GestureState gestureState, OverviewComponentObserver overviewComponentObserver, - RecentsModel recentsModel, InputConsumerController inputConsumer, + GestureState gestureState, InputConsumerController inputConsumer, boolean isLikelyToStartNewTask, boolean continuingLastGesture) { - super(context, deviceState, gestureState, overviewComponentObserver, recentsModel, - inputConsumer); + super(context, deviceState, gestureState, inputConsumer); mLauncherAlpha.value = 1; mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture; @@ -225,9 +221,9 @@ public class FallbackNoButtonInputConsumer extends @Override public Intent getLaunchIntent() { if (mInQuickSwitchMode || mSwipeUpOverHome) { - return mOverviewComponentObserver.getOverviewIntent(); + return mGestureState.getOverviewIntent(); } else { - return mOverviewComponentObserver.getHomeIntent(); + return mGestureState.getHomeIntent(); } } @@ -324,7 +320,7 @@ public class FallbackNoButtonInputConsumer extends if (mSwipeUpOverHome) { mRecentsAnimationController.finish(false, null, false); // Send a home intent to clear the task stack - mContext.startActivity(mOverviewComponentObserver.getHomeIntent()); + mContext.startActivity(mGestureState.getHomeIntent()); } else { mRecentsAnimationController.finish(true, null, true); } @@ -351,7 +347,7 @@ public class FallbackNoButtonInputConsumer extends extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail)); extras.putInt(EXTRA_TASK_ID, runningTaskId); - Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent()) + Intent intent = new Intent(mGestureState.getOverviewIntent()) .putExtras(extras); mContext.startActivity(intent, options.toBundle()); mRecentsAnimationController.cleanupScreenshot(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index f8676ec706..bf2128dd11 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -57,7 +57,6 @@ import com.android.quickstep.TaskAnimationManager; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; -import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; @@ -85,8 +84,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final BaseSwipeUpHandler.Factory mHandlerFactory; - private final NavBarPosition mNavBarPosition; - private final Consumer mOnCompleteCallback; private final MotionPauseDetector mMotionPauseDetector; private final float mMotionPauseMinDisplacement; @@ -142,8 +139,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning(); mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; - - mNavBarPosition = new NavBarPosition(base); mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop(); float slop = QUICKSTEP_TOUCH_SLOP_RATIO * mTouchSlop; @@ -175,7 +170,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mPassedWindowMoveSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( - mNavBarPosition.getRotationMode())); + mDeviceState.getNavBarPosition().getRotationMode())); } int edgeFlags = ev.getEdgeFlags(); ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR); @@ -356,8 +351,10 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC ViewConfiguration.get(this).getScaledMaximumFlingVelocity()); float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = mNavBarPosition.isRightEdge() ? velocityX - : mNavBarPosition.isLeftEdge() ? -velocityX + float velocity = mDeviceState.getNavBarPosition().isRightEdge() + ? velocityX + : mDeviceState.getNavBarPosition().isLeftEdge() + ? -velocityX : velocityY; mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement); @@ -410,9 +407,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } private float getDisplacement(MotionEvent ev) { - if (mNavBarPosition.isRightEdge()) { + if (mDeviceState.getNavBarPosition().isRightEdge()) { return ev.getX() - mDownPos.x; - } else if (mNavBarPosition.isLeftEdge()) { + } else if (mDeviceState.getNavBarPosition().isLeftEdge()) { return mDownPos.x - ev.getX(); } else { return ev.getY() - mDownPos.y; 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 50069ea05c..d700a37414 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 @@ -35,36 +35,35 @@ 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.BaseActivityInterface; import com.android.quickstep.InputConsumer; import com.android.quickstep.GestureState; +import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.util.ActiveGestureLog; -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 { + private final Context mContext; + private final RecentsAnimationDeviceState mDeviceState; + private final GestureState mGestureState; private final InputMonitorCompat mInputMonitor; private final boolean mDisableHorizontalSwipe; private final PointF mDownPos = new PointF(); private final float mSquaredTouchSlop; - private final Context mContext; - private final NavBarPosition mNavBarPosition; - private final BaseActivityInterface mActivityInterface; private boolean mInterceptedTouch; private VelocityTracker mVelocityTracker; - public OverviewWithoutFocusInputConsumer(Context context, GestureState gestureState, + public OverviewWithoutFocusInputConsumer(Context context, + RecentsAnimationDeviceState deviceState, GestureState gestureState, InputMonitorCompat inputMonitor, boolean disableHorizontalSwipe) { + mContext = context; + mDeviceState = deviceState; + mGestureState = gestureState; mInputMonitor = inputMonitor; mDisableHorizontalSwipe = disableHorizontalSwipe; - mContext = context; - mActivityInterface = gestureState.getActivityInterface(); mSquaredTouchSlop = Utilities.squaredTouchSlop(context); - mNavBarPosition = new NavBarPosition(context); - mVelocityTracker = VelocityTracker.obtain(); } @@ -135,8 +134,11 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer { mVelocityTracker.computeCurrentVelocity(100); float velocityX = mVelocityTracker.getXVelocity(); float velocityY = mVelocityTracker.getYVelocity(); - float velocity = mNavBarPosition.isRightEdge() - ? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY); + float velocity = mDeviceState.getNavBarPosition().isRightEdge() + ? -velocityX + : mDeviceState.getNavBarPosition().isLeftEdge() + ? velocityX + : -velocityY; final boolean triggerQuickstep; int touch = Touch.FLING; @@ -150,7 +152,7 @@ public class OverviewWithoutFocusInputConsumer implements InputConsumer { } if (triggerQuickstep) { - mActivityInterface.closeOverlay(); + mGestureState.getActivityInterface().closeOverlay(); ActivityManagerWrapper.getInstance() .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); ActiveGestureLog.INSTANCE.addLog("startQuickstep"); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java deleted file mode 100644 index e2524b1e8f..0000000000 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.launcher3.uioverrides.QuickstepLauncher.ROTATION_LANDSCAPE; -import static com.android.launcher3.uioverrides.QuickstepLauncher.ROTATION_SEASCAPE; -import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; - -import android.content.Context; -import android.view.Surface; - -import com.android.launcher3.graphics.RotationMode; -import com.android.launcher3.util.DefaultDisplay; -import com.android.quickstep.SysUINavigationMode; - -/** - * Utility class to check nav bar position - */ -public class NavBarPosition { - - private final SysUINavigationMode.Mode mMode; - private final int mDisplayRotation; - - public NavBarPosition(Context context) { - mMode = SysUINavigationMode.getMode(context); - mDisplayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation; - } - - public boolean isRightEdge() { - return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90; - } - - public boolean isLeftEdge() { - return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270; - } - - public RotationMode getRotationMode() { - return isLeftEdge() ? ROTATION_SEASCAPE - : (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL); - } -} diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 28ed32ce6a..ae0886b913 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -18,7 +18,9 @@ package com.android.quickstep; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import android.app.ActivityManager; +import android.content.Intent; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.systemui.shared.recents.model.ThumbnailData; import java.util.ArrayList; @@ -57,6 +59,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL public final boolean recentsAttachedToAppWindow; } + private static final String TAG = "GestureState"; + private static final ArrayList STATE_NAMES = new ArrayList<>(); private static int FLAG_COUNT = 0; private static int getFlagForIndex(String name) { @@ -99,6 +103,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL // Needed to interact with the current activity + private final Intent mHomeIntent; + private final Intent mOverviewIntent; private final BaseActivityInterface mActivityInterface; private final MultiStateCallback mStateCallback; private final int mGestureId; @@ -108,19 +114,30 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL // TODO: This can be removed once we stop finishing the animation when starting a new task private int mFinishingRecentsAnimationTaskId = -1; - public GestureState(BaseActivityInterface activityInterface, int gestureId) { - mActivityInterface = activityInterface; + public GestureState(OverviewComponentObserver componentObserver, int gestureId) { + mHomeIntent = componentObserver.getHomeIntent(); + mOverviewIntent = componentObserver.getOverviewIntent(); + mActivityInterface = componentObserver.getActivityInterface(); mStateCallback = new MultiStateCallback(STATE_NAMES.toArray(new String[0])); mGestureId = gestureId; } public GestureState() { // Do nothing, only used for initializing the gesture state prior to user unlock + mHomeIntent = new Intent(); + mOverviewIntent = new Intent(); mActivityInterface = null; mStateCallback = new MultiStateCallback(STATE_NAMES.toArray(new String[0])); mGestureId = -1; } + /** + * @return whether the gesture state has the provided {@param stateMask} flags set. + */ + public boolean hasState(int stateMask) { + return mStateCallback.hasStates(stateMask); + } + /** * Sets the given {@param stateFlag}s. */ @@ -135,6 +152,20 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL mStateCallback.runOnceAtState(stateMask, callback); } + /** + * @return the intent for the Home component. + */ + public Intent getHomeIntent() { + return mHomeIntent; + } + + /** + * @return the intent for the Overview component. + */ + public Intent getOverviewIntent() { + return mOverviewIntent; + } + /** * @return the interface to the activity handing the UI updates for this gesture. */ diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index 9d5120d90d..333e179b19 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -48,11 +48,10 @@ public class RecentsAnimationController { private final Consumer mOnFinishedListener; private final boolean mShouldMinimizeSplitScreen; - private boolean mWindowThresholdCrossed = false; - private InputConsumerController mInputConsumerController; private Supplier mInputProxySupplier; private InputConsumer mInputConsumer; + private boolean mWindowThresholdCrossed = false; private boolean mTouchInProgress; private boolean mFinishPending; @@ -62,8 +61,6 @@ public class RecentsAnimationController { mController = controller; mOnFinishedListener = onFinishedListener; mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen; - - setWindowThresholdCrossed(mWindowThresholdCrossed); } /** diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 1855e64d89..81f411e4e6 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -17,8 +17,10 @@ package com.android.quickstep; import static android.content.Intent.ACTION_USER_UNLOCKED; +import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED; import static com.android.launcher3.ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE; import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS; import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS; @@ -35,14 +37,17 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_S import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Point; import android.graphics.RectF; import android.graphics.Region; import android.os.Process; +import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.MotionEvent; @@ -57,6 +62,7 @@ import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.DefaultDisplay; import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener; +import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; @@ -72,16 +78,17 @@ public class RecentsAnimationDeviceState implements NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener { - private Context mContext; - private UserManagerCompat mUserManager; - private SysUINavigationMode mSysUiNavMode; - private DefaultDisplay mDefaultDisplay; - private int mDisplayId; + private final Context mContext; + private final UserManagerCompat mUserManager; + private final SysUINavigationMode mSysUiNavMode; + private final DefaultDisplay mDefaultDisplay; + private final int mDisplayId; private final ArrayList mOnDestroyActions = new ArrayList<>(); private @SystemUiStateFlags int mSystemUiStateFlags; private SysUINavigationMode.Mode mMode = THREE_BUTTONS; + private NavBarPosition mNavBarPosition; private final RectF mSwipeUpTouchRegion = new RectF(); private final Region mDeferredGestureRegion = new Region(); @@ -108,11 +115,13 @@ public class RecentsAnimationDeviceState implements private ComponentName mGestureBlockedActivity; public RecentsAnimationDeviceState(Context context) { + final ContentResolver resolver = context.getContentResolver(); mContext = context; mUserManager = UserManagerCompat.getInstance(context); mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context); mDefaultDisplay = DefaultDisplay.INSTANCE.get(context); mDisplayId = mDefaultDisplay.getInfo().id; + runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this)); // Register for user unlocked if necessary mIsUserUnlocked = mUserManager.isUserUnlocked(Process.myUserHandle()); @@ -155,7 +164,6 @@ public class RecentsAnimationDeviceState implements for (Runnable r : mOnDestroyActions) { r.run(); } - mDefaultDisplay.removeChangeListener(this); } /** @@ -183,6 +191,7 @@ public class RecentsAnimationDeviceState implements mExclusionListener.unregister(); } mMode = newMode; + mNavBarPosition = new NavBarPosition(mMode, mDefaultDisplay.getInfo()); } @Override @@ -191,6 +200,7 @@ public class RecentsAnimationDeviceState implements return; } + mNavBarPosition = new NavBarPosition(mMode, info); updateGestureTouchRegions(); } @@ -201,6 +211,13 @@ public class RecentsAnimationDeviceState implements return mMode; } + /** + * @return the nav bar position for the current nav bar mode and display rotation. + */ + public NavBarPosition getNavBarPosition() { + return mNavBarPosition; + } + /** * @return whether the current nav mode is fully gestural. */ diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java new file mode 100644 index 0000000000..a4614dec7f --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java @@ -0,0 +1,127 @@ +/* + * 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.quickstep.SysUINavigationMode.Mode.NO_BUTTON; + +import android.content.Context; +import android.graphics.Rect; +import android.view.Gravity; +import android.view.Surface; + +import com.android.launcher3.graphics.RotationMode; +import com.android.launcher3.util.DefaultDisplay; +import com.android.quickstep.SysUINavigationMode; + +/** + * Utility class to check nav bar position. + */ +public class NavBarPosition { + + public static RotationMode ROTATION_LANDSCAPE = new RotationMode(-90) { + @Override + public void mapRect(int left, int top, int right, int bottom, Rect out) { + out.left = top; + out.top = right; + out.right = bottom; + out.bottom = left; + } + + @Override + public void mapInsets(Context context, Rect insets, Rect out) { + // If there is a display cutout, the top insets in portrait would also include the + // cutout, which we will get as the left inset in landscape. Using the max of left and + // top allows us to cover both cases (with or without cutout). + if (SysUINavigationMode.getMode(context) == NO_BUTTON) { + out.top = Math.max(insets.top, insets.left); + out.bottom = Math.max(insets.right, insets.bottom); + out.left = out.right = 0; + } else { + out.top = Math.max(insets.top, insets.left); + out.bottom = insets.right; + out.left = insets.bottom; + out.right = 0; + } + } + }; + + public static RotationMode ROTATION_SEASCAPE = new RotationMode(90) { + @Override + public void mapRect(int left, int top, int right, int bottom, Rect out) { + out.left = bottom; + out.top = left; + out.right = top; + out.bottom = right; + } + + @Override + public void mapInsets(Context context, Rect insets, Rect out) { + if (SysUINavigationMode.getMode(context) == NO_BUTTON) { + out.top = Math.max(insets.top, insets.right); + out.bottom = Math.max(insets.left, insets.bottom); + out.left = out.right = 0; + } else { + out.top = Math.max(insets.top, insets.right); + out.bottom = insets.left; + out.right = insets.bottom; + out.left = 0; + } + } + + @Override + public int toNaturalGravity(int absoluteGravity) { + int horizontalGravity = absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK; + int verticalGravity = absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK; + + if (horizontalGravity == Gravity.RIGHT) { + horizontalGravity = Gravity.LEFT; + } else if (horizontalGravity == Gravity.LEFT) { + horizontalGravity = Gravity.RIGHT; + } + + if (verticalGravity == Gravity.TOP) { + verticalGravity = Gravity.BOTTOM; + } else if (verticalGravity == Gravity.BOTTOM) { + verticalGravity = Gravity.TOP; + } + + return ((absoluteGravity & ~Gravity.HORIZONTAL_GRAVITY_MASK) + & ~Gravity.VERTICAL_GRAVITY_MASK) + | horizontalGravity | verticalGravity; + } + }; + + private final SysUINavigationMode.Mode mMode; + private final int mDisplayRotation; + + public NavBarPosition(SysUINavigationMode.Mode mode, DefaultDisplay.Info info) { + mMode = mode; + mDisplayRotation = info.rotation; + } + + public boolean isRightEdge() { + return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90; + } + + public boolean isLeftEdge() { + return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270; + } + + public RotationMode getRotationMode() { + return isLeftEdge() ? ROTATION_SEASCAPE + : (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL); + } +}