diff options
10 files changed, 149 insertions, 27 deletions
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index 6cfff2e3670f..828065be866e 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -17,7 +17,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:focusable="true"> + android:focusable="true" + android:background="#FFffffff"> <com.android.systemui.recents.views.TaskViewThumbnail android:id="@+id/task_view_thumbnail" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 3db0a2bd0d07..bf80d84b3ad3 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -222,6 +222,9 @@ <!-- The amount to offset when animating into an affiliate group. --> <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen> + <!-- The alpha to apply to a task thumbnail. --> + <item name="recents_task_view_thumbnail_alpha" format="float" type="dimen">0.9</item> + <!-- The height of a task view bar. --> <dimen name="recents_task_bar_height">56dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 3d4d6c43a668..3709c4364184 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -39,6 +39,8 @@ public class Constants { public static final boolean EnableSearchLayout = true; // Enables the dynamic shadows behind each task public static final boolean EnableShadows = true; + // Enables the thumbnail alpha on the front-most task + public static final boolean EnableThumbnailAlphaOnFrontmost = false; // This disables the bitmap and icon caches public static final boolean DisableBackgroundCache = false; // Enables the simulated task affiliations diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 41e06de80112..7fafe7aa28d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -385,7 +385,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Private API calls to make the shadows look better try { Utilities.setShadowProperty("ambientShadowStrength", String.valueOf(35f)); - Utilities.setShadowProperty("ambientRatio", String.valueOf(0.5f)); + Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 3f5018d8290b..b7f6451e3ce2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -81,6 +81,7 @@ public class RecentsConfiguration { public int taskViewRoundedCornerRadiusPx; public int taskViewHighlightPx; public int taskViewAffiliateGroupEnterOffsetPx; + public float taskViewThumbnailAlpha; /** Task bar colors */ public int taskBarViewDefaultBackgroundColor; @@ -217,6 +218,9 @@ public class RecentsConfiguration { taskViewTranslationZMaxPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max); taskViewAffiliateGroupEnterOffsetPx = res.getDimensionPixelSize(R.dimen.recents_task_view_affiliate_group_enter_offset); + TypedValue thumbnailAlphaValue = new TypedValue(); + res.getValue(R.dimen.recents_task_view_thumbnail_alpha, thumbnailAlphaValue, true); + taskViewThumbnailAlpha = thumbnailAlphaValue.getFloat(); // Task bar colors taskBarViewDefaultBackgroundColor = diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java index 4c0ff481a289..c87a901341d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java @@ -16,6 +16,8 @@ package com.android.systemui.recents.misc; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Context; import java.util.ArrayList; @@ -98,10 +100,19 @@ public class ReferenceCountedTrigger { } } - /** Convenience method to decrement this trigger as a runnable */ + /** Convenience method to decrement this trigger as a runnable. */ public Runnable decrementAsRunnable() { return mDecrementRunnable; } + /** Convenience method to decrement this trigger as a animator listener. */ + public Animator.AnimatorListener decrementOnAnimationEnd() { + return new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + decrement(); + } + }; + } /** Returns the current ref count */ public int getCount() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 4fd91366e308..21b62e9c3297 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -73,6 +73,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal boolean mStackViewsDirty = true; boolean mAwaitingFirstLayout = true; boolean mStartEnterAnimationRequestedAfterLayout; + boolean mStartEnterAnimationCompleted; ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext; int[] mTmpVisibleRange = new int[2]; TaskViewTransform mTmpTransform = new TaskViewTransform(); @@ -609,6 +610,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() { @Override public void run() { + mStartEnterAnimationCompleted = true; // Start dozing mUIDozeTrigger.startDozing(); } @@ -814,6 +816,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal tv.setNoUserInteractionState(); } + // If we've finished the start animation, then ensure we always enable the focus animations + if (mStartEnterAnimationCompleted) { + tv.enableFocusAnimations(); + } + // Find the index where this task should be placed in the stack int insertIndex = -1; int taskIndex = mStack.indexOfTask(task); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 236229e6984d..5914b392e671 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -17,7 +17,6 @@ package com.android.systemui.recents.views; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; @@ -55,6 +54,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, float mTaskProgress; ObjectAnimator mTaskProgressAnimator; + ObjectAnimator mDimAnimator; float mMaxDimScale; int mDim; AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1.25f); @@ -222,6 +222,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, * first layout because the actual animation into recents may take a long time. */ void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, boolean occludesLaunchTarget, int offscreenY) { + int initialDim = getDim(); if (mConfig.launchedFromAppWithScreenshot) { if (isTaskViewLaunchTargetTask) { mHeaderView.prepareEnterRecentsAnimation(); @@ -240,7 +241,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Hide the action button if it exists mActionButtonView.setAlpha(0f); // Set the dim to 0 so we can animate it in - setDim(0); + initialDim = 0; } else if (occludesLaunchTarget) { // Move the task view off screen (below) so we can animate it in setTranslationY(offscreenY); @@ -255,6 +256,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, setScaleX(1f); setScaleY(1f); } + // Apply the current dim + setDim(initialDim); + // Prepare the thumbnail view alpha + mThumbnailView.prepareEnterRecentsAnimation(isTaskViewLaunchTargetTask); } /** Animates this task view as it enters recents */ @@ -340,20 +345,24 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Animate the task bar of the first task view mHeaderView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay, mThumbnailView.enableTaskBarClipAsRunnable(mHeaderView)); - - // Animate the dim into view as well - ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", getDimFromTaskProgress()); - anim.setStartDelay(mConfig.taskBarEnterAnimDelay); - anim.setDuration(mConfig.taskBarEnterAnimDuration); - anim.setInterpolator(mConfig.fastOutLinearInInterpolator); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // Decrement the post animation trigger - ctx.postAnimationTrigger.decrement(); - } - }); - anim.start(); + // Animate the dim/overlay + if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) { + // Animate the thumbnail alpha before the dim animation (to prevent updating the + // hardware layer) + mThumbnailView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay, + new Runnable() { + @Override + public void run() { + animateDimToProgress(0, mConfig.taskBarEnterAnimDuration, + ctx.postAnimationTrigger.decrementOnAnimationEnd()); + } + }); + } else { + // Immediately start the dim animation + animateDimToProgress(mConfig.taskBarEnterAnimDelay, + mConfig.taskBarEnterAnimDuration, + ctx.postAnimationTrigger.decrementOnAnimationEnd()); + } ctx.postAnimationTrigger.increment(); // Animate the footer into view @@ -459,8 +468,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, void startLaunchTaskAnimation(final Runnable r, boolean isLaunchingTask, boolean occludesLaunchTarget) { if (isLaunchingTask) { - // Disable the thumbnail clip and animate the bar out + // Disable the thumbnail clip and animate the bar out for the window animation out mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r); + // Animate the thumbnail alpha back into full opacity for the window animation out + mThumbnailView.startLaunchTaskAnimation(); // Animate the dim if (mDim > 0) { @@ -612,10 +623,18 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, /** Returns the current dim. */ public void setDim(int dim) { mDim = dim; - int inverse = 255 - mDim; - mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse)); - mLayerPaint.setColorFilter(mDimColorFilter); - setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint); + // Defer setting hardware layers if we have not yet measured, or there is no dim to draw + if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0 && dim > 0) { + if (mDimAnimator != null) { + mDimAnimator.removeAllListeners(); + mDimAnimator.cancel(); + } + + int inverse = 255 - mDim; + mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse)); + mLayerPaint.setColorFilter(mDimColorFilter); + setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint); + } } /** Returns the current dim. */ @@ -623,6 +642,21 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, return mDim; } + /** Animates the dim to the task progress. */ + void animateDimToProgress(int delay, int duration, Animator.AnimatorListener postAnimRunnable) { + // Animate the dim into view as well + int toDim = getDimFromTaskProgress(); + if (toDim != getDim()) { + ObjectAnimator anim = ObjectAnimator.ofInt(TaskView.this, "dim", toDim); + anim.setStartDelay(delay); + anim.setDuration(duration); + if (postAnimRunnable != null) { + anim.addListener(postAnimRunnable); + } + anim.start(); + } + } + /** Compute the dim as a function of the scale of this view. */ int getDimFromTaskProgress() { float dim = mMaxDimScale * mDimInterpolator.getInterpolation(1f - mTaskProgress); @@ -647,6 +681,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Focus the header bar mHeaderView.onTaskViewFocusChanged(true); } + // Update the thumbnail alpha with the focus + mThumbnailView.onFocusChanged(true); // Call the callback mCb.onTaskViewFocusChanged(this, true); // Workaround, we don't always want it focusable in touch mode, but we want the first task @@ -670,6 +706,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Un-focus the header bar mHeaderView.onTaskViewFocusChanged(false); } + // Update the thumbnail alpha with the focus + mThumbnailView.onFocusChanged(false); // Call the callback mCb.onTaskViewFocusChanged(this, false); invalidate(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java index f836aa3e578b..f223bf3a990f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java @@ -21,12 +21,15 @@ import android.graphics.Bitmap; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; +import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.model.Task; /** The task thumbnail view */ public class TaskViewThumbnail extends FixedSizeImageView { + RecentsConfiguration mConfig; + // Task bar clipping Rect mClipRect = new Rect(); @@ -44,9 +47,15 @@ public class TaskViewThumbnail extends FixedSizeImageView { public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + mConfig = RecentsConfiguration.getInstance(); setScaleType(ScaleType.FIT_XY); } + @Override + protected void onFinishInflate() { + setAlpha(0.9f); + } + /** Updates the clip rect based on the given task bar. */ void enableTaskBarClip(View taskBar) { int top = (int) Math.max(0, taskBar.getTranslationY() + @@ -101,4 +110,51 @@ public class TaskViewThumbnail extends FixedSizeImageView { void unbindFromTask() { setImageDrawable(null); } + + /** Handles focus changes. */ + void onFocusChanged(boolean focused) { + if (focused) { + if (Float.compare(getAlpha(), 1f) != 0) { + startFadeAnimation(1f, 0, 150, null); + } + } else { + if (Float.compare(getAlpha(), mConfig.taskViewThumbnailAlpha) != 0) { + startFadeAnimation(mConfig.taskViewThumbnailAlpha, 0, 150, null); + } + } + } + + /** Prepares for the enter recents animation. */ + void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask) { + if (isTaskViewLaunchTargetTask) { + setAlpha(1f); + } else { + setAlpha(mConfig.taskViewThumbnailAlpha); + } + } + + /** Animates this task thumbnail as it enters recents */ + void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) { + startFadeAnimation(mConfig.taskViewThumbnailAlpha, delay, + mConfig.taskBarEnterAnimDuration, postAnimRunnable); + } + + /** Animates this task thumbnail as it exits recents */ + void startLaunchTaskAnimation() { + startFadeAnimation(1f, 0, mConfig.taskBarExitAnimDuration, null); + } + + /** Animates the thumbnail alpha. */ + void startFadeAnimation(float finalAlpha, int delay, int duration, Runnable postAnimRunnable) { + if (postAnimRunnable != null) { + animate().withEndAction(postAnimRunnable); + } + animate() + .alpha(finalAlpha) + .setStartDelay(delay) + .setInterpolator(mConfig.fastOutSlowInInterpolator) + .setDuration(duration) + .withLayer() + .start(); + } } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 0e1340c27e5d..f6ec86db5478 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -159,7 +159,7 @@ public class AppTransition implements Dump { private final int mConfigShortAnimTime; private final Interpolator mDecelerateInterpolator; private final Interpolator mThumbnailFadeoutInterpolator; - private final Interpolator mThumbnailCubicInterpolator; + private final Interpolator mThumbnailFastOutSlowInInterpolator; private int mCurrentUserId = 0; @@ -170,7 +170,7 @@ public class AppTransition implements Dump { com.android.internal.R.integer.config_shortAnimTime); mDecelerateInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.decelerate_cubic); - mThumbnailCubicInterpolator = AnimationUtils.loadInterpolator(context, + mThumbnailFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); mThumbnailFadeoutInterpolator = new Interpolator() { @Override @@ -635,7 +635,7 @@ public class AppTransition implements Dump { } return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, - THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailCubicInterpolator); + THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator); } /** |