Migrate TaskInfo#isFocused to FocusTransitionObserver for windecor
Confusingly, TaskInfo#isFocused represents per-display focus, not
system-wide focus, which means TaskInfo#isFocused can be true for
multiple apps in multi-monitor environments. This leads to
problems such as:
- Multiple windows are highlighted as focused window.
- Clicking the window decor doesn't bring apps to front in some
cases.
This change fixes these issues by migrating it to
FocusTransitionObserver, which is the only proper way to get
system-wide (global) focus info in WMShell.
- *WindowDecorViewModel are the only places in windowdecor/ that
get system-wide focus changes directly from
FocusTransitionObserver. There are two channels for this:
- FocusTransitionListener#onFocusedTaskChanged(): This is used
for relayouting window decor when only global focus has
changed. The existing APIs such as FreeformTaskTransitionObserver
and FullscreenTaskListener don't notify these changes.
- In the callbacks of FocusTransitionListener and
FreeformTaskTransitionObserver,
FocusTransitionObserver#hasGlobalFocus() is available.
It's guaranteed by [1] and [2] that FocusTransitionObserver
processes a transition earlier than FreeformTaskTransitionObserver.
For FullscreenTaskListener, there's no way to guarantee the order
between *TaskListener and TransitionObserver, so this may lead
to calling relayout() twice in some cases, but at least the
final state is always correct, and we can prevent the second
one by returning early.
- Once *WindowDecoreViewModel receives an update on global focus,
it passes the value to *WindowDecoration via the relayout*() and
update*() functions. Unfortunately it's not allowed to add global
focus to RunningTaskInfo to prevent global focus to be accessed
without synchronization in mind, so this change ends up adding
a parameter for global focus to those functions. This should be
better than calling hasGlobalFocus() in many places to make it
explicit that only *WindowDecorViewModel receives updates and they
are propagated through relayout().
Note that this should be able to be written in a cleaner way once
the unified task repository for WMShell gets ready.
[1] If3ab6dd7a68641cdf797516c8244eaa4bbb1f7ca
[2] I68b6aaa44cf8578d3dcac3277c66e3d07738eef8
Bug: 371095009
Bug: 368200134
Bug: 369227512
Flag: com.android.window.flags.enable_display_focus_in_shell_transitions
Test: atest WMShellUnitTests
Change-Id: Ib51e1cca017bc0c426c7277f8245dcfdb8703620
15 files changed