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

Commit a1183c0d authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Early return for task-start-position-only change" into main

parents 64eff724 1c8fcaa8
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -819,14 +819,20 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            Log.e(TAG, "onTaskFragmentParentInfoChanged on empty Task id=" + taskId);
            return;
        }
        // Checks if container should be updated before apply new parentInfo.
        final boolean shouldUpdateContainer = taskContainer.shouldUpdateContainer(parentInfo);
        taskContainer.updateTaskFragmentParentInfo(parentInfo);
        if (!taskContainer.isVisible()) {
            // Don't update containers if the task is not visible. We only update containers when
            // parentInfo#isVisibleRequested is true.
            return;
        }
        if (isInPictureInPicture(parentInfo.getConfiguration())) {
            // No need to update presentation in PIP until the Task exit PIP.

        // If the last direct activity of the host task is dismissed and the overlay container is
        // the only taskFragment, the overlay container should also be dismissed.
        dismissOverlayContainerIfNeeded(wct, taskContainer);

        if (!shouldUpdateContainer) {
            return;
        }
        updateContainersInTask(wct, taskContainer);
@@ -1947,11 +1953,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    void updateOverlayContainer(@NonNull WindowContainerTransaction wct,
            @NonNull TaskFragmentContainer container) {
        final TaskContainer taskContainer = container.getTaskContainer();
        // Dismiss the overlay container if it's the only container in the task and there's no
        // direct activity in the parent task.
        if (taskContainer.getTaskFragmentContainers().size() == 1
                && !taskContainer.hasDirectActivity()) {
            container.finish(false /* shouldFinishDependent */, mPresenter, wct, this);

        if (dismissOverlayContainerIfNeeded(wct, taskContainer)) {
            return;
        }

@@ -1968,6 +1971,24 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        }
    }

    /** Dismisses the overlay container in the {@code taskContainer} if needed. */
    @GuardedBy("mLock")
    private boolean dismissOverlayContainerIfNeeded(@NonNull WindowContainerTransaction wct,
            @NonNull TaskContainer taskContainer) {
        final TaskFragmentContainer overlayContainer = taskContainer.getOverlayContainer();
        if (overlayContainer == null) {
            return false;
        }
        // Dismiss the overlay container if it's the only container in the task and there's no
        // direct activity in the parent task.
        if (taskContainer.getTaskFragmentContainers().size() == 1
                && !taskContainer.hasDirectActivity()) {
            mPresenter.cleanupContainer(wct, overlayContainer, false /* shouldFinishDependant */);
            return true;
        }
        return false;
    }

    /**
     * Updates {@link SplitContainer} with the given {@link SplitAttributes} if the
     * {@link SplitContainer} is the top most and not finished. If passed {@link SplitAttributes}
+20 −1
Original line number Diff line number Diff line
@@ -137,6 +137,21 @@ class TaskContainer {
        mHasDirectActivity = info.hasDirectActivity();
    }

    /**
     * Returns {@code true} if the container should be updated with {@code info}.
     */
    boolean shouldUpdateContainer(@NonNull TaskFragmentParentInfo info) {
        final Configuration configuration = info.getConfiguration();

        return info.isVisible()
                // No need to update presentation in PIP until the Task exit PIP.
                && !isInPictureInPicture(configuration)
                // If the task properties equals regardless of starting position, don't need to
                // update the container.
                && (mConfiguration.diffPublicOnly(configuration) != 0
                || mDisplayId != info.getDisplayId());
    }

    /**
     * Returns the windowing mode for the TaskFragments below this Task, which should be split with
     * other TaskFragments.
@@ -161,7 +176,11 @@ class TaskContainer {
    }

    boolean isInPictureInPicture() {
        return getWindowingMode() == WINDOWING_MODE_PINNED;
        return isInPictureInPicture(mConfiguration);
    }

    private static boolean isInPictureInPicture(@NonNull Configuration configuration) {
        return configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED;
    }

    boolean isInMultiWindow() {
+3 −0
Original line number Diff line number Diff line
@@ -616,6 +616,9 @@ class TaskFragmentContainer {
     * Removes all activities that belong to this process and finishes other containers/activities
     * configured to finish together.
     */
    // Suppress GuardedBy warning because lint ask to mark this method as
    // @GuardedBy(container.mController.mLock), which is mLock itself
    @SuppressWarnings("GuardedBy")
    @GuardedBy("mController.mLock")
    void finish(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
            @NonNull WindowContainerTransaction wct, @NonNull SplitController controller) {
+13 −1
Original line number Diff line number Diff line
@@ -77,9 +77,11 @@ class TransactionManager {
    @NonNull
    TransactionRecord startNewTransaction(@Nullable IBinder taskFragmentTransactionToken) {
        if (mCurrentTransaction != null) {
            final TransactionRecord lastTransaction = mCurrentTransaction;
            mCurrentTransaction = null;
            throw new IllegalStateException(
                    "The previous transaction has not been applied or aborted,");
                    "The previous transaction:" + lastTransaction + " has not been applied or "
                            + "aborted.");
        }
        mCurrentTransaction = new TransactionRecord(taskFragmentTransactionToken);
        return mCurrentTransaction;
@@ -199,5 +201,15 @@ class TransactionManager {
                    ? mOriginType
                    : TASK_FRAGMENT_TRANSIT_CHANGE;
        }

        @Override
        @NonNull
        public String toString() {
            return TransactionRecord.class.getSimpleName() + "{"
                    + "token=" + mTaskFragmentTransactionToken
                    + ", type=" + getTransactionTransitionType()
                    + ", transaction=" + mTransaction
                    + "}";
        }
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -472,6 +472,29 @@ public class OverlayPresentationTest {
        verify(mSplitPresenter).applyActivityStackAttributes(any(), eq(container), eq(attrs));
    }

    @Test
    public void testOnTaskFragmentParentInfoChanged_positionOnlyChange_earlyReturn() {
        final TaskFragmentContainer overlayContainer = createTestOverlayContainer(TASK_ID, "test");

        final TaskContainer taskContainer = overlayContainer.getTaskContainer();
        spyOn(taskContainer);
        final TaskContainer.TaskProperties taskProperties = taskContainer.getTaskProperties();
        final TaskFragmentParentInfo parentInfo = new TaskFragmentParentInfo(
                new Configuration(taskProperties.getConfiguration()), taskProperties.getDisplayId(),
                true /* visible */, false /* hasDirectActivity */, null /* decorSurface */);
        parentInfo.getConfiguration().windowConfiguration.getBounds().offset(10, 10);

        mSplitController.onTaskFragmentParentInfoChanged(mTransaction, TASK_ID, parentInfo);

        // The parent info must be applied to the task container
        verify(taskContainer).updateTaskFragmentParentInfo(parentInfo);
        verify(mSplitController, never()).updateContainer(any(), any());

        assertWithMessage("The overlay container must still be dismissed even if "
                + "#updateContainer is not called")
                .that(taskContainer.getOverlayContainer()).isNull();
    }

    /**
     * A simplified version of {@link SplitController.ActivityStartMonitor
     * #createOrUpdateOverlayTaskFragmentIfNeeded}