Loading quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java +2 −14 Original line number Diff line number Diff line Loading @@ -17,13 +17,10 @@ package com.android.launcher3.uioverrides.states; 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; /** Loading @@ -45,18 +42,9 @@ public class QuickSwitchState extends OverviewState { 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 Loading quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java +1 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll @Override protected void updateProgress(float progress) { super.updateProgress(progress); updateFullscreenProgress(progress); updateFullscreenProgress(Utilities.boundToRange(progress, 0, 1)); } private void updateFullscreenProgress(float progress) { Loading quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +12 −27 Original line number Diff line number Diff line Loading @@ -301,35 +301,20 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe 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); 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); LauncherState.ScaleAndTranslation fromScaleAndTranslation = clipHelper.getOverviewFullscreenScaleAndTranslation(v); LauncherState.ScaleAndTranslation endScaleAndTranslation = endState.getOverviewScaleAndTranslation(launcher); Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScaleAndTranslation.scale, endScaleAndTranslation.scale); Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y, fromTranslationY, 0); fromScaleAndTranslation.translationY, endScaleAndTranslation.translationY); scale.setInterpolator(LINEAR); translateY.setInterpolator(LINEAR); anim.playTogether(scale, translateY); } } @Override public ActivityInitListener createActivityInitListener( Loading quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +17 −0 Original line number Diff line number Diff line Loading @@ -35,12 +35,14 @@ import androidx.annotation.Nullable; 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; Loading Loading @@ -280,6 +282,21 @@ public class ClipAnimationHelper { } } /** * 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) { Loading quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +47 −30 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.graphics.Paint; 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; Loading @@ -59,7 +60,7 @@ public class TaskThumbnailView extends View { 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") { Loading Loading @@ -87,10 +88,9 @@ public class TaskThumbnailView extends View { 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; Loading Loading @@ -118,7 +118,7 @@ public class TaskThumbnailView extends View { 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) { Loading Loading @@ -201,23 +201,27 @@ public class TaskThumbnailView extends View { @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(); } Loading Loading @@ -275,7 +279,7 @@ public class TaskThumbnailView extends View { } private void updateThumbnailMatrix() { mIsRotated = false; boolean isRotated = false; mClipBottom = -1; if (mBitmapShader != null && mThumbnailData != null) { float scale = mThumbnailData.scale; Loading @@ -296,30 +300,28 @@ public class TaskThumbnailView extends View { 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); Loading @@ -327,13 +329,28 @@ public class TaskThumbnailView extends View { 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; Loading @@ -341,7 +358,7 @@ public class TaskThumbnailView extends View { 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 { Loading Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java +2 −14 Original line number Diff line number Diff line Loading @@ -17,13 +17,10 @@ package com.android.launcher3.uioverrides.states; 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; /** Loading @@ -45,18 +42,9 @@ public class QuickSwitchState extends OverviewState { 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 Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java +1 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll @Override protected void updateProgress(float progress) { super.updateProgress(progress); updateFullscreenProgress(progress); updateFullscreenProgress(Utilities.boundToRange(progress, 0, 1)); } private void updateFullscreenProgress(float progress) { Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +12 −27 Original line number Diff line number Diff line Loading @@ -301,35 +301,20 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe 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); 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); LauncherState.ScaleAndTranslation fromScaleAndTranslation = clipHelper.getOverviewFullscreenScaleAndTranslation(v); LauncherState.ScaleAndTranslation endScaleAndTranslation = endState.getOverviewScaleAndTranslation(launcher); Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScaleAndTranslation.scale, endScaleAndTranslation.scale); Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y, fromTranslationY, 0); fromScaleAndTranslation.translationY, endScaleAndTranslation.translationY); scale.setInterpolator(LINEAR); translateY.setInterpolator(LINEAR); anim.playTogether(scale, translateY); } } @Override public ActivityInitListener createActivityInitListener( Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +17 −0 Original line number Diff line number Diff line Loading @@ -35,12 +35,14 @@ import androidx.annotation.Nullable; 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; Loading Loading @@ -280,6 +282,21 @@ public class ClipAnimationHelper { } } /** * 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) { Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +47 −30 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.graphics.Paint; 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; Loading @@ -59,7 +60,7 @@ public class TaskThumbnailView extends View { 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") { Loading Loading @@ -87,10 +88,9 @@ public class TaskThumbnailView extends View { 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; Loading Loading @@ -118,7 +118,7 @@ public class TaskThumbnailView extends View { 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) { Loading Loading @@ -201,23 +201,27 @@ public class TaskThumbnailView extends View { @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(); } Loading Loading @@ -275,7 +279,7 @@ public class TaskThumbnailView extends View { } private void updateThumbnailMatrix() { mIsRotated = false; boolean isRotated = false; mClipBottom = -1; if (mBitmapShader != null && mThumbnailData != null) { float scale = mThumbnailData.scale; Loading @@ -296,30 +300,28 @@ public class TaskThumbnailView extends View { 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); Loading @@ -327,13 +329,28 @@ public class TaskThumbnailView extends View { 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; Loading @@ -341,7 +358,7 @@ public class TaskThumbnailView extends View { 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 { Loading