Fixing task view heights in paging tasks
- Now, all task views will be bounded by the stack rect, and the
thumbnail bitmaps will be scaled accordingly to fit either by width
(when stacked) or to the view rect (when freeform)
- Fixing issue where the history button was not offset in freeform
- Tweaking thumbnail sizes of fullscreen screenshots
- Still requires changes to fix clipping to the correct aspect ratio in
freeform.
Change-Id: I678b87c2f06947d32f3bb7c60a35f28eb36b5a68
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index f2920e5..75e7959 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -21,11 +21,6 @@
public <init>(android.os.Bundle);
}
--keep class com.android.systemui.recents.views.TaskStackLayoutAlgorithm {
- public float getFocusState();
- public void setFocusState(float);
-}
-
-keep class com.android.systemui.recents.views.TaskView {
public int getDim();
public void setDim(int);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index b094702..0f82cce 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -688,7 +688,7 @@
ArrayList<Task> tasks = stack.getStackTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
- if (SystemServicesProxy.isFreeformStack(task.key.stackId)) {
+ if (task.isFreeformTask()) {
mTmpTransform = stackView.getStackAlgorithm().getStackTransform(task,
stackView.getScroller().getStackScroll(), mTmpTransform, null);
Rect toTaskRect = new Rect();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
index 15989bf..913d427 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -130,7 +130,7 @@
int prevDayKey = -1;
mRows.clear();
for (Task task : tasksMostRecent) {
- if (SystemServicesProxy.isFreeformStack(task.key.stackId)) {
+ if (task.isFreeformTask()) {
continue;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 70370ec..945fdc1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -16,27 +16,53 @@
package com.android.systemui.recents.views;
+import android.animation.ObjectAnimator;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.util.IntProperty;
+import android.util.Property;
import android.view.View;
import android.view.ViewOutlineProvider;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsConfiguration;
/* An outline provider that has a clip and outline that can be animated. */
public class AnimateableViewBounds extends ViewOutlineProvider {
- TaskView mSourceView;
+ View mSourceView;
Rect mClipRect = new Rect();
Rect mClipBounds = new Rect();
int mCornerRadius;
float mAlpha = 1f;
final float mMinAlpha = 0.25f;
- public AnimateableViewBounds(TaskView source, int cornerRadius) {
+ public static final Property<AnimateableViewBounds, Integer> CLIP_BOTTOM =
+ new IntProperty<AnimateableViewBounds>("clipBottom") {
+ @Override
+ public void setValue(AnimateableViewBounds object, int clip) {
+ object.setClipBottom(clip, false /* force */);
+ }
+
+ @Override
+ public Integer get(AnimateableViewBounds object) {
+ return object.getClipBottom();
+ }
+ };
+
+ public static final Property<AnimateableViewBounds, Integer> CLIP_RIGHT =
+ new IntProperty<AnimateableViewBounds>("clipRight") {
+ @Override
+ public void setValue(AnimateableViewBounds object, int clip) {
+ object.setClipRight(clip, false /* force */);
+ }
+
+ @Override
+ public Integer get(AnimateableViewBounds object) {
+ return object.getClipRight();
+ }
+ };
+
+ public AnimateableViewBounds(View source, int cornerRadius) {
mSourceView = source;
mCornerRadius = cornerRadius;
- setClipBottom(getClipBottom(), false /* force */);
}
@Override
@@ -56,18 +82,21 @@
}
}
+ /**
+ * Animates the bottom clip.
+ */
+ public void animateClipBottom(int bottom) {
+ ObjectAnimator animator = ObjectAnimator.ofInt(this, CLIP_BOTTOM, getClipBottom(), bottom);
+ animator.setDuration(150);
+ animator.start();
+ }
+
/** Sets the bottom clip. */
public void setClipBottom(int bottom, boolean force) {
if (bottom != mClipRect.bottom || force) {
mClipRect.bottom = bottom;
mSourceView.invalidateOutline();
updateClipBounds();
-
- RecentsConfiguration config = Recents.getConfiguration();
- if (!config.useHardwareLayers) {
- mSourceView.mThumbnailView.updateThumbnailVisibility(
- bottom - mSourceView.getPaddingBottom());
- }
}
}
@@ -76,6 +105,20 @@
return mClipRect.bottom;
}
+ /** Sets the right clip. */
+ public void setClipRight(int right, boolean force) {
+ if (right != mClipRect.right || force) {
+ mClipRect.right = right;
+ mSourceView.invalidateOutline();
+ updateClipBounds();
+ }
+ }
+
+ /** Returns the right clip. */
+ public int getClipRight() {
+ return mClipRect.right;
+ }
+
private void updateClipBounds() {
mClipBounds.set(mClipRect.left, mClipRect.top,
mSourceView.getWidth() - mClipRect.right,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 765f686..90d62c1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -110,7 +110,7 @@
transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
transformOut.visible = true;
- transformOut.p = 0;
+ transformOut.p = 1f;
if (DEBUG) {
Log.d(TAG, "getTransform: " + task.key + ", " + transformOut);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index f2a3e84..0557f65 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -350,10 +350,10 @@
// Measure the history button with the full space above the stack, but width-constrained
// to the stack
- Rect stackRect = mTaskStackView.mLayoutAlgorithm.mCurrentStackRect;
+ Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
measureChild(mHistoryButton,
- MeasureSpec.makeMeasureSpec(stackRect.width(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mTaskStackView.mLayoutAlgorithm.getStackTopOffset(),
+ MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(historyButtonRect.height(),
MeasureSpec.EXACTLY));
setMeasuredDimension(width, height);
}
@@ -386,10 +386,9 @@
// Layout the history button left-aligned with the stack, but offset from the top of the
// view
- Rect stackRect = mTaskStackView.mLayoutAlgorithm.mCurrentStackRect;
- mHistoryButton.layout(stackRect.left, top + mSystemInsets.top,
- stackRect.left + mHistoryButton.getMeasuredWidth(),
- top + mSystemInsets.top + mHistoryButton.getMeasuredHeight());
+ Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
+ mHistoryButton.layout(historyButtonRect.left, historyButtonRect.top,
+ historyButtonRect.right, historyButtonRect.bottom);
if (mAwaitingFirstLayout) {
mAwaitingFirstLayout = false;
@@ -454,7 +453,7 @@
public void onTaskViewClicked(final TaskStackView stackView, final TaskView tv,
final TaskStack stack, final Task task, final boolean lockToTask,
final Rect bounds, int destinationStack) {
- mLastTaskLaunchedWasFreeform = SystemServicesProxy.isFreeformStack(task.key.stackId);
+ mLastTaskLaunchedWasFreeform = task.isFreeformTask();
mTransitionHelper.launchTaskFromRecents(stack, task, stackView, tv, lockToTask, bounds,
destinationStack);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index f6edb02..6af2ada 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -162,6 +162,8 @@
public Rect mCurrentStackRect = new Rect();
// This is the current system insets
public Rect mSystemInsets = new Rect();
+ // This is the bounds of the history button above the stack rect
+ public Rect mHistoryButtonRect = new Rect();
// The visible ranges when the stack is focused and unfocused
private Range mUnfocusedRange;
@@ -225,8 +227,7 @@
mUnfocusedRange = new Range(res.getFloat(R.integer.recents_layout_unfocused_range_min),
res.getFloat(R.integer.recents_layout_unfocused_range_max));
mFocusState = getDefaultFocusState();
- mFocusedPeekHeight = ssp.hasFreeformWorkspaceSupport() ?
- 0 : res.getDimensionPixelSize(R.dimen.recents_layout_focused_peek_size);
+ mFocusedPeekHeight = res.getDimensionPixelSize(R.dimen.recents_layout_focused_peek_size);
mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
@@ -269,13 +270,6 @@
}
/**
- * Returns the stack top offset, used for measuring the history button space.
- */
- public int getStackTopOffset() {
- return mStackTopOffset;
- }
-
- /**
* Computes the stack and task rects. The given task stack bounds is the whole bounds not
* including the search bar.
*/
@@ -305,15 +299,20 @@
taskStackBounds.top + heightPadding,
taskStackBounds.right - widthPadding,
taskStackBounds.bottom);
+ mCurrentStackRect = ssp.hasFreeformWorkspaceSupport() ? mFreeformStackRect : mStackRect;
+ mHistoryButtonRect.set(mCurrentStackRect.left, mCurrentStackRect.top - heightPadding,
+ mCurrentStackRect.right, mCurrentStackRect.top + mFocusedPeekHeight);
// Anchor the task rect to the top-center of the non-freeform stack rect
float aspect = (float) (taskStackBounds.width() - mSystemInsets.left - mSystemInsets.right)
/ (taskStackBounds.height() - mSystemInsets.bottom);
int width = mStackRect.width();
- int height = debugFlags.isFullscreenThumbnailsEnabled() ? (int) (width / aspect) : width;
+ int minHeight = mCurrentStackRect.height() - mFocusedPeekHeight - mStackBottomOffset;
+ int height = debugFlags.isFullscreenThumbnailsEnabled()
+ ? (int) Math.min(width / aspect, minHeight)
+ : width;
mTaskRect.set(mStackRect.left, mStackRect.top,
mStackRect.left + width, mStackRect.top + height);
- mCurrentStackRect = ssp.hasFreeformWorkspaceSupport() ? mFreeformStackRect : mStackRect;
// Short circuit here if the stack rects haven't changed so we don't do all the work below
if (lastStackRect.equals(mCurrentStackRect)) {
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 fd19979..30efd5f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -551,6 +551,8 @@
* Updates the clip for each of the task views from back to front.
*/
void clipTaskViews(boolean forceUpdate) {
+ RecentsConfiguration config = Recents.getConfiguration();
+
// Update the clip on each task child
List<TaskView> taskViews = getTaskViews();
TaskView tmpTv = null;
@@ -588,6 +590,9 @@
}
}
tv.getViewBounds().setClipBottom(clipBottom, forceUpdate);
+ if (!config.useHardwareLayers) {
+ tv.mThumbnailView.updateThumbnailVisibility(clipBottom - tv.getPaddingBottom());
+ }
}
mStackViewsClipDirty = false;
}
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 44985d4..6db2eb9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -608,7 +608,9 @@
/** Compute the dim as a function of the scale of this view. */
int getDimFromTaskProgress() {
- float x = mTaskProgress < 0 ? 1f : mDimInterpolator.getInterpolation(1f - mTaskProgress);
+ float x = mTaskProgress < 0
+ ? 1f
+ : mDimInterpolator.getInterpolation(1f - mTaskProgress);
float dim = mMaxDimScale * x;
return (int) (dim * 255);
}
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 bc50846..b3d263e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -45,6 +45,8 @@
*/
public class TaskViewThumbnail extends View {
+ private Task mTask;
+
// Drawing
int mCornerRadius;
float mDimAlpha;
@@ -52,6 +54,7 @@
Paint mDrawPaint = new Paint();
RectF mBitmapRect = new RectF();
RectF mLayoutRect = new RectF();
+ float mBitmapScale = 1f;
BitmapShader mBitmapShader;
LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
@@ -165,7 +168,16 @@
/** Updates the thumbnail shader's scale transform. */
void updateThumbnailScale() {
if (mBitmapShader != null) {
- mScaleMatrix.setRectToRect(mBitmapRect, mLayoutRect, Matrix.ScaleToFit.FILL);
+ if (mTask.isFreeformTask()) {
+ // For freeform tasks, we scale the bitmap rect to fit in the layout rect
+ mBitmapScale = Math.min(mLayoutRect.width() / mBitmapRect.width(),
+ mLayoutRect.height() / mBitmapRect.height());
+ } else {
+ // For stack tasks, we scale the bitmap to fit the width
+ mBitmapScale = Math.max(1f, mLayoutRect.width() / mBitmapRect.width());
+ }
+
+ mScaleMatrix.setScale(mBitmapScale, mBitmapScale);
mBitmapShader.setLocalMatrix(mScaleMatrix);
}
}
@@ -202,6 +214,7 @@
/** Binds the thumbnail view to the task */
void rebindToTask(Task t) {
+ mTask = t;
if (t.thumbnail != null) {
setThumbnail(t.thumbnail);
} else {
@@ -211,6 +224,7 @@
/** Unbinds the thumbnail view from the task */
void unbindFromTask() {
+ mTask = null;
setThumbnail(null);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index cd29050..da2c8c5c 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -859,13 +859,11 @@
if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tTaking screenshot");
// When this flag is set, we currently take the fullscreen screenshot of the activity
- // but scaled inversely by the density. This gives us a "good-enough" fullscreen
- // thumbnail to use within SystemUI without using enormous amounts of memory on high
- // density devices.
+ // but scaled to half the size. This gives us a "good-enough" fullscreen thumbnail to
+ // use within SystemUI while keeping memory usage low.
if (mService.mTakeFullscreenScreenshots) {
- Context context = mService.mContext;
w = h = -1;
- scale = (1f / Math.max(1f, context.getResources().getDisplayMetrics().density));
+ scale = 0.5f;
}
return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
w, h, scale);