Merge "Add some basic tests for BubblePositioner" into udc-qpr-dev

This commit is contained in:
Mady Mellor
2023-08-07 18:00:42 +00:00
committed by Android (Google) Code Review

View File

@@ -0,0 +1,271 @@
/*
* Copyright (C) 2023 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.wm.shell.bubbles;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.View.LAYOUT_DIRECTION_LTR;
import static android.view.View.LAYOUT_DIRECTION_RTL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Tests operations and the resulting state managed by {@link BubblePositioner}.
*/
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class BubblePositionerTest extends ShellTestCase {
private static final int MIN_WIDTH_FOR_TABLET = 600;
private BubblePositioner mPositioner;
private Configuration mConfiguration;
@Mock
private WindowManager mWindowManager;
@Mock
private WindowMetrics mWindowMetrics;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mConfiguration = spy(new Configuration());
TestableResources testableResources = mContext.getOrCreateTestableResources();
testableResources.overrideConfiguration(mConfiguration);
mPositioner = new BubblePositioner(mContext, mWindowManager);
}
@Test
public void testUpdate() {
Insets insets = Insets.of(10, 20, 5, 15);
Rect screenBounds = new Rect(0, 0, 1000, 1200);
Rect availableRect = new Rect(screenBounds);
availableRect.inset(insets);
new WindowManagerConfig()
.setInsets(insets)
.setScreenBounds(screenBounds)
.setUpConfig();
mPositioner.update();
assertThat(mPositioner.getAvailableRect()).isEqualTo(availableRect);
assertThat(mPositioner.isLandscape()).isFalse();
assertThat(mPositioner.isLargeScreen()).isFalse();
assertThat(mPositioner.getInsets()).isEqualTo(insets);
}
@Test
public void testShowBubblesVertically_phonePortrait() {
new WindowManagerConfig().setOrientation(ORIENTATION_PORTRAIT).setUpConfig();
mPositioner.update();
assertThat(mPositioner.showBubblesVertically()).isFalse();
}
@Test
public void testShowBubblesVertically_phoneLandscape() {
new WindowManagerConfig().setOrientation(ORIENTATION_LANDSCAPE).setUpConfig();
mPositioner.update();
assertThat(mPositioner.isLandscape()).isTrue();
assertThat(mPositioner.showBubblesVertically()).isTrue();
}
@Test
public void testShowBubblesVertically_tablet() {
new WindowManagerConfig().setLargeScreen().setUpConfig();
mPositioner.update();
assertThat(mPositioner.showBubblesVertically()).isTrue();
}
/** If a resting position hasn't been set, calling it will return the default position. */
@Test
public void testGetRestingPosition_returnsDefaultPosition() {
new WindowManagerConfig().setUpConfig();
mPositioner.update();
PointF restingPosition = mPositioner.getRestingPosition();
PointF defaultPosition = mPositioner.getDefaultStartPosition();
assertThat(restingPosition).isEqualTo(defaultPosition);
}
/** If a resting position has been set, it'll return that instead of the default position. */
@Test
public void testGetRestingPosition_returnsRestingPosition() {
new WindowManagerConfig().setUpConfig();
mPositioner.update();
PointF restingPosition = new PointF(100, 100);
mPositioner.setRestingPosition(restingPosition);
assertThat(mPositioner.getRestingPosition()).isEqualTo(restingPosition);
}
/** Test that the default resting position on phone is in upper left. */
@Test
public void testGetRestingPosition_bubble_onPhone() {
new WindowManagerConfig().setUpConfig();
mPositioner.update();
RectF allowableStackRegion =
mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
PointF restingPosition = mPositioner.getRestingPosition();
assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left);
assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
}
@Test
public void testGetRestingPosition_bubble_onPhone_RTL() {
new WindowManagerConfig().setLayoutDirection(LAYOUT_DIRECTION_RTL).setUpConfig();
mPositioner.update();
RectF allowableStackRegion =
mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
PointF restingPosition = mPositioner.getRestingPosition();
assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right);
assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
}
/** Test that the default resting position on tablet is middle left. */
@Test
public void testGetRestingPosition_chatBubble_onTablet() {
new WindowManagerConfig().setLargeScreen().setUpConfig();
mPositioner.update();
RectF allowableStackRegion =
mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
PointF restingPosition = mPositioner.getRestingPosition();
assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left);
assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
}
@Test
public void testGetRestingPosition_chatBubble_onTablet_RTL() {
new WindowManagerConfig().setLargeScreen().setLayoutDirection(
LAYOUT_DIRECTION_RTL).setUpConfig();
mPositioner.update();
RectF allowableStackRegion =
mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
PointF restingPosition = mPositioner.getRestingPosition();
assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right);
assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
}
/**
* Calculates the Y position bubbles should be placed based on the config. Based on
* the calculations in {@link BubblePositioner#getDefaultStartPosition()} and
* {@link BubbleStackView.RelativeStackPosition}.
*/
private float getDefaultYPosition() {
final float desiredY = mContext.getResources().getDimensionPixelOffset(
R.dimen.bubble_stack_starting_offset_y);
float offsetPercent = desiredY / mPositioner.getAvailableRect().height();
offsetPercent = Math.max(0f, Math.min(1f, offsetPercent));
final RectF allowableStackRegion =
mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
return allowableStackRegion.top + allowableStackRegion.height() * offsetPercent;
}
/**
* Sets up window manager to return config values based on what you need for the test.
* By default it sets up a portrait phone without any insets.
*/
private class WindowManagerConfig {
private Rect mScreenBounds = new Rect(0, 0, 1000, 2000);
private boolean mIsLargeScreen = false;
private int mOrientation = ORIENTATION_PORTRAIT;
private int mLayoutDirection = LAYOUT_DIRECTION_LTR;
private Insets mInsets = Insets.of(0, 0, 0, 0);
public WindowManagerConfig setScreenBounds(Rect screenBounds) {
mScreenBounds = screenBounds;
return this;
}
public WindowManagerConfig setLargeScreen() {
mIsLargeScreen = true;
return this;
}
public WindowManagerConfig setOrientation(int orientation) {
mOrientation = orientation;
return this;
}
public WindowManagerConfig setLayoutDirection(int layoutDirection) {
mLayoutDirection = layoutDirection;
return this;
}
public WindowManagerConfig setInsets(Insets insets) {
mInsets = insets;
return this;
}
public void setUpConfig() {
mConfiguration.smallestScreenWidthDp = mIsLargeScreen
? MIN_WIDTH_FOR_TABLET
: MIN_WIDTH_FOR_TABLET - 1;
mConfiguration.orientation = mOrientation;
when(mConfiguration.getLayoutDirection()).thenReturn(mLayoutDirection);
WindowInsets windowInsets = mock(WindowInsets.class);
when(windowInsets.getInsetsIgnoringVisibility(anyInt())).thenReturn(mInsets);
when(mWindowMetrics.getWindowInsets()).thenReturn(windowInsets);
when(mWindowMetrics.getBounds()).thenReturn(mScreenBounds);
when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics);
}
}
}