mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 16:26:47 +00:00
Merge "Tune springs when app animates home into the hotseat on devices with a taskbar." into tm-qpr-dev
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user