Revert "Move BaseActivityInterface task size methods to DevicePr..." Revert submission 19279487-baseactivityinterface Reason for revert: As per discussion in ag/19341332, make sure DeviceProfile can properly react to inset changes before moving task size calculations there Reverted Changes: I30324d34c:Move BaseActivityInterface task size methods to De... Ia9c1d0387:Move BaseActivityInterface task size methods to De... Bug: 238593212 Change-Id: I0d40fdd4a5d4468494e30cef32a284479ddd2feb
286 lines
13 KiB
Java
286 lines
13 KiB
Java
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.android.quickstep.util;
|
|
|
|
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
|
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
|
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
|
|
|
import android.animation.TimeInterpolator;
|
|
import android.content.Context;
|
|
import android.graphics.Matrix;
|
|
import android.graphics.PointF;
|
|
import android.graphics.Rect;
|
|
import android.graphics.RectF;
|
|
import android.util.FloatProperty;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import com.android.launcher3.DeviceProfile;
|
|
import com.android.launcher3.Launcher;
|
|
import com.android.launcher3.Utilities;
|
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
|
import com.android.launcher3.anim.PendingAnimation;
|
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
|
import com.android.quickstep.LauncherActivityInterface;
|
|
import com.android.quickstep.views.RecentsView;
|
|
|
|
/**
|
|
* Controls an animation that can go beyond progress = 1, at which point resistance should be
|
|
* applied. Internally, this is a wrapper around 2 {@link AnimatorPlaybackController}s, one that
|
|
* runs from progress 0 to 1 like normal, then one that seamlessly continues that animation but
|
|
* starts applying resistance as well.
|
|
*/
|
|
public class AnimatorControllerWithResistance {
|
|
|
|
private enum RecentsResistanceParams {
|
|
FROM_APP(0.75f, 0.5f, 1f, false),
|
|
FROM_APP_TABLET(1f, 0.7f, 1f, true),
|
|
FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
|
|
|
|
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
|
|
float translationFactor, boolean stopScalingAtTop) {
|
|
this.scaleStartResist = scaleStartResist;
|
|
this.scaleMaxResist = scaleMaxResist;
|
|
this.translationFactor = translationFactor;
|
|
this.stopScalingAtTop = stopScalingAtTop;
|
|
}
|
|
|
|
/**
|
|
* Start slowing down the rate of scaling down when recents view is smaller than this scale.
|
|
*/
|
|
public final float scaleStartResist;
|
|
|
|
/**
|
|
* Recents view will reach this scale at the very end of the drag.
|
|
*/
|
|
public final float scaleMaxResist;
|
|
|
|
/**
|
|
* How much translation to apply to RecentsView when the drag reaches the top of the screen,
|
|
* where 0 will keep it centered and 1 will have it barely touch the top of the screen.
|
|
*/
|
|
public final float translationFactor;
|
|
|
|
/**
|
|
* Whether to end scaling effect when the scaled down version of TaskView's top reaches the
|
|
* non-scaled version of TaskView's top.
|
|
*/
|
|
public final boolean stopScalingAtTop;
|
|
}
|
|
|
|
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
|
|
private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
|
|
|
|
private final AnimatorPlaybackController mNormalController;
|
|
private final AnimatorPlaybackController mResistanceController;
|
|
|
|
// Initialize to -1 so the first 0 gets applied.
|
|
private float mLastNormalProgress = -1;
|
|
private float mLastResistProgress;
|
|
|
|
public AnimatorControllerWithResistance(AnimatorPlaybackController normalController,
|
|
AnimatorPlaybackController resistanceController) {
|
|
mNormalController = normalController;
|
|
mResistanceController = resistanceController;
|
|
}
|
|
|
|
public AnimatorPlaybackController getNormalController() {
|
|
return mNormalController;
|
|
}
|
|
|
|
/**
|
|
* Applies the current progress of the animation.
|
|
* @param progress From 0 to maxProgress, where 1 is the target we are animating towards.
|
|
* @param maxProgress > 1, this is where the resistance will be applied.
|
|
*/
|
|
public void setProgress(float progress, float maxProgress) {
|
|
float normalProgress = Utilities.boundToRange(progress, 0, 1);
|
|
if (normalProgress != mLastNormalProgress) {
|
|
mLastNormalProgress = normalProgress;
|
|
mNormalController.setPlayFraction(normalProgress);
|
|
}
|
|
if (maxProgress <= 1) {
|
|
return;
|
|
}
|
|
float resistProgress = progress <= 1 ? 0 : Utilities.getProgress(progress, 1, maxProgress);
|
|
if (resistProgress != mLastResistProgress) {
|
|
mLastResistProgress = resistProgress;
|
|
mResistanceController.setPlayFraction(resistProgress);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Applies resistance to recents when swiping up past its target position.
|
|
* @param normalController The controller to run from 0 to 1 before this resistance applies.
|
|
* @param context Used to compute start and end values.
|
|
* @param recentsOrientedState Used to compute start and end values.
|
|
* @param dp Used to compute start and end values.
|
|
* @param scaleTarget The target for the scaleProperty.
|
|
* @param scaleProperty Animate the value to change the scale of the window/recents view.
|
|
* @param translationTarget The target for the translationProperty.
|
|
* @param translationProperty Animate the value to change the translation of the recents view.
|
|
*/
|
|
public static <SCALE, TRANSLATION> AnimatorControllerWithResistance createForRecents(
|
|
AnimatorPlaybackController normalController, Context context,
|
|
RecentsOrientedState recentsOrientedState, DeviceProfile dp, SCALE scaleTarget,
|
|
FloatProperty<SCALE> scaleProperty, TRANSLATION translationTarget,
|
|
FloatProperty<TRANSLATION> translationProperty) {
|
|
|
|
RecentsParams params = new RecentsParams(context, recentsOrientedState, dp, scaleTarget,
|
|
scaleProperty, translationTarget, translationProperty);
|
|
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
|
|
|
|
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
|
|
return new AnimatorControllerWithResistance(normalController, resistanceController);
|
|
}
|
|
|
|
/**
|
|
* Creates the resistance animation for {@link #createForRecents}, or can be used separately
|
|
* when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
|
|
*/
|
|
public static <SCALE, TRANSLATION> PendingAnimation createRecentsResistanceAnim(
|
|
RecentsParams<SCALE, TRANSLATION> params) {
|
|
Rect startRect = new Rect();
|
|
PagedOrientationHandler orientationHandler = params.recentsOrientedState
|
|
.getOrientationHandler();
|
|
LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect);
|
|
long distanceToCover = startRect.bottom;
|
|
PendingAnimation resistAnim = params.resistAnim != null
|
|
? params.resistAnim
|
|
: new PendingAnimation(distanceToCover * 2);
|
|
|
|
PointF pivot = new PointF();
|
|
float fullscreenScale = params.recentsOrientedState.getFullScreenScaleAndPivot(
|
|
startRect, params.dp, pivot);
|
|
|
|
// Compute where the task view would be based on the end scale.
|
|
RectF endRectF = new RectF(startRect);
|
|
Matrix temp = new Matrix();
|
|
temp.setScale(params.resistanceParams.scaleMaxResist,
|
|
params.resistanceParams.scaleMaxResist, pivot.x, pivot.y);
|
|
temp.mapRect(endRectF);
|
|
// Translate such that the task view touches the top of the screen when drag does.
|
|
float endTranslation = endRectF.top
|
|
* orientationHandler.getSecondaryTranslationDirectionFactor()
|
|
* params.resistanceParams.translationFactor;
|
|
resistAnim.addFloat(params.translationTarget, params.translationProperty,
|
|
params.startTranslation, endTranslation, RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
|
|
|
|
float prevScaleRate = (fullscreenScale - params.startScale)
|
|
/ (params.dp.heightPx - startRect.bottom);
|
|
// This is what the scale would be at the end of the drag if we didn't apply resistance.
|
|
float endScale = params.startScale - prevScaleRate * distanceToCover;
|
|
// Create an interpolator that resists the scale so the scale doesn't get smaller than
|
|
// RECENTS_SCALE_MAX_RESIST.
|
|
float startResist = Utilities.getProgress(params.resistanceParams.scaleStartResist,
|
|
params.startScale, endScale);
|
|
float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
|
|
params.startScale, endScale);
|
|
float stopResist =
|
|
params.resistanceParams.stopScalingAtTop ? 1f - startRect.top / endRectF.top : 1f;
|
|
final TimeInterpolator scaleInterpolator = t -> {
|
|
if (t < startResist) {
|
|
return t;
|
|
}
|
|
if (t > stopResist) {
|
|
return maxResist;
|
|
}
|
|
float resistProgress = Utilities.getProgress(t, startResist, stopResist);
|
|
resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
|
|
return startResist + resistProgress * (maxResist - startResist);
|
|
};
|
|
resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
|
|
scaleInterpolator);
|
|
|
|
return resistAnim;
|
|
}
|
|
|
|
/**
|
|
* Helper method to update or create a PendingAnimation suitable for animating
|
|
* a RecentsView interaction that started from the overview state.
|
|
*/
|
|
public static PendingAnimation createRecentsResistanceFromOverviewAnim(
|
|
Launcher launcher, @Nullable PendingAnimation resistanceAnim) {
|
|
RecentsView recentsView = launcher.getOverviewPanel();
|
|
RecentsParams params = new RecentsParams(launcher, recentsView.getPagedViewOrientedState(),
|
|
launcher.getDeviceProfile(), recentsView, RECENTS_SCALE_PROPERTY, recentsView,
|
|
TASK_SECONDARY_TRANSLATION)
|
|
.setResistAnim(resistanceAnim)
|
|
.setResistanceParams(RecentsResistanceParams.FROM_OVERVIEW)
|
|
.setStartScale(recentsView.getScaleX());
|
|
return createRecentsResistanceAnim(params);
|
|
}
|
|
|
|
/**
|
|
* Params to compute resistance when scaling/translating recents.
|
|
*/
|
|
private static class RecentsParams<SCALE, TRANSLATION> {
|
|
// These are all required and can't have default values, hence are final.
|
|
public final Context context;
|
|
public final RecentsOrientedState recentsOrientedState;
|
|
public final DeviceProfile dp;
|
|
public final SCALE scaleTarget;
|
|
public final FloatProperty<SCALE> scaleProperty;
|
|
public final TRANSLATION translationTarget;
|
|
public final FloatProperty<TRANSLATION> translationProperty;
|
|
|
|
// These are not required, or can have a default value that is generally correct.
|
|
@Nullable public PendingAnimation resistAnim = null;
|
|
public RecentsResistanceParams resistanceParams;
|
|
public float startScale = 1f;
|
|
public float startTranslation = 0f;
|
|
|
|
private RecentsParams(Context context, RecentsOrientedState recentsOrientedState,
|
|
DeviceProfile dp, SCALE scaleTarget, FloatProperty<SCALE> scaleProperty,
|
|
TRANSLATION translationTarget, FloatProperty<TRANSLATION> translationProperty) {
|
|
this.context = context;
|
|
this.recentsOrientedState = recentsOrientedState;
|
|
this.dp = dp;
|
|
this.scaleTarget = scaleTarget;
|
|
this.scaleProperty = scaleProperty;
|
|
this.translationTarget = translationTarget;
|
|
this.translationProperty = translationProperty;
|
|
if (dp.isTablet) {
|
|
resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
|
|
} else {
|
|
resistanceParams = RecentsResistanceParams.FROM_APP;
|
|
}
|
|
}
|
|
|
|
private RecentsParams setResistAnim(PendingAnimation resistAnim) {
|
|
this.resistAnim = resistAnim;
|
|
return this;
|
|
}
|
|
|
|
private RecentsParams setResistanceParams(RecentsResistanceParams resistanceParams) {
|
|
this.resistanceParams = resistanceParams;
|
|
return this;
|
|
}
|
|
|
|
private RecentsParams setStartScale(float startScale) {
|
|
this.startScale = startScale;
|
|
return this;
|
|
}
|
|
|
|
private RecentsParams setStartTranslation(float startTranslation) {
|
|
this.startTranslation = startTranslation;
|
|
return this;
|
|
}
|
|
}
|
|
}
|