Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43df948f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Allow launching placeholder when the TaskFragment is visible" into tm-qpr-dev am: 04f12073

parents 39787adc 04f12073
Loading
Loading
Loading
Loading
+37 −17
Original line number Diff line number Diff line
@@ -425,12 +425,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        if (container != null) {
            // Cleanup if the TaskFragment vanished is not requested by the organizer.
            removeContainer(container);
            // Make sure the top container is updated.
            final TaskFragmentContainer newTopContainer = getTopActiveContainer(
                    container.getTaskId());
            if (newTopContainer != null) {
                updateContainer(wct, newTopContainer);
            }
            // Make sure the containers in the Task are up-to-date.
            updateContainersInTaskIfVisible(wct, container.getTaskId());
        }
        cleanupTaskFragment(taskFragmentInfo.getFragmentToken());
    }
@@ -470,6 +466,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        updateContainersInTask(wct, taskContainer);
    }

    void updateContainersInTaskIfVisible(@NonNull WindowContainerTransaction wct, int taskId) {
        final TaskContainer taskContainer = getTaskContainer(taskId);
        if (taskContainer != null && taskContainer.isVisible()) {
            updateContainersInTask(wct, taskContainer);
        }
    }

    private void updateContainersInTask(@NonNull WindowContainerTransaction wct,
            @NonNull TaskContainer taskContainer) {
        // Update all TaskFragments in the Task. Make a copy of the list since some may be
@@ -1320,9 +1323,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    void removeContainer(@NonNull TaskFragmentContainer container) {
        // Remove all split containers that included this one
        final TaskContainer taskContainer = container.getTaskContainer();
        if (taskContainer == null) {
            return;
        }
        taskContainer.mContainers.remove(container);
        // Marked as a pending removal which will be removed after it is actually removed on the
        // server side (#onTaskFragmentVanished).
@@ -1515,14 +1515,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }

        final TaskFragmentContainer container = getContainerWithActivity(activity);
        // Don't launch placeholder if the container is occluded.
        if (container != null && container != getTopActiveContainer(container.getTaskId())) {
            return false;
        }

        final SplitContainer splitContainer = getActiveSplitForContainer(container);
        if (splitContainer != null && container.equals(splitContainer.getPrimaryContainer())) {
            // Don't launch placeholder in primary split container
        if (container != null && !allowLaunchPlaceholder(container)) {
            // We don't allow activity in this TaskFragment to launch placeholder.
            return false;
        }

@@ -1550,6 +1544,32 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        return true;
    }

    /** Whether or not to allow activity in this container to launch placeholder. */
    @GuardedBy("mLock")
    private boolean allowLaunchPlaceholder(@NonNull TaskFragmentContainer container) {
        final TaskFragmentContainer topContainer = getTopActiveContainer(container.getTaskId());
        if (container != topContainer) {
            // The container is not the top most.
            if (!container.isVisible()) {
                // In case the container is visible (the one on top may be transparent), we may
                // still want to launch placeholder even if it is not the top most.
                return false;
            }
            if (topContainer.isWaitingActivityAppear()) {
                // When the top container appeared info is not sent by the server yet, the visible
                // check above may not be reliable.
                return false;
            }
        }

        final SplitContainer splitContainer = getActiveSplitForContainer(container);
        if (splitContainer != null && container.equals(splitContainer.getPrimaryContainer())) {
            // Don't launch placeholder for primary split container.
            return false;
        }
        return true;
    }

    /**
     * Gets the activity options for starting the placeholder activity. In case the placeholder is
     * launched when the Task is in the background, we don't want to bring the Task to the front.
+2 −6
Original line number Diff line number Diff line
@@ -154,12 +154,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    void cleanupContainer(@NonNull WindowContainerTransaction wct,
            @NonNull TaskFragmentContainer container, boolean shouldFinishDependent) {
        container.finish(shouldFinishDependent, this, wct, mController);

        final TaskFragmentContainer newTopContainer = mController.getTopActiveContainer(
                container.getTaskId());
        if (newTopContainer != null) {
            mController.updateContainer(wct, newTopContainer);
        }
        // Make sure the containers in the Task is up-to-date.
        mController.updateContainersInTaskIfVisible(wct, container.getTaskId());
    }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -184,6 +184,11 @@ class TaskFragmentContainer {
        return allActivities;
    }

    /** Whether this TaskFragment is visible. */
    boolean isVisible() {
        return mInfo != null && mInfo.isVisible();
    }

    /** Whether the TaskFragment is in an intermediate state waiting for the server update.*/
    boolean isInIntermediateState() {
        if (mInfo == null) {
+7 −1
Original line number Diff line number Diff line
@@ -163,11 +163,17 @@ public class EmbeddingTestUtils {
    /** Creates a mock TaskFragmentInfo for the given TaskFragment. */
    static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
            @NonNull Activity activity) {
        return createMockTaskFragmentInfo(container, activity, true /* isVisible */);
    }

    /** Creates a mock TaskFragmentInfo for the given TaskFragment. */
    static TaskFragmentInfo createMockTaskFragmentInfo(@NonNull TaskFragmentContainer container,
            @NonNull Activity activity, boolean isVisible) {
        return new TaskFragmentInfo(container.getTaskFragmentToken(),
                mock(WindowContainerToken.class),
                new Configuration(),
                1,
                true /* isVisible */,
                isVisible,
                Collections.singletonList(activity.getActivityToken()),
                new Point(),
                false /* isTaskClearedForReuse */,
+62 −0
Original line number Diff line number Diff line
@@ -1254,6 +1254,68 @@ public class SplitControllerTest {
        verify(mEmbeddingCallback).accept(any());
    }

    @Test
    public void testLaunchPlaceholderIfNecessary_nonEmbeddedActivity() {
        // Launch placeholder for non embedded activity.
        setupPlaceholderRule(mActivity);
        mTransactionManager.startNewTransaction();
        mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
                true /* isOnCreated */);

        verify(mTransaction).startActivityInTaskFragment(any(), any(), eq(PLACEHOLDER_INTENT),
                any());
    }

    @Test
    public void testLaunchPlaceholderIfNecessary_embeddedInTopTaskFragment() {
        // Launch placeholder for activity in top TaskFragment.
        setupPlaceholderRule(mActivity);
        mTransactionManager.startNewTransaction();
        final TaskFragmentContainer container = mSplitController.newContainer(mActivity, TASK_ID);
        mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
                true /* isOnCreated */);

        assertTrue(container.hasActivity(mActivity.getActivityToken()));
        verify(mTransaction).startActivityInTaskFragment(any(), any(), eq(PLACEHOLDER_INTENT),
                any());
    }

    @Test
    public void testLaunchPlaceholderIfNecessary_embeddedBelowTaskFragment() {
        // Do not launch placeholder for invisible activity below the top TaskFragment.
        setupPlaceholderRule(mActivity);
        mTransactionManager.startNewTransaction();
        final TaskFragmentContainer bottomTf = mSplitController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer topTf = mSplitController.newContainer(new Intent(), mActivity,
                TASK_ID);
        bottomTf.setInfo(mTransaction, createMockTaskFragmentInfo(bottomTf, mActivity,
                false /* isVisible */));
        topTf.setInfo(mTransaction, createMockTaskFragmentInfo(topTf, createMockActivity()));
        assertFalse(bottomTf.isVisible());
        mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
                true /* isOnCreated */);

        verify(mTransaction, never()).startActivityInTaskFragment(any(), any(), any(), any());
    }

    @Test
    public void testLaunchPlaceholderIfNecessary_embeddedBelowTransparentTaskFragment() {
        // Launch placeholder for visible activity below the top TaskFragment.
        setupPlaceholderRule(mActivity);
        mTransactionManager.startNewTransaction();
        final TaskFragmentContainer bottomTf = mSplitController.newContainer(mActivity, TASK_ID);
        final TaskFragmentContainer topTf = mSplitController.newContainer(new Intent(), mActivity,
                TASK_ID);
        bottomTf.setInfo(mTransaction, createMockTaskFragmentInfo(bottomTf, mActivity,
                true /* isVisible */));
        topTf.setInfo(mTransaction, createMockTaskFragmentInfo(topTf, createMockActivity()));
        assertTrue(bottomTf.isVisible());
        mSplitController.launchPlaceholderIfNecessary(mTransaction, mActivity,
                true /* isOnCreated */);

        verify(mTransaction).startActivityInTaskFragment(any(), any(), any(), any());
    }

    /** Creates a mock activity in the organizer process. */
    private Activity createMockActivity() {
        return createMockActivity(TASK_ID);
Loading