From 20eb0e3f67d649dcdc9ce6a6b135089fb874691f Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Thu, 9 Jun 2022 17:40:07 +0000 Subject: [PATCH] Replace shelf height with keep clear areas registration in Launcher. This affects Hotseat only for now. Taskbar will be occluded when unstashed. When in gesture nav and with auto-enter pip, we need to pre-register the Hotseat keep clear areas, as otherwise the event appears after the animator is started and current logic doesn't allow to update those destination bounds in the animator. Test: manually, existing tests pass Bug: 183746978 Change-Id: I4d97ca77225d3502acac1fb6b5e3eff3e81285ed --- .../uioverrides/QuickstepLauncher.java | 26 +++++++++------ .../android/quickstep/AbsSwipeUpHandler.java | 33 ++++++++++++++++++- .../com/android/quickstep/SystemUiProxy.java | 6 ++-- res/layout/hotseat.xml | 1 + 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 0f3ea15b80..c9bc260a21 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -64,6 +64,7 @@ import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; import android.os.CancellationSignal; import android.os.IBinder; +import android.os.SystemProperties; import android.view.Display; import android.view.HapticFeedbackConstants; import android.view.View; @@ -159,6 +160,9 @@ import java.util.stream.Stream; public class QuickstepLauncher extends Launcher { + public static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM = + SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false); + public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false; /** * Reusable command for applying the shelf height on the background thread. @@ -349,16 +353,18 @@ public class QuickstepLauncher extends Launcher { */ private void onStateOrResumeChanging(boolean inTransition) { LauncherState state = getStateManager().getState(); - boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0; - if (started) { - DeviceProfile profile = getDeviceProfile(); - boolean willUserBeActive = - (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0; - boolean visible = (state == NORMAL || state == OVERVIEW) - && (willUserBeActive || isUserActive()) - && !profile.isVerticalBarLayout(); - UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0, - profile.hotseatBarSizePx); + if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) { + boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0; + if (started) { + DeviceProfile profile = getDeviceProfile(); + boolean willUserBeActive = + (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0; + boolean visible = (state == NORMAL || state == OVERVIEW) + && (willUserBeActive || isUserActive()) + && !profile.isVerticalBarLayout(); + UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0, + profile.hotseatBarSizePx); + } } if (state == NORMAL && !inTransition) { ((RecentsView) getOverviewPanel()).setSwipeDownShouldLaunchApp(false); diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 8dee10aa53..7592237b86 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -33,6 +33,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT; +import static com.android.launcher3.uioverrides.QuickstepLauncher.ENABLE_PIP_KEEP_CLEAR_ALGORITHM; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; @@ -1420,12 +1421,13 @@ public abstract class AbsSwipeUpHandler, homeToWindowPositionMap.invert(windowToHomePositionMap); windowToHomePositionMap.mapRect(startRect); + final Rect hotseatKeepClearArea = getKeepClearAreaForHotseat(); final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext) .startSwipePipToHome(taskInfo.topActivity, taskInfo.topActivityInfo, runningTaskTarget.taskInfo.pictureInPictureParams, homeRotation, - mDp.hotseatBarSizePx); + hotseatKeepClearArea); final Rect appBounds = new Rect(); final WindowConfiguration winConfig = taskInfo.configuration.windowConfiguration; // Adjust the appBounds for TaskBar by using the calculated window crop Rect @@ -1488,6 +1490,35 @@ public abstract class AbsSwipeUpHandler, return swipePipToHomeAnimator; } + private Rect getKeepClearAreaForHotseat() { + Rect keepClearArea; + if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) { + // make the height equal to hotseatBarSizePx only + keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, 0); + return keepClearArea; + } + // the keep clear area in global screen coordinates, in pixels + if (mDp.isPhone) { + if (mDp.isSeascape()) { + // in seascape the Hotseat is on the left edge of the screen + keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, mDp.heightPx); + } else if (mDp.isLandscape) { + // in landscape the Hotseat is on the right edge of the screen + keepClearArea = new Rect(mDp.widthPx - mDp.hotseatBarSizePx, 0, + mDp.widthPx, mDp.heightPx); + } else { + // in portrait mode the Hotseat is at the bottom of the screen + keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx, + mDp.widthPx, mDp.heightPx); + } + } else { + // large screens have Hotseat always at the bottom of the screen + keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx, + mDp.widthPx, mDp.heightPx); + } + return keepClearArea; + } + private void startInterceptingTouchesForGesture() { if (mRecentsAnimationController == null) { return; diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 0ec7e628b5..f1d15aa3e6 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -28,7 +28,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Rect; import android.os.Bundle; @@ -509,11 +508,12 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI } public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, - PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) { + PictureInPictureParams pictureInPictureParams, int launcherRotation, + Rect hotseatKeepClearArea) { if (mPip != null) { try { return mPip.startSwipePipToHome(componentName, activityInfo, - pictureInPictureParams, launcherRotation, shelfHeight); + pictureInPictureParams, launcherRotation, hotseatKeepClearArea); } catch (RemoteException e) { Log.w(TAG, "Failed call startSwipePipToHome", e); } diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml index 82b0b8d74e..95ebd94d0e 100644 --- a/res/layout/hotseat.xml +++ b/res/layout/hotseat.xml @@ -21,4 +21,5 @@ android:layout_height="match_parent" android:theme="@style/HomeScreenElementTheme" android:importantForAccessibility="no" + android:preferKeepClear="true" launcher:containerType="hotseat" /> \ No newline at end of file