blob: d79319666c0174b3fe254ba526db5d61c238d5b2 [file] [log] [blame]
/*
* Copyright (C) 2022 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 androidx.window.extensions.embedding;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_END;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_FILL;
import static androidx.window.extensions.embedding.SplitPresenter.POSITION_START;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPANDED;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO;
import static androidx.window.extensions.embedding.SplitPresenter.RESULT_NOT_EXPANDED;
import static androidx.window.extensions.embedding.SplitPresenter.getBoundsForPosition;
import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions;
import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
import android.util.Size;
import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Test class for {@link SplitPresenter}.
*
* Build/Install/Run:
* atest WMJetpackUnitTests:SplitPresenterTest
*/
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class SplitPresenterTest {
@Mock
private Activity mActivity;
@Mock
private Resources mActivityResources;
@Mock
private TaskFragmentInfo mTaskFragmentInfo;
@Mock
private WindowContainerTransaction mTransaction;
private SplitController mController;
private SplitPresenter mPresenter;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new SplitController();
mPresenter = mController.mPresenter;
spyOn(mController);
spyOn(mPresenter);
mActivity = createMockActivity();
}
@Test
public void testCreateTaskFragment() {
final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
mPresenter.createTaskFragment(mTransaction, container.getTaskFragmentToken(),
mActivity.getActivityToken(), TASK_BOUNDS, WINDOWING_MODE_MULTI_WINDOW);
assertTrue(container.areLastRequestedBoundsEqual(TASK_BOUNDS));
assertTrue(container.isLastRequestedWindowingModeEqual(WINDOWING_MODE_MULTI_WINDOW));
verify(mTransaction).createTaskFragment(any());
}
@Test
public void testResizeTaskFragment() {
final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
mPresenter.mFragmentInfos.put(container.getTaskFragmentToken(), mTaskFragmentInfo);
mPresenter.resizeTaskFragment(mTransaction, container.getTaskFragmentToken(), TASK_BOUNDS);
assertTrue(container.areLastRequestedBoundsEqual(TASK_BOUNDS));
verify(mTransaction).setBounds(any(), eq(TASK_BOUNDS));
// No request to set the same bounds.
clearInvocations(mTransaction);
mPresenter.resizeTaskFragment(mTransaction, container.getTaskFragmentToken(), TASK_BOUNDS);
verify(mTransaction, never()).setBounds(any(), any());
}
@Test
public void testUpdateWindowingMode() {
final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
mPresenter.mFragmentInfos.put(container.getTaskFragmentToken(), mTaskFragmentInfo);
mPresenter.updateWindowingMode(mTransaction, container.getTaskFragmentToken(),
WINDOWING_MODE_MULTI_WINDOW);
assertTrue(container.isLastRequestedWindowingModeEqual(WINDOWING_MODE_MULTI_WINDOW));
verify(mTransaction).setWindowingMode(any(), eq(WINDOWING_MODE_MULTI_WINDOW));
// No request to set the same windowing mode.
clearInvocations(mTransaction);
mPresenter.updateWindowingMode(mTransaction, container.getTaskFragmentToken(),
WINDOWING_MODE_MULTI_WINDOW);
verify(mTransaction, never()).setWindowingMode(any(), anyInt());
}
@Test
public void testGetMinDimensionsForIntent() {
final Intent intent = new Intent(ApplicationProvider.getApplicationContext(),
MinimumDimensionActivity.class);
assertEquals(new Size(600, 1200), getMinDimensions(intent));
}
@Test
public void testShouldShowSideBySide() {
Activity secondaryActivity = createMockActivity();
final SplitRule splitRule = createSplitRule(mActivity, secondaryActivity);
assertTrue(shouldShowSideBySide(TASK_BOUNDS, splitRule));
// Set minDimensions of primary container to larger than primary bounds.
final Rect primaryBounds = getSplitBounds(true /* isPrimary */);
Pair<Size, Size> minDimensionsPair = new Pair<>(
new Size(primaryBounds.width() + 1, primaryBounds.height() + 1), null);
assertFalse(shouldShowSideBySide(TASK_BOUNDS, splitRule, minDimensionsPair));
}
@Test
public void testGetBoundsForPosition() {
Activity secondaryActivity = createMockActivity();
final SplitRule splitRule = createSplitRule(mActivity, secondaryActivity);
final Rect primaryBounds = getSplitBounds(true /* isPrimary */);
final Rect secondaryBounds = getSplitBounds(false /* isPrimary */);
assertEquals("Primary bounds must be reported.",
primaryBounds,
getBoundsForPosition(POSITION_START, TASK_BOUNDS, splitRule,
mActivity, null /* miniDimensionsPair */));
assertEquals("Secondary bounds must be reported.",
secondaryBounds,
getBoundsForPosition(POSITION_END, TASK_BOUNDS, splitRule,
mActivity, null /* miniDimensionsPair */));
assertEquals("Task bounds must be reported.",
new Rect(),
getBoundsForPosition(POSITION_FILL, TASK_BOUNDS, splitRule,
mActivity, null /* miniDimensionsPair */));
Pair<Size, Size> minDimensionsPair = new Pair<>(
new Size(primaryBounds.width() + 1, primaryBounds.height() + 1), null);
assertEquals("Fullscreen bounds must be reported because of min dimensions.",
new Rect(),
getBoundsForPosition(POSITION_START, TASK_BOUNDS,
splitRule, mActivity, minDimensionsPair));
}
@Test
public void testExpandSplitContainerIfNeeded() {
SplitContainer splitContainer = mock(SplitContainer.class);
Activity secondaryActivity = createMockActivity();
SplitRule splitRule = createSplitRule(mActivity, secondaryActivity);
TaskFragmentContainer primaryTf = mController.newContainer(mActivity, TASK_ID);
TaskFragmentContainer secondaryTf = mController.newContainer(secondaryActivity, TASK_ID);
doReturn(splitRule).when(splitContainer).getSplitRule();
doReturn(primaryTf).when(splitContainer).getPrimaryContainer();
doReturn(secondaryTf).when(splitContainer).getSecondaryContainer();
assertThrows(IllegalArgumentException.class, () ->
mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity,
null /* secondaryActivity */, null /* secondaryIntent */));
assertEquals(RESULT_NOT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
verify(mPresenter, never()).expandTaskFragment(any(), any());
doReturn(createActivityInfoWithMinDimensions()).when(secondaryActivity).getActivityInfo();
assertEquals(RESULT_EXPAND_FAILED_NO_TF_INFO, mPresenter.expandSplitContainerIfNeeded(
mTransaction, splitContainer, mActivity, secondaryActivity,
null /* secondaryIntent */));
primaryTf.setInfo(createMockTaskFragmentInfo(primaryTf, mActivity));
secondaryTf.setInfo(createMockTaskFragmentInfo(secondaryTf, secondaryActivity));
assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
verify(mPresenter).expandTaskFragment(eq(mTransaction),
eq(primaryTf.getTaskFragmentToken()));
verify(mPresenter).expandTaskFragment(eq(mTransaction),
eq(secondaryTf.getTaskFragmentToken()));
clearInvocations(mPresenter);
assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
splitContainer, mActivity, null /* secondaryActivity */,
new Intent(ApplicationProvider.getApplicationContext(),
MinimumDimensionActivity.class)));
verify(mPresenter).expandTaskFragment(eq(mTransaction),
eq(primaryTf.getTaskFragmentToken()));
verify(mPresenter).expandTaskFragment(eq(mTransaction),
eq(secondaryTf.getTaskFragmentToken()));
}
private Activity createMockActivity() {
final Activity activity = mock(Activity.class);
final Configuration activityConfig = new Configuration();
activityConfig.windowConfiguration.setBounds(TASK_BOUNDS);
activityConfig.windowConfiguration.setMaxBounds(TASK_BOUNDS);
doReturn(mActivityResources).when(activity).getResources();
doReturn(activityConfig).when(mActivityResources).getConfiguration();
doReturn(new ActivityInfo()).when(activity).getActivityInfo();
doReturn(mock(IBinder.class)).when(activity).getActivityToken();
return activity;
}
}