Adding TaskViewSimulator for simulating taskView layout on a remote target am: f2393f1d20
Change-Id: I020e4b56de42e455b92c078bf4c8502fa3f0713c
This commit is contained in:
+5
-7
@@ -30,6 +30,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRA
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
|
||||
import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -37,7 +38,6 @@ import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -49,7 +49,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.SpringAnimationBuilder;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
@@ -199,11 +198,10 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
||||
return ObjectAnimator.ofFloat(mLauncher.getOverviewPanel(),
|
||||
RecentsView.CONTENT_ALPHA, values);
|
||||
case INDEX_RECENTS_TRANSLATE_X_ANIM:
|
||||
PagedOrientationHandler orientationHandler =
|
||||
((RecentsView)mLauncher.getOverviewPanel()).getPagedViewOrientedState()
|
||||
.getOrientationHandler();
|
||||
FloatProperty<View> translate = orientationHandler.getPrimaryViewTranslate();
|
||||
return new SpringAnimationBuilder<>(mLauncher.getOverviewPanel(), translate)
|
||||
// TODO: Do not assume motion across X axis for adjacent page
|
||||
return new SpringAnimationBuilder<>(
|
||||
mLauncher.getOverviewPanel(), ADJACENT_PAGE_OFFSET)
|
||||
.setMinimumVisibleChange(1f / mLauncher.getOverviewPanel().getWidth())
|
||||
.setDampingRatio(0.8f)
|
||||
.setStiffness(250)
|
||||
.setValues(values)
|
||||
|
||||
+9
-6
@@ -61,13 +61,16 @@ public class BackgroundAppState extends OverviewState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {getOverviewScale(launcher), NO_OFFSET};
|
||||
}
|
||||
|
||||
private float getOverviewScale(Launcher launcher) {
|
||||
// Initialize the recents view scale to what it would be when starting swipe up
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
int taskCount = recentsView.getTaskViewCount();
|
||||
if (taskCount == 0) {
|
||||
return super.getOverviewScaleAndTranslation(launcher);
|
||||
}
|
||||
if (taskCount == 0) return 1;
|
||||
|
||||
TaskView dummyTask;
|
||||
if (recentsView.getCurrentPage() >= recentsView.getTaskViewStartIndex()) {
|
||||
if (recentsView.getCurrentPage() <= taskCount - 1) {
|
||||
@@ -78,8 +81,8 @@ public class BackgroundAppState extends OverviewState {
|
||||
} else {
|
||||
dummyTask = recentsView.getTaskViewAt(0);
|
||||
}
|
||||
return recentsView.getTempAppWindowAnimationHelper().updateForFullscreenOverview(dummyTask)
|
||||
.getScaleAndTranslation();
|
||||
return recentsView.getTempAppWindowAnimationHelper()
|
||||
.updateForFullscreenOverview(dummyTask).getSrcToTargetScale();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-10
@@ -24,24 +24,18 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TR
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
|
||||
public class OverviewPeekState extends OverviewState {
|
||||
private static final float OVERVIEW_OFFSET = 0.7f;
|
||||
|
||||
public OverviewPeekState(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
|
||||
ScaleAndTranslation result = super.getOverviewScaleAndTranslation(launcher);
|
||||
result.translationX = NORMAL.getOverviewScaleAndTranslation(launcher).translationX
|
||||
- launcher.getResources().getDimension(R.dimen.overview_peek_distance);
|
||||
if (Utilities.isRtl(launcher.getResources())) {
|
||||
result.translationX = -result.translationX;
|
||||
}
|
||||
return result;
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {NO_SCALE, OVERVIEW_OFFSET};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-3
@@ -24,7 +24,6 @@ import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
||||
import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
@@ -123,8 +122,8 @@ public class OverviewState extends LauncherState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
|
||||
return new ScaleAndTranslation(1f, 0f, 0f);
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {NO_SCALE, NO_OFFSET};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-42
@@ -40,17 +40,15 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
@@ -59,6 +57,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
@@ -237,58 +236,32 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
private void setupOverviewAnimators() {
|
||||
final LauncherState fromState = QUICK_SWITCH;
|
||||
final LauncherState toState = OVERVIEW;
|
||||
LauncherState.ScaleAndTranslation fromScaleAndTranslation = fromState
|
||||
.getOverviewScaleAndTranslation(mLauncher);
|
||||
LauncherState.ScaleAndTranslation toScaleAndTranslation = toState
|
||||
.getOverviewScaleAndTranslation(mLauncher);
|
||||
// Update RecentView's translationX to have it start offscreen.
|
||||
float startScale = Utilities.mapRange(
|
||||
SCALE_DOWN_INTERPOLATOR.getInterpolation(Y_ANIM_MIN_PROGRESS),
|
||||
fromScaleAndTranslation.scale,
|
||||
toScaleAndTranslation.scale);
|
||||
fromScaleAndTranslation.translationX = mRecentsView.getOffscreenTranslationX(startScale);
|
||||
|
||||
// Set RecentView's initial properties.
|
||||
mRecentsView.setScaleX(fromScaleAndTranslation.scale);
|
||||
mRecentsView.setScaleY(fromScaleAndTranslation.scale);
|
||||
mRecentsView.setTranslationX(fromScaleAndTranslation.translationX);
|
||||
mRecentsView.setTranslationY(fromScaleAndTranslation.translationY);
|
||||
SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
|
||||
ADJACENT_PAGE_OFFSET.set(mRecentsView, 1f);
|
||||
mRecentsView.setContentAlpha(1);
|
||||
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
|
||||
|
||||
float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
|
||||
// As we drag right, animate the following properties:
|
||||
// - RecentsView translationX
|
||||
// - OverviewScrim
|
||||
AnimatorSet xOverviewAnim = new AnimatorSet();
|
||||
xOverviewAnim.play(ObjectAnimator.ofFloat(mRecentsView, View.TRANSLATION_X,
|
||||
toScaleAndTranslation.translationX));
|
||||
xOverviewAnim.play(ObjectAnimator.ofFloat(
|
||||
mLauncher.getDragLayer().getOverviewScrim(), OverviewScrim.SCRIM_PROGRESS,
|
||||
toState.getOverviewScrimAlpha(mLauncher)));
|
||||
long xAccuracy = (long) (mXRange * 2);
|
||||
xOverviewAnim.setDuration(xAccuracy);
|
||||
mXOverviewAnim = AnimatorPlaybackController.wrap(xOverviewAnim, xAccuracy);
|
||||
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
|
||||
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], LINEAR);
|
||||
xAnim.setFloat(mLauncher.getDragLayer().getOverviewScrim(), OverviewScrim.SCRIM_PROGRESS,
|
||||
toState.getOverviewScrimAlpha(mLauncher), LINEAR);
|
||||
mXOverviewAnim = xAnim.createPlaybackController();
|
||||
mXOverviewAnim.dispatchOnStart();
|
||||
|
||||
// As we drag up, animate the following properties:
|
||||
// - RecentsView translationY
|
||||
// - RecentsView scale
|
||||
// - RecentsView fullscreenProgress
|
||||
AnimatorSet yAnimation = new AnimatorSet();
|
||||
Animator translateYAnim = ObjectAnimator.ofFloat(mRecentsView, View.TRANSLATION_Y,
|
||||
toScaleAndTranslation.translationY);
|
||||
Animator scaleAnim = ObjectAnimator.ofFloat(mRecentsView, SCALE_PROPERTY,
|
||||
toScaleAndTranslation.scale);
|
||||
Animator fullscreenProgressAnim = ObjectAnimator.ofFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
||||
fromState.getOverviewFullscreenProgress(), toState.getOverviewFullscreenProgress());
|
||||
scaleAnim.setInterpolator(SCALE_DOWN_INTERPOLATOR);
|
||||
fullscreenProgressAnim.setInterpolator(SCALE_DOWN_INTERPOLATOR);
|
||||
yAnimation.play(translateYAnim);
|
||||
yAnimation.play(scaleAnim);
|
||||
yAnimation.play(fullscreenProgressAnim);
|
||||
long yAccuracy = (long) (mYRange * 2);
|
||||
yAnimation.setDuration(yAccuracy);
|
||||
mYOverviewAnim = AnimatorPlaybackController.wrap(yAnimation, yAccuracy);
|
||||
PendingAnimation yAnim = new PendingAnimation((long) (mYRange * 2));
|
||||
yAnim.setFloat(mRecentsView, SCALE_PROPERTY, scaleAndOffset[0], SCALE_DOWN_INTERPOLATOR);
|
||||
yAnim.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
||||
toState.getOverviewFullscreenProgress(), SCALE_DOWN_INTERPOLATOR);
|
||||
mYOverviewAnim = yAnim.createPlaybackController();
|
||||
mYOverviewAnim.dispatchOnStart();
|
||||
}
|
||||
|
||||
|
||||
@@ -135,8 +135,15 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
mInputConsumer = inputConsumer;
|
||||
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
|
||||
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called at the end of constructor of subclasses. This calls various methods which can
|
||||
* depend on proper class initialization.
|
||||
*/
|
||||
protected void initAfterSubclassConstructor() {
|
||||
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
|
||||
.getDeviceProfile(mContext));
|
||||
.getDeviceProfile(mContext));
|
||||
}
|
||||
|
||||
protected void performHapticFeedback() {
|
||||
@@ -241,6 +248,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
return mRecentsAnimationTargets != null && mRecentsAnimationTargets.hasTargets();
|
||||
}
|
||||
|
||||
protected void updateSource(Rect stackBounds, RemoteAnimationTargetCompat runningTarget) {
|
||||
mAppWindowAnimationHelper.updateSource(stackBounds, runningTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController recentsAnimationController,
|
||||
RecentsAnimationTargets targets) {
|
||||
@@ -264,7 +275,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
dp.updateInsets(targets.homeContentInsets);
|
||||
dp.updateIsSeascape(mContext);
|
||||
if (runningTaskTarget != null) {
|
||||
mAppWindowAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
|
||||
updateSource(overviewStackBounds, runningTaskTarget);
|
||||
}
|
||||
|
||||
mAppWindowAnimationHelper.prepareAnimation(dp, false /* isOpening */);
|
||||
@@ -314,6 +325,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
|
||||
mTransitionDragLength = mActivityInterface.getSwipeUpDestinationAndLength(
|
||||
dp, mContext, TEMP_RECT);
|
||||
|
||||
if (!dp.isMultiWindowMode) {
|
||||
// When updating the target rect, also update the home bounds since the location on
|
||||
// screen of the launcher window may be stale (position is not updated until first
|
||||
@@ -409,11 +421,12 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
*/
|
||||
protected void applyTransformUnchecked() {
|
||||
float shift = mCurrentShift.value;
|
||||
float offset = mRecentsView == null ? 0 : mRecentsView.getScrollOffset();
|
||||
float offset = mRecentsView == null ? 0 : mRecentsView.getScrollOffsetScaled();
|
||||
float taskSize = getOrientationHandler()
|
||||
.getPrimarySize(mAppWindowAnimationHelper.getTargetRect());
|
||||
float offsetScale = getTaskCurveScaleForOffset(offset, taskSize);
|
||||
mTransformParams.setProgress(shift)
|
||||
mTransformParams
|
||||
.setProgress(shift)
|
||||
.setOffset(offset)
|
||||
.setOffsetScale(offsetScale)
|
||||
.setTargetSet(mRecentsAnimationTargets)
|
||||
|
||||
@@ -129,6 +129,7 @@ public class FallbackSwipeHandler extends BaseSwipeUpHandler<RecentsActivity, Fa
|
||||
mEndTargetAnimationParams.put(LAST_TASK, new EndTargetAnimationParams(0, 150, 1));
|
||||
mEndTargetAnimationParams.put(NEW_TASK, new EndTargetAnimationParams(0, 150, 1));
|
||||
|
||||
initAfterSubclassConstructor();
|
||||
initStateCallbacks();
|
||||
}
|
||||
|
||||
|
||||
+24
-86
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static android.view.View.TRANSLATION_Y;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_FADE_ANIM;
|
||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_RECENTS_TRANSLATE_X_ANIM;
|
||||
@@ -25,15 +23,14 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.LauncherSwipeHandler.RECENTS_ATTACH_DURATION;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
@@ -57,7 +54,6 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
@@ -81,7 +77,6 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public final class LauncherActivityInterface implements BaseActivityInterface<Launcher> {
|
||||
|
||||
private Runnable mAdjustInterpolatorsRunnable;
|
||||
private Pair<Float, Float> mSwipeUpPullbackStartAndMaxProgress =
|
||||
BaseActivityInterface.super.getSwipeUpPullbackStartAndMaxProgress();
|
||||
|
||||
@@ -242,14 +237,6 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustActivityControllerInterpolators() {
|
||||
if (mAdjustInterpolatorsRunnable != null) {
|
||||
mAdjustInterpolatorsRunnable.run();
|
||||
mAdjustInterpolatorsRunnable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionCancelled() {
|
||||
launcher.getStateManager().goToState(startState, false /* animate */);
|
||||
@@ -272,42 +259,24 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
||||
.createStateElementAnimation(
|
||||
INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
|
||||
|
||||
int runningTaskIndex = recentsView.getRunningTaskIndex();
|
||||
if (runningTaskIndex == recentsView.getTaskViewStartIndex()) {
|
||||
// If we are on the first task (we haven't quick switched), translate recents in
|
||||
// from the side. Calculate the start translation based on current scale/scroll.
|
||||
float currScale = recentsView.getScaleX();
|
||||
float scrollOffsetX = recentsView.getScrollOffset();
|
||||
float offscreenX = recentsView.getOffscreenTranslationX(currScale);
|
||||
|
||||
float fromTranslation = attached ? offscreenX - scrollOffsetX : 0;
|
||||
float toTranslation = attached ? 0 : offscreenX - scrollOffsetX;
|
||||
launcher.getStateManager()
|
||||
.cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_X_ANIM);
|
||||
|
||||
PagedOrientationHandler pagedOrientationHandler =
|
||||
recentsView.getPagedViewOrientedState().getOrientationHandler();
|
||||
if (!recentsView.isShown() && animate) {
|
||||
pagedOrientationHandler
|
||||
.getPrimaryViewTranslate().set(recentsView, fromTranslation);
|
||||
} else {
|
||||
fromTranslation =
|
||||
pagedOrientationHandler.getPrimaryViewTranslate().get(recentsView);
|
||||
}
|
||||
|
||||
if (!animate) {
|
||||
pagedOrientationHandler
|
||||
.getPrimaryViewTranslate().set(recentsView, toTranslation);
|
||||
} else {
|
||||
launcher.getStateManager().createStateElementAnimation(
|
||||
INDEX_RECENTS_TRANSLATE_X_ANIM,
|
||||
fromTranslation, toTranslation).start();
|
||||
}
|
||||
|
||||
fadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2);
|
||||
float fromTranslation = attached ? 1 : 0;
|
||||
float toTranslation = attached ? 0 : 1;
|
||||
launcher.getStateManager()
|
||||
.cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_X_ANIM);
|
||||
if (!recentsView.isShown() && animate) {
|
||||
ADJACENT_PAGE_OFFSET.set(recentsView, fromTranslation);
|
||||
} else {
|
||||
fadeAnim.setInterpolator(ACCEL_DEACCEL);
|
||||
fromTranslation = ADJACENT_PAGE_OFFSET.get(recentsView);
|
||||
}
|
||||
if (!animate) {
|
||||
ADJACENT_PAGE_OFFSET.set(recentsView, toTranslation);
|
||||
} else {
|
||||
launcher.getStateManager().createStateElementAnimation(
|
||||
INDEX_RECENTS_TRANSLATE_X_ANIM,
|
||||
fromTranslation, toTranslation).start();
|
||||
}
|
||||
|
||||
fadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2);
|
||||
fadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0).start();
|
||||
}
|
||||
};
|
||||
@@ -365,51 +334,20 @@ public final class LauncherActivityInterface implements BaseActivityInterface<La
|
||||
return;
|
||||
}
|
||||
|
||||
LauncherState.ScaleAndTranslation fromScaleAndTranslation
|
||||
= fromState.getOverviewScaleAndTranslation(launcher);
|
||||
LauncherState.ScaleAndTranslation endScaleAndTranslation
|
||||
= endState.getOverviewScaleAndTranslation(launcher);
|
||||
float fromTranslationY = fromScaleAndTranslation.translationY;
|
||||
float endTranslationY = endScaleAndTranslation.translationY;
|
||||
float fromFullscreenProgress = fromState.getOverviewFullscreenProgress();
|
||||
float endFullscreenProgress = endState.getOverviewFullscreenProgress();
|
||||
|
||||
Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY,
|
||||
fromScaleAndTranslation.scale, endScaleAndTranslation.scale);
|
||||
Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y,
|
||||
fromTranslationY, endTranslationY);
|
||||
float fromScale = fromState.getOverviewScaleAndOffset(launcher)[0];
|
||||
float endScale = endState.getOverviewScaleAndOffset(launcher)[0];
|
||||
|
||||
Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScale, endScale);
|
||||
Animator applyFullscreenProgress = ObjectAnimator.ofFloat(recentsView,
|
||||
RecentsView.FULLSCREEN_PROGRESS, fromFullscreenProgress, endFullscreenProgress);
|
||||
anim.playTogether(scale, translateY, applyFullscreenProgress);
|
||||
|
||||
mAdjustInterpolatorsRunnable = () -> {
|
||||
// Adjust the translateY interpolator to account for the running task's top inset.
|
||||
// When progress <= 1, this is handled by each task view as they set their fullscreen
|
||||
// progress. However, once we go to progress > 1, fullscreen progress stays at 0, so
|
||||
// recents as a whole needs to translate further to keep up with the app window.
|
||||
TaskView runningTaskView = recentsView.getRunningTaskView();
|
||||
if (runningTaskView == null) {
|
||||
runningTaskView = recentsView.getCurrentPageTaskView();
|
||||
if (runningTaskView == null) {
|
||||
// There are no task views in LockTask mode when Overview is enabled.
|
||||
return;
|
||||
}
|
||||
}
|
||||
TimeInterpolator oldInterpolator = translateY.getInterpolator();
|
||||
Rect fallbackInsets = launcher.getDeviceProfile().getInsets();
|
||||
float extraTranslationY = runningTaskView.getThumbnail().getInsets(fallbackInsets).top;
|
||||
float normalizedTranslationY = extraTranslationY / (fromTranslationY - endTranslationY);
|
||||
translateY.setInterpolator(t -> {
|
||||
float newT = oldInterpolator.getInterpolation(t);
|
||||
return newT <= 1f ? newT : newT + normalizedTranslationY * (newT - 1);
|
||||
});
|
||||
};
|
||||
anim.playTogether(scale, applyFullscreenProgress);
|
||||
|
||||
// Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
|
||||
float pullbackStartProgress = (0.75f - fromScaleAndTranslation.scale)
|
||||
/ (endScaleAndTranslation.scale - fromScaleAndTranslation.scale);
|
||||
float pullbackMaxProgress = (0.5f - fromScaleAndTranslation.scale)
|
||||
/ (endScaleAndTranslation.scale - fromScaleAndTranslation.scale);
|
||||
float pullbackStartProgress = (0.75f - fromScale) / (endScale - fromScale);
|
||||
float pullbackMaxProgress = (0.5f - fromScale) / (endScale - fromScale);
|
||||
mSwipeUpPullbackStartAndMaxProgress = new Pair<>(
|
||||
pullbackStartProgress, pullbackMaxProgress);
|
||||
}
|
||||
|
||||
+54
-17
@@ -17,6 +17,8 @@ package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
@@ -39,16 +41,17 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnApplyWindowInsetsListener;
|
||||
import android.view.ViewTreeObserver.OnDrawListener;
|
||||
@@ -67,7 +70,6 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
@@ -78,9 +80,11 @@ import com.android.quickstep.GestureState.GestureEndTarget;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.views.LiveTileOverlay;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
@@ -177,6 +181,9 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
private AnimatorPlaybackController mLauncherTransitionController;
|
||||
private boolean mHasLauncherTransitionControllerStarted;
|
||||
|
||||
private final TaskViewSimulator mTaskViewSimulator;
|
||||
private AnimatorPlaybackController mWindowTransitionController;
|
||||
|
||||
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||
|
||||
private boolean mWasLauncherAlreadyVisible;
|
||||
@@ -201,6 +208,9 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
mTaskAnimationManager = taskAnimationManager;
|
||||
mTouchTimeMs = touchTimeMs;
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
mTaskViewSimulator = new TaskViewSimulator(context, LayoutUtils::calculateLauncherTaskSize);
|
||||
|
||||
initAfterSubclassConstructor();
|
||||
initStateCallbacks();
|
||||
}
|
||||
|
||||
@@ -473,23 +483,11 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
} else if (mContinuingLastGesture
|
||||
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
|
||||
recentsAttachedToAppWindow = true;
|
||||
animate = false;
|
||||
} else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) {
|
||||
// The window is going away so make sure recents is always visible in this case.
|
||||
recentsAttachedToAppWindow = true;
|
||||
animate = false;
|
||||
} else {
|
||||
recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
|
||||
if (animate) {
|
||||
// Only animate if an adjacent task view is visible on screen.
|
||||
TaskView adjacentTask1 = mRecentsView.getNextTaskView();
|
||||
TaskView adjacentTask2 = mRecentsView.getPreviousTaskView();
|
||||
float prevTranslationX = mRecentsView.getTranslationX();
|
||||
mRecentsView.setTranslationX(0);
|
||||
animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT))
|
||||
|| (adjacentTask2 != null && adjacentTask2.getGlobalVisibleRect(TEMP_RECT));
|
||||
mRecentsView.setTranslationX(prevTranslationX);
|
||||
}
|
||||
}
|
||||
mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
|
||||
}
|
||||
@@ -523,6 +521,34 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateSource(Rect stackBounds, RemoteAnimationTargetCompat runningTarget) {
|
||||
super.updateSource(stackBounds, runningTarget);
|
||||
mTaskViewSimulator.setPreview(runningTarget, mRecentsAnimationTargets);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||
super.initTransitionEndpoints(dp);
|
||||
mTaskViewSimulator.setDp(dp, false /* isOpening */);
|
||||
mTaskViewSimulator.setLayoutRotation(
|
||||
mDeviceState.getCurrentActiveRotation(),
|
||||
mDeviceState.getDisplayRotation());
|
||||
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
anim.setDuration(mTransitionDragLength * 2);
|
||||
anim.setInterpolator(t -> t * mDragLengthFactor);
|
||||
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.recentsViewScale,
|
||||
AnimatedFloat.VALUE,
|
||||
mTaskViewSimulator.getFullScreenScale(), 1));
|
||||
anim.play(ObjectAnimator.ofFloat(mTaskViewSimulator.fullScreenProgress,
|
||||
AnimatedFloat.VALUE,
|
||||
BACKGROUND_APP.getOverviewFullscreenProgress(),
|
||||
OVERVIEW.getOverviewFullscreenProgress()));
|
||||
mWindowTransitionController =
|
||||
AnimatorPlaybackController.wrap(anim, mTransitionDragLength * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
||||
* (it has its own animation) or if we're already animating the current controller.
|
||||
@@ -542,7 +568,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
|
||||
mLauncherTransitionController = anim;
|
||||
mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
|
||||
mAnimationFactory.adjustActivityControllerInterpolators();
|
||||
mLauncherTransitionController.dispatchOnStart();
|
||||
updateLauncherTransitionProgress();
|
||||
}
|
||||
@@ -555,7 +580,9 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
applyTransformUnchecked();
|
||||
// Base class expects applyTransformUnchecked to be called here.
|
||||
// TODO: Remove this dependency for swipe-up animation.
|
||||
// applyTransformUnchecked();
|
||||
updateSysUiFlags(mCurrentShift.value);
|
||||
}
|
||||
|
||||
@@ -575,6 +602,16 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
}
|
||||
}
|
||||
|
||||
if (mWindowTransitionController != null) {
|
||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
||||
mWindowTransitionController.setPlayFraction(progress);
|
||||
mTransformParams
|
||||
.setTargetSet(mRecentsAnimationTargets)
|
||||
.setLauncherOnTop(true);
|
||||
|
||||
mTaskViewSimulator.setScroll(mRecentsView == null ? 0 : mRecentsView.getScrollOffset());
|
||||
mTaskViewSimulator.apply(mTransformParams);
|
||||
}
|
||||
updateLauncherTransitionProgress();
|
||||
}
|
||||
|
||||
@@ -1020,7 +1057,6 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
mLauncherTransitionController.dispatchSetInterpolator(t -> end);
|
||||
} else {
|
||||
mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
|
||||
mAnimationFactory.adjustActivityControllerInterpolators();
|
||||
}
|
||||
mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));
|
||||
|
||||
@@ -1296,6 +1332,7 @@ public class LauncherSwipeHandler<T extends BaseDraggingActivity>
|
||||
|
||||
private void setTargetAlphaProvider(TargetAlphaProvider provider) {
|
||||
mAppWindowAnimationHelper.setTaskAlphaCallback(provider);
|
||||
mTaskViewSimulator.setTaskAlphaCallback(provider);
|
||||
updateFinalShift();
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -26,7 +26,6 @@ import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
@@ -58,7 +57,6 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
private boolean mInOverviewState = true;
|
||||
|
||||
private float mZoomScale = 1f;
|
||||
private float mZoomTranslationY = 0f;
|
||||
|
||||
private RunningTaskInfo mRunningTaskInfo;
|
||||
|
||||
@@ -145,14 +143,11 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
|
||||
if (getTaskViewCount() == 0) {
|
||||
mZoomScale = 1f;
|
||||
mZoomTranslationY = 0f;
|
||||
} else {
|
||||
TaskView dummyTask = getTaskViewAt(0);
|
||||
ScaleAndTranslation sat = getTempAppWindowAnimationHelper()
|
||||
mZoomScale = getTempAppWindowAnimationHelper()
|
||||
.updateForFullscreenOverview(dummyTask)
|
||||
.getScaleAndTranslation();
|
||||
mZoomScale = sat.scale;
|
||||
mZoomTranslationY = sat.translationY;
|
||||
.getSrcToTargetScale();
|
||||
}
|
||||
|
||||
setZoomProgress(mZoomInProgress);
|
||||
@@ -161,7 +156,6 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
|
||||
public void setZoomProgress(float progress) {
|
||||
mZoomInProgress = progress;
|
||||
SCALE_PROPERTY.set(this, Utilities.mapRange(mZoomInProgress, 1, mZoomScale));
|
||||
TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY));
|
||||
FULLSCREEN_PROGRESS.set(this, mZoomInProgress);
|
||||
}
|
||||
|
||||
|
||||
+5
-20
@@ -30,13 +30,11 @@ import android.graphics.Matrix.ScaleToFit;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
@@ -60,7 +58,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
public class AppWindowAnimationHelper {
|
||||
|
||||
// The bounds of the source app in device coordinates
|
||||
private final Rect mSourceStackBounds = new Rect();
|
||||
private final RectF mSourceStackBounds = new RectF();
|
||||
// The insets of the source app
|
||||
private final Rect mSourceInsets = new Rect();
|
||||
// The source app bounds with the source insets applied, in the device coordinates
|
||||
@@ -159,14 +157,10 @@ public class AppWindowAnimationHelper {
|
||||
mSourceRect.set(scaledTargetRect);
|
||||
}
|
||||
|
||||
private float getSrcToTargetScale() {
|
||||
if (mOrientedState == null
|
||||
|| mOrientedState.isHomeRotationAllowed()
|
||||
|| mOrientedState.isDisplayPhoneNatural()) {
|
||||
return mSourceRect.width() / mTargetRect.width();
|
||||
} else {
|
||||
return mSourceRect.height() / mTargetRect.height();
|
||||
}
|
||||
public float getSrcToTargetScale() {
|
||||
return LayoutUtils.getTaskScale(mOrientedState,
|
||||
mSourceRect.width(), mSourceRect.height(),
|
||||
mTargetRect.width(), mTargetRect.height());
|
||||
}
|
||||
|
||||
public void prepareAnimation(DeviceProfile dp, boolean isOpening) {
|
||||
@@ -378,15 +372,6 @@ public class AppWindowAnimationHelper {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The source rect's scale and translation relative to the target rect.
|
||||
*/
|
||||
public LauncherState.ScaleAndTranslation getScaleAndTranslation() {
|
||||
float scale = getSrcToTargetScale();
|
||||
float translationY = mSourceRect.centerY() - mSourceRect.top - mTargetRect.centerY();
|
||||
return new LauncherState.ScaleAndTranslation(scale, 0, translationY);
|
||||
}
|
||||
|
||||
private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
|
||||
SystemUiProxy proxy = SystemUiProxy.INSTANCE.get(activity);
|
||||
if (proxy.isActive()) {
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
|
||||
import static com.android.quickstep.util.AppWindowAnimationHelper.applySurfaceParams;
|
||||
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
|
||||
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.RecentsAnimationTargets;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
|
||||
import com.android.quickstep.views.RecentsView.ScrollState;
|
||||
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||
|
||||
/**
|
||||
* A utility class which emulates the layout behavior of TaskView and RecentsView
|
||||
*/
|
||||
public class TaskViewSimulator {
|
||||
|
||||
private final Rect mTmpCropRect = new Rect();
|
||||
private final RectF mTempRectF = new RectF();
|
||||
|
||||
private final RecentsOrientedState mOrientationState;
|
||||
private final Context mContext;
|
||||
private final TaskSizeProvider mSizeProvider;
|
||||
|
||||
private final Rect mTaskRect = new Rect();
|
||||
private final PointF mPivot = new PointF();
|
||||
private DeviceProfile mDp;
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private RemoteAnimationTargetCompat mRunningTarget;
|
||||
private RecentsAnimationTargets mAllTargets;
|
||||
|
||||
// Whether to boost the opening animation target layers, or the closing
|
||||
private int mBoostModeTargetLayers = -1;
|
||||
private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
|
||||
|
||||
// Thumbnail view properties
|
||||
private final Rect mThumbnailPosition = new Rect();
|
||||
private final ThumbnailData mThumbnailData = new ThumbnailData();
|
||||
private final PreviewPositionHelper mPositionHelper;
|
||||
private final Matrix mInversePositionMatrix = new Matrix();
|
||||
|
||||
// TaskView properties
|
||||
private final FullscreenDrawParams mCurrentFullscreenParams;
|
||||
private float mCurveScale = 1;
|
||||
|
||||
// RecentsView properties
|
||||
public final AnimatedFloat recentsViewScale = new AnimatedFloat(() -> { });
|
||||
public final AnimatedFloat fullScreenProgress = new AnimatedFloat(() -> { });
|
||||
private final ScrollState mScrollState = new ScrollState();
|
||||
private final int mPageSpacing;
|
||||
|
||||
// Cached calculations
|
||||
private boolean mLayoutValid = false;
|
||||
private boolean mScrollValid = false;
|
||||
|
||||
public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider) {
|
||||
mContext = context;
|
||||
mSizeProvider = sizeProvider;
|
||||
mPositionHelper = new PreviewPositionHelper(context);
|
||||
mOrientationState = new RecentsOrientedState(context);
|
||||
|
||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||
mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the device profile for the current state
|
||||
*/
|
||||
public void setDp(DeviceProfile dp, boolean isOpening) {
|
||||
mDp = dp;
|
||||
mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING;
|
||||
mLayoutValid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int)
|
||||
*/
|
||||
public void setLayoutRotation(int touchRotation, int displayRotation) {
|
||||
if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
|
||||
return;
|
||||
}
|
||||
mOrientationState.update(touchRotation, displayRotation,
|
||||
mOrientationState.getLauncherRotation());
|
||||
mLayoutValid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.android.quickstep.views.RecentsView#FULLSCREEN_PROGRESS
|
||||
*/
|
||||
public float getFullScreenScale() {
|
||||
if (mDp == null) {
|
||||
return 1;
|
||||
}
|
||||
mSizeProvider.calculateTaskSize(mContext, mDp, mTaskRect);
|
||||
return mOrientationState.getFullScreenScaleAndPivot(mTaskRect, mDp, mPivot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the targets which the simulator will control
|
||||
*/
|
||||
public void setPreview(
|
||||
RemoteAnimationTargetCompat runningTarget, RecentsAnimationTargets allTargets) {
|
||||
mRunningTarget = runningTarget;
|
||||
mAllTargets = allTargets;
|
||||
|
||||
mThumbnailData.insets.set(mRunningTarget.contentInsets);
|
||||
// TODO: What is this?
|
||||
mThumbnailData.windowingMode = WINDOWING_MODE_FULLSCREEN;
|
||||
|
||||
mThumbnailPosition.set(runningTarget.screenSpaceBounds);
|
||||
// TODO: Should sourceContainerBounds already have this offset?
|
||||
mThumbnailPosition.offsetTo(mRunningTarget.position.x, mRunningTarget.position.y);
|
||||
|
||||
mLayoutValid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the scroll for RecentsView
|
||||
*/
|
||||
public void setScroll(int scroll) {
|
||||
if (mScrollState.scroll != scroll) {
|
||||
mScrollState.scroll = scroll;
|
||||
mScrollValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alternate function which can be used to control the alpha
|
||||
*/
|
||||
public void setTaskAlphaCallback(TargetAlphaProvider callback) {
|
||||
mTaskAlphaCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the target to the previously set parameters
|
||||
*/
|
||||
public void apply(TransformParams params) {
|
||||
if (mDp == null || mRunningTarget == null) {
|
||||
return;
|
||||
}
|
||||
if (!mLayoutValid) {
|
||||
mLayoutValid = true;
|
||||
|
||||
getFullScreenScale();
|
||||
mThumbnailData.rotation = FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()
|
||||
? mOrientationState.getDisplayRotation() : mPositionHelper.getCurrentRotation();
|
||||
|
||||
mPositionHelper.updateThumbnailMatrix(mThumbnailPosition, mThumbnailData,
|
||||
mDp.isMultiWindowMode, mTaskRect.width(), mTaskRect.height());
|
||||
|
||||
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
|
||||
|
||||
PagedOrientationHandler poh = mOrientationState.getOrientationHandler();
|
||||
mScrollState.halfPageSize =
|
||||
poh.getPrimaryValue(mTaskRect.width(), mTaskRect.height()) / 2;
|
||||
mScrollState.halfScreenSize = poh.getPrimaryValue(mDp.widthPx, mDp.heightPx) / 2;
|
||||
mScrollValid = false;
|
||||
}
|
||||
|
||||
if (!mScrollValid) {
|
||||
mScrollValid = true;
|
||||
int start = mOrientationState.getOrientationHandler()
|
||||
.getPrimaryValue(mTaskRect.left, mTaskRect.top);
|
||||
mScrollState.screenCenter = start + mScrollState.scroll + mScrollState.halfPageSize;
|
||||
mScrollState.updateInterpolation(start, mPageSpacing);
|
||||
mCurveScale = TaskView.getCurveScaleForInterpolation(mScrollState.linearInterpolation);
|
||||
}
|
||||
|
||||
float progress = Utilities.boundToRange(fullScreenProgress.value, 0, 1);
|
||||
mCurrentFullscreenParams.setProgress(
|
||||
progress, recentsViewScale.value, mTaskRect.width(), mDp, mPositionHelper);
|
||||
|
||||
// Apply thumbnail matrix
|
||||
RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets;
|
||||
float scale = mCurrentFullscreenParams.mScale;
|
||||
float taskWidth = mTaskRect.width();
|
||||
float taskHeight = mTaskRect.height();
|
||||
|
||||
mMatrix.set(mPositionHelper.getMatrix());
|
||||
mMatrix.postScale(scale, scale);
|
||||
mMatrix.postTranslate(insets.left, insets.top);
|
||||
|
||||
// Apply TaskView matrix: scale, translate, scroll
|
||||
mMatrix.postScale(mCurveScale, mCurveScale, taskWidth / 2, taskHeight / 2);
|
||||
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
|
||||
mOrientationState.getOrientationHandler().set(
|
||||
mMatrix, MATRIX_POST_TRANSLATE, mScrollState.scroll);
|
||||
|
||||
// Apply recensView matrix
|
||||
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
|
||||
postDisplayRotation(mOrientationState.getDisplayRotation(),
|
||||
mDp.widthPx, mDp.heightPx, mMatrix);
|
||||
|
||||
// Crop rect is the inverse of thumbnail matrix
|
||||
mTempRectF.set(-insets.left, -insets.top,
|
||||
taskWidth + insets.right, taskHeight + insets.bottom);
|
||||
mInversePositionMatrix.mapRect(mTempRectF);
|
||||
mTempRectF.roundOut(mTmpCropRect);
|
||||
|
||||
SurfaceParams[] surfaceParams = new SurfaceParams[mAllTargets.unfilteredApps.length];
|
||||
for (int i = 0; i < mAllTargets.unfilteredApps.length; i++) {
|
||||
RemoteAnimationTargetCompat app = mAllTargets.unfilteredApps[i];
|
||||
SurfaceParams.Builder builder = new SurfaceParams.Builder(app.leash)
|
||||
.withLayer(RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers));
|
||||
|
||||
if (app.mode == mAllTargets.targetMode) {
|
||||
float alpha = mTaskAlphaCallback.getAlpha(app, params.getTargetAlpha());
|
||||
if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||
// Fade out Assistant overlay.
|
||||
if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT
|
||||
&& app.isNotInRecents) {
|
||||
alpha = Interpolators.ACCEL_2.getInterpolation(fullScreenProgress.value);
|
||||
}
|
||||
|
||||
builder.withAlpha(alpha)
|
||||
.withMatrix(mMatrix)
|
||||
.withWindowCrop(mTmpCropRect)
|
||||
.withCornerRadius(mCurrentFullscreenParams.mCurrentDrawnCornerRadius);
|
||||
} else if (params.getTargetSet().hasRecents) {
|
||||
// If home has a different target then recents, reverse anim the home target.
|
||||
builder.withAlpha(fullScreenProgress.value * params.getTargetAlpha());
|
||||
}
|
||||
} else {
|
||||
builder.withAlpha(1);
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.isLauncherOnTop()) {
|
||||
builder.withLayer(Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
surfaceParams[i] = builder.build();
|
||||
}
|
||||
|
||||
applySurfaceParams(params.getSyncTransactionApplier(), surfaceParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for calculating taskSize
|
||||
*/
|
||||
public interface TaskSizeProvider {
|
||||
|
||||
/**
|
||||
* Sets the outRect to the expected taskSize
|
||||
*/
|
||||
void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect);
|
||||
}
|
||||
|
||||
}
|
||||
-21
@@ -183,27 +183,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
||||
LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The translationX to apply to this view so that the first task is just offscreen.
|
||||
*/
|
||||
public float getOffscreenTranslationX(float recentsScale) {
|
||||
LauncherState.ScaleAndTranslation overviewScaleAndTranslation =
|
||||
NORMAL.getOverviewScaleAndTranslation(mActivity);
|
||||
float offscreen = mOrientationHandler.getTranslationValue(overviewScaleAndTranslation);
|
||||
// Offset since scale pushes tasks outwards.
|
||||
getTaskSize(sTempRect);
|
||||
int taskSize = mOrientationHandler.getPrimarySize(sTempRect);
|
||||
offscreen += taskSize * (recentsScale - 1) / 2;
|
||||
if (mRunningTaskTileHidden) {
|
||||
// The first task is hidden, so offset by its width.
|
||||
offscreen -= (taskSize + getPageSpacing()) * recentsScale;
|
||||
}
|
||||
if (isRtl()) {
|
||||
offscreen = -offscreen;
|
||||
}
|
||||
return offscreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) {
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
|
||||
@@ -56,6 +56,7 @@ import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
@@ -90,7 +91,6 @@ import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.PagedView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -123,7 +123,6 @@ import com.android.quickstep.TaskThumbnailCache;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.ViewUtils;
|
||||
import com.android.quickstep.util.AppWindowAnimationHelper;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.systemui.plugins.ResourceProvider;
|
||||
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
||||
@@ -175,8 +174,23 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
}
|
||||
};
|
||||
|
||||
protected RecentsOrientedState mOrientationState;
|
||||
public static final FloatProperty<RecentsView> ADJACENT_PAGE_OFFSET =
|
||||
new FloatProperty<RecentsView>("adjacentPageOffset") {
|
||||
@Override
|
||||
public void setValue(RecentsView recentsView, float v) {
|
||||
if (recentsView.mAdjacentPageOffset != v) {
|
||||
recentsView.mAdjacentPageOffset = v;
|
||||
recentsView.updateAdjacentPageOffset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView recentsView) {
|
||||
return recentsView.mAdjacentPageOffset;
|
||||
}
|
||||
};
|
||||
|
||||
protected final RecentsOrientedState mOrientationState;
|
||||
private OrientationEventListener mOrientationListener;
|
||||
private int mPreviousRotation;
|
||||
protected RecentsAnimationController mRecentsAnimationController;
|
||||
@@ -188,6 +202,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
protected boolean mEnableDrawingLiveTile = false;
|
||||
protected final Rect mTempRect = new Rect();
|
||||
protected final RectF mTempRectF = new RectF();
|
||||
private final PointF mTempPointF = new PointF();
|
||||
|
||||
private static final int DISMISS_TASK_DURATION = 300;
|
||||
private static final int ADDITION_TASK_DURATION = 200;
|
||||
@@ -198,7 +213,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
private final float mFastFlingVelocity;
|
||||
private final RecentsModel mModel;
|
||||
private final int mTaskTopMargin;
|
||||
private final int mTaskBottomMargin;
|
||||
private final ClearAllButton mClearAllButton;
|
||||
private final Rect mClearAllButtonDeadZoneRect = new Rect();
|
||||
private final Rect mTaskViewDeadZoneRect = new Rect();
|
||||
@@ -217,6 +231,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
private boolean mOverlayEnabled;
|
||||
protected boolean mFreezeViewVisibility;
|
||||
|
||||
private float mAdjacentPageOffset = 0;
|
||||
|
||||
/**
|
||||
* TODO: Call reloadIdNeeded in onTaskStackChanged.
|
||||
*/
|
||||
@@ -352,7 +368,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
mFastFlingVelocity = getResources()
|
||||
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
|
||||
mActivity = (T) BaseActivity.fromContext(context);
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mModel = RecentsModel.INSTANCE.get(context);
|
||||
mIdp = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
mTempAppWindowAnimationHelper =
|
||||
@@ -368,7 +384,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
|
||||
mTaskTopMargin = getResources()
|
||||
.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
|
||||
mTaskBottomMargin = LayoutUtils.thumbnailBottomMargin(context);
|
||||
mSquaredTouchSlop = squaredTouchSlop(context);
|
||||
|
||||
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
|
||||
@@ -830,7 +845,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
mTaskHeight = mTempRect.height();
|
||||
|
||||
mTempRect.top -= mTaskTopMargin;
|
||||
mTempRect.bottom += mTaskBottomMargin;
|
||||
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
|
||||
dp.widthPx - mInsets.right - mTempRect.right,
|
||||
dp.heightPx - mInsets.bottom - mTempRect.bottom);
|
||||
@@ -1621,11 +1635,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getPreviousTaskView() {
|
||||
return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() - 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TaskView getCurrentPageTaskView() {
|
||||
return getTaskViewAtByAbsoluteIndex(getCurrentPage());
|
||||
@@ -1685,11 +1694,29 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
|
||||
updateEmptyStateUi(changed);
|
||||
|
||||
// Set the pivot points to match the task preview center
|
||||
setPivotY(((mInsets.top + getPaddingTop() + mTaskTopMargin)
|
||||
+ (getHeight() - mInsets.bottom - getPaddingBottom() - mTaskBottomMargin)) / 2);
|
||||
setPivotX(((mInsets.left + getPaddingLeft())
|
||||
+ (getWidth() - mInsets.right - getPaddingRight())) / 2);
|
||||
// Update the pivots such that when the task is scaled, it fills the full page
|
||||
getTaskSize(mTempRect);
|
||||
getPagedViewOrientedState().getFullScreenScaleAndPivot(
|
||||
mTempRect, mActivity.getDeviceProfile(), mTempPointF);
|
||||
setPivotX(mTempPointF.x);
|
||||
setPivotY(mTempPointF.y);
|
||||
updateAdjacentPageOffset();
|
||||
}
|
||||
|
||||
private void updateAdjacentPageOffset() {
|
||||
float offset = mAdjacentPageOffset * getWidth();
|
||||
if (mIsRtl) {
|
||||
offset = -offset;
|
||||
}
|
||||
int count = getChildCount();
|
||||
|
||||
TaskView runningTask = mRunningTaskId == -1 ? null : getTaskView(mRunningTaskId);
|
||||
int midPoint = runningTask == null ? -1 : indexOfChild(runningTask);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
getChildAt(i).setTranslationX(i == midPoint ? 0 : (i < midPoint ? -offset : offset));
|
||||
}
|
||||
updateCurveProperties();
|
||||
}
|
||||
|
||||
private void updateDeadZoneRects() {
|
||||
@@ -1771,14 +1798,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
int centerTaskIndex = getCurrentPage();
|
||||
boolean launchingCenterTask = taskIndex == centerTaskIndex;
|
||||
|
||||
LauncherState.ScaleAndTranslation toScaleAndTranslation = appWindowAnimationHelper
|
||||
.getScaleAndTranslation();
|
||||
float toScale = toScaleAndTranslation.scale;
|
||||
float toTranslationY = toScaleAndTranslation.translationY;
|
||||
float toScale = appWindowAnimationHelper.getSrcToTargetScale();
|
||||
if (launchingCenterTask) {
|
||||
RecentsView recentsView = tv.getRecentsView();
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, toScale));
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y, toTranslationY));
|
||||
anim.play(ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS, 1));
|
||||
} else {
|
||||
// We are launching an adjacent task, so parallax the center and other adjacent task.
|
||||
@@ -2038,17 +2061,23 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
||||
return mClearAllButton;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return How many pixels the running task is offset on the x-axis due to the current scrollX.
|
||||
*/
|
||||
public float getScrollOffset() {
|
||||
public int getScrollOffset() {
|
||||
if (getRunningTaskIndex() == -1) {
|
||||
return 0;
|
||||
}
|
||||
int startScroll = getScrollForPage(getRunningTaskIndex());
|
||||
int offsetX = startScroll - mOrientationHandler.getPrimaryScroll(this);
|
||||
offsetX *= mOrientationHandler.getPrimaryScale(this);
|
||||
return offsetX;
|
||||
return getScrollForPage(getRunningTaskIndex()) - mOrientationHandler.getPrimaryScroll(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many pixels the running task is offset on the x-axis due to the current scrollX
|
||||
* and parent scale.
|
||||
*/
|
||||
public float getScrollOffsetScaled() {
|
||||
return getScrollOffset() * mOrientationHandler.getPrimaryScale(this);
|
||||
}
|
||||
|
||||
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
|
||||
|
||||
+179
-131
@@ -36,11 +36,9 @@ import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.util.Property;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.R;
|
||||
@@ -50,7 +48,7 @@ import com.android.launcher3.util.SystemUiController;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
|
||||
import com.android.quickstep.util.TaskCornerRadius;
|
||||
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
|
||||
import com.android.systemui.plugins.OverviewScreenshotActions;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -66,6 +64,8 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
private static final ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
|
||||
private static final RectF EMPTY_RECT_F = new RectF();
|
||||
|
||||
private static final FullscreenDrawParams TEMP_PARAMS = new FullscreenDrawParams();
|
||||
|
||||
public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
|
||||
new FloatProperty<TaskThumbnailView>("dimAlpha") {
|
||||
@Override
|
||||
@@ -87,12 +87,11 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
private final Paint mClearPaint = new Paint();
|
||||
private final Paint mDimmingPaintAfterClearing = new Paint();
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
|
||||
private float mClipBottom = -1;
|
||||
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
|
||||
private RectF mClippedInsets = new RectF();
|
||||
private TaskView.FullscreenDrawParams mFullscreenParams;
|
||||
private final Rect mPreviewRect = new Rect();
|
||||
private final PreviewPositionHelper mPreviewPositionHelper;
|
||||
// Initialize with dummy value. It is overridden later by TaskView
|
||||
private TaskView.FullscreenDrawParams mFullscreenParams = TEMP_PARAMS;
|
||||
|
||||
private Task mTask;
|
||||
private ThumbnailData mThumbnailData;
|
||||
@@ -103,7 +102,6 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
private float mSaturation = 1f;
|
||||
|
||||
private boolean mOverlayEnabled;
|
||||
private boolean mIsOrientationChanged;
|
||||
private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
|
||||
|
||||
public TaskThumbnailView(Context context) {
|
||||
@@ -123,7 +121,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
mDimmingPaintAfterClearing.setColor(Color.BLACK);
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
|
||||
mFullscreenParams = new TaskView.FullscreenDrawParams(TaskCornerRadius.get(context));
|
||||
mPreviewPositionHelper = new PreviewPositionHelper(context);
|
||||
}
|
||||
|
||||
public void bind(Task task) {
|
||||
@@ -172,8 +170,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
mOverlay.reset();
|
||||
}
|
||||
if (mOverviewScreenshotActionsPlugin != null) {
|
||||
mOverviewScreenshotActionsPlugin
|
||||
.setupActions((ViewGroup) getTaskView(), getThumbnail(), mActivity);
|
||||
mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
|
||||
}
|
||||
updateThumbnailPaintFilter();
|
||||
}
|
||||
@@ -270,9 +267,8 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
|
||||
}
|
||||
|
||||
public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
|
||||
// Don't show insets in multi window mode.
|
||||
return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
|
||||
public PreviewPositionHelper getPreviewPositionHelper() {
|
||||
return mPreviewPositionHelper;
|
||||
}
|
||||
|
||||
public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
|
||||
@@ -294,16 +290,17 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
// Draw the background in all cases, except when the thumbnail data is opaque
|
||||
final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
|
||||
|| mThumbnailData == null;
|
||||
if (drawBackgroundOnly || mClipBottom > 0 || mThumbnailData.isTranslucent) {
|
||||
if (drawBackgroundOnly || mPreviewPositionHelper.mClipBottom > 0
|
||||
|| mThumbnailData.isTranslucent) {
|
||||
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
|
||||
if (drawBackgroundOnly) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mClipBottom > 0) {
|
||||
if (mPreviewPositionHelper.mClipBottom > 0) {
|
||||
canvas.save();
|
||||
canvas.clipRect(x, y, width, mClipBottom);
|
||||
canvas.clipRect(x, y, width, mPreviewPositionHelper.mClipBottom);
|
||||
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
|
||||
canvas.restore();
|
||||
} else {
|
||||
@@ -324,8 +321,9 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
|
||||
private void updateOverlay() {
|
||||
// The overlay doesn't really work when the screenshot is rotated, so don't add it.
|
||||
if (mOverlayEnabled && !mIsOrientationChanged && mBitmapShader != null && mThumbnailData != null) {
|
||||
mOverlay.initOverlay(mTask, mThumbnailData, mMatrix);
|
||||
if (mOverlayEnabled && !mPreviewPositionHelper.mIsOrientationChanged
|
||||
&& mBitmapShader != null && mThumbnailData != null) {
|
||||
mOverlay.initOverlay(mTask, mThumbnailData, mPreviewPositionHelper.mMatrix);
|
||||
} else {
|
||||
mOverlay.reset();
|
||||
}
|
||||
@@ -346,76 +344,17 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
}
|
||||
|
||||
private void updateThumbnailMatrix() {
|
||||
boolean isRotated = false;
|
||||
boolean isOrientationDifferent = false;
|
||||
mClipBottom = -1;
|
||||
mPreviewPositionHelper.mClipBottom = -1;
|
||||
mPreviewPositionHelper.mIsOrientationChanged = false;
|
||||
if (mBitmapShader != null && mThumbnailData != null) {
|
||||
float scale = mThumbnailData.scale;
|
||||
Rect thumbnailInsets = mThumbnailData.insets;
|
||||
final float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
|
||||
(thumbnailInsets.left + thumbnailInsets.right) * scale;
|
||||
final float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
|
||||
(thumbnailInsets.top + thumbnailInsets.bottom) * scale;
|
||||
mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
|
||||
mThumbnailData.thumbnail.getHeight());
|
||||
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
|
||||
mActivity.isInMultiWindowMode(), getMeasuredWidth(), getMeasuredHeight());
|
||||
|
||||
final float thumbnailScale;
|
||||
int thumbnailRotation = mThumbnailData.rotation;
|
||||
int currentRotation = ConfigurationCompat.getWindowConfigurationRotation(
|
||||
getResources().getConfiguration());
|
||||
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
|
||||
// Landscape vs portrait change
|
||||
boolean windowingModeSupportsRotation = !mActivity.isInMultiWindowMode()
|
||||
&& mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
|
||||
isOrientationDifferent = isOrientationChange(deltaRotate)
|
||||
&& windowingModeSupportsRotation;
|
||||
if (getMeasuredWidth() == 0) {
|
||||
// If we haven't measured , skip the thumbnail drawing and only draw the background
|
||||
// color
|
||||
thumbnailScale = 0f;
|
||||
} else {
|
||||
// Rotate the screenshot if not in multi-window mode
|
||||
isRotated = deltaRotate > 0 && windowingModeSupportsRotation;
|
||||
// Scale the screenshot to always fit the width of the card.
|
||||
|
||||
thumbnailScale = isOrientationDifferent
|
||||
? getMeasuredWidth() / thumbnailHeight
|
||||
: getMeasuredWidth() / thumbnailWidth;
|
||||
}
|
||||
|
||||
if (!isRotated) {
|
||||
// No Rotation
|
||||
mClippedInsets.offsetTo(thumbnailInsets.left * scale,
|
||||
thumbnailInsets.top * scale);
|
||||
mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
|
||||
} else {
|
||||
setThumbnailRotation(deltaRotate, thumbnailInsets, scale);
|
||||
}
|
||||
|
||||
final float widthWithInsets;
|
||||
final float heightWithInsets;
|
||||
if (isOrientationDifferent) {
|
||||
widthWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
|
||||
heightWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
|
||||
} else {
|
||||
widthWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
|
||||
heightWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
|
||||
}
|
||||
mClippedInsets.left *= thumbnailScale;
|
||||
mClippedInsets.top *= thumbnailScale;
|
||||
mClippedInsets.right = widthWithInsets - mClippedInsets.left - getMeasuredWidth();
|
||||
mClippedInsets.bottom = heightWithInsets - mClippedInsets.top - getMeasuredHeight();
|
||||
|
||||
mMatrix.postScale(thumbnailScale, thumbnailScale);
|
||||
mBitmapShader.setLocalMatrix(mMatrix);
|
||||
|
||||
float bitmapHeight = Math.max((isOrientationDifferent ? thumbnailWidth : thumbnailHeight)
|
||||
* thumbnailScale, 0);
|
||||
if (Math.round(bitmapHeight) < getMeasuredHeight()) {
|
||||
mClipBottom = bitmapHeight;
|
||||
}
|
||||
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix);
|
||||
mPaint.setShader(mBitmapShader);
|
||||
}
|
||||
|
||||
mIsOrientationChanged = isOrientationDifferent;
|
||||
invalidate();
|
||||
|
||||
// Update can be called from {@link #onSizeChanged} during layout, post handling of overlay
|
||||
@@ -423,51 +362,6 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
post(this::updateOverlay);
|
||||
}
|
||||
|
||||
private int getRotationDelta(int oldRotation, int newRotation) {
|
||||
int delta = newRotation - oldRotation;
|
||||
if (delta < 0) delta += 4;
|
||||
return delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deltaRotation the number of 90 degree turns from the current orientation
|
||||
* @return {@code true} if the change in rotation results in a shift from landscape to portrait
|
||||
* or vice versa, {@code false} otherwise
|
||||
*/
|
||||
private boolean isOrientationChange(int deltaRotation) {
|
||||
return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270;
|
||||
}
|
||||
|
||||
private void setThumbnailRotation(int deltaRotate, Rect thumbnailInsets, float scale) {
|
||||
int newLeftInset = 0;
|
||||
int newTopInset = 0;
|
||||
int translateX = 0;
|
||||
int translateY = 0;
|
||||
|
||||
mMatrix.setRotate(90 * deltaRotate);
|
||||
switch (deltaRotate) { /* Counter-clockwise */
|
||||
case Surface.ROTATION_90:
|
||||
newLeftInset = thumbnailInsets.bottom;
|
||||
newTopInset = thumbnailInsets.left;
|
||||
translateX = mThumbnailData.thumbnail.getHeight();
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
newLeftInset = thumbnailInsets.top;
|
||||
newTopInset = thumbnailInsets.right;
|
||||
translateY = mThumbnailData.thumbnail.getWidth();
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
newLeftInset = -thumbnailInsets.top;
|
||||
newTopInset = -thumbnailInsets.left;
|
||||
translateX = mThumbnailData.thumbnail.getWidth();
|
||||
translateY = mThumbnailData.thumbnail.getHeight();
|
||||
break;
|
||||
}
|
||||
mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
|
||||
mMatrix.postTranslate(translateX - mClippedInsets.left,
|
||||
translateY - mClippedInsets.top);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
@@ -511,4 +405,158 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
}
|
||||
return mThumbnailData.thumbnail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to position the thumbnail in the TaskView
|
||||
*/
|
||||
public static class PreviewPositionHelper {
|
||||
|
||||
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
|
||||
private final RectF mClippedInsets = new RectF();
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private float mClipBottom = -1;
|
||||
private boolean mIsOrientationChanged;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public PreviewPositionHelper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public int getCurrentRotation() {
|
||||
return ConfigurationCompat.getWindowConfigurationRotation(
|
||||
mContext.getResources().getConfiguration());
|
||||
}
|
||||
|
||||
public Matrix getMatrix() {
|
||||
return mMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the matrix based on the provided parameters
|
||||
*/
|
||||
public void updateThumbnailMatrix(Rect thumbnailPosition, ThumbnailData thumbnailData,
|
||||
boolean isInMultiWindowMode, int canvasWidth, int canvasHeight) {
|
||||
boolean isRotated = false;
|
||||
boolean isOrientationDifferent;
|
||||
mClipBottom = -1;
|
||||
|
||||
float scale = thumbnailData.scale;
|
||||
Rect thumbnailInsets = thumbnailData.insets;
|
||||
final float thumbnailWidth = thumbnailPosition.width()
|
||||
- (thumbnailInsets.left + thumbnailInsets.right) * scale;
|
||||
final float thumbnailHeight = thumbnailPosition.height()
|
||||
- (thumbnailInsets.top + thumbnailInsets.bottom) * scale;
|
||||
|
||||
final float thumbnailScale;
|
||||
int thumbnailRotation = thumbnailData.rotation;
|
||||
int currentRotation = getCurrentRotation();
|
||||
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
|
||||
|
||||
// Landscape vs portrait change
|
||||
boolean windowingModeSupportsRotation = !isInMultiWindowMode
|
||||
&& thumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
|
||||
isOrientationDifferent = isOrientationChange(deltaRotate)
|
||||
&& windowingModeSupportsRotation;
|
||||
if (canvasWidth == 0) {
|
||||
// If we haven't measured , skip the thumbnail drawing and only draw the background
|
||||
// color
|
||||
thumbnailScale = 0f;
|
||||
} else {
|
||||
// Rotate the screenshot if not in multi-window mode
|
||||
isRotated = deltaRotate > 0 && windowingModeSupportsRotation;
|
||||
// Scale the screenshot to always fit the width of the card.
|
||||
thumbnailScale = isOrientationDifferent
|
||||
? canvasWidth / thumbnailHeight
|
||||
: canvasWidth / thumbnailWidth;
|
||||
}
|
||||
|
||||
if (!isRotated) {
|
||||
// No Rotation
|
||||
mClippedInsets.offsetTo(thumbnailInsets.left * scale,
|
||||
thumbnailInsets.top * scale);
|
||||
mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
|
||||
} else {
|
||||
setThumbnailRotation(deltaRotate, thumbnailInsets, scale, thumbnailPosition);
|
||||
}
|
||||
mMatrix.postTranslate(-thumbnailPosition.left, -thumbnailPosition.top);
|
||||
|
||||
final float widthWithInsets;
|
||||
final float heightWithInsets;
|
||||
if (isOrientationDifferent) {
|
||||
widthWithInsets = thumbnailPosition.height() * thumbnailScale;
|
||||
heightWithInsets = thumbnailPosition.width() * thumbnailScale;
|
||||
} else {
|
||||
widthWithInsets = thumbnailPosition.width() * thumbnailScale;
|
||||
heightWithInsets = thumbnailPosition.height() * thumbnailScale;
|
||||
}
|
||||
mClippedInsets.left *= thumbnailScale;
|
||||
mClippedInsets.top *= thumbnailScale;
|
||||
mClippedInsets.right = widthWithInsets - mClippedInsets.left - canvasWidth;
|
||||
mClippedInsets.bottom = heightWithInsets - mClippedInsets.top - canvasHeight;
|
||||
|
||||
mMatrix.postScale(thumbnailScale, thumbnailScale);
|
||||
|
||||
float bitmapHeight = Math.max(0,
|
||||
(isOrientationDifferent ? thumbnailWidth : thumbnailHeight) * thumbnailScale);
|
||||
if (Math.round(bitmapHeight) < canvasHeight) {
|
||||
mClipBottom = bitmapHeight;
|
||||
}
|
||||
mIsOrientationChanged = isOrientationDifferent;
|
||||
}
|
||||
|
||||
private int getRotationDelta(int oldRotation, int newRotation) {
|
||||
int delta = newRotation - oldRotation;
|
||||
if (delta < 0) delta += 4;
|
||||
return delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deltaRotation the number of 90 degree turns from the current orientation
|
||||
* @return {@code true} if the change in rotation results in a shift from landscape to
|
||||
* portrait or vice versa, {@code false} otherwise
|
||||
*/
|
||||
private boolean isOrientationChange(int deltaRotation) {
|
||||
return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270;
|
||||
}
|
||||
|
||||
private void setThumbnailRotation(int deltaRotate, Rect thumbnailInsets, float scale,
|
||||
Rect thumbnailPosition) {
|
||||
int newLeftInset = 0;
|
||||
int newTopInset = 0;
|
||||
int translateX = 0;
|
||||
int translateY = 0;
|
||||
|
||||
mMatrix.setRotate(90 * deltaRotate);
|
||||
switch (deltaRotate) { /* Counter-clockwise */
|
||||
case Surface.ROTATION_90:
|
||||
newLeftInset = thumbnailInsets.bottom;
|
||||
newTopInset = thumbnailInsets.left;
|
||||
translateX = thumbnailPosition.height();
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
newLeftInset = thumbnailInsets.top;
|
||||
newTopInset = thumbnailInsets.right;
|
||||
translateY = thumbnailPosition.width();
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
newLeftInset = -thumbnailInsets.top;
|
||||
newTopInset = -thumbnailInsets.left;
|
||||
translateX = thumbnailPosition.width();
|
||||
translateY = thumbnailPosition.height();
|
||||
break;
|
||||
}
|
||||
mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
|
||||
mMatrix.postTranslate(translateX - mClippedInsets.left,
|
||||
translateY - mClippedInsets.top);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insets to used for clipping the thumbnail (in case it is drawing outside its own space)
|
||||
*/
|
||||
public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
|
||||
// Don't show insets in multi window mode.
|
||||
return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
@@ -77,11 +78,11 @@ import com.android.quickstep.TaskIconCache;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
import com.android.quickstep.TaskThumbnailCache;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.util.TaskCornerRadius;
|
||||
import com.android.quickstep.views.RecentsView.PageCallbacks;
|
||||
import com.android.quickstep.views.RecentsView.ScrollState;
|
||||
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||
@@ -157,8 +158,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
private float mCurveScale;
|
||||
private float mFullscreenProgress;
|
||||
private final FullscreenDrawParams mCurrentFullscreenParams;
|
||||
private final float mCornerRadius;
|
||||
private final float mWindowCornerRadius;
|
||||
private final BaseDraggingActivity mActivity;
|
||||
|
||||
private ObjectAnimator mIconAndDimAnimator;
|
||||
@@ -211,9 +210,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
|
||||
mActivity.getStatsLogManager().log(TASK_LAUNCH_TAP, buildProto());
|
||||
});
|
||||
mCornerRadius = TaskCornerRadius.get(context);
|
||||
mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
|
||||
mCurrentFullscreenParams = new FullscreenDrawParams(mCornerRadius);
|
||||
|
||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||
mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
|
||||
|
||||
mOutlineProvider = new TaskOutlineProvider(getContext(), mCurrentFullscreenParams);
|
||||
@@ -236,11 +234,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
super.onFinishInflate();
|
||||
mSnapshotView = findViewById(R.id.snapshot);
|
||||
mIconView = findViewById(R.id.icon);
|
||||
final Context context = getContext();
|
||||
|
||||
TaskView.LayoutParams thumbnailParams = (LayoutParams) mSnapshotView.getLayoutParams();
|
||||
thumbnailParams.bottomMargin = LayoutUtils.thumbnailBottomMargin(context);
|
||||
mSnapshotView.setLayoutParams(thumbnailParams);
|
||||
}
|
||||
|
||||
public boolean isTaskOverlayModal() {
|
||||
@@ -473,8 +466,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
int iconRotation = orientationState.getTouchRotation();
|
||||
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
|
||||
boolean isRtl = orientationHandler.getRecentsRtlSetting(getResources());
|
||||
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
|
||||
snapshotParams.bottomMargin = LayoutUtils.thumbnailBottomMargin(getContext());
|
||||
int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
|
||||
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
|
||||
int rotation = orientationState.getTouchRotationDegrees();
|
||||
@@ -501,7 +492,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
iconParams.bottomMargin = 0;
|
||||
break;
|
||||
}
|
||||
mSnapshotView.setLayoutParams(snapshotParams);
|
||||
mIconView.setLayoutParams(iconParams);
|
||||
mIconView.setRotation(rotation);
|
||||
}
|
||||
@@ -699,21 +689,16 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
|
||||
}
|
||||
|
||||
public void setCurveScale(float curveScale) {
|
||||
private void setCurveScale(float curveScale) {
|
||||
mCurveScale = curveScale;
|
||||
onScaleChanged();
|
||||
setScaleX(mCurveScale);
|
||||
setScaleY(mCurveScale);
|
||||
}
|
||||
|
||||
public float getCurveScale() {
|
||||
return mCurveScale;
|
||||
}
|
||||
|
||||
private void onScaleChanged() {
|
||||
float scale = mCurveScale;
|
||||
setScaleX(scale);
|
||||
setScaleY(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
// TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
|
||||
@@ -723,13 +708,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
private static final class TaskOutlineProvider extends ViewOutlineProvider {
|
||||
|
||||
private final int mMarginTop;
|
||||
private final int mMarginBottom;
|
||||
private FullscreenDrawParams mFullscreenParams;
|
||||
|
||||
TaskOutlineProvider(Context context, FullscreenDrawParams fullscreenParams) {
|
||||
mMarginTop = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.task_thumbnail_top_margin);
|
||||
mMarginBottom = LayoutUtils.thumbnailBottomMargin(context);
|
||||
mFullscreenParams = fullscreenParams;
|
||||
}
|
||||
|
||||
@@ -744,7 +727,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
outline.setRoundRect(0,
|
||||
(int) (mMarginTop * scale),
|
||||
(int) ((insets.left + view.getWidth() + insets.right) * scale),
|
||||
(int) ((insets.top + view.getHeight() + insets.bottom - mMarginBottom) * scale),
|
||||
(int) ((insets.top + view.getHeight() + insets.bottom) * scale),
|
||||
mFullscreenParams.mCurrentDrawnCornerRadius);
|
||||
}
|
||||
}
|
||||
@@ -917,23 +900,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
setClipToPadding(!isFullscreen);
|
||||
|
||||
TaskThumbnailView thumbnail = getThumbnail();
|
||||
boolean isMultiWindowMode = mActivity.getDeviceProfile().isMultiWindowMode;
|
||||
RectF insets = thumbnail.getInsetsToDrawInFullscreen(isMultiWindowMode);
|
||||
float currentInsetsLeft = insets.left * mFullscreenProgress;
|
||||
float currentInsetsRight = insets.right * mFullscreenProgress;
|
||||
mCurrentFullscreenParams.setInsets(currentInsetsLeft,
|
||||
insets.top * mFullscreenProgress,
|
||||
currentInsetsRight,
|
||||
insets.bottom * mFullscreenProgress);
|
||||
float fullscreenCornerRadius = isMultiWindowMode ? 0 : mWindowCornerRadius;
|
||||
mCurrentFullscreenParams.setCornerRadius(Utilities.mapRange(mFullscreenProgress,
|
||||
mCornerRadius, fullscreenCornerRadius) / getRecentsView().getScaleX());
|
||||
// We scaled the thumbnail to fit the content (excluding insets) within task view width.
|
||||
// Now that we are drawing left/right insets again, we need to scale down to fit them.
|
||||
if (getWidth() > 0) {
|
||||
mCurrentFullscreenParams.setScale(getWidth()
|
||||
/ (getWidth() + currentInsetsLeft + currentInsetsRight));
|
||||
}
|
||||
mCurrentFullscreenParams.setProgress(
|
||||
mFullscreenProgress,
|
||||
getRecentsView().getScaleX(),
|
||||
getWidth(), mActivity.getDeviceProfile(),
|
||||
thumbnail.getPreviewPositionHelper());
|
||||
|
||||
if (!getRecentsView().isTaskIconScaledDown(this)) {
|
||||
// Some of the items in here are dependent on the current fullscreen params, but don't
|
||||
@@ -971,26 +942,51 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
/**
|
||||
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
|
||||
*/
|
||||
static class FullscreenDrawParams {
|
||||
RectF mCurrentDrawnInsets = new RectF();
|
||||
float mCurrentDrawnCornerRadius;
|
||||
public static class FullscreenDrawParams {
|
||||
|
||||
private final float mCornerRadius;
|
||||
private final float mWindowCornerRadius;
|
||||
|
||||
public RectF mCurrentDrawnInsets = new RectF();
|
||||
public float mCurrentDrawnCornerRadius;
|
||||
/** The current scale we apply to the thumbnail to adjust for new left/right insets. */
|
||||
float mScale = 1;
|
||||
public float mScale = 1;
|
||||
|
||||
public FullscreenDrawParams(float cornerRadius) {
|
||||
setCornerRadius(cornerRadius);
|
||||
public FullscreenDrawParams(Context context) {
|
||||
mCornerRadius = TaskCornerRadius.get(context);
|
||||
mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
|
||||
|
||||
mCurrentDrawnCornerRadius = mCornerRadius;
|
||||
}
|
||||
|
||||
public void setInsets(float left, float top, float right, float bottom) {
|
||||
mCurrentDrawnInsets.set(left, top, right, bottom);
|
||||
public FullscreenDrawParams() {
|
||||
mCurrentDrawnCornerRadius = mWindowCornerRadius = mCornerRadius = 0;
|
||||
}
|
||||
|
||||
public void setCornerRadius(float cornerRadius) {
|
||||
mCurrentDrawnCornerRadius = cornerRadius;
|
||||
/**
|
||||
* Sets the progress in range [0, 1]
|
||||
*/
|
||||
public void setProgress(float fullscreenProgress, float parentScale, int previewWidth,
|
||||
DeviceProfile dp, PreviewPositionHelper pph) {
|
||||
boolean isMultiWindowMode = dp.isMultiWindowMode;
|
||||
RectF insets = pph.getInsetsToDrawInFullscreen(isMultiWindowMode);
|
||||
|
||||
float currentInsetsLeft = insets.left * fullscreenProgress;
|
||||
float currentInsetsRight = insets.right * fullscreenProgress;
|
||||
mCurrentDrawnInsets.set(currentInsetsLeft, insets.top * fullscreenProgress,
|
||||
currentInsetsRight, insets.bottom * fullscreenProgress);
|
||||
float fullscreenCornerRadius = isMultiWindowMode ? 0 : mWindowCornerRadius;
|
||||
|
||||
mCurrentDrawnCornerRadius =
|
||||
Utilities.mapRange(fullscreenProgress, mCornerRadius, fullscreenCornerRadius)
|
||||
/ parentScale;
|
||||
|
||||
// We scaled the thumbnail to fit the content (excluding insets) within task view width.
|
||||
// Now that we are drawing left/right insets again, we need to scale down to fit them.
|
||||
if (previewWidth > 0) {
|
||||
mScale = previewWidth / (previewWidth + currentInsetsLeft + currentInsetsRight);
|
||||
}
|
||||
}
|
||||
|
||||
public void setScale(float scale) {
|
||||
mScale = scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.WellbeingModel;
|
||||
@@ -38,7 +37,6 @@ import com.android.launcher3.proxy.ProxyActivityStarter;
|
||||
import com.android.launcher3.proxy.StartActivityParams;
|
||||
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.uioverrides.RecentsViewStateController;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
@@ -204,17 +202,6 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
return new QuickstepOnboardingPrefs(this, sharedPrefs, stateManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScaleAndTranslation getOverviewScaleAndTranslationForNormalState() {
|
||||
if (SysUINavigationMode.getMode(this) == Mode.NO_BUTTON) {
|
||||
PagedOrientationHandler layoutVertical =
|
||||
((RecentsView)getOverviewPanel()).getPagedViewOrientedState().getOrientationHandler();
|
||||
return layoutVertical.getScaleAndTranslation(getDeviceProfile(),
|
||||
getOverviewPanel());
|
||||
}
|
||||
return super.getOverviewScaleAndTranslationForNormalState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
|
||||
QuickstepAppTransitionManagerImpl appTransitionManager =
|
||||
@@ -237,6 +224,12 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
}, signal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getNormalOverviewScaleAndOffset() {
|
||||
return SysUINavigationMode.getMode(this) == Mode.NO_BUTTON
|
||||
? new float[] {1, 1} : new float[] {1.1f, 0};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragLayerHierarchyChanged() {
|
||||
onLauncherStateOrFocusChanged();
|
||||
|
||||
+9
-23
@@ -17,8 +17,6 @@
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
|
||||
@@ -26,23 +24,22 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FA
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
* State handler for recents view. Manages UI changes and animations for recents view based off the
|
||||
@@ -50,7 +47,7 @@ import com.android.launcher3.states.StateAnimationConfig;
|
||||
*
|
||||
* @param <T> the recents view
|
||||
*/
|
||||
public abstract class BaseRecentsViewStateController<T extends View>
|
||||
public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
implements StateHandler {
|
||||
protected final T mRecentsView;
|
||||
protected final BaseQuickstepLauncher mLauncher;
|
||||
@@ -62,14 +59,9 @@ public abstract class BaseRecentsViewStateController<T extends View>
|
||||
|
||||
@Override
|
||||
public void setState(@NonNull LauncherState state) {
|
||||
ScaleAndTranslation scaleAndTranslation = state.getOverviewScaleAndTranslation(mLauncher);
|
||||
float translationX = scaleAndTranslation.translationX;
|
||||
if (mRecentsView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
|
||||
translationX = -translationX;
|
||||
}
|
||||
SCALE_PROPERTY.set(mRecentsView, scaleAndTranslation.scale);
|
||||
mRecentsView.setTranslationX(translationX);
|
||||
mRecentsView.setTranslationY(scaleAndTranslation.translationY);
|
||||
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
|
||||
SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
|
||||
ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]);
|
||||
|
||||
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
|
||||
OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
|
||||
@@ -98,17 +90,11 @@ public abstract class BaseRecentsViewStateController<T extends View>
|
||||
*/
|
||||
void setStateWithAnimationInternal(@NonNull final LauncherState toState,
|
||||
@NonNull StateAnimationConfig config, @NonNull PendingAnimation setter) {
|
||||
ScaleAndTranslation scaleAndTranslation = toState.getOverviewScaleAndTranslation(mLauncher);
|
||||
float translationX = scaleAndTranslation.translationX;
|
||||
if (mRecentsView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
|
||||
translationX = -translationX;
|
||||
}
|
||||
setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleAndTranslation.scale,
|
||||
float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
|
||||
setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleAndOffset[0],
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||
setter.setFloat(mRecentsView, VIEW_TRANSLATE_X, translationX,
|
||||
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||
setter.setFloat(mRecentsView, VIEW_TRANSLATE_Y, scaleAndTranslation.translationY,
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
|
||||
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
|
||||
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
|
||||
|
||||
@@ -102,9 +102,8 @@ public class AllAppsState extends LauncherState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
|
||||
float slightParallax = -launcher.getDeviceProfile().allAppsCellHeightPx * 0.3f;
|
||||
return new ScaleAndTranslation(0.9f, 0f, slightParallax);
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {0.9f, 0};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -135,8 +135,6 @@ public interface BaseActivityInterface<T extends BaseDraggingActivity> {
|
||||
|
||||
void createActivityInterface(long transitionLength);
|
||||
|
||||
default void adjustActivityControllerInterpolators() { }
|
||||
|
||||
default void onTransitionCancelled() { }
|
||||
|
||||
default void setShelfState(ShelfPeekAnim.ShelfAnimState animState,
|
||||
|
||||
@@ -63,7 +63,7 @@ public class LayoutUtils {
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
|
||||
//TODO: this needs to account for the swipe gesture height and accessibility
|
||||
// UI when shown.
|
||||
extraSpace = 0;
|
||||
extraSpace = res.getDimensionPixelSize(R.dimen.overview_actions_height);
|
||||
} else {
|
||||
extraSpace = getDefaultSwipeHeight(context, dp) + dp.workspacePageIndicatorHeight
|
||||
+ res.getDimensionPixelSize(
|
||||
@@ -75,7 +75,14 @@ public class LayoutUtils {
|
||||
}
|
||||
|
||||
public static void calculateFallbackTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||
calculateTaskSize(context, dp, 0, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE, outRect);
|
||||
float extraSpace;
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
|
||||
extraSpace = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.overview_actions_height);
|
||||
} else {
|
||||
extraSpace = 0;
|
||||
}
|
||||
calculateTaskSize(context, dp, extraSpace, MULTI_WINDOW_STRATEGY_DEVICE_PROFILE, outRect);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -123,8 +130,6 @@ public class LayoutUtils {
|
||||
}
|
||||
|
||||
float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
|
||||
float bottomMargin = thumbnailBottomMargin(context);
|
||||
|
||||
float paddingVert = overviewActionsEnabled && removeShelfFromOverview(context)
|
||||
? 0 : res.getDimension(R.dimen.task_card_vert_space);
|
||||
|
||||
@@ -134,7 +139,7 @@ public class LayoutUtils {
|
||||
int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
|
||||
|
||||
float availableHeight = launcherVisibleHeight
|
||||
- topIconMargin - extraVerticalSpace - paddingVert - bottomMargin;
|
||||
- topIconMargin - extraVerticalSpace - paddingVert;
|
||||
float availableWidth = launcherVisibleWidth - paddingHorz;
|
||||
|
||||
float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
|
||||
@@ -144,7 +149,7 @@ public class LayoutUtils {
|
||||
// Center in the visible space
|
||||
float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
|
||||
float y = insets.top + Math.max(topIconMargin,
|
||||
(launcherVisibleHeight - extraVerticalSpace - outHeight - bottomMargin) / 2);
|
||||
(launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
|
||||
outRect.set(Math.round(x), Math.round(y),
|
||||
Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
|
||||
}
|
||||
@@ -163,14 +168,16 @@ public class LayoutUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the margin that the task thumbnail view should use.
|
||||
* @return the margin in pixels.
|
||||
* Gets the scale that should be applied to the TaskView so that it matches the target
|
||||
*/
|
||||
public static int thumbnailBottomMargin(Context context) {
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) {
|
||||
return context.getResources().getDimensionPixelSize(R.dimen.overview_actions_height);
|
||||
public static float getTaskScale(RecentsOrientedState orientedState,
|
||||
float srcWidth, float srcHeight, float targetWidth, float targetHeight) {
|
||||
if (orientedState == null
|
||||
|| orientedState.isHomeRotationAllowed()
|
||||
|| orientedState.isDisplayPhoneNatural()) {
|
||||
return srcWidth / targetWidth;
|
||||
} else {
|
||||
return 0;
|
||||
return srcHeight / targetHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.android.quickstep.util;
|
||||
|
||||
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_180;
|
||||
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.Surface.ROTATION_180;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATI
|
||||
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
|
||||
import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
@@ -36,6 +37,8 @@ import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
@@ -45,6 +48,7 @@ import android.view.Surface;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
@@ -135,7 +139,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
||||
*/
|
||||
public boolean update(
|
||||
@SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation,
|
||||
int launcherRotation) {
|
||||
@SurfaceRotation int launcherRotation) {
|
||||
if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
|
||||
return false;
|
||||
}
|
||||
@@ -277,6 +281,25 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scale and pivot so that the provided taskRect can fit the provided full size
|
||||
*/
|
||||
public float getFullScreenScaleAndPivot(Rect taskView, DeviceProfile dp, PointF outPivot) {
|
||||
Rect insets = dp.getInsets();
|
||||
float fullWidth = dp.widthPx - insets.left - insets.right;
|
||||
float fullHeight = dp.heightPx - insets.top - insets.bottom;
|
||||
final float scale = LayoutUtils.getTaskScale(this,
|
||||
fullWidth, fullHeight, taskView.width(), taskView.height());
|
||||
|
||||
if (scale == 1) {
|
||||
outPivot.set(fullWidth / 2, fullHeight / 2);
|
||||
} else {
|
||||
float factor = scale / (scale - 1);
|
||||
outPivot.set(taskView.left * factor, taskView.top * factor);
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
public PagedOrientationHandler getOrientationHandler() {
|
||||
return mOrientationHandler;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
|
||||
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.NO_OFFSET;
|
||||
import static com.android.launcher3.LauncherState.NO_SCALE;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
@@ -85,7 +87,6 @@ import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.DropTarget.DragObject;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
@@ -2698,10 +2699,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
return new TouchController[] {getDragController(), new AllAppsSwipeController(this)};
|
||||
}
|
||||
|
||||
protected ScaleAndTranslation getOverviewScaleAndTranslationForNormalState() {
|
||||
return new ScaleAndTranslation(1.1f, 0f, 0f);
|
||||
}
|
||||
|
||||
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) { }
|
||||
|
||||
public void onDragLayerHierarchyChanged() { }
|
||||
@@ -2724,6 +2721,14 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
return Stream.of(APP_INFO, WIDGETS, INSTALL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see LauncherState#getOverviewScaleAndOffset(Launcher)
|
||||
*/
|
||||
public float[] getNormalOverviewScaleAndOffset() {
|
||||
return new float[] {NO_SCALE, NO_OFFSET};
|
||||
}
|
||||
|
||||
public static Launcher getLauncher(Context context) {
|
||||
return fromContext(context);
|
||||
}
|
||||
@@ -2735,6 +2740,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
return (T) activityContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for listening for onResume
|
||||
*/
|
||||
|
||||
@@ -90,6 +90,9 @@ public abstract class LauncherState {
|
||||
protected static final int FLAG_HIDE_BACK_BUTTON = 1 << 8;
|
||||
protected static final int FLAG_HAS_SYS_UI_SCRIM = 1 << 9;
|
||||
|
||||
public static final float NO_OFFSET = 0;
|
||||
public static final float NO_SCALE = 1;
|
||||
|
||||
protected static final PageAlphaProvider DEFAULT_ALPHA_PROVIDER =
|
||||
new PageAlphaProvider(ACCEL_2) {
|
||||
@Override
|
||||
@@ -220,7 +223,7 @@ public abstract class LauncherState {
|
||||
public abstract int getTransitionDuration(Launcher launcher);
|
||||
|
||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||
return new ScaleAndTranslation(1, 0, 0);
|
||||
return new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
||||
}
|
||||
|
||||
public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) {
|
||||
@@ -228,12 +231,18 @@ public abstract class LauncherState {
|
||||
return getWorkspaceScaleAndTranslation(launcher);
|
||||
}
|
||||
|
||||
public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) {
|
||||
return launcher.getOverviewScaleAndTranslationForNormalState();
|
||||
/**
|
||||
* Returns an array of two elements.
|
||||
* The first specifies the scale for the overview
|
||||
* The second is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview
|
||||
* should be shifted horizontally.
|
||||
*/
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return launcher.getNormalOverviewScaleAndOffset();
|
||||
}
|
||||
|
||||
public ScaleAndTranslation getQsbScaleAndTranslation(Launcher launcher) {
|
||||
return new ScaleAndTranslation(1, 0, 0);
|
||||
return new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
||||
}
|
||||
|
||||
public float getOverviewFullscreenProgress() {
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.PagedView;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.OverScroller;
|
||||
@@ -119,11 +118,6 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
return view.getMeasuredHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrimarySize(Rect rect) {
|
||||
return rect.height();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPrimarySize(RectF rect) {
|
||||
return rect.height();
|
||||
@@ -134,17 +128,6 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
return view.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getScaleAndTranslation(DeviceProfile dp, View view) {
|
||||
float offscreenTranslationY = dp.heightPx - view.getPaddingTop();
|
||||
return new ScaleAndTranslation(1f, 0f, offscreenTranslationY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationValue(ScaleAndTranslation scaleAndTranslation) {
|
||||
return scaleAndTranslation.translationY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatProperty<View> getPrimaryViewTranslate() {
|
||||
return VIEW_TRANSLATE_Y;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher3.touch;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
@@ -28,7 +29,6 @@ import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.PagedView;
|
||||
import com.android.launcher3.util.OverScroller;
|
||||
|
||||
@@ -53,16 +53,15 @@ public interface PagedOrientationHandler {
|
||||
Int2DAction<View> VIEW_SCROLL_BY = View::scrollBy;
|
||||
Int2DAction<View> VIEW_SCROLL_TO = View::scrollTo;
|
||||
Float2DAction<Canvas> CANVAS_TRANSLATE = Canvas::translate;
|
||||
Float2DAction<Matrix> MATRIX_POST_TRANSLATE = Matrix::postTranslate;
|
||||
|
||||
<T> void set(T target, Int2DAction<T> action, int param);
|
||||
<T> void set(T target, Float2DAction<T> action, float param);
|
||||
float getPrimaryDirection(MotionEvent event, int pointerIndex);
|
||||
float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId);
|
||||
int getMeasuredSize(View view);
|
||||
int getPrimarySize(Rect rect);
|
||||
float getPrimarySize(RectF rect);
|
||||
int getSecondaryDimension(View view);
|
||||
LauncherState.ScaleAndTranslation getScaleAndTranslation(DeviceProfile dp, View view);
|
||||
float getTranslationValue(LauncherState.ScaleAndTranslation scaleAndTranslation);
|
||||
FloatProperty<View> getPrimaryViewTranslate();
|
||||
FloatProperty<View> getSecondaryViewTranslate();
|
||||
void setPrimaryAndResetSecondaryTranslate(View view, float translation);
|
||||
@@ -98,7 +97,6 @@ public interface PagedOrientationHandler {
|
||||
*/
|
||||
void adjustFloatingIconStartVelocity(PointF velocity);
|
||||
|
||||
|
||||
class CurveProperties {
|
||||
public int scroll;
|
||||
public int halfPageSize;
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.PagedView;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.OverScroller;
|
||||
@@ -117,11 +116,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
return view.getMeasuredWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrimarySize(Rect rect) {
|
||||
return rect.width();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPrimarySize(RectF rect) {
|
||||
return rect.width();
|
||||
@@ -132,17 +126,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
return view.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getScaleAndTranslation(DeviceProfile dp, View view) {
|
||||
float offscreenTranslationX = dp.widthPx - view.getPaddingStart();
|
||||
return new ScaleAndTranslation(1f, offscreenTranslationX, 0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationValue(ScaleAndTranslation scaleAndTranslation) {
|
||||
return scaleAndTranslation.translationX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatProperty<View> getPrimaryViewTranslate() {
|
||||
return VIEW_TRANSLATE_X;
|
||||
|
||||
Reference in New Issue
Block a user