diff options
author | Winson Chung <winsonc@google.com> | 2014-04-09 23:50:32 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-09 23:50:33 +0000 |
commit | 2adb95860f9682ed2c4893da58679540cd8cac56 (patch) | |
tree | 74362aca810b438d0adcc8653820dc2b0e9321f0 /packages | |
parent | bc1a8f42d9eb5f1d91c872904a9a283781291fcb (diff) | |
parent | 0d767551c55d9e594a0b944bd1926c21a344b5ae (diff) | |
download | frameworks_base-2adb95860f9682ed2c4893da58679540cd8cac56.zip frameworks_base-2adb95860f9682ed2c4893da58679540cd8cac56.tar.gz frameworks_base-2adb95860f9682ed2c4893da58679540cd8cac56.tar.bz2 |
Merge "Allow for different rects when animating to a single task stack view and a multiple task stack view."
Diffstat (limited to 'packages')
10 files changed, 116 insertions, 99 deletions
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index 96da21f..8297878 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -43,7 +43,11 @@ android:textSize="24sp" android:textColor="#ffffffff" android:text="@string/recents_empty_message" - android:fontFamily="sans-serif-thin" /> + android:fontFamily="sans-serif-thin" + android:singleLine="true" + android:maxLines="2" + android:ellipsize="marquee" + android:fadingEdge="horizontal" /> <ImageView android:id="@+id/activity_icon" android:layout_width="@dimen/recents_task_view_activity_icon_size" diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 77944c8..672c1d0 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -112,5 +112,7 @@ <integer name="recents_filter_animate_current_views_min_duration">175</integer> <!-- The min animation duration for animating views that are newly visible. --> <integer name="recents_filter_animate_new_views_min_duration">125</integer> + <!-- The min animation duration for animating views that are newly visible. --> + <integer name="recents_animate_task_bar_enter_duration">200</integer> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index 8543b97..b72294b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -44,6 +44,7 @@ import android.view.View; import android.view.WindowManager; import com.android.systemui.R; +import java.util.Iterator; import java.util.List; /** A proxy implementation for the recents component */ @@ -57,8 +58,11 @@ public class AlternateRecentsComponent { Resources res = mContext.getResources(); float statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); - mFirstTaskRect = (Rect) msg.getData().getParcelable("taskRect"); - mFirstTaskRect.offset(0, (int) statusBarHeight); + Bundle replyData = msg.getData().getParcelable("replyData"); + mSingleCountFirstTaskRect = replyData.getParcelable("singleCountTaskRect"); + mSingleCountFirstTaskRect.offset(0, (int) statusBarHeight); + mMultipleCountFirstTaskRect = replyData.getParcelable("multipleCountTaskRect"); + mMultipleCountFirstTaskRect.offset(0, (int) statusBarHeight); } } } @@ -114,7 +118,8 @@ public class AlternateRecentsComponent { RecentsServiceConnection mConnection = new RecentsServiceConnection(); View mStatusBarView; - Rect mFirstTaskRect = new Rect(); + Rect mSingleCountFirstTaskRect = new Rect(); + Rect mMultipleCountFirstTaskRect = new Rect(); long mLastToggleTime; public AlternateRecentsComponent(Context context) { @@ -227,20 +232,24 @@ public class AlternateRecentsComponent { return null; } - /** Returns whether there is a first task */ - boolean hasFirstTask() { + /** Returns whether there is are multiple recents tasks */ + boolean hasMultipleRecentsTask() { + // NOTE: Currently there's no method to get the number of non-home tasks, so we have to + // compute this ourselves SystemServicesProxy ssp = mSystemServicesProxy; - List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1, + List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(4, UserHandle.CURRENT.getIdentifier()); - for (ActivityManager.RecentTaskInfo t : tasks) { + Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); + while (iter.hasNext()) { + ActivityManager.RecentTaskInfo t = iter.next(); + // Skip tasks in the home stack if (ssp.isInHomeStack(t.persistentId)) { + iter.remove(); continue; } - - return true; } - return false; + return (tasks.size() > 1); } /** Converts from the device rotation to the degree */ @@ -287,8 +296,10 @@ public class AlternateRecentsComponent { // to launch the first task or dismiss itself SystemServicesProxy ssp = mSystemServicesProxy; List<ActivityManager.RunningTaskInfo> tasks = ssp.getRunningTasks(1); + boolean isTopTaskHome = false; if (!tasks.isEmpty()) { - ComponentName topActivity = tasks.get(0).topActivity; + ActivityManager.RunningTaskInfo topTask = tasks.get(0); + ComponentName topActivity = topTask.topActivity; // Check if the front most activity is recents if (topActivity.getPackageName().equals(sRecentsPackage) && @@ -311,16 +322,30 @@ public class AlternateRecentsComponent { mLastToggleTime = System.currentTimeMillis(); return; } + + // Determine whether the top task is currently home + isTopTaskHome = ssp.isInHomeStack(topTask.id); } // Otherwise, Recents is not the front-most activity and we should animate into it - Rect taskRect = mFirstTaskRect; - if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) { + boolean hasMultipleTasks = hasMultipleRecentsTask(); + Rect taskRect = hasMultipleTasks ? mMultipleCountFirstTaskRect : mSingleCountFirstTaskRect; + if (!isTopTaskHome && taskRect != null && taskRect.width() > 0 && taskRect.height() > 0) { // Loading from thumbnail Bitmap thumbnail; Bitmap firstThumbnail = loadFirstTaskThumbnail(); - if (firstThumbnail == null) { - // Load the thumbnail from the screenshot + 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); @@ -328,29 +353,18 @@ public class AlternateRecentsComponent { int size = Math.min(screenshot.getWidth(), screenshot.getHeight()); int statusBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); - thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.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, mFirstTaskRect.width(), mFirstTaskRect.height()), null); + new Rect(0, 0, taskRect.width(), taskRect.height()), null); c.setBitmap(null); - // Recycle the old screenshot + // Recycle the temporary screenshot screenshot.recycle(); - } else { - // Create the thumbnail - thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.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, mFirstTaskRect.width(), mFirstTaskRect.height()), null); - c.setBitmap(null); - // Recycle the old thumbnail - firstThumbnail.recycle(); } ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, - thumbnail, mFirstTaskRect.left, mFirstTaskRect.top, null); + thumbnail, taskRect.left, taskRect.top, null); startAlternateRecentsActivity(opts); } else { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 86f188e..26446cf 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -72,8 +72,6 @@ public class Constants { public static class Window { // The dark background dim is set behind the empty recents view public static final float DarkBackgroundDim = 0.5f; - // The background dim is set behind the card stack - public static final float BackgroundDim = 0.35f; } public static class RecentsTaskLoader { @@ -100,9 +98,6 @@ public class Constants { public static class TaskView { public static final boolean AnimateFrontTaskIconOnEnterRecents = true; public static final boolean AnimateFrontTaskIconOnLeavingRecents = true; - - public static final boolean UseRoundedCorners = false; - public static final float RoundedCornerRadiusDps = 3; } } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 94a655f..017581a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -39,6 +39,7 @@ public class RecentsConfiguration { public int filteringCurrentViewsMinAnimDuration; public int filteringNewViewsMinAnimDuration; + public int taskBarEnterAnimDuration; /** Private constructor */ private RecentsConfiguration() {} @@ -76,6 +77,8 @@ public class RecentsConfiguration { res.getInteger(R.integer.recents_filter_animate_current_views_min_duration); filteringNewViewsMinAnimDuration = res.getInteger(R.integer.recents_filter_animate_new_views_min_duration); + taskBarEnterAnimDuration = + res.getInteger(R.integer.recents_animate_task_bar_enter_duration); } public void updateSystemInsets(Rect insets) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java index 22363bb..96fbf30 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java @@ -26,6 +26,7 @@ import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskViewTransform; @@ -62,14 +63,27 @@ class SystemUIMessageHandler extends Handler { // Create a dummy task stack & compute the rect for the thumbnail to animate to TaskStack stack = new TaskStack(context); TaskStackView tsv = new TaskStackView(context, stack); - // Since the nav bar height is already accounted for in the windowRect, don't pass - // in a bottom inset + Bundle replyData = new Bundle(); + TaskViewTransform transform; + + // Calculate the target task rect for when there is one task + // NOTE: Since the nav bar height is already accounted for in the windowRect, don't + // pass in a bottom inset + stack.addTask(new Task()); + tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0); + tsv.boundScroll(); + transform = tsv.getStackTransform(0, tsv.getStackScroll()); + replyData.putParcelable("singleCountTaskRect", new Rect(transform.rect)); + + // Also calculate the target task rect when there are multiple tasks + stack.addTask(new Task()); tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0); + tsv.setStackScrollRaw(Integer.MAX_VALUE); tsv.boundScroll(); - TaskViewTransform transform = tsv.getStackTransform(0, tsv.getStackScroll()); - Rect taskRect = new Rect(transform.rect); + transform = tsv.getStackTransform(1, tsv.getStackScroll()); + replyData.putParcelable("multipleCountTaskRect", new Rect(transform.rect)); - data.putParcelable("taskRect", taskRect); + data.putParcelable("replyData", replyData); Message reply = Message.obtain(null, RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0); reply.setData(data); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java index 754d956..3c34e90 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java @@ -358,18 +358,9 @@ public class RecentsTaskLoader { return mSystemServicesProxy; } - /** Reload the set of recent tasks */ - SpaceNode reload(Context context, int preloadCount) { - Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]"); - Resources res = context.getResources(); - ArrayList<Task> tasksToForceLoad = new ArrayList<Task>(); - TaskStack stack = new TaskStack(context); - SpaceNode root = new SpaceNode(context); - root.setStack(stack); - + private List<ActivityManager.RecentTaskInfo> getRecentTasks(Context context) { long t1 = System.currentTimeMillis(); - // Get the recent tasks SystemServicesProxy ssp = mSystemServicesProxy; List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(25, UserHandle.CURRENT.getIdentifier()); @@ -397,6 +388,24 @@ public class RecentsTaskLoader { } } + return tasks; + } + + /** Reload the set of recent tasks */ + SpaceNode reload(Context context, int preloadCount) { + long t1 = System.currentTimeMillis(); + + Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]"); + Resources res = context.getResources(); + ArrayList<Task> tasksToForceLoad = new ArrayList<Task>(); + TaskStack stack = new TaskStack(context); + SpaceNode root = new SpaceNode(context); + root.setStack(stack); + + // Get the recent tasks + SystemServicesProxy ssp = mSystemServicesProxy; + List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(context); + // Add each task to the task stack t1 = System.currentTimeMillis(); int taskCount = tasks.size(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index a0ff3b7..189f358 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -69,6 +69,10 @@ public class Task { TaskCallbacks mCb; + public Task() { + // Only used by RecentsService for task rect calculations. + } + public Task(int id, boolean isActive, Intent intent, String activityTitle, Bitmap activityIcon, int userId) { this.key = new TaskKey(id, intent); 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 c9a491e..ce0d91f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -171,7 +171,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal transform.visible = false; } else { transform.rect.offset(0, transform.translationY); - Utilities.scaleRectAboutCenter(transform.rect, scale); + Utilities.scaleRectAboutCenter(transform.rect, transform.scale); transform.visible = Rect.intersects(mRect, transform.rect); } transform.t = t; @@ -388,8 +388,14 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal int stackHeight = mStackRectSansPeek.height(); int maxScrollHeight = taskHeight + (int) ((numTasks - 1) * Constants.Values.TaskStackView.StackOverlapPct * taskHeight); - mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight; - mMaxScroll = maxScrollHeight - stackHeight; + + if (numTasks <= 1) { + // If there is only one task, then center the task in the stack rect (sans peek) + mMinScroll = mMaxScroll = -(stackHeight - taskHeight) / 2; + } else { + mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight; + mMaxScroll = maxScrollHeight - stackHeight; + } // Debug logging if (Constants.DebugFlags.UI.MeasureAndLayout) { @@ -479,8 +485,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Clip against the next view (if we aren't animating its alpha) nextTv = (TaskView) getChildAt(curIndex + 1); if (nextTv.getAlpha() == 1f) { - Rect curRect = tv.getClippingRect(mTmpRect, false); - Rect nextRect = nextTv.getClippingRect(mTmpRect2, true); + Rect curRect = tv.getClippingRect(mTmpRect); + Rect nextRect = nextTv.getClippingRect(mTmpRect2); RecentsConfiguration config = RecentsConfiguration.getInstance(); // The hit rects are relative to the task view, which needs to be offset by the // system bar height @@ -523,7 +529,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal int minHeight = (int) (mStackRect.height() - (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height())); int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height())); - int centerX = mStackRect.centerX(); mTaskRect.set(mStackRect.left, mStackRectSansPeek.top, mStackRect.right, mStackRectSansPeek.top + size); 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 e99fecb..a3056ec 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -20,9 +20,8 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; -import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; +import android.graphics.Outline; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; @@ -36,8 +35,6 @@ import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.Utilities; import com.android.systemui.recents.model.Task; -import java.util.Random; - /* A task view */ public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks { @@ -54,8 +51,6 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. TaskBarView mBarView; TaskViewCallbacks mCb; - Path mRoundedRectClipPath = new Path(); - public TaskView(Context context) { this(context, null); @@ -71,7 +66,6 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - setWillNotDraw(false); } @Override @@ -85,31 +79,6 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Update the rounded rect clip path - RecentsConfiguration config = RecentsConfiguration.getInstance(); - float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps); - mRoundedRectClipPath.reset(); - mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()), - radius, radius, Path.Direction.CW); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - int restoreCount = 0; - if (Constants.Values.TaskView.UseRoundedCorners) { - restoreCount = canvas.save(); - canvas.clipPath(mRoundedRectClipPath); - } - super.dispatchDraw(canvas); - if (Constants.Values.TaskView.UseRoundedCorners) { - canvas.restoreToCount(restoreCount); - } - } - /** Set callback */ void setCallbacks(TaskViewCallbacks cb) { mCb = cb; @@ -195,7 +164,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. .translationY(0) .setStartDelay(235) .setInterpolator(BakedBezierInterpolator.INSTANCE) - .setDuration(Utilities.calculateTranslationAnimationDuration(translate)) + .setDuration(config.taskBarEnterAnimDuration) .withLayer() .start(); } @@ -214,23 +183,21 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task. .setInterpolator(BakedBezierInterpolator.INSTANCE) .setDuration(Utilities.calculateTranslationAnimationDuration(translate)) .withLayer() - .withEndAction(r) + .withEndAction(new Runnable() { + @Override + public void run() { + post(r); + } + }) .start(); } /** Returns the rect we want to clip (it may not be the full rect) */ - Rect getClippingRect(Rect outRect, boolean accountForRoundedRects) { + Rect getClippingRect(Rect outRect) { getHitRect(outRect); // XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster outRect.right = outRect.left + mThumbnailView.getRight(); outRect.bottom = outRect.top + mThumbnailView.getBottom(); - // We need to shrink the next rect by the rounded corners since those are draw on - // top of the current view - if (accountForRoundedRects) { - RecentsConfiguration config = RecentsConfiguration.getInstance(); - float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps); - outRect.inset((int) radius, (int) radius); - } return outRect; } |