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
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index aae8a56..24faa39 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.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 @@
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 @@
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 @@
}
};
- SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
- mStartingWindowListener);
+ mSystemUiProxy.setStartingWindowListener(mStartingWindowListener);
}
mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
@@ -504,12 +507,6 @@
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 @@
};
}
+ 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 @@
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 @@
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 @@
@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 1345e0b..020b9e2 100644
--- a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
+++ b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
@@ -18,6 +18,9 @@
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 @@
var isHomeVisible = true
private set
+ @Volatile var navbarInsetPosition = 0
+
private var listeners = mutableSetOf<VisibilityChangeListener>()
fun addListener(l: VisibilityChangeListener) = listeners.add(l)
@@ -50,6 +55,11 @@
},
)
}
+ override fun onDisplayInsetsChanged(insetsState: InsetsState) {
+ val bottomInset = insetsState.calculateInsets(insetsState.displayFrame,
+ WindowInsets.Type.navigationBars(), false).bottom
+ navbarInsetPosition = insetsState.displayFrame.bottom - bottomInset
+ }
}
)
} catch (e: RemoteException) {