Snap for 7632648 from 148b33b552ecda668486b43f50fc70ca2353c18e to sc-v2-release
Change-Id: I50c9094ad345ce052b99b55ea27377f681c4ad75
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index aba16c2..85daeff 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -108,6 +108,13 @@
}
};
+ private final Runnable mOpaquenessListener = new Runnable() {
+ @Override
+ public void run() {
+ dispatchTransactionSurface(mDepth);
+ }
+ };
+
private final Launcher mLauncher;
/**
* Blur radius when completely zoomed out, in pixels.
@@ -158,23 +165,28 @@
if (windowToken != null) {
mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
}
- CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
- mCrossWindowBlurListener);
+ onAttached();
}
@Override
public void onViewDetachedFromWindow(View view) {
CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
+ mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
}
};
mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
if (mLauncher.getRootView().isAttachedToWindow()) {
- CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
- mCrossWindowBlurListener);
+ onAttached();
}
}
}
+ private void onAttached() {
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
+ mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
+ }
+
/**
* Sets if the underlying activity is started or not
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index b5c834d..56c28f0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -38,9 +38,9 @@
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
-
/**
* A data source which integrates with a Launcher instance
*/
@@ -159,8 +159,7 @@
* automatically reset once the recents animation finishes
*/
public Animator createAnimToLauncher(@NonNull LauncherState toState,
- @NonNull RecentsAnimationCallbacks callbacks,
- long duration) {
+ @NonNull RecentsAnimationCallbacks callbacks, long duration) {
TaskbarStashController stashController = mControllers.taskbarStashController;
ObjectAnimator animator = mIconAlignmentForGestureState
.animateToValue(1)
@@ -180,31 +179,15 @@
stashController.animateToIsStashed(false, duration);
}
});
- callbacks.addListener(new RecentsAnimationListener() {
- @Override
- public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
- endGestureStateOverride(true);
- }
- @Override
- public void onRecentsAnimationFinished(RecentsAnimationController controller) {
- endGestureStateOverride(!controller.getFinishTargetIsLauncher());
- }
-
- private void endGestureStateOverride(boolean finishedToApp) {
- callbacks.removeListener(this);
- mIsAnimatingToLauncherViaGesture = false;
-
- mIconAlignmentForGestureState
- .animateToValue(0)
- .start();
-
- if (finishedToApp) {
- // We only need this for the exiting live tile case.
- stashController.animateToIsStashed(stashController.isStashedInApp());
- }
- }
+ TaskBarRecentsAnimationListener listener = new TaskBarRecentsAnimationListener(callbacks);
+ callbacks.addListener(listener);
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ recentsView.setTaskLaunchListener(() -> {
+ listener.endGestureStateOverride(true);
+ callbacks.removeListener(listener);
});
+
return animator;
}
@@ -249,4 +232,36 @@
mIconAlphaForHome.setValue(isVisible ? 1 : 0);
mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f);
}
+
+ private final class TaskBarRecentsAnimationListener implements RecentsAnimationListener {
+ private final RecentsAnimationCallbacks mCallbacks;
+
+ TaskBarRecentsAnimationListener(RecentsAnimationCallbacks callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ @Override
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
+ endGestureStateOverride(true);
+ }
+
+ @Override
+ public void onRecentsAnimationFinished(RecentsAnimationController controller) {
+ endGestureStateOverride(!controller.getFinishTargetIsLauncher());
+ }
+
+ private void endGestureStateOverride(boolean finishedToApp) {
+ mCallbacks.removeListener(this);
+ mIsAnimatingToLauncherViaGesture = false;
+
+ mIconAlignmentForGestureState
+ .animateToValue(0)
+ .start();
+
+ TaskbarStashController controller = mControllers.taskbarStashController;
+ if (finishedToApp) {
+ controller.animateToIsStashed(controller.isStashedInApp());
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index f1b4e3d..baca76c 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -48,15 +48,16 @@
public class AnimatorControllerWithResistance {
private enum RecentsResistanceParams {
- FROM_APP(0.75f, 0.5f, 1f),
- FROM_APP_TABLET(0.9f, 0.75f, 1f),
- FROM_OVERVIEW(1f, 0.75f, 0.5f);
+ FROM_APP(0.75f, 0.5f, 1f, false),
+ FROM_APP_TABLET(1f, 0.7f, 1f, true),
+ FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
- float translationFactor) {
+ float translationFactor, boolean stopScalingAtTop) {
this.scaleStartResist = scaleStartResist;
this.scaleMaxResist = scaleMaxResist;
this.translationFactor = translationFactor;
+ this.stopScalingAtTop = stopScalingAtTop;
}
/**
@@ -74,6 +75,12 @@
* where 0 will keep it centered and 1 will have it barely touch the top of the screen.
*/
public final float translationFactor;
+
+ /**
+ * Whether to end scaling effect when the scaled down version of TaskView's top reaches the
+ * non-scaled version of TaskView's top.
+ */
+ public final boolean stopScalingAtTop;
}
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
@@ -161,26 +168,6 @@
PointF pivot = new PointF();
float fullscreenScale = params.recentsOrientedState.getFullScreenScaleAndPivot(
startRect, params.dp, pivot);
- float prevScaleRate = (fullscreenScale - params.startScale)
- / (params.dp.heightPx - startRect.bottom);
- // This is what the scale would be at the end of the drag if we didn't apply resistance.
- float endScale = params.startScale - prevScaleRate * distanceToCover;
- // Create an interpolator that resists the scale so the scale doesn't get smaller than
- // RECENTS_SCALE_MAX_RESIST.
- float startResist = Utilities.getProgress(params.resistanceParams.scaleStartResist,
- params.startScale, endScale);
- float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
- params.startScale, endScale);
- final TimeInterpolator scaleInterpolator = t -> {
- if (t < startResist) {
- return t;
- }
- float resistProgress = Utilities.getProgress(t, startResist, 1);
- resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
- return startResist + resistProgress * (maxResist - startResist);
- };
- resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
- scaleInterpolator);
// Compute where the task view would be based on the end scale.
RectF endRectF = new RectF(startRect);
@@ -195,6 +182,32 @@
resistAnim.addFloat(params.translationTarget, params.translationProperty,
params.startTranslation, endTranslation, RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
+ float prevScaleRate = (fullscreenScale - params.startScale)
+ / (params.dp.heightPx - startRect.bottom);
+ // This is what the scale would be at the end of the drag if we didn't apply resistance.
+ float endScale = params.startScale - prevScaleRate * distanceToCover;
+ // Create an interpolator that resists the scale so the scale doesn't get smaller than
+ // RECENTS_SCALE_MAX_RESIST.
+ float startResist = Utilities.getProgress(params.resistanceParams.scaleStartResist,
+ params.startScale, endScale);
+ float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
+ params.startScale, endScale);
+ float stopResist =
+ params.resistanceParams.stopScalingAtTop ? 1f - startRect.top / endRectF.top : 1f;
+ final TimeInterpolator scaleInterpolator = t -> {
+ if (t < startResist) {
+ return t;
+ }
+ if (t > stopResist) {
+ return maxResist;
+ }
+ float resistProgress = Utilities.getProgress(t, startResist, stopResist);
+ resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
+ return startResist + resistProgress * (maxResist - startResist);
+ };
+ resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
+ scaleInterpolator);
+
return resistAnim;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 935305a..3aed7cc 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -602,6 +602,7 @@
};
private RunnableList mSideTaskLaunchCallback;
+ private TaskLaunchListener mTaskLaunchListener;
public RecentsView(Context context, AttributeSet attrs, int defStyleAttr,
BaseActivityInterface sizeStrategy) {
@@ -882,6 +883,21 @@
mSideTaskLaunchCallback.add(callback::executeAllAndDestroy);
}
+ /**
+ * This is a one-time callback when touching in live tile mode. It's reset to null right
+ * after it's called.
+ */
+ public void setTaskLaunchListener(TaskLaunchListener taskLaunchListener) {
+ mTaskLaunchListener = taskLaunchListener;
+ }
+
+ public void onTaskLaunchedInLiveTileMode() {
+ if (mTaskLaunchListener != null) {
+ mTaskLaunchListener.onTaskLaunched();
+ mTaskLaunchListener = null;
+ }
+ }
+
private void executeSideTaskLaunchCallback() {
if (mSideTaskLaunchCallback != null) {
mSideTaskLaunchCallback.executeAllAndDestroy();
@@ -1172,7 +1188,7 @@
mMovingTaskView = focusedTaskView;
removeView(focusedTaskView);
mMovingTaskView = null;
- focusedTaskView.onRecycle();
+ focusedTaskView.resetPersistentViewTransforms();
addView(focusedTaskView, mTaskViewStartIndex);
setCurrentPage(mTaskViewStartIndex);
@@ -4210,4 +4226,8 @@
// Set locus context is a binder call, don't want it to happen during a transition
UI_HELPER_EXECUTOR.post(() -> mActivity.setLocusContext(id, Bundle.EMPTY));
}
+
+ public interface TaskLaunchListener {
+ void onTaskLaunched();
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 02c5d84..2c33b6d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -584,6 +584,7 @@
}
});
anim.start();
+ recentsView.onTaskLaunchedInLiveTileMode();
} else {
launchTaskAnimated();
}
@@ -614,12 +615,14 @@
ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this, null);
if (ActivityManagerWrapper.getInstance()
.startActivityFromRecents(mTask.key, opts.options)) {
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
- getRecentsView().getRunningTaskViewId() != -1) {
+ RecentsView recentsView = getRecentsView();
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskViewId() != -1) {
+ recentsView.onTaskLaunchedInLiveTileMode();
+
// Return a fresh callback in the live tile case, so that it's not accidentally
// triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
RunnableList callbackList = new RunnableList();
- getRecentsView().addSideTaskLaunchCallback(callbackList);
+ recentsView.addSideTaskLaunchCallback(callbackList);
return callbackList;
}
return opts.onEndCallback;
@@ -871,6 +874,12 @@
setIconAndDimTransitionProgress(iconScale, invert);
}
+ protected void resetPersistentViewTransforms() {
+ mNonGridTranslationX = mNonGridTranslationY =
+ mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
+ resetViewTransforms();
+ }
+
protected void resetViewTransforms() {
// fullscreenTranslation and accumulatedTranslation should not be reset, as
// resetViewTransforms is called during Quickswitch scrolling.
@@ -894,9 +903,7 @@
@Override
public void onRecycle() {
- mNonGridTranslationX = mNonGridTranslationY =
- mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
- resetViewTransforms();
+ resetPersistentViewTransforms();
// Clear any references to the thumbnail (it will be re-read either from the cache or the
// system on next bind)
mSnapshotView.setThumbnail(mTask, null);
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 1eb79ad..4c0bfde 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -25,23 +25,27 @@
import android.util.AttributeSet;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.Insettable;
import com.android.launcher3.util.SystemUiController;
+import java.util.ArrayList;
+
/**
* Simple scrim which draws a flat color
*/
public class ScrimView extends View implements Insettable {
private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
+ private final ArrayList<Runnable> mOpaquenessListeners = new ArrayList<>(1);
private SystemUiController mSystemUiController;
-
private ScrimDrawingController mDrawingController;
private int mBackgroundColor;
private boolean mIsVisible = true;
+ private boolean mLastDispatchedOpaqueness;
public ScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -60,6 +64,7 @@
@Override
protected boolean onSetAlpha(int alpha) {
updateSysUiColors();
+ dispatchVisibilityListenersIfNeeded();
return super.onSetAlpha(alpha);
}
@@ -67,6 +72,7 @@
public void setBackgroundColor(int color) {
mBackgroundColor = color;
updateSysUiColors();
+ dispatchVisibilityListenersIfNeeded();
super.setBackgroundColor(color);
}
@@ -74,6 +80,7 @@
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
mIsVisible = isVisible;
+ dispatchVisibilityListenersIfNeeded();
}
public boolean isFullyOpaque() {
@@ -108,6 +115,17 @@
}
}
+ private void dispatchVisibilityListenersIfNeeded() {
+ boolean fullyOpaque = isFullyOpaque();
+ if (mLastDispatchedOpaqueness == fullyOpaque) {
+ return;
+ }
+ mLastDispatchedOpaqueness = fullyOpaque;
+ for (int i = 0; i < mOpaquenessListeners.size(); i++) {
+ mOpaquenessListeners.get(i).run();
+ }
+ }
+
private SystemUiController getSystemUiController() {
if (mSystemUiController == null) {
mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController();
@@ -136,6 +154,22 @@
}
/**
+ * Registers a listener to be notified of whether the scrim is occluding other UI elements.
+ * @see #isFullyOpaque()
+ */
+ public void addOpaquenessListener(@NonNull Runnable listener) {
+ mOpaquenessListeners.add(listener);
+ }
+
+ /**
+ * Removes previously registered listener.
+ * @see #addOpaquenessListener(Runnable)
+ */
+ public void removeOpaquenessListener(@NonNull Runnable listener) {
+ mOpaquenessListeners.remove(listener);
+ }
+
+ /**
* A Utility interface allowing for other surfaces to draw on ScrimView
*/
public interface ScrimDrawingController {
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 167eb09..a8ed154 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -325,10 +325,10 @@
return;
}
if (drawable != null) {
+ // Scale down the preview size if it's wider than the cell.
float scale = 1f;
- if (getWidth() > 0 && getHeight() > 0) {
- // Scale down the preview size if it's wider than the cell.
- float maxWidth = getWidth();
+ if (mTargetPreviewWidth > 0) {
+ float maxWidth = mTargetPreviewWidth;
float previewWidth = drawable.getIntrinsicWidth() * mPreviewContainerScale;
scale = Math.min(maxWidth / previewWidth, 1);
}