Merge "Update SplitContainer for non-finishing containers" into tm-dev

This commit is contained in:
Charles Chen
2022-05-03 06:37:26 +00:00
committed by Android (Google) Code Review
4 changed files with 91 additions and 10 deletions

View File

@@ -621,14 +621,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
} }
final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId()) final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId())
.mSplitContainers; .mSplitContainers;
if (splitContainers == null if (splitContainer != splitContainers.get(splitContainers.size() - 1)) {
|| splitContainer != splitContainers.get(splitContainers.size() - 1)) {
// Skip position update - it isn't the topmost split. // Skip position update - it isn't the topmost split.
return; return;
} }
if (splitContainer.getPrimaryContainer().isEmpty() if (splitContainer.getPrimaryContainer().isFinished()
|| splitContainer.getSecondaryContainer().isEmpty()) { || splitContainer.getSecondaryContainer().isFinished()) {
// Skip position update - one or both containers are empty. // Skip position update - one or both containers are finished.
return; return;
} }
if (dismissPlaceholderIfNecessary(splitContainer)) { if (dismissPlaceholderIfNecessary(splitContainer)) {
@@ -645,7 +644,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
private SplitContainer getActiveSplitForContainer(@NonNull TaskFragmentContainer container) { private SplitContainer getActiveSplitForContainer(@NonNull TaskFragmentContainer container) {
final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId()) final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId())
.mSplitContainers; .mSplitContainers;
if (splitContainers == null) { if (splitContainers.isEmpty()) {
return null; return null;
} }
for (int i = splitContainers.size() - 1; i >= 0; i--) { for (int i = splitContainers.size() - 1; i >= 0; i--) {
@@ -723,7 +722,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return true; return true;
} }
private boolean dismissPlaceholderIfNecessary(@NonNull SplitContainer splitContainer) { @VisibleForTesting
boolean dismissPlaceholderIfNecessary(@NonNull SplitContainer splitContainer) {
if (!splitContainer.isPlaceholderContainer()) { if (!splitContainer.isPlaceholderContainer()) {
return false; return false;
} }

View File

@@ -47,9 +47,11 @@ class TaskContainer {
private int mWindowingMode = WINDOWING_MODE_UNDEFINED; private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
/** Active TaskFragments in this Task. */ /** Active TaskFragments in this Task. */
@NonNull
final List<TaskFragmentContainer> mContainers = new ArrayList<>(); final List<TaskFragmentContainer> mContainers = new ArrayList<>();
/** Active split pairs in this Task. */ /** Active split pairs in this Task. */
@NonNull
final List<SplitContainer> mSplitContainers = new ArrayList<>(); final List<SplitContainer> mSplitContainers = new ArrayList<>();
/** /**

View File

@@ -341,14 +341,15 @@ class TaskFragmentContainer {
private String toString(boolean includeContainersToFinishOnExit) { private String toString(boolean includeContainersToFinishOnExit) {
return "TaskFragmentContainer{" return "TaskFragmentContainer{"
+ " token=" + mToken + " token=" + mToken
+ " info=" + mInfo
+ " topNonFinishingActivity=" + getTopNonFinishingActivity() + " topNonFinishingActivity=" + getTopNonFinishingActivity()
+ " runningActivityCount=" + getRunningActivityCount()
+ " isFinished=" + mIsFinished
+ " lastRequestedBounds=" + mLastRequestedBounds
+ " pendingAppearedActivities=" + mPendingAppearedActivities + " pendingAppearedActivities=" + mPendingAppearedActivities
+ (includeContainersToFinishOnExit ? " containersToFinishOnExit=" + (includeContainersToFinishOnExit ? " containersToFinishOnExit="
+ containersToFinishOnExitToString() : "") + containersToFinishOnExitToString() : "")
+ " activitiesToFinishOnExit=" + mActivitiesToFinishOnExit + " activitiesToFinishOnExit=" + mActivitiesToFinishOnExit
+ " isFinished=" + mIsFinished + " info=" + mInfo
+ " lastRequestedBounds=" + mLastRequestedBounds
+ "}"; + "}";
} }

View File

@@ -25,6 +25,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@@ -35,6 +37,7 @@ import android.content.res.Resources;
import android.graphics.Rect; import android.graphics.Rect;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.window.TaskFragmentInfo; import android.window.TaskFragmentInfo;
import android.window.WindowContainerTransaction;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
@@ -45,6 +48,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.List;
/** /**
* Test class for {@link SplitController}. * Test class for {@link SplitController}.
* *
@@ -64,6 +69,8 @@ public class SplitControllerTest {
private Resources mActivityResources; private Resources mActivityResources;
@Mock @Mock
private TaskFragmentInfo mInfo; private TaskFragmentInfo mInfo;
@Mock
private WindowContainerTransaction mTransaction;
private SplitController mSplitController; private SplitController mSplitController;
private SplitPresenter mSplitPresenter; private SplitPresenter mSplitPresenter;
@@ -140,4 +147,75 @@ public class SplitControllerTest {
assertNotNull(taskContainer); assertNotNull(taskContainer);
assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds()); assertEquals(TASK_BOUNDS, taskContainer.getTaskBounds());
} }
@Test
public void testUpdateContainer() {
// Make SplitController#launchPlaceholderIfNecessary(TaskFragmentContainer) return true
// and verify if shouldContainerBeExpanded() not called.
final TaskFragmentContainer tf = mSplitController.newContainer(mActivity, TASK_ID);
spyOn(tf);
doReturn(mActivity).when(tf).getTopNonFinishingActivity();
doReturn(true).when(tf).isEmpty();
doReturn(true).when(mSplitController).launchPlaceholderIfNecessary(mActivity);
doNothing().when(mSplitPresenter).updateSplitContainer(any(), any(), any());
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitController, never()).shouldContainerBeExpanded(any());
// Verify if tf should be expanded, getTopActiveContainer() won't be called
doReturn(null).when(tf).getTopNonFinishingActivity();
doReturn(true).when(mSplitController).shouldContainerBeExpanded(tf);
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitController, never()).getTopActiveContainer(TASK_ID);
// Verify if tf is not in split, dismissPlaceholderIfNecessary won't be called.
doReturn(false).when(mSplitController).shouldContainerBeExpanded(tf);
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitController, never()).dismissPlaceholderIfNecessary(any());
// Verify if tf is not in the top splitContainer,
final SplitContainer splitContainer = mock(SplitContainer.class);
doReturn(tf).when(splitContainer).getPrimaryContainer();
doReturn(tf).when(splitContainer).getSecondaryContainer();
final List<SplitContainer> splitContainers =
mSplitController.getTaskContainer(TASK_ID).mSplitContainers;
splitContainers.add(splitContainer);
// Add a mock SplitContainer on top of splitContainer
splitContainers.add(1, mock(SplitContainer.class));
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitController, never()).dismissPlaceholderIfNecessary(any());
// Verify if one or both containers in the top SplitContainer are finished,
// dismissPlaceholder() won't be called.
splitContainers.remove(1);
doReturn(true).when(tf).isFinished();
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitController, never()).dismissPlaceholderIfNecessary(any());
// Verify if placeholder should be dismissed, updateSplitContainer() won't be called.
doReturn(false).when(tf).isFinished();
doReturn(true).when(mSplitController)
.dismissPlaceholderIfNecessary(splitContainer);
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitPresenter, never()).updateSplitContainer(any(), any(), any());
// Verify if the top active split is updated if both of its containers are not finished.
doReturn(false).when(mSplitController)
.dismissPlaceholderIfNecessary(splitContainer);
mSplitController.updateContainer(mTransaction, tf);
verify(mSplitPresenter).updateSplitContainer(eq(splitContainer), eq(tf), eq(mTransaction));
}
} }