From d057a2a636104ee734dc16db325a27861cd5c0fa Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 9 May 2024 15:05:57 -0700 Subject: [PATCH] Crop based on real-time insets This crops above taskbar unless app is immersive Bug: 336511494 Test: Enable pinned taskbar, launch app, note correct bounds Flag: com.android.wm.shell.enable_dynamic_insets_for_app_launch Change-Id: Ie8124ae18176d167986f9861876d426ec2c6097f --- .../launcher3/QuickstepTransitionManager.java | 66 ++++++++++++++++--- .../android/quickstep/HomeVisibilityState.kt | 10 +++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index aae8a56593..24faa393ed 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -66,6 +66,7 @@ import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback; import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary; import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius; import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows; +import static com.android.wm.shell.Flags.enableDynamicInsetsForAppLaunch; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -279,6 +280,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private final Interpolator mOpeningXInterpolator; private final Interpolator mOpeningInterpolator; + private final SystemUiProxy mSystemUiProxy; + public QuickstepTransitionManager(Context context) { mLauncher = Launcher.cast(Launcher.getLauncher(context)); mDragLayer = mLauncher.getDragLayer(); @@ -293,6 +296,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mMaxShadowRadius = res.getDimensionPixelSize(R.dimen.max_shadow_radius); mLauncher.addOnDeviceProfileChangeListener(this); + mSystemUiProxy = SystemUiProxy.INSTANCE.get(mLauncher); if (ENABLE_SHELL_STARTING_SURFACE) { mTaskStartParams = new LinkedHashMap<>(MAX_NUM_TASKS) { @@ -302,8 +306,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } }; - SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener( - mStartingWindowListener); + mSystemUiProxy.setStartingWindowListener(mStartingWindowListener); } mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x); @@ -504,12 +507,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener 4 - rotationChange); } } - if (mDeviceProfile.isTaskbarPresentInApps - && !target.willShowImeOnTarget - && !isTransientTaskbar(mLauncher)) { - // Animate to above the taskbar. - bounds.bottom -= target.contentInsets.bottom; - } return bounds; } @@ -676,6 +673,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener }; } + private boolean shouldCropToInset(RemoteAnimationTarget target) { + return enableDynamicInsetsForAppLaunch() + && mDeviceProfile.isTaskbarPresentInApps + && target != null && !target.willShowImeOnTarget + && !isTransientTaskbar(mLauncher); + } + /** * @return Animator that controls the window of the opening targets from app icons. */ @@ -684,8 +688,19 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener RemoteAnimationTarget[] wallpaperTargets, RemoteAnimationTarget[] nonAppTargets, boolean launcherClosing) { + RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets, + wallpaperTargets, nonAppTargets, MODE_OPENING); int rotationChange = getRotationChange(appTargets); Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange); + final int[] bottomInsetPos = new int[]{ + mSystemUiProxy.getHomeVisibilityState().getNavbarInsetPosition()}; + final RemoteAnimationTarget target = openingTargets.getFirstAppTarget(); + final boolean cropToInset = shouldCropToInset(target); + if (cropToInset) { + // Animate to above the taskbar. + windowTargetBounds.bottom = Math.min(bottomInsetPos[0], + windowTargetBounds.bottom); + } boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets); RectF launcherIconBounds = new RectF(); @@ -698,8 +713,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener Rect crop = new Rect(); Matrix matrix = new Matrix(); - RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets, - wallpaperTargets, nonAppTargets, MODE_OPENING); SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView); openingTargets.addReleaseCheck(surfaceApplier); @@ -805,6 +818,39 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onUpdate(float percent, boolean initOnly) { + if (cropToInset && bottomInsetPos[0] != mSystemUiProxy.getHomeVisibilityState() + .getNavbarInsetPosition()) { + final RemoteAnimationTarget target = openingTargets.getFirstAppTarget(); + bottomInsetPos[0] = mSystemUiProxy.getHomeVisibilityState() + .getNavbarInsetPosition(); + final Rect bounds = target != null + ? target.screenSpaceBounds : windowTargetBounds; + // Animate to above the taskbar. + int bottomLevel = Math.min(bottomInsetPos[0], bounds.bottom); + windowTargetBounds.bottom = bottomLevel; + final int endHeight = bottomLevel - bounds.top; + + AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), + mDeviceProfile, windowTargetBounds, launcherIconBounds, v, + dragLayerBounds[0], dragLayerBounds[1], hasSplashScreen, + floatingView.isDifferentFromAppIcon()); + mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd, + mOpeningInterpolator); + mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, + mOpeningInterpolator); + mDy = new FloatProp(0, prop.dY, mOpeningInterpolator); + mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale, + prop.finalAppIconScale, mOpeningInterpolator); + float interpolatedPercent = mOpeningInterpolator.getInterpolation(percent); + mCropRectHeight.value = Utilities.mapRange(interpolatedPercent, + prop.cropHeightStart, prop.cropHeightEnd); + mCropRectCenterY.value = Utilities.mapRange(interpolatedPercent, + prop.cropCenterYStart, prop.cropCenterYEnd); + mDy.value = Utilities.mapRange(interpolatedPercent, 0, prop.dY); + mIconScaleToFitScreen.value = Utilities.mapRange(interpolatedPercent, + prop.initialAppIconScale, prop.finalAppIconScale); + } + // Calculate the size of the scaled icon. float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value; float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value; diff --git a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt index 1345e0b344..020b9e2fab 100644 --- a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt +++ b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt @@ -18,6 +18,9 @@ package com.android.quickstep import android.os.RemoteException import android.util.Log +import android.view.InsetsState +import android.view.WindowInsets + import com.android.launcher3.Utilities import com.android.launcher3.config.FeatureFlags import com.android.launcher3.util.Executors @@ -30,6 +33,8 @@ class HomeVisibilityState { var isHomeVisible = true private set + @Volatile var navbarInsetPosition = 0 + private var listeners = mutableSetOf() fun addListener(l: VisibilityChangeListener) = listeners.add(l) @@ -50,6 +55,11 @@ class HomeVisibilityState { }, ) } + override fun onDisplayInsetsChanged(insetsState: InsetsState) { + val bottomInset = insetsState.calculateInsets(insetsState.displayFrame, + WindowInsets.Type.navigationBars(), false).bottom + navbarInsetPosition = insetsState.displayFrame.bottom - bottomInset + } } ) } catch (e: RemoteException) {