Merge "Make sure the secondary TaskFragment is above the primary" into tm-qpr-dev
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -162,4 +162,8 @@ class TaskContainer {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int indexOf(@NonNull TaskFragmentContainer child) {
|
||||
return mContainers.indexOf(child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user