Merge "Make sure the secondary TaskFragment is above the primary" into tm-qpr-dev

This commit is contained in:
Chris Li
2022-08-31 01:37:21 +00:00
committed by Android (Google) Code Review
6 changed files with 58 additions and 2 deletions

View File

@@ -792,6 +792,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
* Checks if there is a rule to split the two activities. If there is one, puts them into split
* and returns {@code true}. Otherwise, returns {@code false}.
*/
// Suppress GuardedBy warning because lint ask to mark this method as
// @GuardedBy(mPresenter.mController.mLock), which is mLock itself
@SuppressWarnings("GuardedBy")
@GuardedBy("mLock")
private boolean putActivitiesIntoSplitIfNecessary(@NonNull WindowContainerTransaction wct,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) {

View File

@@ -38,6 +38,7 @@ import android.view.WindowInsets;
import android.view.WindowMetrics;
import android.window.WindowContainerTransaction;
import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -171,6 +172,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
* created and the activity will be re-parented to it.
* @param rule The split rule to be applied to the container.
*/
@GuardedBy("mController.mLock")
void createNewSplitContainer(@NonNull WindowContainerTransaction wct,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity,
@NonNull SplitPairRule rule) {
@@ -187,8 +189,10 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
final TaskFragmentContainer curSecondaryContainer = mController.getContainerWithActivity(
secondaryActivity);
TaskFragmentContainer containerToAvoid = primaryContainer;
if (rule.shouldClearTop() && curSecondaryContainer != null) {
// Do not reuse the current TaskFragment if the rule is to clear top.
if (curSecondaryContainer != null
&& (rule.shouldClearTop() || primaryContainer.isAbove(curSecondaryContainer))) {
// Do not reuse the current TaskFragment if the rule is to clear top, or if it is below
// the primary TaskFragment.
containerToAvoid = curSecondaryContainer;
}
final TaskFragmentContainer secondaryContainer = prepareContainerForActivity(wct,

View File

@@ -162,4 +162,8 @@ class TaskContainer {
}
return null;
}
int indexOf(@NonNull TaskFragmentContainer child) {
return mContainers.indexOf(child);
}
}

View File

@@ -501,6 +501,18 @@ class TaskFragmentContainer {
return new Size(maxMinWidth, maxMinHeight);
}
/** Whether the current TaskFragment is above the {@code other} TaskFragment. */
boolean isAbove(@NonNull TaskFragmentContainer other) {
if (mTaskContainer != other.mTaskContainer) {
throw new IllegalArgumentException(
"Trying to compare two TaskFragments in different Task.");
}
if (this == other) {
throw new IllegalArgumentException("Trying to compare a TaskFragment with itself.");
}
return mTaskContainer.indexOf(this) > mTaskContainer.indexOf(other);
}
@Override
public String toString() {
return toString(true /* includeContainersToFinishOnExit */);

View File

@@ -39,6 +39,7 @@ 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.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -247,6 +248,26 @@ public class SplitPresenterTest {
verify(mPresenter).expandTaskFragment(mTransaction, secondaryTf.getTaskFragmentToken());
}
@Test
public void testCreateNewSplitContainer_secondaryAbovePrimary() {
final Activity secondaryActivity = createMockActivity();
final TaskFragmentContainer bottomTf = mController.newContainer(secondaryActivity, TASK_ID);
final TaskFragmentContainer primaryTf = mController.newContainer(mActivity, TASK_ID);
final SplitPairRule rule = new SplitPairRule.Builder(pair ->
pair.first == mActivity && pair.second == secondaryActivity, pair -> false,
metrics -> true)
.setShouldClearTop(false)
.build();
mPresenter.createNewSplitContainer(mTransaction, mActivity, secondaryActivity, rule);
assertEquals(primaryTf, mController.getContainerWithActivity(mActivity));
final TaskFragmentContainer secondaryTf = mController.getContainerWithActivity(
secondaryActivity);
assertNotEquals(bottomTf, secondaryTf);
assertTrue(secondaryTf.isAbove(primaryTf));
}
private Activity createMockActivity() {
final Activity activity = mock(Activity.class);
final Configuration activityConfig = new Configuration();

View File

@@ -287,6 +287,18 @@ public class TaskFragmentContainerTest {
assertEquals(1, container.collectNonFinishingActivities().size());
}
@Test
public void testIsAbove() {
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
final TaskFragmentContainer container0 = new TaskFragmentContainer(null /* activity */,
mIntent, taskContainer, mController);
final TaskFragmentContainer container1 = new TaskFragmentContainer(null /* activity */,
mIntent, taskContainer, mController);
assertTrue(container1.isAbove(container0));
assertFalse(container0.isAbove(container1));
}
@Test
public void testGetBottomMostActivity() {
final TaskContainer taskContainer = new TaskContainer(TASK_ID);