Snap for 11545716 from 60101ae7fc to 24Q3-release
Change-Id: Iac01a4f2a68a4125548bc9a463701f7e07b172c6
This commit is contained in:
+13
-5
@@ -23,15 +23,23 @@ filegroup {
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "launcher3-quickstep-robolectric-src",
|
||||
path: "robolectric_tests",
|
||||
srcs: ["robolectric_tests/src/**/*.java"],
|
||||
name: "launcher3-quickstep-robo-src",
|
||||
path: "tests/multivalentTests",
|
||||
srcs: [
|
||||
"tests/multivalentTests/src/**/*.java",
|
||||
"tests/multivalentTests/src/**/*.kt",
|
||||
],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "launcher3-quickstep-tests-src",
|
||||
path: "tests",
|
||||
srcs: ["tests/src/**/*.java", "tests/src/**/*.kt"],
|
||||
srcs: [
|
||||
"tests/multivalentTests/src/**/*.java",
|
||||
"tests/multivalentTests/src/**/*.kt",
|
||||
"tests/src/**/*.java",
|
||||
"tests/src/**/*.kt",
|
||||
],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
@@ -44,5 +52,5 @@ filegroup {
|
||||
"tests/src/com/android/quickstep/TaplOverviewIconTest.java",
|
||||
"tests/src/com/android/quickstep/TaplTestsQuickstep.java",
|
||||
"tests/src/com/android/quickstep/TaplTestsSplitscreen.java",
|
||||
]
|
||||
],
|
||||
}
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
<com.android.launcher3.taskbar.bubbles.BubbleBarView
|
||||
android:id="@+id/taskbar_bubbles"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/bubblebar_size"
|
||||
android:layout_height="@dimen/bubblebar_size_with_pointer"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="@dimen/transient_taskbar_bottom_margin"
|
||||
android:layout_marginHorizontal="@dimen/transient_taskbar_bottom_margin"
|
||||
android:paddingTop="@dimen/bubblebar_pointer_size"
|
||||
android:paddingEnd="@dimen/taskbar_icon_spacing"
|
||||
android:paddingStart="@dimen/taskbar_icon_spacing"
|
||||
android:visibility="gone"
|
||||
|
||||
@@ -413,6 +413,8 @@
|
||||
<dimen name="bubblebar_stashed_size">@dimen/transient_taskbar_stashed_height</dimen>
|
||||
<dimen name="bubblebar_stashed_handle_height">@dimen/taskbar_stashed_handle_height</dimen>
|
||||
<dimen name="bubblebar_pointer_size">8dp</dimen>
|
||||
<!-- Container size with pointer included: bubblebar_size + bubblebar_pointer_size -->
|
||||
<dimen name="bubblebar_size_with_pointer">80dp</dimen>
|
||||
<dimen name="bubblebar_elevation">1dp</dimen>
|
||||
<dimen name="bubblebar_hotseat_adjustment_threshold">90dp</dimen>
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.ShapeDrawable
|
||||
import com.android.app.animation.Interpolators
|
||||
@@ -122,14 +123,22 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun
|
||||
|
||||
// Draw background.
|
||||
val radius = backgroundHeight / 2f
|
||||
val left = if (anchorLeft) 0f else canvas.width.toFloat() - width
|
||||
val right = if (anchorLeft) width else canvas.width.toFloat()
|
||||
canvas.drawRoundRect(left, 0f, right, canvas.height.toFloat(), radius, radius, paint)
|
||||
val left = if (anchorLeft) 0f else bounds.width().toFloat() - width
|
||||
val right = if (anchorLeft) width else bounds.width().toFloat()
|
||||
canvas.drawRoundRect(
|
||||
left,
|
||||
pointerSize,
|
||||
right,
|
||||
bounds.height().toFloat(),
|
||||
radius,
|
||||
radius,
|
||||
paint
|
||||
)
|
||||
|
||||
if (showingArrow) {
|
||||
// Draw arrow.
|
||||
val transX = arrowPositionX - pointerSize / 2f
|
||||
canvas.translate(transX, -pointerSize)
|
||||
canvas.translate(transX, 0f)
|
||||
arrowDrawable.draw(canvas)
|
||||
}
|
||||
|
||||
@@ -137,11 +146,20 @@ class BubbleBarBackground(context: TaskbarActivityContext, private val backgroun
|
||||
}
|
||||
|
||||
override fun getOpacity(): Int {
|
||||
return paint.alpha
|
||||
return when (paint.alpha) {
|
||||
255 -> PixelFormat.OPAQUE
|
||||
0 -> PixelFormat.TRANSPARENT
|
||||
else -> PixelFormat.TRANSLUCENT
|
||||
}
|
||||
}
|
||||
|
||||
override fun setAlpha(alpha: Int) {
|
||||
paint.alpha = alpha
|
||||
arrowDrawable.paint.alpha = alpha
|
||||
}
|
||||
|
||||
override fun getAlpha(): Int {
|
||||
return paint.alpha
|
||||
}
|
||||
|
||||
override fun setColorFilter(colorFilter: ColorFilter?) {
|
||||
|
||||
@@ -73,6 +73,7 @@ import com.android.launcher3.util.Executors.SimpleThreadFactory;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.wm.shell.Flags;
|
||||
import com.android.wm.shell.bubbles.IBubblesListener;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
|
||||
import com.android.wm.shell.common.bubbles.BubbleInfo;
|
||||
import com.android.wm.shell.common.bubbles.RemovedBubble;
|
||||
@@ -155,12 +156,14 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
* {@link BubbleBarBubble}s so that it can be used to update the views.
|
||||
*/
|
||||
private static class BubbleBarViewUpdate {
|
||||
final boolean initialState;
|
||||
boolean expandedChanged;
|
||||
boolean expanded;
|
||||
boolean shouldShowEducation;
|
||||
String selectedBubbleKey;
|
||||
String suppressedBubbleKey;
|
||||
String unsuppressedBubbleKey;
|
||||
BubbleBarLocation bubbleBarLocation;
|
||||
List<RemovedBubble> removedBubbles;
|
||||
List<String> bubbleKeysInOrder;
|
||||
|
||||
@@ -170,12 +173,14 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
List<BubbleBarBubble> currentBubbles;
|
||||
|
||||
BubbleBarViewUpdate(BubbleBarUpdate update) {
|
||||
initialState = update.initialState;
|
||||
expandedChanged = update.expandedChanged;
|
||||
expanded = update.expanded;
|
||||
shouldShowEducation = update.shouldShowEducation;
|
||||
selectedBubbleKey = update.selectedBubbleKey;
|
||||
suppressedBubbleKey = update.suppressedBubbleKey;
|
||||
unsuppressedBubbleKey = update.unsupressedBubbleKey;
|
||||
bubbleBarLocation = update.bubbleBarLocation;
|
||||
removedBubbles = update.removedBubbles;
|
||||
bubbleKeysInOrder = update.bubbleKeysInOrder;
|
||||
}
|
||||
@@ -400,6 +405,14 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
Log.w(TAG, "expansion was changed but is the same");
|
||||
}
|
||||
}
|
||||
if (update.bubbleBarLocation != null) {
|
||||
if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) {
|
||||
// Animate when receiving updates. Skip it if we received the initial state.
|
||||
boolean animate = !update.initialState;
|
||||
mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation, animate);
|
||||
mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Tells WMShell to show the currently selected bubble. */
|
||||
@@ -593,7 +606,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
Rect location = new Rect();
|
||||
// currentBarBounds is only useful for distance from left or right edge.
|
||||
// It contains the current bounds, calculate the expanded bounds.
|
||||
if (mBarView.isOnLeft()) {
|
||||
if (mBarView.getBubbleBarLocation().isOnLeft(mBarView.isLayoutRtl())) {
|
||||
location.left = currentBarBounds.left;
|
||||
location.right = (int) (currentBarBounds.left + mBarView.expandedWidth());
|
||||
} else {
|
||||
@@ -601,7 +614,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
|
||||
location.right = currentBarBounds.right;
|
||||
}
|
||||
final int translation = (int) abs(mBubbleStashController.getBubbleBarTranslationY());
|
||||
location.top = displaySize.y - mBarView.getHeight() - translation;
|
||||
location.top = displaySize.y - currentBarBounds.height() - translation;
|
||||
location.bottom = displaySize.y - translation;
|
||||
return location;
|
||||
}
|
||||
|
||||
@@ -15,21 +15,33 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar.bubbles;
|
||||
|
||||
import static com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.LayoutDirection;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.SpringAnimationBuilder;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -70,6 +82,18 @@ public class BubbleBarView extends FrameLayout {
|
||||
private static final int ARROW_POSITION_ANIMATION_DURATION_MS = 200;
|
||||
private static final int WIDTH_ANIMATION_DURATION_MS = 200;
|
||||
|
||||
private static final long FADE_OUT_ANIM_ALPHA_DURATION_MS = 50L;
|
||||
private static final long FADE_OUT_ANIM_ALPHA_DELAY_MS = 50L;
|
||||
private static final long FADE_OUT_ANIM_POSITION_DURATION_MS = 100L;
|
||||
// During fade out animation we shift the bubble bar 1/80th of the screen width
|
||||
private static final float FADE_OUT_ANIM_POSITION_SHIFT = 1 / 80f;
|
||||
|
||||
private static final long FADE_IN_ANIM_ALPHA_DURATION_MS = 100L;
|
||||
// Use STIFFNESS_MEDIUMLOW which is not defined in the API constants
|
||||
private static final float FADE_IN_ANIM_POSITION_SPRING_STIFFNESS = 400f;
|
||||
// During fade in animation we shift the bubble bar 1/60th of the screen width
|
||||
private static final float FADE_IN_ANIM_POSITION_SHIFT = 1 / 60f;
|
||||
|
||||
private final BubbleBarBackground mBubbleBarBackground;
|
||||
|
||||
/**
|
||||
@@ -86,11 +110,13 @@ public class BubbleBarView extends FrameLayout {
|
||||
private final float mIconSize;
|
||||
// The elevation of the bubbles within the bar
|
||||
private final float mBubbleElevation;
|
||||
private final int mPointerSize;
|
||||
|
||||
// Whether the bar is expanded (i.e. the bubble activity is being displayed).
|
||||
private boolean mIsBarExpanded = false;
|
||||
// The currently selected bubble view.
|
||||
private BubbleView mSelectedBubbleView;
|
||||
private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT;
|
||||
// The click listener when the bubble bar is collapsed.
|
||||
private View.OnClickListener mOnClickListener;
|
||||
|
||||
@@ -102,6 +128,9 @@ public class BubbleBarView extends FrameLayout {
|
||||
// collapsed state and 1 to the fully expanded state.
|
||||
private final ValueAnimator mWidthAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
|
||||
@Nullable
|
||||
private Animator mBubbleBarLocationAnimator = null;
|
||||
|
||||
// We don't reorder the bubbles when they are expanded as it could be jarring for the user
|
||||
// this runnable will be populated with any reordering of the bubbles that should be applied
|
||||
// once they are collapsed.
|
||||
@@ -114,6 +143,8 @@ public class BubbleBarView extends FrameLayout {
|
||||
@Nullable
|
||||
private BubbleView mDraggedBubbleView;
|
||||
|
||||
private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED;
|
||||
|
||||
public BubbleBarView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -136,6 +167,8 @@ public class BubbleBarView extends FrameLayout {
|
||||
mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
|
||||
mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
|
||||
mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation);
|
||||
mPointerSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_pointer_size);
|
||||
|
||||
setClipToPadding(false);
|
||||
|
||||
mBubbleBarBackground = new BubbleBarBackground(activityContext,
|
||||
@@ -184,7 +217,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
mBubbleBarBounds.left = left;
|
||||
mBubbleBarBounds.top = top;
|
||||
mBubbleBarBounds.top = top + mPointerSize;
|
||||
mBubbleBarBounds.right = right;
|
||||
mBubbleBarBounds.bottom = bottom;
|
||||
|
||||
@@ -199,24 +232,123 @@ public class BubbleBarView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public void onRtlPropertiesChanged(int layoutDirection) {
|
||||
// TODO(b/313661121): set this based on bubble bar position and not LTR or RTL
|
||||
boolean onLeft = layoutDirection == LAYOUT_DIRECTION_RTL;
|
||||
if (mBubbleBarLocation == BubbleBarLocation.DEFAULT
|
||||
&& mPreviousLayoutDirection != layoutDirection) {
|
||||
Log.d(TAG, "BubbleBar RTL properties changed, new layoutDirection=" + layoutDirection
|
||||
+ " previous layoutDirection=" + mPreviousLayoutDirection);
|
||||
mPreviousLayoutDirection = layoutDirection;
|
||||
onBubbleBarLocationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void onBubbleBarLocationChanged() {
|
||||
final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
mBubbleBarBackground.setAnchorLeft(onLeft);
|
||||
mRelativePivotX = onLeft ? 0f : 1f;
|
||||
ViewGroup.LayoutParams layoutParams = getLayoutParams();
|
||||
if (layoutParams instanceof LayoutParams lp) {
|
||||
lp.gravity = Gravity.BOTTOM | (onLeft ? Gravity.LEFT : Gravity.RIGHT);
|
||||
setLayoutParams(lp);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> when bar is pinned to the left edge of the screen
|
||||
* @return current {@link BubbleBarLocation}
|
||||
*/
|
||||
public boolean isOnLeft() {
|
||||
return getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||
public BubbleBarLocation getBubbleBarLocation() {
|
||||
return mBubbleBarLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update {@link BubbleBarLocation}
|
||||
*/
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
|
||||
if (animate) {
|
||||
animateToBubbleBarLocation(bubbleBarLocation);
|
||||
} else {
|
||||
setBubbleBarLocationInternal(bubbleBarLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBubbleBarLocationInternal(BubbleBarLocation bubbleBarLocation) {
|
||||
if (bubbleBarLocation != mBubbleBarLocation) {
|
||||
mBubbleBarLocation = bubbleBarLocation;
|
||||
onBubbleBarLocationChanged();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void animateToBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
if (bubbleBarLocation == mBubbleBarLocation) {
|
||||
// nothing to do, already at expected location
|
||||
return;
|
||||
}
|
||||
if (mBubbleBarLocationAnimator != null && mBubbleBarLocationAnimator.isRunning()) {
|
||||
mBubbleBarLocationAnimator.cancel();
|
||||
}
|
||||
|
||||
// Location animation uses two separate animators.
|
||||
// First animator hides the bar.
|
||||
// After it completes, location update is sent to layout the bar in the new location.
|
||||
// Second animator is started to show the bar.
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeOutAnimator();
|
||||
mBubbleBarLocationAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
// Bubble bar is not visible, update the location
|
||||
setBubbleBarLocationInternal(bubbleBarLocation);
|
||||
// Animate it in
|
||||
mBubbleBarLocationAnimator = getLocationUpdateFadeInAnimator();
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}
|
||||
});
|
||||
mBubbleBarLocationAnimator.start();
|
||||
}
|
||||
|
||||
private AnimatorSet getLocationUpdateFadeOutAnimator() {
|
||||
final float shift =
|
||||
getResources().getDisplayMetrics().widthPixels * FADE_OUT_ANIM_POSITION_SHIFT;
|
||||
final float tx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;
|
||||
|
||||
ObjectAnimator positionAnim = ObjectAnimator.ofFloat(this, TRANSLATION_X, tx)
|
||||
.setDuration(FADE_OUT_ANIM_POSITION_DURATION_MS);
|
||||
positionAnim.setInterpolator(EMPHASIZED_ACCELERATE);
|
||||
|
||||
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(this, ALPHA, 0f)
|
||||
.setDuration(FADE_OUT_ANIM_ALPHA_DURATION_MS);
|
||||
alphaAnim.setStartDelay(FADE_OUT_ANIM_ALPHA_DELAY_MS);
|
||||
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(positionAnim, alphaAnim);
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
private Animator getLocationUpdateFadeInAnimator() {
|
||||
final float shift =
|
||||
getResources().getDisplayMetrics().widthPixels * FADE_IN_ANIM_POSITION_SHIFT;
|
||||
final float startTx = mBubbleBarLocation.isOnLeft(isLayoutRtl()) ? shift : -shift;
|
||||
|
||||
ValueAnimator positionAnim = new SpringAnimationBuilder(getContext())
|
||||
.setStartValue(startTx)
|
||||
.setEndValue(0)
|
||||
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
|
||||
.setStiffness(FADE_IN_ANIM_POSITION_SPRING_STIFFNESS)
|
||||
.build(this, VIEW_TRANSLATE_X);
|
||||
|
||||
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(this, ALPHA, 1f)
|
||||
.setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS);
|
||||
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(positionAnim, alphaAnim);
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the bounds with translation that may have been applied and returns the result.
|
||||
*/
|
||||
public Rect getBubbleBarBounds() {
|
||||
mBubbleBarBounds.top = getTop() + (int) getTranslationY();
|
||||
mBubbleBarBounds.top = getTop() + (int) getTranslationY() + mPointerSize;
|
||||
mBubbleBarBounds.bottom = getBottom() + (int) getTranslationY();
|
||||
return mBubbleBarBounds;
|
||||
}
|
||||
@@ -290,7 +422,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
int bubbleCount = getChildCount();
|
||||
final float ty = (mBubbleBarBounds.height() - mIconSize) / 2f;
|
||||
final boolean animate = getVisibility() == VISIBLE;
|
||||
final boolean onLeft = isOnLeft();
|
||||
final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
|
||||
for (int i = 0; i < bubbleCount; i++) {
|
||||
BubbleView bv = (BubbleView) getChildAt(i);
|
||||
bv.setTranslationY(ty);
|
||||
@@ -453,7 +585,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
private float arrowPositionForSelectedWhenExpanded() {
|
||||
final int index = indexOfChild(mSelectedBubbleView);
|
||||
final int bubblePosition;
|
||||
if (isOnLeft()) {
|
||||
if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
// Bubble positions are reversed. First bubble is on the right.
|
||||
bubblePosition = getChildCount() - index - 1;
|
||||
} else {
|
||||
@@ -465,7 +597,7 @@ public class BubbleBarView extends FrameLayout {
|
||||
private float arrowPositionForSelectedWhenCollapsed() {
|
||||
final int index = indexOfChild(mSelectedBubbleView);
|
||||
final int bubblePosition;
|
||||
if (isOnLeft()) {
|
||||
if (mBubbleBarLocation.isOnLeft(isLayoutRtl())) {
|
||||
// Bubble positions are reversed. First bubble may be shifted, if there are more
|
||||
// bubbles than the current bubble and overflow.
|
||||
bubblePosition = index == 0 && getChildCount() > 2 ? 1 : 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
import com.android.launcher3.util.MultiPropertyFactory;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -54,6 +55,7 @@ public class BubbleBarViewController {
|
||||
private final TaskbarActivityContext mActivity;
|
||||
private final BubbleBarView mBarView;
|
||||
private final int mIconSize;
|
||||
private final int mPointerSize;
|
||||
|
||||
// Initialized in init.
|
||||
private BubbleStashController mBubbleStashController;
|
||||
@@ -86,6 +88,8 @@ public class BubbleBarViewController {
|
||||
mBubbleBarAlpha = new MultiValueAlpha(mBarView, 1 /* num alpha channels */);
|
||||
mBubbleBarAlpha.setUpdateVisibility(true);
|
||||
mIconSize = activity.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
|
||||
mPointerSize = activity.getResources().getDimensionPixelSize(
|
||||
R.dimen.bubblebar_pointer_size);
|
||||
}
|
||||
|
||||
public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) {
|
||||
@@ -96,9 +100,11 @@ public class BubbleBarViewController {
|
||||
mTaskbarInsetsController = controllers.taskbarInsetsController;
|
||||
|
||||
mActivity.addOnDeviceProfileChangeListener(dp ->
|
||||
mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight
|
||||
mBarView.getLayoutParams().height =
|
||||
mActivity.getDeviceProfile().taskbarHeight + mPointerSize
|
||||
);
|
||||
mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight;
|
||||
mBarView.getLayoutParams().height =
|
||||
mActivity.getDeviceProfile().taskbarHeight + mPointerSize;
|
||||
mBubbleBarScale.updateValue(1f);
|
||||
mBubbleClickListener = v -> onBubbleClicked(v);
|
||||
mBubbleBarClickListener = v -> onBubbleBarClicked();
|
||||
@@ -168,6 +174,20 @@ public class BubbleBarViewController {
|
||||
return mBubbleBarController.getSelectedBubbleKey() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current {@link BubbleBarLocation}
|
||||
*/
|
||||
public BubbleBarLocation getBubbleBarLocation() {
|
||||
return mBarView.getBubbleBarLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update bar {@link BubbleBarLocation}
|
||||
*/
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, boolean animate) {
|
||||
mBarView.setBubbleBarLocation(bubbleBarLocation, animate);
|
||||
}
|
||||
|
||||
/**
|
||||
* The bounds of the bubble bar.
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.launcher3.taskbar.TaskbarControllers;
|
||||
import com.android.launcher3.taskbar.TaskbarInsetsController;
|
||||
import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
import com.android.launcher3.util.MultiPropertyFactory;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
|
||||
/**
|
||||
* Coordinates between controllers such as BubbleBarView and BubbleHandleViewController to
|
||||
@@ -356,4 +357,9 @@ public class BubbleStashController {
|
||||
public boolean isEventOverStashHandle(MotionEvent ev) {
|
||||
return mHandleViewController.isEventOverHandle(ev);
|
||||
}
|
||||
|
||||
/** Set a bubble bar location */
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
mHandleViewController.setBubbleBarLocation(bubbleBarLocation);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -16,7 +16,6 @@
|
||||
package com.android.launcher3.taskbar.bubbles;
|
||||
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.LAYOUT_DIRECTION_RTL;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -39,6 +38,7 @@ import com.android.launcher3.util.Executors;
|
||||
import com.android.launcher3.util.MultiPropertyFactory;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
|
||||
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
|
||||
|
||||
/**
|
||||
* Handles properties/data collection, then passes the results to our stashed handle View to render.
|
||||
@@ -119,14 +119,14 @@ public class BubbleStashedHandleViewController {
|
||||
}, Executors.UI_HELPER_EXECUTOR);
|
||||
|
||||
mStashedHandleView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) ->
|
||||
updateBounds());
|
||||
updateBounds(mBarViewController.getBubbleBarLocation()));
|
||||
}
|
||||
|
||||
private void updateBounds() {
|
||||
private void updateBounds(BubbleBarLocation bubbleBarLocation) {
|
||||
// As more bubbles get added, the icon bounds become larger. To ensure a consistent
|
||||
// handle bar position, we pin it to the edge of the screen.
|
||||
final int stashedCenterY = mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2;
|
||||
if (isOnLeft()) {
|
||||
if (bubbleBarLocation.isOnLeft(mStashedHandleView.isLayoutRtl())) {
|
||||
final int left = mBarViewController.getHorizontalMargin();
|
||||
mStashedHandleBounds.set(
|
||||
left,
|
||||
@@ -149,11 +149,6 @@ public class BubbleStashedHandleViewController {
|
||||
mStashedHandleView.setPivotY(mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2f);
|
||||
}
|
||||
|
||||
private boolean isOnLeft() {
|
||||
// TODO(b/313661121): set this based on bubble bar position and not LTR or RTL
|
||||
return mStashedHandleView.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
mRegionSamplingHelper.stopAndDestroy();
|
||||
mRegionSamplingHelper = null;
|
||||
@@ -301,4 +296,9 @@ public class BubbleStashedHandleViewController {
|
||||
public boolean containsX(int x) {
|
||||
return x >= mStashedHandleBounds.left && x <= mStashedHandleBounds.right;
|
||||
}
|
||||
|
||||
/** Set a bubble bar location */
|
||||
public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
|
||||
updateBounds(bubbleBarLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
|
||||
import com.android.launcher3.model.WellbeingModel;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.popup.SystemShortcut.AppInfo;
|
||||
import com.android.launcher3.util.InstantAppResolver;
|
||||
@@ -61,6 +62,7 @@ import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFutur
|
||||
import com.android.systemui.shared.recents.view.RecentsTransition;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
@@ -319,13 +321,18 @@ public interface TaskShortcutFactory {
|
||||
recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView));
|
||||
boolean shouldShowActionsButtonInstead =
|
||||
isLargeTileFocusedTask && isInExpectedScrollPosition;
|
||||
boolean hasUnpinnableApp = Arrays.stream(taskView.getTaskIdAttributeContainers())
|
||||
.anyMatch(att -> att != null && att.getItemInfo() != null
|
||||
&& ((att.getItemInfo().runtimeStatusFlags
|
||||
& ItemInfoWithIcon.FLAG_NOT_PINNABLE) != 0));
|
||||
|
||||
// No "save app pair" menu item if:
|
||||
// - app pairs feature is not enabled
|
||||
// - the task in question is a single task
|
||||
// - at least one app in app pair is unpinnable
|
||||
// - the Overview Actions Button should be visible
|
||||
if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks()
|
||||
|| shouldShowActionsButtonInstead) {
|
||||
|| hasUnpinnableApp || shouldShowActionsButtonInstead) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
|
||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
@@ -83,6 +84,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
@@ -501,6 +503,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
if (getRecentsView() != null) {
|
||||
stubInfo.screenId = getRecentsView().indexOfChild(this);
|
||||
}
|
||||
if (Flags.privateSpaceRestrictAccessibilityDrag()) {
|
||||
if (UserCache.getInstance(getContext()).getUserInfo(componentKey.user).isPrivate()) {
|
||||
stubInfo.runtimeStatusFlags |= FLAG_NOT_PINNABLE;
|
||||
}
|
||||
}
|
||||
return stubInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.quickstep
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RobolectricTest {
|
||||
@Test
|
||||
fun test1() {
|
||||
val actual = 1 + 1
|
||||
assertThat(actual).isEqualTo(2)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
./multivalentTests
|
||||
@@ -0,0 +1 @@
|
||||
./multivalentTests
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3
|
||||
|
||||
import android.graphics.Rect
|
||||
|
||||
/**
|
||||
* Fit [this] into [targetRect] with letter boxing. After calling this method, [this] will be
|
||||
* modified to be letter boxed.
|
||||
*
|
||||
* @param targetRect target [Rect] that [this] should be fitted into
|
||||
*/
|
||||
fun Rect.letterBox(targetRect: Rect) {
|
||||
letterBox(targetRect, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fit [this] into [targetRect] with letter boxing. After calling this method, [resultRect] will be
|
||||
* modified to be letter boxed.
|
||||
*
|
||||
* @param targetRect target [Rect] that [this] should be fitted into
|
||||
* @param resultRect the letter boxed [Rect]
|
||||
*/
|
||||
fun Rect.letterBox(targetRect: Rect, resultRect: Rect) {
|
||||
val widthRatio: Float = 1f * targetRect.width() / width()
|
||||
val heightRatio: Float = 1f * targetRect.height() / height()
|
||||
if (widthRatio < heightRatio) {
|
||||
val scaledHeight: Int = (widthRatio * height()).toInt()
|
||||
val verticalPadding: Int = (targetRect.height() - scaledHeight) / 2
|
||||
resultRect.set(
|
||||
targetRect.left,
|
||||
targetRect.top + verticalPadding,
|
||||
targetRect.right,
|
||||
targetRect.bottom - verticalPadding
|
||||
)
|
||||
} else {
|
||||
val scaledWidth: Int = (heightRatio * width()).toInt()
|
||||
val horizontalPadding: Int = (targetRect.width() - scaledWidth) / 2
|
||||
resultRect.set(
|
||||
targetRect.left + horizontalPadding,
|
||||
targetRect.top,
|
||||
targetRect.right - horizontalPadding,
|
||||
targetRect.bottom
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class WorkProfileManager extends UserProfileManager
|
||||
* Posts quite mode enable/disable call for work profile user
|
||||
*/
|
||||
public void setWorkProfileEnabled(boolean enabled) {
|
||||
setCurrentState(STATE_TRANSITION);
|
||||
updateCurrentState(STATE_TRANSITION);
|
||||
setQuietMode(!enabled);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,11 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
@@ -53,7 +55,6 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.RectUtilsKt;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
@@ -77,9 +78,9 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
||||
|
||||
private final Rect mRect = new Rect();
|
||||
|
||||
private final Rect mPreviewBitmapRect = new Rect();
|
||||
private final Rect mCanvasRect = new Rect();
|
||||
private final Rect mLetterBoxedPreviewBitmapRect = new Rect();
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private final RectF mPreviewBitmapRect = new RectF();
|
||||
private final RectF mCanvasRect = new RectF();
|
||||
|
||||
private final LauncherWidgetHolder mWidgetHolder;
|
||||
private final LauncherAppWidgetProviderInfo mAppwidget;
|
||||
@@ -458,9 +459,8 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
||||
mPreviewBitmapRect.set(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
|
||||
mCanvasRect.set(0, 0, getWidth(), getHeight());
|
||||
|
||||
RectUtilsKt.letterBox(mPreviewBitmapRect, mCanvasRect, mLetterBoxedPreviewBitmapRect);
|
||||
canvas.drawBitmap(mPreviewBitmap, mPreviewBitmapRect, mLetterBoxedPreviewBitmapRect,
|
||||
mPreviewPaint);
|
||||
mMatrix.setRectToRect(mPreviewBitmapRect, mCanvasRect, Matrix.ScaleToFit.CENTER);
|
||||
canvas.drawBitmap(mPreviewBitmap, mMatrix, mPreviewPaint);
|
||||
return;
|
||||
}
|
||||
if (mCenterDrawable == null) {
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-instrumentation" />
|
||||
|
||||
<option name="max-tmp-logcat-file" value="104857600" /> <!-- 100 * 1024 * 1024 -->
|
||||
|
||||
<logger class="com.android.tradefed.log.FileLogger">
|
||||
<option name="max-log-size" value="20" />
|
||||
</logger>
|
||||
|
||||
<!-- Disables the "Ramdump uploader to betterbug" -->
|
||||
<option name="post-boot-command" value="am broadcast --async --user 0 -a com.google.gservices.intent.action.GSERVICES_OVERRIDE -e betterbug_enable_ramdump_uploader false" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
|
||||
<option name="set-test-harness" value="true" />
|
||||
|
||||
@@ -34,6 +43,9 @@
|
||||
<option name="run-command" value="settings delete secure assistant" />
|
||||
<option name="run-command" value="settings put global airplane_mode_on 1" />
|
||||
<option name="run-command" value="am broadcast -a android.intent.action.AIRPLANE_MODE" />
|
||||
|
||||
<option name="run-command" value="settings put system pointer_location 1" />
|
||||
<option name="run-command" value="settings put system show_touches 1" />
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3
|
||||
|
||||
import android.graphics.Rect
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RectUtilsTest {
|
||||
|
||||
private val srcRect = Rect()
|
||||
private val destRect = Rect()
|
||||
private val letterBoxedRect = Rect()
|
||||
|
||||
@Test
|
||||
fun letterBoxSelf_toSameRect_noScale() {
|
||||
srcRect.set(0, 0, 100, 100)
|
||||
destRect.set(0, 0, 100, 100)
|
||||
|
||||
srcRect.letterBox(destRect)
|
||||
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 100, 100))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBox_toSameRect_noScale() {
|
||||
srcRect.set(0, 0, 100, 100)
|
||||
destRect.set(0, 0, 100, 100)
|
||||
|
||||
srcRect.letterBox(destRect, letterBoxedRect)
|
||||
|
||||
assertThat(letterBoxedRect).isEqualTo(Rect(0, 0, 100, 100))
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 100, 100))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxSelf_toSmallHeight_scaleDownHorizontally() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(0, 0, 939, 520)
|
||||
|
||||
srcRect.letterBox(destRect)
|
||||
|
||||
assertThat(srcRect).isEqualTo(Rect(114, 0, 825, 520))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxRect_toSmallHeight_scaleDownHorizontally() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(0, 0, 939, 520)
|
||||
|
||||
srcRect.letterBox(destRect, letterBoxedRect)
|
||||
|
||||
assertThat(letterBoxedRect).isEqualTo(Rect(114, 0, 825, 520))
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 2893, 2114))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxSelf_toSmallHeightWithOffset_scaleDownHorizontally() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(10, 20, 949, 540)
|
||||
|
||||
srcRect.letterBox(destRect)
|
||||
|
||||
assertThat(srcRect).isEqualTo(Rect(124, 20, 835, 540))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxRect_toSmallHeightWithOffset_scaleDownHorizontally() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(10, 20, 949, 540)
|
||||
|
||||
srcRect.letterBox(destRect, letterBoxedRect)
|
||||
|
||||
assertThat(letterBoxedRect).isEqualTo(Rect(124, 20, 835, 540))
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 2893, 2114))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxSelf_toSmallWidth_scaleDownVertically() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(0, 0, 520, 939)
|
||||
|
||||
srcRect.letterBox(destRect)
|
||||
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 280, 520, 659))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxRect_toSmallWidth_scaleDownVertically() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(0, 0, 520, 939)
|
||||
|
||||
srcRect.letterBox(destRect, letterBoxedRect)
|
||||
|
||||
assertThat(letterBoxedRect).isEqualTo(Rect(0, 280, 520, 659))
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 2893, 2114))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxSelf_toSmallWidthWithOffset_scaleDownVertically() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(40, 60, 560, 999)
|
||||
|
||||
srcRect.letterBox(destRect)
|
||||
|
||||
assertThat(srcRect).isEqualTo(Rect(40, 340, 560, 719))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun letterBoxRect_toSmallWidthWithOffset_scaleDownVertically() {
|
||||
srcRect.set(0, 0, 2893, 2114)
|
||||
destRect.set(40, 60, 560, 999)
|
||||
|
||||
srcRect.letterBox(destRect, letterBoxedRect)
|
||||
|
||||
assertThat(letterBoxedRect).isEqualTo(Rect(40, 340, 560, 719))
|
||||
assertThat(srcRect).isEqualTo(Rect(0, 0, 2893, 2114))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user