Merge "Fixing issue with animation not running after SystemUI crashes (Bug 14453240)"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 28de6ac..d763bd6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -227,6 +227,12 @@
<!-- The radius of the rounded corners on a task view. -->
<dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
+ <!-- The min translation in the Z index for the last task. -->
+ <dimen name="recents_task_view_z_min">3dp</dimen>
+
+ <!-- The translation in the Z index for each task above the last task. -->
+ <dimen name="recents_task_view_z_increment">5dp</dimen>
+
<!-- The amount of space a user has to scroll to dismiss any info panes. -->
<dimen name="recents_task_stack_scroll_dismiss_info_pane_distance">50dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index f2e322d..396cb14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -64,6 +64,17 @@
mSingleCountFirstTaskRect.offset(0, (int) statusBarHeight);
mMultipleCountFirstTaskRect = replyData.getParcelable(KEY_MULTIPLE_TASK_STACK_RECT);
mMultipleCountFirstTaskRect.offset(0, (int) statusBarHeight);
+ Console.log(Constants.DebugFlags.App.RecentsComponent,
+ "[RecentsComponent|RecentsMessageHandler|handleMessage]",
+ "singleTaskRect: " + mSingleCountFirstTaskRect +
+ " multipleTaskRect: " + mMultipleCountFirstTaskRect);
+
+ // If we had the update the animation rects as a result of onServiceConnected, then
+ // we check for whether we need to toggle the recents here.
+ if (mToggleRecentsUponServiceBound) {
+ startAlternateRecentsActivity();
+ mToggleRecentsUponServiceBound = false;
+ }
}
}
}
@@ -78,11 +89,16 @@
mService = new Messenger(service);
mServiceIsBound = true;
- // Toggle recents if this service connection was triggered by hitting the recents button
- if (mToggleRecentsUponServiceBound) {
- startAlternateRecentsActivity();
+ if (hasValidTaskRects()) {
+ // Toggle recents if this new service connection was triggered by hitting recents
+ if (mToggleRecentsUponServiceBound) {
+ startAlternateRecentsActivity();
+ mToggleRecentsUponServiceBound = false;
+ }
+ } else {
+ // Otherwise, update the animation rects before starting the recents if requested
+ updateAnimationRects();
}
- mToggleRecentsUponServiceBound = false;
}
@Override
@@ -191,6 +207,26 @@
}
public void onConfigurationChanged(Configuration newConfig) {
+ updateAnimationRects();
+ }
+
+ /** Binds to the recents implementation */
+ private void bindToRecentsService(boolean toggleRecentsUponConnection) {
+ mToggleRecentsUponServiceBound = toggleRecentsUponConnection;
+ Intent intent = new Intent();
+ intent.setClassName(sRecentsPackage, sRecentsService);
+ mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ /** Returns whether we have valid task rects to animate to. */
+ boolean hasValidTaskRects() {
+ return mSingleCountFirstTaskRect != null && mSingleCountFirstTaskRect.width() > 0 &&
+ mSingleCountFirstTaskRect.height() > 0 && mMultipleCountFirstTaskRect != null &&
+ mMultipleCountFirstTaskRect.width() > 0 && mMultipleCountFirstTaskRect.height() > 0;
+ }
+
+ /** Updates each of the task animation rects. */
+ void updateAnimationRects() {
if (mServiceIsBound) {
Resources res = mContext.getResources();
int statusBarHeight = res.getDimensionPixelSize(
@@ -216,14 +252,6 @@
}
}
- /** Binds to the recents implementation */
- private void bindToRecentsService(boolean toggleRecentsUponConnection) {
- mToggleRecentsUponServiceBound = toggleRecentsUponConnection;
- Intent intent = new Intent();
- intent.setClassName(sRecentsPackage, sRecentsService);
- mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- }
-
/** Loads the first task thumbnail */
Bitmap loadFirstTaskThumbnail() {
SystemServicesProxy ssp = mSystemServicesProxy;
@@ -300,6 +328,49 @@
return SurfaceControl.screenshot((int) dims[0], (int) dims[1]);
}
+ /** Creates the activity options for a thumbnail transition. */
+ ActivityOptions getThumbnailTransitionActivityOptions(Rect taskRect) {
+ // Loading from thumbnail
+ Bitmap thumbnail;
+ Bitmap firstThumbnail = loadFirstTaskThumbnail();
+ if (firstThumbnail != null) {
+ // Create the thumbnail
+ thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
+ Bitmap.Config.ARGB_8888);
+ int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
+ Canvas c = new Canvas(thumbnail);
+ c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
+ new Rect(0, 0, taskRect.width(), taskRect.height()), null);
+ c.setBitmap(null);
+ // Recycle the old thumbnail
+ firstThumbnail.recycle();
+ } else {
+ // Load the thumbnail from the screenshot if can't get one from the system
+ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ Bitmap screenshot = takeScreenshot(display);
+ if (screenshot != null) {
+ Resources res = mContext.getResources();
+ int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
+ int statusBarHeight = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
+ Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(thumbnail);
+ c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight +
+ size), new Rect(0, 0, taskRect.width(), taskRect.height()), null);
+ c.setBitmap(null);
+ // Recycle the temporary screenshot
+ screenshot.recycle();
+ } else {
+ return null;
+ }
+ }
+
+ return ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, thumbnail,
+ taskRect.left, taskRect.top, null);
+ }
+
/** Starts the recents activity */
void startAlternateRecentsActivity() {
// If the user has toggled it too quickly, then just eat up the event here (it's better than
@@ -351,47 +422,28 @@
// number of items in the list.
List<ActivityManager.RecentTaskInfo> recentTasks =
ssp.getRecentTasks(4, UserHandle.CURRENT.getIdentifier());
- boolean hasMultipleTasks = hasMultipleRecentsTask(recentTasks);
+ Rect taskRect = hasMultipleRecentsTask(recentTasks) ? mMultipleCountFirstTaskRect :
+ mSingleCountFirstTaskRect;
boolean isTaskExcludedFromRecents = isTopTaskExcludeFromRecents(recentTasks);
- Rect taskRect = hasMultipleTasks ? mMultipleCountFirstTaskRect : mSingleCountFirstTaskRect;
- if (!isTopTaskHome && !isTaskExcludedFromRecents &&
- (taskRect != null) && (taskRect.width() > 0) && (taskRect.height() > 0)) {
- // Loading from thumbnail
- Bitmap thumbnail;
- Bitmap firstThumbnail = loadFirstTaskThumbnail();
- if (firstThumbnail != null) {// Create the thumbnail
- thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
- Bitmap.Config.ARGB_8888);
- int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
- Canvas c = new Canvas(thumbnail);
- c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
- new Rect(0, 0, taskRect.width(), taskRect.height()), null);
- c.setBitmap(null);
- // Recycle the old thumbnail
- firstThumbnail.recycle();
- } else {
- // Load the thumbnail from the screenshot if can't get one from the system
- WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- Bitmap screenshot = takeScreenshot(display);
- Resources res = mContext.getResources();
- int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
- int statusBarHeight = res.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height);
- thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
- Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(thumbnail);
- c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size),
- new Rect(0, 0, taskRect.width(), taskRect.height()), null);
- c.setBitmap(null);
- // Recycle the temporary screenshot
- screenshot.recycle();
- }
+ boolean useThumbnailTransition = !isTopTaskHome && !isTaskExcludedFromRecents &&
+ hasValidTaskRects();
- ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView,
- thumbnail, taskRect.left, taskRect.top, null);
- startAlternateRecentsActivity(opts, true);
- } else {
+ if (useThumbnailTransition) {
+ // Try starting with a thumbnail transition
+ ActivityOptions opts = getThumbnailTransitionActivityOptions(taskRect);
+ if (opts != null) {
+ startAlternateRecentsActivity(opts, true);
+ } else {
+ // Fall through below to the non-thumbnail transition
+ useThumbnailTransition = false;
+ }
+ }
+
+ // If there is no thumbnail transition, then just use a generic transition
+ // XXX: This should be different between home and from a recents-excluded app, perhaps the
+ // recents-excluded app should still show up in recents, when the app is in the
+ // foreground
+ if (!useThumbnailTransition) {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.recents_from_launcher_enter,
R.anim.recents_from_launcher_exit);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index bc8ab45..90ea873 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -91,11 +91,8 @@
public static final int TaskStackOverscrollRange = 150;
public static final int FilterStartDelay = 25;
- // The amount to inverse scale the movement if we are overscrolling
- public static final float TouchOverscrollScaleFactor = 3f;
-
// The padding will be applied to the smallest dimension, and then applied to all sides
- public static final float StackPaddingPct = 0.15f;
+ public static final float StackPaddingPct = 0.1f;
// The overlap height relative to the task height
public static final float StackOverlapPct = 0.65f;
// The height of the peek space relative to the stack height
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 23a0179..d1a3954 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -49,6 +49,8 @@
public int taskStackScrollDismissInfoPaneDistance;
public int taskStackMaxDim;
public int taskViewInfoPaneAnimDuration;
+ public int taskViewTranslationZMinPx;
+ public int taskViewTranslationZIncrementPx;
public int taskViewRoundedCornerRadiusPx;
public int searchBarSpaceHeightPx;
@@ -108,6 +110,9 @@
res.getInteger(R.integer.recents_animate_task_view_info_pane_duration);
taskViewRoundedCornerRadiusPx =
res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
+ taskViewTranslationZMinPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
+ taskViewTranslationZIncrementPx =
+ res.getDimensionPixelSize(R.dimen.recents_task_view_z_increment);
searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskInfoView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskInfoView.java
index 983ad49..c6c29a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskInfoView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskInfoView.java
@@ -20,10 +20,12 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.TouchFeedbackDrawable;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.FrameLayout;
@@ -151,6 +153,15 @@
RecentsConfiguration configuration = RecentsConfiguration.getInstance();
if (Constants.DebugFlags.App.EnableTaskBarThemeColors && t.colorPrimary != 0) {
setBackgroundColor(t.colorPrimary);
+ // Workaround: The button currently doesn't support setting a custom background tint
+ // not defined in the theme. Just lower the alpha on the button to make it blend more
+ // into the background.
+ if (mAppInfoButton.getBackground() instanceof TouchFeedbackDrawable) {
+ TouchFeedbackDrawable d = (TouchFeedbackDrawable) mAppInfoButton.getBackground();
+ if (d != null) {
+ d.setAlpha(96);
+ }
+ }
} else {
setBackgroundColor(configuration.taskBarViewDefaultBackgroundColor);
}
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 e273ecf..ce43b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -395,12 +395,20 @@
return false;
}
- /** Returns whether the specified scroll is out of bounds */
- boolean isScrollOutOfBounds(int scroll) {
- return (scroll < mMinScroll) || (scroll > mMaxScroll);
+
+ /** Returns the amount that the scroll is out of bounds */
+ int getScrollAmountOutOfBounds(int scroll) {
+ if (scroll < mMinScroll) {
+ return mMinScroll - scroll;
+ } else if (scroll > mMaxScroll) {
+ return scroll - mMaxScroll;
+ }
+ return 0;
}
+
+ /** Returns whether the specified scroll is out of bounds */
boolean isScrollOutOfBounds() {
- return isScrollOutOfBounds(getStackScroll());
+ return getScrollAmountOutOfBounds(getStackScroll()) != 0;
}
/** Updates the min and max virtual scroll bounds */
@@ -561,7 +569,7 @@
int smallestDimension = Math.min(width, height);
int padding = (int) (Constants.Values.TaskStackView.StackPaddingPct * smallestDimension / 2f);
if (Constants.DebugFlags.App.EnableSearchButton) {
- // Don't need to pad the top since we have some padding on the search bar already
+ mStackRect.top += padding;
mStackRect.left += padding;
mStackRect.right -= padding;
mStackRect.bottom -= padding;
@@ -1297,9 +1305,13 @@
}
if (mIsScrolling) {
int curStackScroll = mSv.getStackScroll();
- if (mSv.isScrollOutOfBounds(curStackScroll + deltaY)) {
- // Scale the touch if we are overscrolling
- deltaY /= Constants.Values.TaskStackView.TouchOverscrollScaleFactor;
+ int overScrollAmount = mSv.getScrollAmountOutOfBounds(curStackScroll + deltaY);
+ if (overScrollAmount != 0) {
+ // Bound the overscroll to a fixed amount, and inversely scale the y-movement
+ // relative to how close we are to the max overscroll
+ float maxOverScroll = mSv.mTaskRect.height() / 3f;
+ deltaY = Math.round(deltaY * (1f - (Math.min(maxOverScroll, overScrollAmount)
+ / maxOverScroll)));
}
mSv.setStackScroll(curStackScroll + deltaY);
if (mSv.isScrollOutOfBounds()) {
@@ -1319,6 +1331,7 @@
if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
// Enable HW layers on the stack
mSv.addHwLayersRefCount("flingScroll");
+ // XXX: Make this animation a function of the velocity AND distance
int overscrollRange = (int) (Math.min(1f,
Math.abs((float) velocity / mMaximumVelocity)) *
Constants.Values.TaskStackView.TaskStackOverscrollRange);
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 ecd0c45..801de24 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -20,6 +20,7 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Outline;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
@@ -33,7 +34,6 @@
import com.android.systemui.recents.BakedBezierInterpolator;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.Utilities;
import com.android.systemui.recents.model.Task;
@@ -108,6 +108,11 @@
mRoundedRectClipPath.reset();
mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()),
radius, radius, Path.Direction.CW);
+
+ // Update the outline
+ Outline o = new Outline();
+ o.setRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), radius);
+ setOutline(o);
}
@Override
@@ -134,14 +139,20 @@
/** Synchronizes this view's properties with the task's transform */
void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform,
TaskViewTransform toTransform, int duration) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ int minZ = config.taskViewTranslationZMinPx;
+ int incZ = config.taskViewTranslationZIncrementPx;
+
if (duration > 0) {
if (animateFromTransform != null) {
setTranslationY(animateFromTransform.translationY);
+ setTranslationZ(Math.max(minZ, minZ + (animateFromTransform.t * incZ)));
setScaleX(animateFromTransform.scale);
setScaleY(animateFromTransform.scale);
setAlpha(animateFromTransform.alpha);
}
animate().translationY(toTransform.translationY)
+ .translationZ(Math.max(minZ, minZ + (toTransform.t * incZ)))
.scaleX(toTransform.scale)
.scaleY(toTransform.scale)
.alpha(toTransform.alpha)
@@ -157,6 +168,7 @@
.start();
} else {
setTranslationY(toTransform.translationY);
+ setTranslationZ(Math.max(minZ, minZ + (toTransform.t * incZ)));
setScaleX(toTransform.scale);
setScaleY(toTransform.scale);
setAlpha(toTransform.alpha);
@@ -169,6 +181,7 @@
void resetViewProperties() {
setTranslationX(0f);
setTranslationY(0f);
+ setTranslationZ(0f);
setScaleX(1f);
setScaleY(1f);
setAlpha(1f);
@@ -363,7 +376,7 @@
@Override
public void onClick(View v) {
if (v == mInfoView) {
- // Do nothing
+ hideInfoPane();
} else if (v == mBarView.mApplicationIcon) {
mCb.onTaskIconClicked(this);
} else if (v == mInfoView.mAppInfoButton) {