diff options
3 files changed, 43 insertions, 46 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java index 2f5059f3161c..399e39a920fc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java @@ -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; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java index d37b4cf4b4b3..d63158c29688 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java @@ -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); + } } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index c48590fba00d..fde502f2306c 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -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); + if (reportedOnTop == null) { + if (mOnTopTasksStart.contains(task)) continue; + } else if (reportedOnTop.contains(task)) { + continue; } - 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() { |