From 61b22f90baf517b785cbca777f0eb3e5d60fdd4e Mon Sep 17 00:00:00 2001 From: Kazuki Takise Date: Fri, 27 Sep 2024 19:14:52 +0900 Subject: [PATCH] Listen to display focus state in Launcher As part of the Connected Display project, some UI features in Launcher such as Alt-Tab need to be shown only on the focused display. This change adds FocusState, which registers to WMShell, and provides a listener to other components in Launcher so they can easily consume the display focus state (following the same pattern of HomeVisibilityState). Bug: 356109871 Flag: com.android.window.flags.enable_display_focus_in_shell_transitions Test: Switching focus between displays and confirm signals are sent to Launcher. Change-Id: I51d51ac0ce3e24afa363607cdfb41728748a4a5f --- .../src/com/android/quickstep/FocusState.kt | 63 +++++++++++++++++++ .../com/android/quickstep/SystemUiProxy.java | 7 +++ 2 files changed, 70 insertions(+) create mode 100644 quickstep/src/com/android/quickstep/FocusState.kt diff --git a/quickstep/src/com/android/quickstep/FocusState.kt b/quickstep/src/com/android/quickstep/FocusState.kt new file mode 100644 index 0000000000..ba3991fdff --- /dev/null +++ b/quickstep/src/com/android/quickstep/FocusState.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep + +import android.os.RemoteException +import android.util.Log +import android.view.Display.DEFAULT_DISPLAY +import com.android.launcher3.util.Executors +import com.android.wm.shell.shared.IFocusTransitionListener.Stub +import com.android.wm.shell.shared.IShellTransitions + +/** Class to track focus state of displays and windows */ +class FocusState { + + var focusedDisplayId = DEFAULT_DISPLAY + private set + + private var listeners = mutableSetOf() + + fun addListener(l: FocusChangeListener) = listeners.add(l) + + fun removeListener(l: FocusChangeListener) = listeners.remove(l) + + fun init(transitions: IShellTransitions?) { + try { + transitions?.setFocusTransitionListener( + object : Stub() { + override fun onFocusedDisplayChanged(displayId: Int) { + Executors.MAIN_EXECUTOR.execute { + listeners.forEach { it.onFocusedDisplayChanged(displayId) } + } + } + } + ) + } catch (e: RemoteException) { + Log.w(TAG, "Failed call setFocusTransitionListener", e) + } + } + + interface FocusChangeListener { + fun onFocusedDisplayChanged(displayId: Int) + } + + override fun toString() = "{FocusState focusedDisplayId=$focusedDisplayId}" + + companion object { + private const val TAG = "FocusState" + } +} diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 34435d52c1..a55cf186ea 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -161,6 +161,7 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { private IRemoteAnimationRunner mBackToLauncherRunner; private IDragAndDrop mDragAndDrop; private final HomeVisibilityState mHomeVisibilityState = new HomeVisibilityState(); + private final FocusState mFocusState = new FocusState(); // Used to dedupe calls to SystemUI private int mLastShelfHeight; @@ -300,6 +301,7 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { registerSplitScreenListener(mSplitScreenListener); registerSplitSelectListener(mSplitSelectListener); mHomeVisibilityState.init(mShellTransitions); + mFocusState.init(mShellTransitions); setStartingWindowListener(mStartingWindowListener); setLauncherUnlockAnimationController( mLauncherActivityClass, mLauncherUnlockAnimationController); @@ -1144,6 +1146,10 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { return mHomeVisibilityState; } + public FocusState getFocusState() { + return mFocusState; + } + /** * Returns a surface which can be used to attach overlays to home task or null if * the task doesn't exist or sysui is not connected @@ -1592,6 +1598,7 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { pw.println("\tmOneHanded=" + mOneHanded); pw.println("\tmShellTransitions=" + mShellTransitions); pw.println("\tmHomeVisibilityState=" + mHomeVisibilityState); + pw.println("\tmFocusState=" + mFocusState); pw.println("\tmStartingWindow=" + mStartingWindow); pw.println("\tmStartingWindowListener=" + mStartingWindowListener); pw.println("\tmSysuiUnlockAnimationController=" + mSysuiUnlockAnimationController);