Merge "add CHAR LIMIT for home settings menu" into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 0019ecb..6c64bf7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -30,6 +30,7 @@
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.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.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 @@
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)
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index a87d6d1..e57e841 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -61,13 +61,16 @@
}
@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 @@
} else {
dummyTask = recentsView.getTaskViewAt(0);
}
- return recentsView.getTempAppWindowAnimationHelper().updateForFullscreenOverview(dummyTask)
- .getScaleAndTranslation();
+ return recentsView.getTempAppWindowAnimationHelper()
+ .updateForFullscreenOverview(dummyTask).getSrcToTargetScale();
}
@Override
@@ -106,7 +109,7 @@
}
@Override
- public float getDepth(Context context) {
+ protected float getDepthUnchecked(Context context) {
return 1f;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
index 1288e7b..b27f16a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
@@ -24,24 +24,18 @@
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
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index fc28da3..e44f59f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -24,7 +24,6 @@
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 @@
}
@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
@@ -204,7 +203,7 @@
}
@Override
- public float getDepth(Context context) {
+ protected float getDepthUnchecked(Context context) {
return 1f;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index c92a872..f4f8bc9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -40,17 +40,15 @@
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.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 @@
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();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 3513ad5..32ab98b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -135,8 +135,15 @@
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 @@
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 @@
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 @@
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 @@
*/
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)
@@ -459,6 +472,7 @@
FloatingIconView fiv = (FloatingIconView) floatingView;
anim.addAnimatorListener(fiv);
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ fiv.setFastFinishRunnable(anim::end);
}
AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
index b4492d8..1b2979b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -129,6 +129,7 @@
mEndTargetAnimationParams.put(LAST_TASK, new EndTargetAnimationParams(0, 150, 1));
mEndTargetAnimationParams.put(NEW_TASK, new EndTargetAnimationParams(0, 150, 1));
+ initAfterSubclassConstructor();
initStateCallbacks();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index 455ae76..b4764dc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -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.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.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 @@
*/
public final class LauncherActivityInterface implements BaseActivityInterface<Launcher> {
- private Runnable mAdjustInterpolatorsRunnable;
private Pair<Float, Float> mSwipeUpPullbackStartAndMaxProgress =
BaseActivityInterface.super.getSwipeUpPullbackStartAndMaxProgress();
@@ -243,14 +238,6 @@
}
@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 @@
.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 @@
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);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
index 31a2814..5a64382 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
@@ -17,6 +17,8 @@
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 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.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.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 @@
private AnimatorPlaybackController mLauncherTransitionController;
private boolean mHasLauncherTransitionControllerStarted;
+ private final TaskViewSimulator mTaskViewSimulator;
+ private AnimatorPlaybackController mWindowTransitionController;
+
private AnimationFactory mAnimationFactory = (t) -> { };
private boolean mWasLauncherAlreadyVisible;
@@ -201,6 +208,9 @@
mTaskAnimationManager = taskAnimationManager;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
+ mTaskViewSimulator = new TaskViewSimulator(context, LayoutUtils::calculateLauncherTaskSize);
+
+ initAfterSubclassConstructor();
initStateCallbacks();
}
@@ -473,23 +483,11 @@
} 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 @@
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 @@
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
mLauncherTransitionController = anim;
mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
- mAnimationFactory.adjustActivityControllerInterpolators();
mLauncherTransitionController.dispatchOnStart();
updateLauncherTransitionProgress();
}
@@ -555,7 +580,9 @@
@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 @@
}
}
+ 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 @@
mLauncherTransitionController.dispatchSetInterpolator(t -> end);
} else {
mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
- mAnimationFactory.adjustActivityControllerInterpolators();
}
mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));
@@ -1296,6 +1332,7 @@
private void setTargetAlphaProvider(TargetAlphaProvider provider) {
mAppWindowAnimationHelper.setTaskAlphaCallback(provider);
+ mTaskViewSimulator.setTaskAlphaCallback(provider);
updateFinalShift();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 6d1bf11..235ac16 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -26,7 +26,6 @@
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 @@
private boolean mInOverviewState = true;
private float mZoomScale = 1f;
- private float mZoomTranslationY = 0f;
private RunningTaskInfo mRunningTaskInfo;
@@ -145,14 +143,11 @@
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 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);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index b739838..00329b8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -30,13 +30,11 @@
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 @@
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 @@
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 @@
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()) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index dde7605..8a6c4a1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -207,9 +207,23 @@
mRectScaleAnim.skipToEnd();
}
}
+ mRectXAnimEnded = true;
+ mRectYAnimEnded = true;
+ mRectScaleAnimEnded = true;
+ maybeOnEnd();
+ }
+
+ private boolean isEnded() {
+ return mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded;
}
private void onUpdate() {
+ if (isEnded()) {
+ // Prevent further updates from being called. This can happen between callbacks for
+ // ending the x/y/scale animations.
+ return;
+ }
+
if (!mOnUpdateListeners.isEmpty()) {
float currentWidth = Utilities.mapRange(mCurrentScaleProgress, mStartRect.width(),
mTargetRect.width());
@@ -229,7 +243,7 @@
}
private void maybeOnEnd() {
- if (mAnimsStarted && mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded) {
+ if (mAnimsStarted && isEnded()) {
mAnimsStarted = false;
for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
animatorListener.onAnimationEnd(null);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
new file mode 100644
index 0000000..0131fdf
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -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);
+ }
+
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 78d75c5..454223e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -183,27 +183,6 @@
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()) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 24eae18..b687920 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -56,6 +56,7 @@
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.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.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 @@
}
};
- 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 @@
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 @@
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 @@
private boolean mOverlayEnabled;
protected boolean mFreezeViewVisibility;
+ private float mAdjacentPageOffset = 0;
+
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
*/
@@ -285,6 +301,9 @@
}
};
+ private final RecentsOrientedState.SystemRotationChangeListener mSystemRotationChangeListener =
+ enabled -> toggleOrientationEventListener();
+
private final PinnedStackAnimationListener mIPinnedStackAnimationListener =
new PinnedStackAnimationListener();
@@ -349,7 +368,7 @@
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 =
@@ -365,7 +384,6 @@
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);
@@ -484,6 +502,7 @@
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
mIPinnedStackAnimationListener);
mOrientationState.init();
+ mOrientationState.addSystemRotationChangeListener(mSystemRotationChangeListener);
}
@Override
@@ -498,6 +517,7 @@
mIdp.removeOnChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
mIPinnedStackAnimationListener.setActivity(null);
+ mOrientationState.removeSystemRotationChangeListener(mSystemRotationChangeListener);
mOrientationState.destroy();
}
@@ -554,13 +574,6 @@
}
public void setOverviewStateEnabled(boolean enabled) {
- if (canEnableOverviewRotationAnimation()) {
- if (enabled) {
- mOrientationListener.enable();
- } else {
- mOrientationListener.disable();
- }
- }
mOverviewStateEnabled = enabled;
updateTaskStackListenerState();
if (!enabled) {
@@ -568,13 +581,26 @@
// its thumbnail
mTmpRunningTask = null;
}
+ toggleOrientationEventListener();
+ }
+
+ private void toggleOrientationEventListener() {
+ boolean canEnable = canEnableOverviewRotationAnimation() && mOverviewStateEnabled;
+ UI_HELPER_EXECUTOR.execute(() -> {
+ if (canEnable) {
+ mOrientationListener.enable();
+ } else {
+ mOrientationListener.disable();
+ }
+ });
}
private boolean canEnableOverviewRotationAnimation() {
return supportsVerticalLandscape() // not 3P launcher
&& !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests..
&& mOrientationListener.canDetectOrientation() // ..but does the hardware even work?
- && !mOrientationState.canLauncherAutoRotate(); // launcher is going to rotate itself
+ && (mOrientationState.isSystemRotationAllowed() &&
+ !mOrientationState.canLauncherRotate()); // launcher is going to rotate itself
}
public void onDigitalWellbeingToastShown() {
@@ -819,7 +845,6 @@
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);
@@ -1073,7 +1098,7 @@
*/
public void showCurrentTask(int runningTaskId) {
if (getTaskView(runningTaskId) == null) {
- boolean wasEmpty = getTaskViewCount() == 0;
+ boolean wasEmpty = getChildCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
addView(taskView, mTaskViewStartIndex);
@@ -1611,11 +1636,6 @@
}
@Nullable
- public TaskView getPreviousTaskView() {
- return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() - 1);
- }
-
- @Nullable
public TaskView getCurrentPageTaskView() {
return getTaskViewAtByAbsoluteIndex(getCurrentPage());
}
@@ -1674,11 +1694,29 @@
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() {
@@ -1760,14 +1798,10 @@
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.
@@ -2027,17 +2061,23 @@
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) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 178ff32..a05e0fa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -36,11 +36,9 @@
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.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 @@
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 @@
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 @@
private float mSaturation = 1f;
private boolean mOverlayEnabled;
- private boolean mIsOrientationChanged;
private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
public TaskThumbnailView(Context context) {
@@ -123,7 +121,7 @@
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 @@
mOverlay.reset();
}
if (mOverviewScreenshotActionsPlugin != null) {
- mOverviewScreenshotActionsPlugin
- .setupActions((ViewGroup) getTaskView(), getThumbnail(), mActivity);
+ mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
}
updateThumbnailPaintFilter();
}
@@ -270,9 +267,8 @@
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 @@
// 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 @@
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 @@
}
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 @@
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 @@
}
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;
+ }
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 470b720..b0758c9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -56,6 +56,7 @@
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.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 @@
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 @@
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 @@
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 @@
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 @@
iconParams.bottomMargin = 0;
break;
}
- mSnapshotView.setLayoutParams(snapshotParams);
mIconView.setLayoutParams(iconParams);
mIconView.setRotation(rotation);
}
@@ -699,21 +689,16 @@
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 @@
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 @@
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 @@
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 @@
/**
* 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;
- }
}
}
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index a688f9a..2b11ca0 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -13,13 +13,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources xmlns:tools="http://schemas.android.com/tools">
+<resources>
<string name="task_overlay_factory_class" translatable="false"/>
<!-- Activities which block home gesture -->
- <string-array name="gesture_blocking_activities" tools:ignore="InconsistentArrays">
- <item>com.android.launcher3/com.android.quickstep.interaction.GestureSandboxActivity</item>
- </string-array>
+ <string-array name="gesture_blocking_activities" translatable="false"/>
<string name="stats_log_manager_class" translatable="false">com.android.quickstep.logging.StatsLogCompatManager</string>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index b7abd61..65763d4 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -29,7 +29,6 @@
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.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;
@@ -205,17 +203,6 @@
}
@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 =
(QuickstepAppTransitionManagerImpl) getAppTransitionManager();
@@ -238,6 +225,12 @@
}
@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();
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 0f45196..33011ac 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -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_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 @@
*
* @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 @@
@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 @@
*/
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));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 93e02a1..ea71d97 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -87,7 +87,7 @@
}
@Override
- public float getDepth(Context context) {
+ protected float getDepthUnchecked(Context context) {
return 1f;
}
@@ -102,9 +102,8 @@
}
@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
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 94ef15a..e4bb9aa 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -135,8 +135,6 @@
void createActivityInterface(long transitionLength);
- default void adjustActivityControllerInterpolators() { }
-
default void onTransitionCancelled() { }
default void setShelfState(ShelfPeekAnim.ShelfAnimState animState,
diff --git a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
index 2a0fe32..dfb8c1d 100644
--- a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
+++ b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
@@ -28,7 +28,7 @@
public class ActivityInitListener<T extends BaseActivity> implements SchedulerCallback<T> {
- private final BiPredicate<T, Boolean> mOnInitListener;
+ private BiPredicate<T, Boolean> mOnInitListener;
private final ActivityTracker<T> mActivityTracker;
private boolean mIsRegistered = false;
@@ -72,6 +72,7 @@
*/
public void unregister() {
mIsRegistered = false;
+ mOnInitListener = null;
}
/**
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 1f1a999..4edf2fb 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -63,7 +63,7 @@
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 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 @@
}
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 @@
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 @@
// 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 @@
}
/**
- * 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;
}
}
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index eefe8ac..5be0675 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -18,9 +18,9 @@
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.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.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,12 +48,15 @@
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;
import com.android.launcher3.touch.PortraitPagedViewHandler;
import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.List;
/**
* Container to hold orientation/rotation related information for Launcher.
@@ -81,6 +87,10 @@
private @SurfaceRotation int mDisplayRotation = ROTATION_0;
private @SurfaceRotation int mLauncherRotation = Surface.ROTATION_0;
+ public interface SystemRotationChangeListener {
+ void onSystemRotationChanged(boolean enabled);
+ }
+
/**
* If {@code true} we default to {@link PortraitPagedViewHandler} and don't support any fake
* launcher orientations.
@@ -93,6 +103,7 @@
private final SharedPreferences mSharedPrefs;
private final boolean mAllowConfigurationDefaultValue;
+ private List<SystemRotationChangeListener> mSystemRotationChangeListeners = new ArrayList<>();
private final Matrix mTmpMatrix = new Matrix();
private final Matrix mTmpInverseMatrix = new Matrix();
@@ -128,7 +139,7 @@
*/
public boolean update(
@SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation,
- int launcherRotation) {
+ @SurfaceRotation int launcherRotation) {
if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
return false;
}
@@ -167,14 +178,6 @@
return true;
}
- public boolean areMultipleLayoutOrientationsDisabled() {
- return mDisableMultipleOrientations;
- }
-
- public boolean canLauncherAutoRotate() {
- return mIsHomeRotationAllowed && mIsSystemRotationAllowed;
- }
-
/**
* Setting this preference renders future calls to {@link #update(int, int, int)} as a no-op.
*/
@@ -198,6 +201,10 @@
} catch (Settings.SettingNotFoundException e) {
Log.e(TAG, "autorotate setting not found", e);
}
+
+ for (SystemRotationChangeListener listener : mSystemRotationChangeListeners) {
+ listener.onSystemRotationChanged(mIsSystemRotationAllowed);
+ }
}
private void updateHomeRotationSetting() {
@@ -205,6 +212,15 @@
mAllowConfigurationDefaultValue);
}
+ public void addSystemRotationChangeListener(SystemRotationChangeListener listener) {
+ mSystemRotationChangeListeners.add(listener);
+ listener.onSystemRotationChanged(mIsSystemRotationAllowed);
+ }
+
+ public void removeSystemRotationChangeListener(SystemRotationChangeListener listener) {
+ mSystemRotationChangeListeners.remove(listener);
+ }
+
public void init() {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
mContentResolver.registerContentObserver(
@@ -217,6 +233,7 @@
public void destroy() {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
+ mSystemRotationChangeListeners.clear();
}
@SurfaceRotation
@@ -229,12 +246,25 @@
return mTouchRotation;
}
+ @SurfaceRotation
+ public int getLauncherRotation() {
+ return mLauncherRotation;
+ }
+
+ public boolean areMultipleLayoutOrientationsDisabled() {
+ return mDisableMultipleOrientations;
+ }
+
+ public boolean isSystemRotationAllowed() {
+ return mIsSystemRotationAllowed;
+ }
+
public boolean isHomeRotationAllowed() {
return mIsHomeRotationAllowed;
}
- public int getLauncherRotation() {
- return mLauncherRotation;
+ public boolean canLauncherRotate() {
+ return isSystemRotationAllowed() && isHomeRotationAllowed();
}
public int getTouchRotationDegrees() {
@@ -251,6 +281,25 @@
}
}
+ /**
+ * 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;
}
diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml
index b8b5b8c..5a81f70 100644
--- a/res/layout/system_shortcut_icon_only.xml
+++ b/res/layout/system_shortcut_icon_only.xml
@@ -19,7 +19,7 @@
android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
android:background="?android:attr/selectableItemBackgroundBorderless"
- android:tint="?android:attr/textColorHint"
+ android:tint="?attr/iconOnlyShortcutColor"
android:tintMode="src_in"
android:padding="@dimen/system_shortcut_header_icon_padding"
android:theme="@style/PopupItem" />
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index e946835..d4cb6d7 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -34,6 +34,7 @@
<attr name="workspaceStatusBarScrim" format="reference" />
<attr name="widgetsTheme" format="reference" />
<attr name="loadingIconColor" format="color" />
+ <attr name="iconOnlyShortcutColor" format="color"/>
<attr name="folderDotColor" format="color" />
<attr name="folderFillColor" format="color" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0b589a2..31b12ad 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -200,7 +200,7 @@
<dimen name="system_shortcut_icon_size">24dp</dimen>
<!-- popup_arrow_center_start - system_shortcut_icon_size / 2 -->
<dimen name="system_shortcut_margin_start">16dp</dimen>
- <dimen name="system_shortcut_header_height">40dp</dimen>
+ <dimen name="system_shortcut_header_height">48dp</dimen>
<dimen name="system_shortcut_header_icon_touch_size">48dp</dimen>
<!-- (touch_size - icon_size) / 2 -->
<dimen name="system_shortcut_header_icon_padding">12dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fcc651b..a2c0f23 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -30,11 +30,12 @@
</style>
<style name="LauncherTheme" parent="@style/BaseLauncherTheme">
- <item name="allAppsScrimColor">#EAFFFFFF</item>
+ <item name="android:textColorSecondary">#DE000000</item>
+ <item name="allAppsScrimColor">#FFFFFFFF</item>
<item name="allAppsInterimScrimAlpha">46</item>
<item name="allAppsNavBarScrimColor">#66FFFFFF</item>
<item name="popupColorPrimary">#FFF</item>
- <item name="popupColorSecondary">#F5F5F5</item> <!-- Gray 100 -->
+ <item name="popupColorSecondary">#F1F3F4</item>
<item name="popupColorTertiary">#E0E0E0</item> <!-- Gray 300 -->
<item name="isMainColorDark">false</item>
<item name="isWorkspaceDarkText">false</item>
@@ -50,6 +51,7 @@
<item name="folderTextColor">#FF212121</item>
<item name="folderHintColor">#FF616161</item>
<item name="loadingIconColor">#CCFFFFFF</item>
+ <item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
<item name="workProfileOverlayTextColor">#FF212121</item>
<item name="android:windowTranslucentStatus">false</item>
@@ -88,11 +90,11 @@
<item name="android:textColorHint">#A0FFFFFF</item>
<item name="android:colorControlHighlight">#A0FFFFFF</item>
<item name="android:colorPrimary">#FF212121</item>
- <item name="allAppsScrimColor">#EA212121</item>
+ <item name="allAppsScrimColor">#FF212121</item>
<item name="allAppsInterimScrimAlpha">102</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
<item name="popupColorPrimary">#3C4043</item> <!-- Gray 800 -->
- <item name="popupColorSecondary">#5F6368</item> <!-- Gray 700 -->
+ <item name="popupColorSecondary">#202124</item>
<item name="popupColorTertiary">#757575</item> <!-- Gray 600 -->
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="folderDotColor">#FF464646</item>
@@ -102,6 +104,7 @@
<item name="folderHintColor">#FFCCCCCC</item>
<item name="isMainColorDark">true</item>
<item name="loadingIconColor">#99FFFFFF</item>
+ <item name="iconOnlyShortcutColor">#B3FFFFFF</item>
<item name="workProfileOverlayTextColor">@android:color/white</item>
</style>
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index f69c8ed..e4f201c 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -181,7 +181,9 @@
sourceContainer);
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
- getStatsLogManager().log(APP_LAUNCH_TAP, item.buildProto(null, null));
+
+ getStatsLogManager().log(APP_LAUNCH_TAP, item == null ? null
+ : item.buildProto(null, null));
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bf05a24..c4eab8f 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -25,6 +25,8 @@
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.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 @@
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 @@
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 @@
return (T) activityContext;
}
+
/**
* Callback for listening for onResume
*/
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 504666a..54d8f0d 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -90,6 +90,9 @@
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 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 @@
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() {
@@ -276,7 +285,14 @@
*
* 0 means completely zoomed in, without blurs. 1 is zoomed out, with blurs.
*/
- public float getDepth(Context context) {
+ public final float getDepth(Context context) {
+ if (BaseDraggingActivity.fromContext(context).getDeviceProfile().isMultiWindowMode) {
+ return 0;
+ }
+ return getDepthUnchecked(context);
+ }
+
+ protected float getDepthUnchecked(Context context) {
return 0f;
}
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 2ba624c..b2ff69a 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -78,7 +78,7 @@
}
@Override
- public float getDepth(Context context) {
+ protected float getDepthUnchecked(Context context) {
return 0.5f;
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index f9f3bf4..e290685 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -32,7 +32,6 @@
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;
@@ -120,11 +119,6 @@
}
@Override
- public int getPrimarySize(Rect rect) {
- return rect.height();
- }
-
- @Override
public float getPrimarySize(RectF rect) {
return rect.height();
}
@@ -135,17 +129,6 @@
}
@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;
}
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index ba4c064..b8396e1 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -18,6 +18,7 @@
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.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 @@
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 @@
*/
void adjustFloatingIconStartVelocity(PointF velocity);
-
class CurveProperties {
public int scroll;
public int halfPageSize;
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 7c44eba..dad00a4 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -32,7 +32,6 @@
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;
@@ -118,11 +117,6 @@
}
@Override
- public int getPrimarySize(Rect rect) {
- return rect.width();
- }
-
- @Override
public float getPrimarySize(RectF rect) {
return rect.width();
}
@@ -133,17 +127,6 @@
}
@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;
}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 5b3840f..6e21512 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -19,7 +19,6 @@
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
-import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.animation.Animator;
@@ -100,6 +99,7 @@
private AnimatorSet mFadeAnimatorSet;
private ListenerView mListenerView;
+ private Runnable mFastFinishRunnable;
public FloatingIconView(Context context) {
this(context, null);
@@ -443,9 +443,21 @@
}
}
+ /**
+ * Sets a runnable that is called after a call to {@link #fastFinish()}.
+ */
+ public void setFastFinishRunnable(Runnable runnable) {
+ mFastFinishRunnable = runnable;
+ }
+
public void fastFinish() {
+ if (mFastFinishRunnable != null) {
+ mFastFinishRunnable.run();
+ mFastFinishRunnable = null;
+ }
if (mLoadIconSignal != null) {
mLoadIconSignal.cancel();
+ mLoadIconSignal = null;
}
if (mEndRunnable != null) {
mEndRunnable.run();
@@ -655,6 +667,7 @@
sTmpObjArray[0] = null;
mIconLoadResult = null;
mClipIconView.recycle();
+ mFastFinishRunnable = null;
}
private static class IconLoadResult {