We want to show the splash if the aspect ratio or rotation of the thumbnail would be + * different from the task. + */ + boolean shouldShowSplashView() { + return isThumbnailAspectRatioDifferentFromThumbnailData() + || isThumbnailRotationDifferentFromTask(); + } + + private void updateSplashView(Drawable icon) { + if (icon == null || icon.getConstantState() == null) { + return; + } + mSplashViewDrawable = icon.getConstantState().newDrawable().mutate(); + mSplashViewDrawable.setAlpha(mSplashAlpha); + ImageView imageView = mSplashView == null ? new ImageView(getContext()) : mSplashView; + imageView.setImageDrawable(mSplashViewDrawable); + + imageView.setScaleType(ImageView.ScaleType.MATRIX); + Matrix matrix = new Matrix(); + + float drawableWidth = mSplashViewDrawable.getIntrinsicWidth(); + float drawableHeight = mSplashViewDrawable.getIntrinsicHeight(); + float viewWidth = getMeasuredWidth(); + float viewCenterX = viewWidth / 2f; + float viewHeight = getMeasuredHeight(); + float viewCenterY = viewHeight / 2f; + float centeredDrawableLeft = (viewWidth - drawableWidth) / 2f; + float centeredDrawableTop = (viewHeight - drawableHeight) / 2f; + float nonGridScale = getTaskView() == null ? 1 : 1 / getTaskView().getNonGridScale(); + float recentsMaxScale = getTaskView() == null || getTaskView().getRecentsView() == null + ? 1 : 1 / getTaskView().getRecentsView().getMaxScaleForFullScreen(); + float scale = nonGridScale * recentsMaxScale; + + // Center the image in the view. + matrix.setTranslate(centeredDrawableLeft, centeredDrawableTop); + // Apply scale transformation after translation, pivoting around center of view. + matrix.postScale(scale, scale, viewCenterX, viewCenterY); + + imageView.setImageMatrix(matrix); + mSplashView = imageView; + } + + private boolean isThumbnailAspectRatioDifferentFromThumbnailData() { + if (mThumbnailData == null || mThumbnailData.thumbnail == null) { + return false; + } + + float thumbnailViewAspect = getWidth() / (float) getHeight(); + float thumbnailDataAspect = + mThumbnailData.thumbnail.getWidth() / (float) mThumbnailData.thumbnail.getHeight(); + + return Utilities.isRelativePercentDifferenceGreaterThan(thumbnailViewAspect, + thumbnailDataAspect, MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT); + } + + private boolean isThumbnailRotationDifferentFromTask() { + RecentsView recents = getTaskView().getRecentsView(); + if (recents == null || mThumbnailData == null) { + return false; + } + + if (recents.getPagedOrientationHandler() == PagedOrientationHandler.PORTRAIT) { + int currentRotation = recents.getPagedViewOrientedState().getRecentsActivityRotation(); + return (currentRotation - mThumbnailData.rotation) % 2 != 0; + } else { + return recents.getPagedOrientationHandler().getRotation() != mThumbnailData.rotation; + } + } + /** * Potentially re-init the task overlay. Be cautious when calling this as the overlay may * do processing on initialization. @@ -463,8 +579,9 @@ public class TaskThumbnailView extends View { float availableAspect = isRotated ? availableHeight / availableWidth : availableWidth / availableHeight; - boolean isAspectLargelyDifferent = Utilities.isRelativePercentDifferenceGreaterThan( - canvasAspect, availableAspect, 0.1f); + boolean isAspectLargelyDifferent = + Utilities.isRelativePercentDifferenceGreaterThan(canvasAspect, + availableAspect, MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT); if (isRotated && isAspectLargelyDifferent) { // Do not rotate thumbnail if it would not improve fit isRotated = false; diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 1bc538614b..ded0ea620b 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -18,6 +18,7 @@ package com.android.quickstep.views; import static android.view.Display.DEFAULT_DISPLAY; import static android.widget.Toast.LENGTH_SHORT; +import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR; import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; @@ -333,6 +334,7 @@ public class TaskView extends FrameLayout implements Reusable { protected final DigitalWellBeingToast mDigitalWellBeingToast; private float mFullscreenProgress; private float mGridProgress; + protected float mOverviewProgress; private float mNonGridScale = 1; private float mDismissScale = 1; protected final FullscreenDrawParams mCurrentFullscreenParams; @@ -392,7 +394,6 @@ public class TaskView extends FrameLayout implements Reusable { private boolean mIsClickableAsLiveTile = true; - public TaskView(Context context) { this(context, null); } @@ -660,6 +661,9 @@ public class TaskView extends FrameLayout implements Reusable { if (freezeTaskList) { ActivityOptionsCompat.setFreezeRecentTasksList(opts); } + // TODO(b/202826469): Replace setSplashScreenStyle with setDisableStartingWindow. + opts.setSplashScreenStyle(mSnapshotView.shouldShowSplashView() + ? SPLASH_SCREEN_STYLE_SOLID_COLOR : opts.getSplashScreenStyle()); Task.TaskKey key = mTask.key; UI_HELPER_EXECUTOR.execute(() -> { if (!ActivityManagerWrapper.getInstance().startActivityFromRecents(key, opts)) { @@ -1060,6 +1064,21 @@ public class TaskView extends FrameLayout implements Reusable { return scale; } + /** + * Updates progress of task view for entering/exiting overview on swipe up/down. + * + *
Updates the alpha of any splash screen over the thumbnail if it exists. + */ + public void setOverviewProgress(float overviewProgress) { + mOverviewProgress = overviewProgress; + applyThumbnailSplashAlpha(); + } + + protected void applyThumbnailSplashAlpha() { + mSnapshotView.setSplashAlpha( + Utilities.mapToRange(mOverviewProgress, 0f, 1f, 1f, 0f, LINEAR)); + } + private void setSplitSelectTranslationX(float x) { mSplitSelectTranslationX = x; applyTranslationX();