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

Commit 0098f3db authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Report display change for display focus switch" into main

parents 2533fe98 d4e27d9a
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -17,13 +17,13 @@
package com.android.wm.shell.transition;

import static android.view.Display.INVALID_DISPLAY;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;

import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
import static com.android.wm.shell.transition.Transitions.TransitionObserver;

import android.annotation.NonNull;
import android.app.ActivityManager.RunningTaskInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -62,10 +62,9 @@ public class FocusTransitionObserver implements TransitionObserver {
        final List<TransitionInfo.Change> changes = info.getChanges();
        for (int i = changes.size() - 1; i >= 0; i--) {
            final TransitionInfo.Change change = changes.get(i);
            final RunningTaskInfo task = change.getTaskInfo();
            if (task != null && task.isFocused && change.hasFlags(FLAG_MOVED_TO_TOP)) {
                if (mFocusedDisplayId != task.displayId) {
                    mFocusedDisplayId = task.displayId;
            if (change.hasFlags(FLAG_IS_DISPLAY) && change.hasFlags(FLAG_MOVED_TO_TOP)) {
                if (mFocusedDisplayId != change.getEndDisplayId()) {
                    mFocusedDisplayId = change.getEndDisplayId();
                    notifyFocusedDisplayChanged();
                }
                return;
+20 −24
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.wm.shell.transition;

import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -97,50 +97,38 @@ public class FocusTransitionObserverTest extends ShellTestCase {
    }

    @Test
    public void testTransitionWithMovedToFrontFlagChangesDisplayFocus() throws RemoteException {
    public void testOnlyDisplayChangeAffectsDisplayFocus() throws RemoteException {
        final IBinder binder = mock(IBinder.class);
        final SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class);

        // Open a task on the default display, which doesn't change display focus because the
        // default display already has it.
        // Open a task on the secondary display, but it doesn't change display focus because it only
        // has a task change.
        TransitionInfo info = mock(TransitionInfo.class);
        final List<TransitionInfo.Change> changes = new ArrayList<>();
        setupChange(changes, 123 /* taskId */, TRANSIT_OPEN, DEFAULT_DISPLAY,
        setupTaskChange(changes, 123 /* taskId */, TRANSIT_OPEN, SECONDARY_DISPLAY_ID,
                true /* focused */);
        when(info.getChanges()).thenReturn(changes);
        mFocusTransitionObserver.onTransitionReady(binder, info, tx, tx);
        verify(mListener, never()).onFocusedDisplayChanged(SECONDARY_DISPLAY_ID);
        clearInvocations(mListener);

        // Open a new task on the secondary display and verify display focus changes to the display.
        // Moving the secondary display to front must change display focus to it.
        changes.clear();
        setupChange(changes, 456 /* taskId */, TRANSIT_OPEN, SECONDARY_DISPLAY_ID,
                true /* focused */);
        setupDisplayToTopChange(changes, SECONDARY_DISPLAY_ID);
        when(info.getChanges()).thenReturn(changes);
        mFocusTransitionObserver.onTransitionReady(binder, info, tx, tx);
        verify(mListener, times(1)).onFocusedDisplayChanged(SECONDARY_DISPLAY_ID);
        clearInvocations(mListener);
        verify(mListener, times(1))
                .onFocusedDisplayChanged(SECONDARY_DISPLAY_ID);

        // Open the first task to front and verify display focus goes back to the default display.
        // Moving the secondary display to front must change display focus back to it.
        changes.clear();
        setupChange(changes, 123 /* taskId */, TRANSIT_TO_FRONT, DEFAULT_DISPLAY,
                true /* focused */);
        setupDisplayToTopChange(changes, DEFAULT_DISPLAY);
        when(info.getChanges()).thenReturn(changes);
        mFocusTransitionObserver.onTransitionReady(binder, info, tx, tx);
        verify(mListener, times(1)).onFocusedDisplayChanged(DEFAULT_DISPLAY);
        clearInvocations(mListener);

        // Open another task on the default display and verify no display focus switch as it's
        // already on the default display.
        changes.clear();
        setupChange(changes, 789 /* taskId */, TRANSIT_OPEN, DEFAULT_DISPLAY,
                true /* focused */);
        when(info.getChanges()).thenReturn(changes);
        mFocusTransitionObserver.onTransitionReady(binder, info, tx, tx);
        verify(mListener, never()).onFocusedDisplayChanged(DEFAULT_DISPLAY);
    }

    private void setupChange(List<TransitionInfo.Change> changes, int taskId,
    private void setupTaskChange(List<TransitionInfo.Change> changes, int taskId,
            @TransitionMode int mode, int displayId, boolean focused) {
        TransitionInfo.Change change = mock(TransitionInfo.Change.class);
        RunningTaskInfo taskInfo = mock(RunningTaskInfo.class);
@@ -152,4 +140,12 @@ public class FocusTransitionObserverTest extends ShellTestCase {
        when(change.getMode()).thenReturn(mode);
        changes.add(change);
    }

    private void setupDisplayToTopChange(List<TransitionInfo.Change> changes, int displayId) {
        TransitionInfo.Change change = mock(TransitionInfo.Change.class);
        when(change.hasFlags(FLAG_MOVED_TO_TOP)).thenReturn(true);
        when(change.hasFlags(FLAG_IS_DISPLAY)).thenReturn(true);
        when(change.getEndDisplayId()).thenReturn(displayId);
        changes.add(change);
    }
}
+19 −17
Original line number Diff line number Diff line
@@ -2188,30 +2188,32 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
            for (int i = onTopTasksEnd.size() - 1; i >= 0; --i) {
                final Task task = onTopTasksEnd.get(i);
                if (task.getDisplayId() != displayId) continue;
                if (!enableDisplayFocusInShellTransitions()
                        || mOnTopDisplayStart == onTopDisplayEnd
                        || displayId != onTopDisplayEnd.mDisplayId) {
                    // If it didn't change since last report, don't report
                if (reportedOnTop == null) {
                    if (mOnTopTasksStart.contains(task)) continue;
                } else if (reportedOnTop.contains(task)) {
                    continue;
                }
                }
                // Need to report it.
                mParticipants.add(task);
                int changeIdx = mChanges.indexOfKey(task);
                if (changeIdx < 0) {
                    mChanges.put(task, new ChangeInfo(task));
                    changeIdx = mChanges.indexOfKey(task);
                }
                mChanges.valueAt(changeIdx).mFlags |= ChangeInfo.FLAG_CHANGE_MOVED_TO_TOP;
                addToTopChange(task);
            }
            // Swap in the latest on-top tasks.
            mController.mLatestOnTopTasksReported.put(displayId, onTopTasksEnd);
            onTopTasksEnd = reportedOnTop != null ? reportedOnTop : new ArrayList<>();
            onTopTasksEnd.clear();

            if (enableDisplayFocusInShellTransitions()
                    && mOnTopDisplayStart != onTopDisplayEnd
                    && displayId == onTopDisplayEnd.mDisplayId) {
                addToTopChange(onTopDisplayEnd);
            }
        }
    }

    private void addToTopChange(@NonNull WindowContainer wc) {
        mParticipants.add(wc);
        if (!mChanges.containsKey(wc)) {
            mChanges.put(wc, new ChangeInfo(wc));
        }
        mChanges.get(wc).mFlags |= ChangeInfo.FLAG_CHANGE_MOVED_TO_TOP;
    }

    private void postCleanupOnFailure() {