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

Commit 5cc9e2ab authored by Annie Lin's avatar Annie Lin Committed by Android (Google) Code Review
Browse files

Merge "[Divider] Fix flicker when dragging to dismiss secondary container." into main

parents fffdd91a 0b5729fe
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -169,6 +169,11 @@ class DividerPresenter implements View.OnTouchListener {
    @GuardedBy("mLock")
    private int mDividerPosition;

    /** Indicates if there are containers to be finished since the divider has appeared. */
    @GuardedBy("mLock")
    @VisibleForTesting
    private boolean mHasContainersToFinish = false;

    DividerPresenter(int taskId, @NonNull DragEventCallback dragEventCallback,
            @NonNull Executor callbackExecutor) {
        mTaskId = taskId;
@@ -180,7 +185,8 @@ class DividerPresenter implements View.OnTouchListener {
    void updateDivider(
            @NonNull WindowContainerTransaction wct,
            @NonNull TaskFragmentParentInfo parentInfo,
            @Nullable SplitContainer topSplitContainer) {
            @Nullable SplitContainer topSplitContainer,
            boolean isTaskFragmentVanished) {
        if (!Flags.activityEmbeddingInteractiveDividerFlag()) {
            return;
        }
@@ -188,6 +194,18 @@ class DividerPresenter implements View.OnTouchListener {
        synchronized (mLock) {
            // Clean up the decor surface if top SplitContainer is null.
            if (topSplitContainer == null) {
                // Check if there are containers to finish but the TaskFragment hasn't vanished yet.
                // Don't remove the decor surface and divider if so as the removal should happen in
                // a following step when the TaskFragment has vanished. This ensures that the decor
                // surface is removed only after the resulting Activity is ready to be shown,
                // otherwise there may be flicker.
                if (mHasContainersToFinish) {
                    if (isTaskFragmentVanished) {
                        setHasContainersToFinish(false);
                    } else {
                        return;
                    }
                }
                removeDecorSurfaceAndDivider(wct);
                return;
            }
@@ -868,6 +886,12 @@ class DividerPresenter implements View.OnTouchListener {
        }
    }

    void setHasContainersToFinish(boolean hasContainersToFinish) {
        synchronized (mLock) {
            mHasContainersToFinish = hasContainersToFinish;
        }
    }

    private static boolean isDraggingToFullscreenAllowed(
            @NonNull DividerAttributes dividerAttributes) {
        // TODO(b/293654166) Use DividerAttributes.isDraggingToFullscreenAllowed when extension is
+18 −7
Original line number Diff line number Diff line
@@ -673,7 +673,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                        break;
                    case TYPE_TASK_FRAGMENT_VANISHED:
                        mPresenter.removeTaskFragmentInfo(info);
                        onTaskFragmentVanished(wct, info);
                        onTaskFragmentVanished(wct, info, taskId);
                        break;
                    case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED:
                        onTaskFragmentParentInfoChanged(wct, taskId,
@@ -834,7 +834,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    @VisibleForTesting
    @GuardedBy("mLock")
    void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct,
            @NonNull TaskFragmentInfo taskFragmentInfo) {
            @NonNull TaskFragmentInfo taskFragmentInfo, int taskId) {
        final TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
        if (container != null) {
            // Cleanup if the TaskFragment vanished is not requested by the organizer.
@@ -843,6 +843,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
            updateContainersInTaskIfVisible(wct, container.getTaskId());
        }
        cleanupTaskFragment(taskFragmentInfo.getFragmentToken());
        final TaskContainer taskContainer = getTaskContainer(taskId);
        if (taskContainer != null) {
            // Update the divider to clean up any decor surfaces.
            updateDivider(wct, taskContainer, true /* isTaskFragmentVanished */);
        }
    }

    /**
@@ -884,7 +889,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
        // The divider need to be updated even if shouldUpdateContainer is false, because the decor
        // surface may change in TaskFragmentParentInfo, which requires divider update but not
        // container update.
        updateDivider(wct, taskContainer);
        updateDivider(wct, taskContainer, false /* isTaskFragmentVanished */);

        // If the last direct activity of the host task is dismissed and there's an always-on-top
        // overlay container in the task, the overlay container should also be dismissed.
@@ -3257,12 +3262,15 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
    }

    @GuardedBy("mLock")
    void updateDivider(
            @NonNull WindowContainerTransaction wct, @NonNull TaskContainer taskContainer) {
    void updateDivider(@NonNull WindowContainerTransaction wct,
            @NonNull TaskContainer taskContainer, boolean isTaskFragmentVanished) {
        final DividerPresenter dividerPresenter = mDividerPresenters.get(taskContainer.getTaskId());
        final TaskFragmentParentInfo parentInfo = taskContainer.getTaskFragmentParentInfo();
        final SplitContainer topSplitContainer = taskContainer.getTopNonFinishingSplitContainer();
        if (dividerPresenter != null) {
            dividerPresenter.updateDivider(
                wct, parentInfo, taskContainer.getTopNonFinishingSplitContainer());
                    wct, parentInfo, topSplitContainer, isTaskFragmentVanished);
        }
    }

    @Override
@@ -3292,6 +3300,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                final List<TaskFragmentContainer> containersToFinish = new ArrayList<>();
                taskContainer.updateTopSplitContainerForDivider(
                        dividerPresenter, containersToFinish);
                if (!containersToFinish.isEmpty()) {
                    dividerPresenter.setHasContainersToFinish(true);
                }
                for (final TaskFragmentContainer container : containersToFinish) {
                    mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */);
                }
+3 −2
Original line number Diff line number Diff line
@@ -374,7 +374,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
        updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
        updateAnimationParams(wct, primaryContainer.getTaskFragmentToken(), splitAttributes);
        updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes);
        mController.updateDivider(wct, taskContainer);
        mController.updateDivider(wct, taskContainer, false /* isTaskFragmentVanished */);
    }

    private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -757,7 +757,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
    void expandTaskFragment(@NonNull WindowContainerTransaction wct,
            @NonNull TaskFragmentContainer container) {
        super.expandTaskFragment(wct, container);
        mController.updateDivider(wct, container.getTaskContainer());
        mController.updateDivider(
                wct, container.getTaskContainer(), false /* isTaskFragmentVanished */);
    }

    static boolean shouldShowSplit(@NonNull SplitContainer splitContainer) {
+45 −5
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import java.util.concurrent.Executor;
 */
@Presubmit
@SmallTest
@SuppressWarnings("GuardedBy")
@RunWith(AndroidJUnit4.class)
public class DividerPresenterTest {
    @Rule
@@ -186,7 +187,8 @@ public class DividerPresenterTest {
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                mSplitContainer);
                mSplitContainer,
                false /* isTaskFragmentVanished */);

        assertNotEquals(mProperties, mDividerPresenter.mProperties);
        verify(mRenderer).update();
@@ -206,7 +208,8 @@ public class DividerPresenterTest {
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                mSplitContainer);
                mSplitContainer,
                false /* isTaskFragmentVanished */);

        assertNotEquals(mProperties, mDividerPresenter.mProperties);
        verify(mRenderer).update();
@@ -222,7 +225,8 @@ public class DividerPresenterTest {
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                mSplitContainer);
                mSplitContainer,
                false /* isTaskFragmentVanished */);

        assertEquals(mProperties, mDividerPresenter.mProperties);
        verify(mRenderer, never()).update();
@@ -234,7 +238,42 @@ public class DividerPresenterTest {
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                null /* splitContainer */);
                null /* splitContainer */,
                false /* isTaskFragmentVanished */);
        final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
                OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
                .build();

        verify(mTransaction).addTaskFragmentOperation(
                mPrimaryContainerToken, taskFragmentOperation);
        verify(mRenderer).release();
        assertNull(mDividerPresenter.mRenderer);
        assertNull(mDividerPresenter.mProperties);
        assertNull(mDividerPresenter.mDecorSurfaceOwner);
    }

    @Test
    public void testUpdateDivider_noChangeWhenHasContainersToFinishButTaskFragmentNotVanished() {
        mDividerPresenter.setHasContainersToFinish(true);
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                null /* splitContainer */,
                false /* isTaskFragmentVanished */);

        assertEquals(mProperties, mDividerPresenter.mProperties);
        verify(mRenderer, never()).update();
        verify(mTransaction, never()).addTaskFragmentOperation(any(), any());
    }

    @Test
    public void testUpdateDivider_dividerRemovedWhenHasContainersToFinishAndTaskFragmentVanished() {
        mDividerPresenter.setHasContainersToFinish(true);
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                null /* splitContainer */,
                true /* isTaskFragmentVanished */);
        final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
                OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
                .build();
@@ -254,7 +293,8 @@ public class DividerPresenterTest {
        mDividerPresenter.updateDivider(
                mTransaction,
                mParentInfo,
                mSplitContainer);
                mSplitContainer,
                false /* isTaskFragmentVanished */);
        final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
                OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
                .build();
+4 −2
Original line number Diff line number Diff line
@@ -200,12 +200,14 @@ public class SplitControllerTest {
    public void testOnTaskFragmentVanished() {
        final TaskFragmentContainer tf = createTfContainer(mSplitController, mActivity);
        doReturn(tf.getTaskFragmentToken()).when(mInfo).getFragmentToken();
        doReturn(createTestTaskContainer()).when(mSplitController).getTaskContainer(TASK_ID);

        // The TaskFragment has been removed in the server, we only need to cleanup the reference.
        mSplitController.onTaskFragmentVanished(mTransaction, mInfo);
        mSplitController.onTaskFragmentVanished(mTransaction, mInfo, TASK_ID);

        verify(mSplitPresenter, never()).deleteTaskFragment(any(), any());
        verify(mSplitController).removeContainer(tf);
        verify(mSplitController).updateDivider(any(), any(), anyBoolean());
        verify(mTransaction, never()).finishActivity(any());
    }

@@ -1152,7 +1154,7 @@ public class SplitControllerTest {
                .setTaskFragmentInfo(info));
        mSplitController.onTransactionReady(transaction);

        verify(mSplitController).onTaskFragmentVanished(any(), eq(info));
        verify(mSplitController).onTaskFragmentVanished(any(), eq(info), anyInt());
        verify(mSplitPresenter).onTransactionHandled(eq(transaction.getTransactionToken()), any(),
                anyInt(), anyBoolean());
    }