Merge "Tune springs when app animates home into the hotseat on devices with a taskbar." into tm-qpr-dev

This commit is contained in:
Jon Miranda
2023-03-20 20:54:27 +00:00
committed by Android (Google) Code Review
8 changed files with 161 additions and 35 deletions

View File

@@ -136,6 +136,8 @@ import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.util.SurfaceTransaction;
@@ -1342,6 +1344,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
// Get floating view and target rect.
boolean isInHotseat = false;
if (launcherView instanceof LauncherAppWidgetHostView) {
Size windowSize = new Size(mDeviceProfile.availableWidthPx,
mDeviceProfile.availableHeightPx);
@@ -1357,12 +1360,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
? null
: mLauncher.getTaskbarUIController().findMatchingView(launcherView),
true /* hideOriginal */, targetRect, false /* isOpening */);
isInHotseat = launcherView.getTag() instanceof ItemInfo
&& ((ItemInfo) launcherView.getTag()).isInHotseat();
} else {
targetRect.set(getDefaultWindowTargetRect());
}
RectFSpringAnim anim = new RectFSpringAnim(closingWindowStartRect, targetRect, mLauncher,
mDeviceProfile);
boolean useTaskbarHotseatParams = mDeviceProfile.isTaskbarPresent && isInHotseat;
RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRect, targetRect)
: new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRect,
targetRect));
// Hook up floating views to the closing window animators.
final int rotationChange = getRotationChange(targets);

View File

@@ -38,6 +38,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ObjectWrapper;
@@ -122,6 +123,12 @@ public class LauncherSwipeHandlerV2 extends
return workspaceView;
}
@Override
public boolean isInHotseat() {
return workspaceView.getTag() instanceof ItemInfo
&& ((ItemInfo) workspaceView.getTag()).isInHotseat();
}
@NonNull
@Override
public RectF getWindowTargetRect() {

View File

@@ -39,6 +39,8 @@ import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
@@ -157,6 +159,13 @@ public abstract class SwipeUpAnimationLogic implements
protected abstract class HomeAnimationFactory {
protected float mSwipeVelocity;
/**
* Returns true if we know the home animation involves an item in the hotseat.
*/
public boolean isInHotseat() {
return false;
}
public @NonNull RectF getWindowTargetRect() {
PagedOrientationHandler orientationHandler = getOrientationHandler();
DeviceProfile dp = mDp;
@@ -288,7 +297,11 @@ public abstract class SwipeUpAnimationLogic implements
homeToWindowPositionMap.invert(windowToHomePositionMap);
windowToHomePositionMap.mapRect(startRect);
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext, mDp);
boolean useTaskbarHotseatParams = mDp.isTaskbarPresent
&& homeAnimationFactory.isInHotseat();
RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
? new TaskbarHotseatSpringConfig(mContext, startRect, targetRect)
: new DefaultSpringConfig(mContext, mDp, startRect, targetRect));
homeAnimationFactory.setAnimation(anim);
SpringAnimationRunner runner = new SpringAnimationRunner(

View File

@@ -128,37 +128,27 @@ public class RectFSpringAnim extends ReleaseCheck {
@Tracking
public final int mTracking;
protected final float mStiffnessX;
protected final float mStiffnessY;
protected final float mDampingX;
protected final float mDampingY;
protected final float mRectStiffness;
public RectFSpringAnim(RectF startRect, RectF targetRect, Context context,
@Nullable DeviceProfile deviceProfile) {
mStartRect = startRect;
mTargetRect = targetRect;
public RectFSpringAnim(SpringConfig config) {
mStartRect = config.startRect;
mTargetRect = config.targetRect;
mCurrentCenterX = mStartRect.centerX();
ResourceProvider rp = DynamicResource.provider(context);
mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
mMaxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
mMinVisChange = config.minVisChange;
mMaxVelocityPxPerS = config.maxVelocityPxPerS;
setCanRelease(true);
if (deviceProfile == null) {
mTracking = startRect.bottom < targetRect.bottom
? TRACKING_BOTTOM
: TRACKING_TOP;
} else {
int heightPx = deviceProfile.heightPx;
Rect padding = deviceProfile.workspacePadding;
final float topThreshold = heightPx / 3f;
final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
if (targetRect.bottom > bottomThreshold) {
mTracking = TRACKING_BOTTOM;
} else if (targetRect.top < topThreshold) {
mTracking = TRACKING_TOP;
} else {
mTracking = TRACKING_CENTER;
}
}
mTracking = config.tracking;
mStiffnessX = config.stiffnessX;
mStiffnessY = config.stiffnessY;
mDampingX = config.dampingX;
mDampingY = config.dampingY;
mRectStiffness = config.rectStiffness;
mCurrentY = getTrackedYFromRect(mStartRect);
}
@@ -240,14 +230,15 @@ public class RectFSpringAnim extends ReleaseCheck {
float maxXValue = Math.max(startX, endX);
mRectXAnim = new FlingSpringAnim(this, context, RECT_CENTER_X, startX, endX,
dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, onXEndListener);
dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, mDampingX, mStiffnessX,
onXEndListener);
float startY = mCurrentY;
float endY = getTrackedYFromRect(mTargetRect);
float minYValue = Math.min(startY, endY);
float maxYValue = Math.max(startY, endY);
mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, dampedYVelocityPxPerS,
mMinVisChange, minYValue, maxYValue, onYEndListener);
mMinVisChange, minYValue, maxYValue, mDampingY, mStiffnessY, onYEndListener);
float minVisibleChange = Math.abs(1f / mStartRect.height());
ResourceProvider rp = DynamicResource.provider(context);
@@ -368,4 +359,98 @@ public class RectFSpringAnim extends ReleaseCheck {
default void onCancel() { }
}
private abstract static class SpringConfig {
protected RectF startRect;
protected RectF targetRect;
protected @Tracking int tracking;
protected float stiffnessX;
protected float stiffnessY;
protected float dampingX;
protected float dampingY;
protected float rectStiffness;
protected float minVisChange;
protected int maxVelocityPxPerS;
private SpringConfig(Context context, RectF start, RectF target) {
startRect = start;
targetRect = target;
ResourceProvider rp = DynamicResource.provider(context);
minVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
maxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
}
}
/**
* Standard spring configuration parameters.
*/
public static class DefaultSpringConfig extends SpringConfig {
public DefaultSpringConfig(Context context, DeviceProfile deviceProfile,
RectF startRect, RectF targetRect) {
super(context, startRect, targetRect);
ResourceProvider rp = DynamicResource.provider(context);
tracking = getDefaultTracking(deviceProfile);
stiffnessX = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
stiffnessY = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
dampingX = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
dampingY = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
this.startRect = startRect;
this.targetRect = targetRect;
// Increase the stiffness for devices where we want the window size to transform
// quicker.
boolean shouldUseHigherStiffness = deviceProfile != null
&& (deviceProfile.isLandscape || deviceProfile.isTablet);
rectStiffness = shouldUseHigherStiffness
? rp.getFloat(R.dimen.swipe_up_rect_scale_higher_stiffness)
: rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
}
private @Tracking int getDefaultTracking(@Nullable DeviceProfile deviceProfile) {
@Tracking int tracking;
if (deviceProfile == null) {
tracking = startRect.bottom < targetRect.bottom
? TRACKING_BOTTOM
: TRACKING_TOP;
} else {
int heightPx = deviceProfile.heightPx;
Rect padding = deviceProfile.workspacePadding;
final float topThreshold = heightPx / 3f;
final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
if (targetRect.bottom > bottomThreshold) {
tracking = TRACKING_BOTTOM;
} else if (targetRect.top < topThreshold) {
tracking = TRACKING_TOP;
} else {
tracking = TRACKING_CENTER;
}
}
return tracking;
}
}
/**
* Spring configuration parameters for Taskbar/Hotseat items on devices that have a taskbar.
*/
public static class TaskbarHotseatSpringConfig extends SpringConfig {
public TaskbarHotseatSpringConfig(Context context, RectF start, RectF target) {
super(context, start, target);
ResourceProvider rp = DynamicResource.provider(context);
tracking = TRACKING_CENTER;
stiffnessX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_stiffness);
stiffnessY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_stiffness);
dampingX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_damping);
dampingY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_damping);
rectStiffness = rp.getFloat(R.dimen.taskbar_swipe_up_rect_scale_stiffness);
}
}
}

View File

@@ -124,7 +124,8 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
int cornerRadius,
int shadowRadius,
@NonNull View view) {
super(startBounds, new RectF(destinationBoundsTransformed), context, null);
super(new DefaultSpringConfig(context, null, startBounds,
new RectF(destinationBoundsTransformed)));
mTaskId = taskId;
mActivityInfo = activityInfo;
mLeash = leash;

View File

@@ -164,6 +164,13 @@
<item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
<item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
<!-- These params are only used for hotseat items on devices that have a taskbar. -->
<item name="taskbar_swipe_up_rect_x_stiffness" type="dimen" format="float">350</item>
<item name="taskbar_swipe_up_rect_x_damping" type="dimen" format="float">0.9</item>
<item name="taskbar_swipe_up_rect_y_stiffness" type="dimen" format="float">200</item>
<item name="taskbar_swipe_up_rect_y_damping" type="dimen" format="float">0.78</item>
<item name="taskbar_swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
<item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
<item name="staggered_stiffness" type="dimen" format="float">150</item>
<dimen name="unlock_staggered_velocity_dp_per_s">2dp</dimen>

View File

@@ -41,11 +41,9 @@ public class FlingSpringAnim {
public <K> FlingSpringAnim(K object, Context context, FloatPropertyCompat<K> property,
float startPosition, float targetPosition, float startVelocityPxPerS,
float minVisChange, float minValue, float maxValue,
float minVisChange, float minValue, float maxValue, float damping, float stiffness,
OnAnimationEndListener onEndListener) {
ResourceProvider rp = DynamicResource.provider(context);
float damping = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
float stiffness = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
float friction = rp.getFloat(R.dimen.swipe_up_rect_xy_fling_friction);
mFlingAnim = new FlingAnimation(object, property)

View File

@@ -306,6 +306,13 @@ public class ItemInfo {
return container == CONTAINER_HOTSEAT_PREDICTION || container == CONTAINER_PREDICTION;
}
/**
* Returns if an Item is in the hotseat.
*/
public boolean isInHotseat() {
return container == CONTAINER_HOTSEAT || container == CONTAINER_HOTSEAT_PREDICTION;
}
/**
* Returns whether this item should use the background animation.
*/