Merge "Fix TaskView cropping for transient taskbar" into tm-qpr-dev

This commit is contained in:
Thales Lima
2023-03-13 13:27:37 +00:00
committed by Android (Google) Code Review
9 changed files with 73 additions and 209 deletions

View File

@@ -244,6 +244,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
float maxScale = res.getFloat(R.dimen.overview_max_scale);
int taskMargin = dp.overviewTaskMarginPx;
calculateTaskSizeInternal(
context,
dp,
dp.overviewTaskThumbnailTopMarginPx,
dp.getOverviewActionsClaimedSpace(),
@@ -259,10 +260,10 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
float maxScale = res.getFloat(R.dimen.overview_max_scale);
Rect gridRect = new Rect();
calculateGridSize(dp, gridRect);
calculateTaskSizeInternal(dp, gridRect, maxScale, Gravity.CENTER, outRect);
calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
}
private void calculateTaskSizeInternal(DeviceProfile dp, int claimedSpaceAbove,
private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
Rect outRect) {
Rect insets = dp.getInsets();
@@ -275,12 +276,12 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
minimumHorizontalPadding,
claimedSpaceBelow);
calculateTaskSizeInternal(dp, potentialTaskRect, maxScale, gravity, outRect);
calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
}
private void calculateTaskSizeInternal(DeviceProfile dp,
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
Rect potentialTaskRect, float maxScale, int gravity, Rect outRect) {
PointF taskDimension = getTaskDimension(dp);
PointF taskDimension = getTaskDimension(context, dp);
float scale = Math.min(
potentialTaskRect.width() / taskDimension.x,
@@ -292,19 +293,19 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
}
private static PointF getTaskDimension(DeviceProfile dp) {
private static PointF getTaskDimension(Context context, DeviceProfile dp) {
PointF dimension = new PointF();
getTaskDimension(dp, dimension);
getTaskDimension(context, dp, dimension);
return dimension;
}
/**
* Gets the dimension of the task in the current system state.
*/
public static void getTaskDimension(DeviceProfile dp, PointF out) {
public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
out.x = dp.widthPx;
out.y = dp.heightPx;
if (dp.isTablet) {
if (dp.isTablet && !DisplayController.isTransientTaskbar(context)) {
out.y -= dp.taskbarSize;
}
}
@@ -339,7 +340,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
float rowHeight = (potentialTaskRect.height() + dp.overviewTaskThumbnailTopMarginPx
- dp.overviewRowSpacing) / 2f;
PointF taskDimension = getTaskDimension(dp);
PointF taskDimension = getTaskDimension(context, dp);
float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
int outWidth = Math.round(scale * taskDimension.x);
int outHeight = Math.round(scale * taskDimension.y);
@@ -373,6 +374,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
}
calculateTaskSizeInternal(
context,
dp,
dp.overviewTaskMarginPx,
claimedSpaceBelow,

View File

@@ -396,7 +396,7 @@ public class RecentsOrientedState implements
* Returns the scale and pivot so that the provided taskRect can fit the provided full size
*/
public float getFullScreenScaleAndPivot(Rect taskView, DeviceProfile dp, PointF outPivot) {
getTaskDimension(dp, outPivot);
getTaskDimension(mContext, dp, outPivot);
float scale = Math.min(outPivot.x / taskView.width(), outPivot.y / taskView.height());
if (scale == 1) {
outPivot.set(taskView.centerX(), taskView.centerY());

View File

@@ -272,9 +272,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
*/
public RectF getCurrentCropRect() {
// Crop rect is the inverse of thumbnail matrix
RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets;
mTempRectF.set(-insets.left, -insets.top,
mTaskRect.width() + insets.right, mTaskRect.height() + insets.bottom);
mTempRectF.set(0, 0, mTaskRect.width(), mTaskRect.height());
mInversePositionMatrix.mapRect(mTempRectF);
return mTempRectF;
}
@@ -351,14 +349,10 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
/* taskViewScale= */1f, mTaskRect.width(), mDp, mPositionHelper);
// Apply thumbnail matrix
RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets;
float scale = mCurrentFullscreenParams.mScale;
float taskWidth = mTaskRect.width();
float taskHeight = mTaskRect.height();
mMatrix.set(mPositionHelper.getMatrix());
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
// Apply TaskView matrix: taskRect, translate
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
@@ -378,8 +372,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
applyWindowToHomeRotation(mMatrix);
// Crop rect is the inverse of thumbnail matrix
mTempRectF.set(-insets.left, -insets.top,
taskWidth + insets.right, taskHeight + insets.bottom);
mTempRectF.set(0, 0, taskWidth, taskHeight);
mInversePositionMatrix.mapRect(mTempRectF);
mTempRectF.roundOut(mTmpCropRect);
@@ -389,7 +382,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
return;
}
Log.d(TAG, "progress: " + fullScreenProgress
+ " scale: " + scale
+ " recentsViewScale: " + recentsViewScale.value
+ " crop: " + mTmpCropRect
+ " radius: " + getCurrentCornerRadius()

View File

@@ -97,11 +97,6 @@ public final class DigitalWellBeingToast {
private View mBanner;
private ViewOutlineProvider mOldBannerOutlineProvider;
private float mBannerOffsetPercentage;
/**
* Clips rect provided by {@link #mOldBannerOutlineProvider} when in the model state to
* hide this banner as the taskView scales up and down
*/
private float mModalOffset = 0f;
@Nullable
private SplitBounds mSplitBounds;
private int mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN;
@@ -336,17 +331,15 @@ public final class DigitalWellBeingToast {
@Override
public void getOutline(View view, Outline outline) {
mOldBannerOutlineProvider.getOutline(view, outline);
float verticalTranslation = -view.getTranslationY() + mModalOffset
+ mSplitOffsetTranslationY;
float verticalTranslation = -view.getTranslationY() + mSplitOffsetTranslationY;
outline.offset(0, Math.round(verticalTranslation));
}
});
mBanner.setClipToOutline(true);
}
void updateBannerOffset(float offsetPercentage, float verticalOffset) {
void updateBannerOffset(float offsetPercentage) {
if (mBanner != null && mBannerOffsetPercentage != offsetPercentage) {
mModalOffset = verticalOffset;
mBannerOffsetPercentage = offsetPercentage;
updateTranslationY();
mBanner.invalidateOutline();
@@ -359,10 +352,7 @@ public final class DigitalWellBeingToast {
}
mBanner.setTranslationY(
(mBannerOffsetPercentage * mBanner.getHeight()) +
mModalOffset +
mSplitOffsetTranslationY
);
(mBannerOffsetPercentage * mBanner.getHeight()) + mSplitOffsetTranslationY);
}
private void updateTranslationX() {

View File

@@ -391,9 +391,7 @@ public class GroupedTaskView extends TaskView {
// Value set by super call
float scale = mIconView.getAlpha();
mIconView2.setAlpha(scale);
mDigitalWellBeingToast2.updateBannerOffset(1f - scale,
mCurrentFullscreenParams.mCurrentDrawnInsets.top
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
mDigitalWellBeingToast2.updateBannerOffset(1f - scale);
}
@Override

View File

@@ -338,16 +338,9 @@ public class TaskThumbnailView extends View {
@Override
protected void onDraw(Canvas canvas) {
RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets;
canvas.save();
canvas.scale(mFullscreenParams.mScale, mFullscreenParams.mScale);
canvas.translate(currentDrawnInsets.left, currentDrawnInsets.top);
// Draw the insets if we're being drawn fullscreen (we do this for quick switch).
drawOnCanvas(canvas,
-currentDrawnInsets.left,
-currentDrawnInsets.top,
getMeasuredWidth() + currentDrawnInsets.right,
getMeasuredHeight() + currentDrawnInsets.bottom,
drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(),
mFullscreenParams.mCurrentDrawnCornerRadius);
canvas.restore();
}
@@ -506,9 +499,7 @@ public class TaskThumbnailView extends View {
return false;
}
RectF insets = mPreviewPositionHelper.getClippedInsets();
float thumbnailViewAspect = (getWidth() + insets.left + insets.right)
/ (getHeight() + insets.top + insets.bottom);
float thumbnailViewAspect = getWidth() / (float) getHeight();
float thumbnailDataAspect =
mThumbnailData.thumbnail.getWidth() / (float) mThumbnailData.thumbnail.getHeight();

View File

@@ -84,7 +84,6 @@ import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
@@ -561,9 +560,7 @@ public class TaskView extends FrameLayout implements Reusable {
}
mModalness = modalness;
mIconView.setAlpha(1 - modalness);
mDigitalWellBeingToast.updateBannerOffset(modalness,
mCurrentFullscreenParams.mCurrentDrawnInsets.top
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
mDigitalWellBeingToast.updateBannerOffset(modalness);
}
public DigitalWellBeingToast getDigitalWellBeingToast() {
@@ -1148,9 +1145,7 @@ public class TaskView extends FrameLayout implements Reusable {
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
.getInterpolation(progress);
mIconView.setAlpha(scale);
mDigitalWellBeingToast.updateBannerOffset(1f - scale,
mCurrentFullscreenParams.mCurrentDrawnInsets.top
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
mDigitalWellBeingToast.updateBannerOffset(1f - scale);
}
public void setIconScaleAnimStartProgress(float startProgress) {
@@ -1771,17 +1766,11 @@ public class TaskView extends FrameLayout implements Reusable {
private final float mCornerRadius;
private final float mWindowCornerRadius;
public RectF mCurrentDrawnInsets = new RectF();
public float mCurrentDrawnCornerRadius;
/** The current scale we apply to the thumbnail to adjust for new left/right insets. */
public float mScale = 1;
private boolean mIsTaskbarTransient;
public FullscreenDrawParams(Context context) {
mCornerRadius = TaskCornerRadius.get(context);
mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context);
mIsTaskbarTransient = DisplayController.isTransientTaskbar(context);
mCurrentDrawnCornerRadius = mCornerRadius;
}
@@ -1791,36 +1780,9 @@ public class TaskView extends FrameLayout implements Reusable {
*/
public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
RectF insets = getInsetsToDrawInFullscreen(pph, dp, mIsTaskbarTransient);
float currentInsetsLeft = insets.left * fullscreenProgress;
float currentInsetsTop = insets.top * fullscreenProgress;
float currentInsetsRight = insets.right * fullscreenProgress;
float currentInsetsBottom = insets.bottom * fullscreenProgress;
mCurrentDrawnInsets.set(
currentInsetsLeft, currentInsetsTop, currentInsetsRight, currentInsetsBottom);
mCurrentDrawnCornerRadius =
Utilities.mapRange(fullscreenProgress, mCornerRadius, mWindowCornerRadius)
/ parentScale / taskViewScale;
// 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 (previewWidth > 0) {
mScale = previewWidth / (previewWidth + currentInsetsLeft + currentInsetsRight);
}
}
/**
* Insets to used for clipping the thumbnail (in case it is drawing outside its own space)
*/
private static RectF getInsetsToDrawInFullscreen(PreviewPositionHelper pph,
DeviceProfile dp, boolean isTaskbarTransient) {
if (dp.isTaskbarPresent && isTaskbarTransient) {
return pph.getClippedInsets();
}
return dp.isTaskbarPresent && !dp.isTaskbarPresentInApps
? pph.getClippedInsets() : EMPTY_RECT_F;
}
}

View File

@@ -16,16 +16,14 @@
package com.android.quickstep
import android.graphics.Rect
import android.graphics.RectF
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.FakeInvariantDeviceProfileTest
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
import com.android.quickstep.util.TaskCornerRadius
import com.android.quickstep.views.TaskView.FullscreenDrawParams
import com.android.systemui.shared.recents.model.ThumbnailData
import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
import com.android.wm.shell.util.SplitBounds
import com.android.systemui.shared.system.QuickStepContract
import com.google.common.truth.Truth.assertThat
import kotlin.math.roundToInt
import org.junit.Before
@@ -50,7 +48,42 @@ class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
}
@Test
fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets() {
fun setStartProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
val currentRotation = 0
val isRtl = false
mPreviewPositionHelper.updateThumbnailMatrix(
previewRect,
mThumbnailData,
canvasWidth,
canvasHeight,
dp.widthPx,
dp.heightPx,
dp.taskbarSize,
dp.isTablet,
currentRotation,
isRtl
)
params.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
/* previewWidth= */ 0,
dp,
mPreviewPositionHelper
)
val expectedRadius = TaskCornerRadius.get(context)
assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
fun setFullProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
@@ -80,122 +113,19 @@ class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
mPreviewPositionHelper
)
val expectedClippedInsets = RectF(0f, 0f, 0f, dp.taskbarSize * TASK_SCALE)
assertThat(params.mCurrentDrawnInsets).isEqualTo(expectedClippedInsets)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitPortrait() {
initializeVarsForTablet()
fun setStartProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
val canvasHeight = (dp.heightPx * TASK_SCALE / 2).roundToInt()
val currentRotation = 0
val isRtl = false
// portrait/vertical split apps
val dividerSize = 10
val splitBounds =
SplitBounds(
Rect(0, 0, dp.widthPx, (dp.heightPx - dividerSize) / 2),
Rect(0, (dp.heightPx + dividerSize) / 2, dp.widthPx, dp.heightPx),
0 /*lefTopTaskId*/,
0 /*rightBottomTaskId*/
)
mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_BOTTOM_OR_RIGHT)
mPreviewPositionHelper.updateThumbnailMatrix(
previewRect,
mThumbnailData,
canvasWidth,
canvasHeight,
dp.widthPx,
dp.heightPx,
dp.taskbarSize,
dp.isTablet,
currentRotation,
isRtl
)
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
/* previewWidth= */ 0,
dp,
mPreviewPositionHelper
)
// Probably unhelpful, but also unclear how to test otherwise ¯\_(ツ)_/¯
val fullscreenTaskHeight =
dp.heightPx * (1 - (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent))
val canvasScreenRatio = canvasHeight / fullscreenTaskHeight
val expectedBottomHint = dp.taskbarSize * canvasScreenRatio
assertThat(params.mCurrentDrawnInsets.bottom).isWithin(1f).of(expectedBottomHint)
}
@Test
fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromTopForTablets_splitPortrait() {
initializeVarsForTablet()
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
val canvasHeight = (dp.heightPx * TASK_SCALE / 2).roundToInt()
val currentRotation = 0
val isRtl = false
// portrait/vertical split apps
val dividerSize = 10
val splitBounds =
SplitBounds(
Rect(0, 0, dp.widthPx, (dp.heightPx - dividerSize) / 2),
Rect(0, (dp.heightPx + dividerSize) / 2, dp.widthPx, dp.heightPx),
0 /*lefTopTaskId*/,
0 /*rightBottomTaskId*/
)
mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_TOP_OR_LEFT)
mPreviewPositionHelper.updateThumbnailMatrix(
previewRect,
mThumbnailData,
canvasWidth,
canvasHeight,
dp.widthPx,
dp.heightPx,
dp.taskbarSize,
dp.isTablet,
currentRotation,
isRtl
)
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
/* previewWidth= */ 0,
dp,
mPreviewPositionHelper
)
assertThat(params.mCurrentDrawnInsets.bottom).isWithin(1f).of((0f))
}
@Test
fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitLandscape() {
initializeVarsForTablet(isLandscape = true)
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
val canvasWidth = (dp.widthPx * TASK_SCALE / 2).roundToInt()
val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
val currentRotation = 0
val isRtl = false
// portrait/vertical split apps
val dividerSize = 10
val splitBounds =
SplitBounds(
Rect(0, 0, (dp.widthPx - dividerSize) / 2, dp.heightPx),
Rect((dp.widthPx + dividerSize) / 2, 0, dp.widthPx, dp.heightPx),
0 /*lefTopTaskId*/,
0 /*rightBottomTaskId*/
)
mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_BOTTOM_OR_RIGHT)
mPreviewPositionHelper.updateThumbnailMatrix(
previewRect,
@@ -210,7 +140,7 @@ class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
isRtl
)
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
/* previewWidth= */ 0,
@@ -218,11 +148,12 @@ class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
mPreviewPositionHelper
)
assertThat(params.mCurrentDrawnInsets.bottom).isWithin(1f).of((dp.taskbarSize * TASK_SCALE))
val expectedRadius = TaskCornerRadius.get(context)
assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
}
@Test
fun setFullProgress_currentDrawnInsets_doNotClipTaskbarSizeFromBottomForPhones() {
fun setFullProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
val dp = newDP()
val previewRect = Rect(0, 0, 100, 100)
@@ -252,7 +183,7 @@ class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
mPreviewPositionHelper
)
val expectedClippedInsets = RectF(0f, 0f, 0f, 0f)
assertThat(params.mCurrentDrawnInsets).isEqualTo(expectedClippedInsets)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
assertThat(params.mCurrentDrawnCornerRadius).isEqualTo(expectedRadius)
}
}

View File

@@ -582,8 +582,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
? splitInfo.dividerHeightPercent
: splitInfo.dividerWidthPercent;
int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize;
float scale = (float) outRect.height() / deviceHeightWithoutTaskbar;
float scale = (float) outRect.height() / dp.availableHeightPx;
float topTaskHeight = dp.availableHeightPx * topLeftTaskPercent;
float scaledTopTaskHeight = topTaskHeight * scale;
float dividerHeight = dp.availableHeightPx * dividerBarPercent;
@@ -639,8 +638,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
// Reset unused translations
primarySnapshot.setTranslationY(0);
} else {
int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize;
float scale = (float) totalThumbnailHeight / deviceHeightWithoutTaskbar;
float scale = (float) totalThumbnailHeight / dp.availableHeightPx;
float topTaskHeight = dp.availableHeightPx * taskPercent;
float finalDividerHeight = dividerBar * scale;
float scaledTopTaskHeight = topTaskHeight * scale;