summaryrefslogtreecommitdiffstats
path: root/go
diff options
context:
space:
mode:
authorKevin <kevhan@google.com>2019-05-07 17:40:32 -0700
committerKevin <kevhan@google.com>2019-05-07 18:01:23 -0700
commit1b4b960ff113794232e3a779ab01f4450f8e3ed9 (patch)
tree0bc1f352247730077fa26766a5da467b0f4453ac /go
parentf95e84a3852e1c85b2326b03431fd4b2ae20ed74 (diff)
downloadandroid_packages_apps_Trebuchet-1b4b960ff113794232e3a779ab01f4450f8e3ed9.tar.gz
android_packages_apps_Trebuchet-1b4b960ff113794232e3a779ab01f4450f8e3ed9.tar.bz2
android_packages_apps_Trebuchet-1b4b960ff113794232e3a779ab01f4450f8e3ed9.zip
Polish app => recents animation (2/N)
This CL moves the core "app to overview" animation logic into the main view as the newer animation would need to animate over several of the main view's children and so the animation logic needs knowledge of those children. Bug: 132112131 Test: Build and test, functions as before Change-Id: I9cbde55a582bee62e0a97e38c5fdf1d5841502db
Diffstat (limited to 'go')
-rw-r--r--go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java107
-rw-r--r--go/quickstep/src/com/android/quickstep/views/IconRecentsView.java103
2 files changed, 106 insertions, 104 deletions
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index c228bb94f..2dc25546d 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -15,30 +15,21 @@
*/
package com.android.quickstep;
-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.FAST_OUT_SLOW_IN;
-import static com.android.quickstep.util.RemoteAnimationProvider.getLayer;
+import static com.android.quickstep.views.IconRecentsView.REMOTE_APP_TO_OVERVIEW_DURATION;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.Rect;
import android.util.Log;
import android.view.View;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.BaseDraggingActivity;
-import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.IconRecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
/**
* Provider for the atomic remote window animation from the app to the overview.
@@ -47,9 +38,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
*/
final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> implements
RemoteAnimationProvider {
-
- private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
- private static final long APP_SCALE_DOWN_DURATION = 400;
private static final String TAG = "AppToOverviewAnimationProvider";
private final ActivityControlHelper<T> mHelper;
@@ -131,106 +119,17 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
return anim;
}
- View thumbnailView = mRecentsView.getBottomThumbnailView();
- if (thumbnailView == null) {
- // This can be null if there were previously 0 tasks and the recycler view has not had
- // enough time to take in the data change, bind a new view, and lay out the new view.
- // TODO: Have a fallback to animate to
- if (Log.isLoggable(TAG, Log.WARN)) {
- Log.w(TAG, "No thumbnail view for running task. Using stub animation.");
- }
- anim.play(ValueAnimator.ofInt(0, 1).setDuration(getRecentsLaunchDuration()));
- return anim;
- }
-
- playAppScaleDownAnim(anim, closingAppTarget, recentsTarget, thumbnailView);
+ mRecentsView.playAppScaleDownAnim(anim, closingAppTarget, recentsTarget);
return anim;
}
/**
- * Animate a closing app to scale down to the location of the thumbnail view in recents.
- *
- * @param anim animator set
- * @param appTarget the app surface thats closing
- * @param recentsTarget the surface containing recents
- * @param thumbnailView the thumbnail view to animate to
- */
- private void playAppScaleDownAnim(@NonNull AnimatorSet anim,
- @NonNull RemoteAnimationTargetCompat appTarget,
- @NonNull RemoteAnimationTargetCompat recentsTarget, @NonNull View thumbnailView) {
-
- // Identify where the entering remote app should animate to.
- Rect endRect = new Rect();
- thumbnailView.getGlobalVisibleRect(endRect);
-
- Rect appBounds = appTarget.sourceContainerBounds;
-
- ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
- valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
-
- SyncRtSurfaceTransactionApplierCompat surfaceApplier =
- new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
-
- // Keep recents visible throughout the animation.
- SurfaceParams[] params = new SurfaceParams[2];
- // Closing app should stay on top.
- int boostedMode = MODE_CLOSING;
- params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
- null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
-
- valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
- private final FloatProp mScaleX;
- private final FloatProp mScaleY;
- private final FloatProp mTranslationX;
- private final FloatProp mTranslationY;
- private final FloatProp mAlpha;
-
- {
- // Scale down and move to view location.
- float endScaleX = ((float) endRect.width()) / appBounds.width();
- mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
- ACCEL_DEACCEL);
- float endScaleY = ((float) endRect.height()) / appBounds.height();
- mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
- ACCEL_DEACCEL);
- float endTranslationX = endRect.left -
- (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
- mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
- ACCEL_DEACCEL);
- float endTranslationY = endRect.top -
- (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
- mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
- ACCEL_DEACCEL);
-
- // Fade out quietly near the end to be replaced by the real view.
- mAlpha = new FloatProp(1.0f, 0,
- APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
- APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
- }
-
- @Override
- public void onUpdate(float percent) {
- Matrix m = new Matrix();
- m.setScale(mScaleX.value, mScaleY.value,
- appBounds.width() / 2.0f, appBounds.height() / 2.0f);
- m.postTranslate(mTranslationX.value, mTranslationY.value);
-
- params[1] = new SurfaceParams(appTarget.leash, mAlpha.value, m,
- null /* windowCrop */, getLayer(appTarget, boostedMode),
- 0 /* cornerRadius */);
- surfaceApplier.scheduleApply(params);
- }
- });
- anim.play(valueAnimator);
- }
-
- /**
* Get duration of animation from app to overview.
*
* @return duration of animation
*/
long getRecentsLaunchDuration() {
- return APP_SCALE_DOWN_DURATION;
+ return REMOTE_APP_TO_OVERVIEW_DURATION;
}
}
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index c69e53458..89d248cd3 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -19,10 +19,14 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
import static com.android.quickstep.TaskAdapter.ITEM_TYPE_CLEAR_ALL;
import static com.android.quickstep.TaskAdapter.ITEM_TYPE_TASK;
import static com.android.quickstep.TaskAdapter.TASKS_START_POSITION;
+import static com.android.quickstep.util.RemoteAnimationProvider.getLayer;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -32,6 +36,7 @@ import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.ArraySet;
@@ -64,7 +69,11 @@ import com.android.quickstep.TaskAdapter;
import com.android.quickstep.TaskHolder;
import com.android.quickstep.TaskListLoader;
import com.android.quickstep.TaskSwipeCallback;
+import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import java.util.ArrayList;
import java.util.List;
@@ -102,6 +111,11 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
private static final float ITEM_ANIMATE_OUT_TRANSLATION_X_RATIO = .25f;
private static final long CLEAR_ALL_FADE_DELAY = 120;
+ private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
+ private static final long APP_SCALE_DOWN_DURATION = 400;
+
+ public static final long REMOTE_APP_TO_OVERVIEW_DURATION = APP_SCALE_DOWN_DURATION;
+
/**
* A ratio representing the view's relative placement within its padded space. For example, 0
* is top aligned and 0.5 is centered vertically.
@@ -565,6 +579,95 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
mLayoutAnimation.start();
}
+ /**
+ * Animate a closing app to scale down to the location of the thumbnail view in recents.
+ *
+ * @param anim animator set
+ * @param appTarget the app surface thats closing
+ * @param recentsTarget the surface containing recents
+ */
+ public void playAppScaleDownAnim(@NonNull AnimatorSet anim,
+ @NonNull RemoteAnimationTargetCompat appTarget,
+ @NonNull RemoteAnimationTargetCompat recentsTarget) {
+
+ View thumbnailView = getBottomThumbnailView();
+
+ if (thumbnailView == null) {
+ // This can be null if there were previously 0 tasks and the recycler view has not had
+ // enough time to take in the data change, bind a new view, and lay out the new view.
+ // TODO: Have a fallback to animate to
+ anim.play(ValueAnimator.ofInt(0, 1).setDuration(REMOTE_APP_TO_OVERVIEW_DURATION));
+ }
+
+ // Identify where the entering remote app should animate to.
+ Rect endRect = new Rect();
+ thumbnailView.getGlobalVisibleRect(endRect);
+
+ Rect appBounds = appTarget.sourceContainerBounds;
+
+ ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
+ valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
+
+ SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+ new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
+
+ // Keep recents visible throughout the animation.
+ SurfaceParams[] params = new SurfaceParams[2];
+ // Closing app should stay on top.
+ int boostedMode = MODE_CLOSING;
+ params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
+ null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
+
+ valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ private final FloatProp mScaleX;
+ private final FloatProp mScaleY;
+ private final FloatProp mTranslationX;
+ private final FloatProp mTranslationY;
+ private final FloatProp mAlpha;
+
+ {
+ // Scale down and move to view location.
+ float endScaleX = ((float) endRect.width()) / appBounds.width();
+ mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endScaleY = ((float) endRect.height()) / appBounds.height();
+ mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endTranslationX = endRect.left -
+ (appBounds.width() - thumbnailView.getWidth()) / 2.0f;
+ mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+ float endTranslationY = endRect.top -
+ (appBounds.height() - thumbnailView.getHeight()) / 2.0f;
+ mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
+ ACCEL_DEACCEL);
+
+ // Fade out quietly near the end to be replaced by the real view.
+ mAlpha = new FloatProp(1.0f, 0,
+ APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
+ APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
+ }
+
+ @Override
+ public void onUpdate(float percent) {
+ Matrix m = new Matrix();
+ m.setScale(mScaleX.value, mScaleY.value,
+ appBounds.width() / 2.0f, appBounds.height() / 2.0f);
+ m.postTranslate(mTranslationX.value, mTranslationY.value);
+
+ params[1] = new SurfaceParams(appTarget.leash, mAlpha.value, m,
+ null /* windowCrop */, getLayer(appTarget, boostedMode),
+ 0 /* cornerRadius */);
+ surfaceApplier.scheduleApply(params);
+ }
+ });
+ anim.play(valueAnimator);
+ }
+
+ public long getAppToOverviewAnimationDuration() {
+ return APP_SCALE_DOWN_DURATION;
+ }
+
@Override
public void setInsets(Rect insets) {
mInsets = insets;