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

Commit 389fce14 authored by Matt Sziklay's avatar Matt Sziklay Committed by mattsziklay
Browse files

Defer display content removal on disconnect.

Currently, display content is removed as part of transaction handling in WindowOrganizerController. However, this can interfere with other task changes in the same transaction as this occurs before handling of hierarchy ops. To fix this, move the display content removal to after hierarchy ops handling in WindowOrganizerController#applyTransaction.

Bug: 435672235
Test: Manual
Flag: com.android.window.flags.enable_display_disconnect_interaction

Change-Id: I812760d1c6159f8ec166b70f03bbdca60900c6a9
parent a4f3d47a
Loading
Loading
Loading
Loading
+26 −6
Original line number Original line Diff line number Diff line
@@ -3613,8 +3613,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
     * check whether to deliver the new configuration to clients and whether the changes will
     * check whether to deliver the new configuration to clients and whether the changes will
     * potentially affect lifecycles.
     * potentially affect lifecycles.
     */
     */
    boolean applyDisplayChangeIfNeeded(@NonNull ArraySet<WindowContainer<?>> activitiesMayChange) {
    void applyDisplayChangeIfNeeded(@NonNull ArraySet<WindowContainer<?>> activitiesMayChange) {
        boolean affectsLifecycle = false;
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
            final WindowContainer<?> wc = mParticipants.valueAt(i);
            final WindowContainer<?> wc = mParticipants.valueAt(i);
            final DisplayContent dc = wc.asDisplayContent();
            final DisplayContent dc = wc.asDisplayContent();
@@ -3622,9 +3621,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            final ChangeInfo displayChange = mChanges.get(dc);
            final ChangeInfo displayChange = mChanges.get(dc);
            if (ENABLE_DISPLAY_DISCONNECT_INTERACTION.isTrue()
            if (ENABLE_DISPLAY_DISCONNECT_INTERACTION.isTrue()
                    && displayChange.mExistenceChanged) {
                    && displayChange.mExistenceChanged) {
                dc.remove();
                // If this change is a display disconnection, we can skip it for now.
                affectsLifecycle = true;
                // It will be handled via applyDisplayRemovalIfNeeded below.
                mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(dc.mDisplayId);
                continue;
                continue;
            }
            }
            if (!displayChange.hasChanged()) continue;
            if (!displayChange.hasChanged()) continue;
@@ -3647,7 +3645,29 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                });
                });
            }
            }
        }
        }
        return affectsLifecycle;
    }

    /**
     * If this transition involves display removal(s), remove the DisplayContent here. Separated
     * from the above method since this method needs to occur after task changes to ensure
     * tasks do not have their hierarchy ops invalidated by being orphaned.
     * @return whether or not a DisplayContent was removed.
     */
    boolean applyDisplayRemovalsIfNeeded() {
        if (!ENABLE_DISPLAY_DISCONNECT_INTERACTION.isTrue()) return false;
        boolean displayRemoved = false;
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
            final WindowContainer<?> wc = mParticipants.valueAt(i);
            final DisplayContent dc = wc.asDisplayContent();
            if (dc == null) continue;
            final ChangeInfo displayChange = mChanges.get(dc);
            if (displayChange.mExistenceChanged) {
                dc.remove();
                mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(dc.mDisplayId);
                displayRemoved = true;
            }
        }
        return displayRemoved;
    }
    }


    boolean getLegacyIsReady() {
    boolean getLegacyIsReady() {
+4 −3
Original line number Original line Diff line number Diff line
@@ -664,9 +664,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
        try {
        try {
            final ArraySet<WindowContainer<?>> haveConfigChanges = new ArraySet<>();
            final ArraySet<WindowContainer<?>> haveConfigChanges = new ArraySet<>();
            if (transition != null) {
            if (transition != null) {
                if (transition.applyDisplayChangeIfNeeded(haveConfigChanges)) {
                transition.applyDisplayChangeIfNeeded(haveConfigChanges);
                    effects |= TRANSACT_EFFECTS_LIFECYCLE;
                }
                if (!haveConfigChanges.isEmpty()) {
                if (!haveConfigChanges.isEmpty()) {
                    effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
                    effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
                }
                }
@@ -776,6 +774,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                            t.getTaskFragmentOrganizer());
                            t.getTaskFragmentOrganizer());
                }
                }
            }
            }
            if (transition != null && transition.applyDisplayRemovalsIfNeeded()) {
                effects |= TRANSACT_EFFECTS_LIFECYCLE;
            }
            if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
            if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
                mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
                mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
                mService.mTaskSupervisor.endDeferResume();
                mService.mTaskSupervisor.endDeferResume();