Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +6 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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, Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +4 −0 Original line number Diff line number Diff line Loading @@ -162,4 +162,8 @@ class TaskContainer { } return null; } int indexOf(@NonNull TaskFragmentContainer child) { return mContainers.indexOf(child); } } libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 */); Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +6 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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, Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +4 −0 Original line number Diff line number Diff line Loading @@ -162,4 +162,8 @@ class TaskContainer { } return null; } int indexOf(@NonNull TaskFragmentContainer child) { return mContainers.indexOf(child); } }
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +12 −0 Original line number Diff line number Diff line Loading @@ -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 */); Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading