Merge "Fix fullscreen and landscape task insets" into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index fa07e27..c26a1d0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -17,13 +17,10 @@
import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
-import android.graphics.Rect;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
/**
@@ -45,18 +42,9 @@
if (recentsView.getTaskViewCount() == 0) {
return super.getOverviewScaleAndTranslation(launcher);
}
- // Compute scale and translation y such that the most recent task view fills the screen.
- TaskThumbnailView dummyThumbnail = recentsView.getTaskViewAt(0).getThumbnail();
+ TaskView dummyTask = recentsView.getTaskViewAt(0);
ClipAnimationHelper clipAnimationHelper = new ClipAnimationHelper(launcher);
- clipAnimationHelper.fromTaskThumbnailView(dummyThumbnail, recentsView);
- Rect targetRect = new Rect();
- recentsView.getTaskSize(targetRect);
- clipAnimationHelper.updateTargetRect(targetRect);
- float toScale = clipAnimationHelper.getSourceRect().width()
- / clipAnimationHelper.getTargetRect().width();
- float toTranslationY = clipAnimationHelper.getSourceRect().centerY()
- - clipAnimationHelper.getTargetRect().centerY();
- return new ScaleAndTranslation(toScale, 0, toTranslationY);
+ return clipAnimationHelper.getOverviewFullscreenScaleAndTranslation(dummyTask);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 3b664b7..a1a790c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -124,7 +124,7 @@
@Override
protected void updateProgress(float progress) {
super.updateProgress(progress);
- updateFullscreenProgress(progress);
+ updateFullscreenProgress(Utilities.boundToRange(progress, 0, 1));
}
private void updateFullscreenProgress(float progress) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index e932452..c33d25c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -301,34 +301,19 @@
return;
}
- // Setup the clip animation helper source/target rects in the final transformed state
- // of the recents view (a scale/translationY may be applied prior to this animation
- // starting to line up the side pages during swipe up)
- float prevRvScale = recentsView.getScaleX();
- float prevRvTransY = recentsView.getTranslationY();
- float targetRvScale = endState.getOverviewScaleAndTranslation(launcher).scale;
- SCALE_PROPERTY.set(recentsView, targetRvScale);
- recentsView.setTranslationY(0);
ClipAnimationHelper clipHelper = new ClipAnimationHelper(launcher);
- float tmpCurveScale = v.getCurveScale();
- v.setCurveScale(1f);
- clipHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), null);
- v.setCurveScale(tmpCurveScale);
- SCALE_PROPERTY.set(recentsView, prevRvScale);
- recentsView.setTranslationY(prevRvTransY);
+ LauncherState.ScaleAndTranslation fromScaleAndTranslation
+ = clipHelper.getOverviewFullscreenScaleAndTranslation(v);
+ LauncherState.ScaleAndTranslation endScaleAndTranslation
+ = endState.getOverviewScaleAndTranslation(launcher);
- if (!clipHelper.getSourceRect().isEmpty() && !clipHelper.getTargetRect().isEmpty()) {
- float fromScale = clipHelper.getSourceRect().width()
- / clipHelper.getTargetRect().width();
- float fromTranslationY = clipHelper.getSourceRect().centerY()
- - clipHelper.getTargetRect().centerY();
- Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScale, 1);
- Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y,
- fromTranslationY, 0);
- scale.setInterpolator(LINEAR);
- translateY.setInterpolator(LINEAR);
- anim.playTogether(scale, translateY);
- }
+ Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY,
+ fromScaleAndTranslation.scale, endScaleAndTranslation.scale);
+ Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y,
+ fromScaleAndTranslation.translationY, endScaleAndTranslation.translationY);
+ scale.setInterpolator(LINEAR);
+ translateY.setInterpolator(LINEAR);
+ anim.playTogether(scale, translateY);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
index 3109921..a650113 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -35,12 +35,14 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
+import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.utilities.RectFEvaluator;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -280,6 +282,21 @@
}
}
+ /**
+ * Compute scale and translation y such that the specified task view fills the screen.
+ */
+ public LauncherState.ScaleAndTranslation getOverviewFullscreenScaleAndTranslation(TaskView v) {
+ TaskThumbnailView thumbnailView = v.getThumbnail();
+ RecentsView recentsView = v.getRecentsView();
+ fromTaskThumbnailView(thumbnailView, recentsView);
+ Rect taskSize = new Rect();
+ recentsView.getTaskSize(taskSize);
+ updateTargetRect(taskSize);
+ float scale = mSourceRect.width() / mTargetRect.width();
+ float translationY = mSourceRect.centerY() - mSourceRect.top - mTargetRect.centerY();
+ return new LauncherState.ScaleAndTranslation(scale, 0, translationY);
+ }
+
private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
if (sysUiProxy != null) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 7e15d52..a9184ec 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -33,6 +33,7 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -59,7 +60,7 @@
private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
- private final static Rect EMPTY_RECT = new Rect();
+ private final static RectF EMPTY_RECT_F = new RectF();
public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
new FloatProperty<TaskThumbnailView>("dimAlpha") {
@@ -87,10 +88,9 @@
private final Matrix mMatrix = new Matrix();
private float mClipBottom = -1;
- private Rect mScaledInsets = new Rect();
- private Rect mCurrentDrawnInsets = new Rect();
- private float mCurrentDrawnCornerRadius;
- private boolean mIsRotated;
+ // Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
+ private RectF mClippedInsets = new RectF();
+ private TaskView.FullscreenDrawParams mFullscreenParams;
private Task mTask;
private ThumbnailData mThumbnailData;
@@ -118,7 +118,7 @@
mDimmingPaintAfterClearing.setColor(Color.BLACK);
mActivity = BaseActivity.fromContext(context);
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
- setCurrentDrawnInsetsAndRadius(EMPTY_RECT, mCornerRadius);
+ mFullscreenParams = new TaskView.FullscreenDrawParams(mCornerRadius);
}
public void bind(Task task) {
@@ -201,23 +201,27 @@
@Override
protected void onDraw(Canvas canvas) {
+ RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets;
+ canvas.save();
+ canvas.translate(currentDrawnInsets.left, currentDrawnInsets.top);
+ canvas.scale(mFullscreenParams.mScale, mFullscreenParams.mScale);
// Draw the insets if we're being drawn fullscreen (we do this for quick switch).
drawOnCanvas(canvas,
- -mCurrentDrawnInsets.left,
- -mCurrentDrawnInsets.top,
- getMeasuredWidth() + mCurrentDrawnInsets.right,
- getMeasuredHeight() + mCurrentDrawnInsets.bottom,
- mCurrentDrawnCornerRadius);
+ -currentDrawnInsets.left,
+ -currentDrawnInsets.top,
+ getMeasuredWidth() + currentDrawnInsets.right,
+ getMeasuredHeight() + currentDrawnInsets.bottom,
+ mFullscreenParams.mCurrentDrawnCornerRadius);
+ canvas.restore();
}
- public Rect getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
- // Don't show insets in the wrong orientation or in multi window mode.
- return mIsRotated || isMultiWindowMode ? EMPTY_RECT : mScaledInsets;
+ public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
+ // Don't show insets in multi window mode.
+ return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
}
- public void setCurrentDrawnInsetsAndRadius(Rect insets, float radius) {
- mCurrentDrawnInsets.set(insets);
- mCurrentDrawnCornerRadius = radius;
+ public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
+ mFullscreenParams = fullscreenParams;
invalidate();
}
@@ -275,7 +279,7 @@
}
private void updateThumbnailMatrix() {
- mIsRotated = false;
+ boolean isRotated = false;
mClipBottom = -1;
if (mBitmapShader != null && mThumbnailData != null) {
float scale = mThumbnailData.scale;
@@ -296,30 +300,28 @@
final Configuration configuration =
getContext().getResources().getConfiguration();
// Rotate the screenshot if not in multi-window mode
- mIsRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
+ isRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
configuration.orientation != mThumbnailData.orientation &&
!mActivity.isInMultiWindowMode() &&
mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
// Scale the screenshot to always fit the width of the card.
- thumbnailScale = mIsRotated
+ thumbnailScale = isRotated
? getMeasuredWidth() / thumbnailHeight
: getMeasuredWidth() / thumbnailWidth;
}
- mScaledInsets.set(thumbnailInsets);
- Utilities.scaleRect(mScaledInsets, thumbnailScale);
-
- if (mIsRotated) {
+ if (isRotated) {
int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
mMatrix.setRotate(90 * rotationDir);
int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
int newTopInset = rotationDir == 1 ? thumbnailInsets.left : thumbnailInsets.right;
- mMatrix.postTranslate(-newLeftInset * scale, -newTopInset * scale);
+ mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
if (rotationDir == -1) {
// Crop the right/bottom side of the screenshot rather than left/top
float excessHeight = thumbnailWidth * thumbnailScale - getMeasuredHeight();
- mMatrix.postTranslate(0, -excessHeight);
+ mClippedInsets.offset(0, excessHeight);
}
+ mMatrix.postTranslate(-mClippedInsets.left, -mClippedInsets.top);
// Move the screenshot to the thumbnail window (rotation moved it out).
if (rotationDir == 1) {
mMatrix.postTranslate(mThumbnailData.thumbnail.getHeight(), 0);
@@ -327,13 +329,28 @@
mMatrix.postTranslate(0, mThumbnailData.thumbnail.getWidth());
}
} else {
- mMatrix.setTranslate(-mThumbnailData.insets.left * scale,
- -mThumbnailData.insets.top * scale);
+ mClippedInsets.offsetTo(thumbnailInsets.left * scale, thumbnailInsets.top * scale);
+ mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
}
+
+ final float widthWithInsets;
+ final float heightWithInsets;
+ if (isRotated) {
+ widthWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
+ heightWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
+ } else {
+ widthWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
+ heightWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
+ }
+ mClippedInsets.left *= thumbnailScale;
+ mClippedInsets.top *= thumbnailScale;
+ mClippedInsets.right = widthWithInsets - mClippedInsets.left - getMeasuredWidth();
+ mClippedInsets.bottom = heightWithInsets - mClippedInsets.top - getMeasuredHeight();
+
mMatrix.postScale(thumbnailScale, thumbnailScale);
mBitmapShader.setLocalMatrix(mMatrix);
- float bitmapHeight = Math.max((mIsRotated ? thumbnailWidth : thumbnailHeight)
+ float bitmapHeight = Math.max((isRotated ? thumbnailWidth : thumbnailHeight)
* thumbnailScale, 0);
if (Math.round(bitmapHeight) < getMeasuredHeight()) {
mClipBottom = bitmapHeight;
@@ -341,7 +358,7 @@
mPaint.setShader(mBitmapShader);
}
- if (mIsRotated) {
+ if (isRotated) {
// The overlay doesn't really work when the screenshot is rotated, so don't add it.
mOverlay.reset();
} else {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 6cd46d9..2b86f5e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -32,6 +32,7 @@
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -166,7 +167,7 @@
private float mCurveScale;
private float mZoomScale;
private float mFullscreenProgress;
- private final Rect mCurrentDrawnInsets = new Rect();
+ private final FullscreenDrawParams mCurrentFullscreenParams;
private final float mCornerRadius;
private final float mWindowCornerRadius;
private final BaseDraggingActivity mActivity;
@@ -214,7 +215,8 @@
});
mCornerRadius = TaskCornerRadius.get(context);
mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
- mOutlineProvider = new TaskOutlineProvider(getResources(), mCornerRadius);
+ mCurrentFullscreenParams = new FullscreenDrawParams(mCornerRadius);
+ mOutlineProvider = new TaskOutlineProvider(getResources(), mCurrentFullscreenParams);
setOutlineProvider(mOutlineProvider);
}
@@ -540,26 +542,26 @@
private static final class TaskOutlineProvider extends ViewOutlineProvider {
private final int mMarginTop;
- private final Rect mInsets = new Rect();
- private float mRadius;
+ private FullscreenDrawParams mFullscreenParams;
- TaskOutlineProvider(Resources res, float radius) {
+ TaskOutlineProvider(Resources res, FullscreenDrawParams fullscreenParams) {
mMarginTop = res.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
- mRadius = radius;
+ mFullscreenParams = fullscreenParams;
}
- public void setCurrentDrawnInsetsAndRadius(Rect insets, float radius) {
- mInsets.set(insets);
- mRadius = radius;
+ public void setFullscreenParams(FullscreenDrawParams params) {
+ mFullscreenParams = params;
}
@Override
public void getOutline(View view, Outline outline) {
- outline.setRoundRect(-mInsets.left,
- mMarginTop - mInsets.top,
- view.getWidth() + mInsets.right,
- view.getHeight() + mInsets.bottom,
- mRadius);
+ RectF insets = mFullscreenParams.mCurrentDrawnInsets;
+ float scale = mFullscreenParams.mScale;
+ outline.setRoundRect(0,
+ (int) (mMarginTop * scale),
+ (int) ((insets.left + view.getWidth() + insets.right) * scale),
+ (int) ((insets.top + view.getHeight() + insets.bottom) * scale),
+ mFullscreenParams.mCurrentDrawnCornerRadius);
}
}
@@ -658,17 +660,25 @@
TaskThumbnailView thumbnail = getThumbnail();
boolean isMultiWindowMode = mActivity.getDeviceProfile().isMultiWindowMode;
- Rect insets = thumbnail.getInsetsToDrawInFullscreen(isMultiWindowMode);
- mCurrentDrawnInsets.set((int) (insets.left * mFullscreenProgress),
- (int) (insets.top * mFullscreenProgress),
- (int) (insets.right * mFullscreenProgress),
- (int) (insets.bottom * mFullscreenProgress));
+ RectF insets = thumbnail.getInsetsToDrawInFullscreen(isMultiWindowMode);
+ float currentInsetsLeft = insets.left * mFullscreenProgress;
+ float currentInsetsRight = insets.right * mFullscreenProgress;
+ mCurrentFullscreenParams.setInsets(currentInsetsLeft,
+ insets.top * mFullscreenProgress,
+ currentInsetsRight,
+ insets.bottom * mFullscreenProgress);
float fullscreenCornerRadius = isMultiWindowMode ? 0 : mWindowCornerRadius;
- float cornerRadius = Utilities.mapRange(mFullscreenProgress, mCornerRadius,
- fullscreenCornerRadius) / getRecentsView().getScaleX();
+ mCurrentFullscreenParams.setCornerRadius(Utilities.mapRange(mFullscreenProgress,
+ mCornerRadius, fullscreenCornerRadius) / getRecentsView().getScaleX());
+ // We scaled the thumbnail to fit the content (excluding insets) within task view width.
+ // Now that we are drawing left/right insets again, we need to scale down to fit them.
+ if (getWidth() > 0) {
+ mCurrentFullscreenParams.setScale(getWidth()
+ / (getWidth() + currentInsetsLeft + currentInsetsRight));
+ }
- thumbnail.setCurrentDrawnInsetsAndRadius(mCurrentDrawnInsets, cornerRadius);
- mOutlineProvider.setCurrentDrawnInsetsAndRadius(mCurrentDrawnInsets, cornerRadius);
+ thumbnail.setFullscreenParams(mCurrentFullscreenParams);
+ mOutlineProvider.setFullscreenParams(mCurrentFullscreenParams);
invalidateOutline();
}
@@ -686,4 +696,30 @@
}
return mShowScreenshot;
}
+
+ /**
+ * We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
+ */
+ static class FullscreenDrawParams {
+ RectF mCurrentDrawnInsets = new RectF();
+ float mCurrentDrawnCornerRadius;
+ /** The current scale we apply to the thumbnail to adjust for new left/right insets. */
+ float mScale = 1;
+
+ public FullscreenDrawParams(float cornerRadius) {
+ setCornerRadius(cornerRadius);
+ }
+
+ public void setInsets(float left, float top, float right, float bottom) {
+ mCurrentDrawnInsets.set(left, top, right, bottom);
+ }
+
+ public void setCornerRadius(float cornerRadius) {
+ mCurrentDrawnCornerRadius = cornerRadius;
+ }
+
+ public void setScale(float scale) {
+ mScale = scale;
+ }
+ }
}