Loading libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md +4 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ Specifically, to support calling into a controller from an external process (lik - Inject `ShellController` and add the instance of the implementation as external interface - In Launcher, update `TouchInteractionService` to pass the interface to `SystemUIProxy`, and then call the SystemUIProxy method as needed in that code - If Launcher needs to register a listener for callbacks, the recommendation is to have a single registered listener, and to internally track and dispatch callbacks through that listener in `SystemUIProxy`. This reduces binder overhead (1 call vs many), and simplifies the re-registration path if SysUI ever restarts (register the tracker vs individual listeners) ### Component initialization To initialize the component: Loading libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md +24 −2 Original line number Diff line number Diff line Loading @@ -55,12 +55,11 @@ For example, you might have: Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently necessary to maintain proper threading and logic isolation. ## Listening for Configuration changes & other SysUI events ## Listening for SysUI events Aside from direct calls into Shell controllers for exposed features, the Shell also receives common event callbacks from SysUI via the `ShellController`. This includes things like: - Configuration changes - Keyguard events - Shell init - Shell dumps & commands Loading @@ -69,6 +68,29 @@ For other events which are specific to the Shell feature, then you can add callb the Shell feature interface. Any such calls should <u>**never**</u> be synchronous calls as they will need to post to the Shell main thread to run. ## Listening for configuration changes It is recommended for Shell features to listen for configuration changes as close to the part of the hierarchy that they care about, ie. - Normal windows - UI within a normal window should respond to configuration changes via callbacks from the view system and not via other callbacks, this ensures that resources and other dependent components are updated prior to your handling of the change - Tasks - There are specific changes to tasks that currently come through `ShellTaskOrganizer` in the form of `TaskInfo` changes, if your feature is relevant only for a specific task (ie. caption, overlay, etc), you can use that configuration. Task info changes are not guaranteed to be synchronized with transitions or other configuration change callbacks (ie. display changes can result in both display callbacks & task info changes in different orders) - Displays, Display areas, Windowless windows - Even if your logic is not tied to a specific window or task, it likely manages these components within a display. To get notified for display configuration changes, you can register a listener via `DisplayController#addDisplayWindowListener()` - Application -- Shell features should never need to use the application configuration as it will be wrong when there are multiple displays - Windowless windows - These do not receive configuration changes from WM, so the owner of these windows are responsible for updating its configuration directly. This will usually be the configuration of the container that it is associated with (ie. Task or Display/DisplayArea) ## Shell commands & Dumps Since the Shell library is a part of the SysUI process, it relies on SysUI to trigger commands Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +7 −4 Original line number Diff line number Diff line Loading @@ -204,6 +204,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, public IBinder startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options, @Nullable WindowContainerTransaction wct, IApplicationThread appThread, IRecentsAnimationRunner listener) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "startRecentsTransition"); // only care about latest one. mAnimApp = appThread; Loading Loading @@ -250,7 +253,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, private IBinder startSyntheticRecentsTransition(@NonNull IRecentsAnimationRunner listener, int displayId) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsTransitionHandler.startRecentsTransition(synthetic)"); "RecentsTransitionHandler.startSyntheticRecentsTransition"); // Create a new synthetic transition and start it immediately final RecentsController controller = new RecentsController(listener, displayId); Loading @@ -266,7 +269,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, @Nullable WindowContainerTransaction requestWct, IRecentsAnimationRunner listener, int displayId) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsTransitionHandler.startRecentsTransition, displayId=%d", displayId); "RecentsTransitionHandler.startRealRecentsTransition(): displayId=%d", displayId); final WindowContainerTransaction wct = requestWct != null ? requestWct : new WindowContainerTransaction(); Loading Loading @@ -518,8 +521,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.cancel: toHome=%b reason=%s", mInstanceId, toHome, reason); "[%d] RecentsController.cancel: toHome=%b withScreenshots=%b reason=%s", mInstanceId, toHome, withScreenshots, reason); if (mListener != null) { if (withScreenshots) { sendCancelWithSnapshots(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java +12 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener; import com.android.wm.shell.common.ExternalInterfaceBinder; Loading Loading @@ -174,7 +175,13 @@ public class ShellController { /** * Adds a new configuration listener. The configuration change callbacks are not made in any * particular order. * * Note: This callback only propagates the application configuration from SysUI which will be * incomplete for multi-display scenarios. To cover both single and multi-display scenarios, * you should use {@link DisplayController#addDisplayChangingController()} to register for * callbacks for your display. */ @Deprecated public void addConfigurationChangeListener(ConfigurationChangeListener listener) { mConfigChangeListeners.remove(listener); mConfigChangeListeners.add(listener); Loading @@ -182,14 +189,17 @@ public class ShellController { /** * Removes an existing configuration listener. * * Note: Callers use {@link DisplayController#add/removeDisplayChangingController()} */ @Deprecated public void removeConfigurationChangeListener(ConfigurationChangeListener listener) { mConfigChangeListeners.remove(listener); } /** * Adds a new Keyguard listener. The Keyguard change callbacks are not made in any * particular order. * particular order, and are not synchronized with transitions. */ public void addKeyguardChangeListener(KeyguardChangeListener listener) { mKeyguardChangeListeners.remove(listener); Loading @@ -205,7 +215,7 @@ public class ShellController { /** * Adds a new user-change listener. The user change callbacks are not made in any * particular order. * particular order, and are not synchronized with transitions. */ public void addUserChangeListener(UserChangeListener listener) { mUserChangeListeners.remove(listener); Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java +7 −3 Original line number Diff line number Diff line Loading @@ -157,6 +157,9 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Received remote transition finished callback for (#%d)", info.getDebugId()); unhandleDeath(remote.asBinder(), finishCallback); if (sct != null) { finishTransaction.merge(sct); Loading Loading @@ -223,16 +226,17 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { final RemoteTransition remoteTransition = mRequestedRemotes.get(mergeTarget); if (remoteTransition == null) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Merge into remote: %s", remoteTransition); final IRemoteTransition remote = remoteTransition.getRemoteTransition(); if (remote == null) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Requesting merge (#%d) into remote: %s", info.getDebugId(), remoteTransition); IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Merged (#%d) into remote", info.getDebugId()); // We have merged, since we sent the transaction over binder, the one in this // process won't be cleared if the remote applied it. We don't actually know if the // remote applied the transaction, but applying twice will break surfaceflinger Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md +4 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ Specifically, to support calling into a controller from an external process (lik - Inject `ShellController` and add the instance of the implementation as external interface - In Launcher, update `TouchInteractionService` to pass the interface to `SystemUIProxy`, and then call the SystemUIProxy method as needed in that code - If Launcher needs to register a listener for callbacks, the recommendation is to have a single registered listener, and to internally track and dispatch callbacks through that listener in `SystemUIProxy`. This reduces binder overhead (1 call vs many), and simplifies the re-registration path if SysUI ever restarts (register the tracker vs individual listeners) ### Component initialization To initialize the component: Loading
libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md +24 −2 Original line number Diff line number Diff line Loading @@ -55,12 +55,11 @@ For example, you might have: Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently necessary to maintain proper threading and logic isolation. ## Listening for Configuration changes & other SysUI events ## Listening for SysUI events Aside from direct calls into Shell controllers for exposed features, the Shell also receives common event callbacks from SysUI via the `ShellController`. This includes things like: - Configuration changes - Keyguard events - Shell init - Shell dumps & commands Loading @@ -69,6 +68,29 @@ For other events which are specific to the Shell feature, then you can add callb the Shell feature interface. Any such calls should <u>**never**</u> be synchronous calls as they will need to post to the Shell main thread to run. ## Listening for configuration changes It is recommended for Shell features to listen for configuration changes as close to the part of the hierarchy that they care about, ie. - Normal windows - UI within a normal window should respond to configuration changes via callbacks from the view system and not via other callbacks, this ensures that resources and other dependent components are updated prior to your handling of the change - Tasks - There are specific changes to tasks that currently come through `ShellTaskOrganizer` in the form of `TaskInfo` changes, if your feature is relevant only for a specific task (ie. caption, overlay, etc), you can use that configuration. Task info changes are not guaranteed to be synchronized with transitions or other configuration change callbacks (ie. display changes can result in both display callbacks & task info changes in different orders) - Displays, Display areas, Windowless windows - Even if your logic is not tied to a specific window or task, it likely manages these components within a display. To get notified for display configuration changes, you can register a listener via `DisplayController#addDisplayWindowListener()` - Application -- Shell features should never need to use the application configuration as it will be wrong when there are multiple displays - Windowless windows - These do not receive configuration changes from WM, so the owner of these windows are responsible for updating its configuration directly. This will usually be the configuration of the container that it is associated with (ie. Task or Display/DisplayArea) ## Shell commands & Dumps Since the Shell library is a part of the SysUI process, it relies on SysUI to trigger commands Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +7 −4 Original line number Diff line number Diff line Loading @@ -204,6 +204,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, public IBinder startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options, @Nullable WindowContainerTransaction wct, IApplicationThread appThread, IRecentsAnimationRunner listener) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "startRecentsTransition"); // only care about latest one. mAnimApp = appThread; Loading Loading @@ -250,7 +253,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, private IBinder startSyntheticRecentsTransition(@NonNull IRecentsAnimationRunner listener, int displayId) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsTransitionHandler.startRecentsTransition(synthetic)"); "RecentsTransitionHandler.startSyntheticRecentsTransition"); // Create a new synthetic transition and start it immediately final RecentsController controller = new RecentsController(listener, displayId); Loading @@ -266,7 +269,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, @Nullable WindowContainerTransaction requestWct, IRecentsAnimationRunner listener, int displayId) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsTransitionHandler.startRecentsTransition, displayId=%d", displayId); "RecentsTransitionHandler.startRealRecentsTransition(): displayId=%d", displayId); final WindowContainerTransaction wct = requestWct != null ? requestWct : new WindowContainerTransaction(); Loading Loading @@ -518,8 +521,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.cancel: toHome=%b reason=%s", mInstanceId, toHome, reason); "[%d] RecentsController.cancel: toHome=%b withScreenshots=%b reason=%s", mInstanceId, toHome, withScreenshots, reason); if (mListener != null) { if (withScreenshots) { sendCancelWithSnapshots(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java +12 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener; import com.android.wm.shell.common.ExternalInterfaceBinder; Loading Loading @@ -174,7 +175,13 @@ public class ShellController { /** * Adds a new configuration listener. The configuration change callbacks are not made in any * particular order. * * Note: This callback only propagates the application configuration from SysUI which will be * incomplete for multi-display scenarios. To cover both single and multi-display scenarios, * you should use {@link DisplayController#addDisplayChangingController()} to register for * callbacks for your display. */ @Deprecated public void addConfigurationChangeListener(ConfigurationChangeListener listener) { mConfigChangeListeners.remove(listener); mConfigChangeListeners.add(listener); Loading @@ -182,14 +189,17 @@ public class ShellController { /** * Removes an existing configuration listener. * * Note: Callers use {@link DisplayController#add/removeDisplayChangingController()} */ @Deprecated public void removeConfigurationChangeListener(ConfigurationChangeListener listener) { mConfigChangeListeners.remove(listener); } /** * Adds a new Keyguard listener. The Keyguard change callbacks are not made in any * particular order. * particular order, and are not synchronized with transitions. */ public void addKeyguardChangeListener(KeyguardChangeListener listener) { mKeyguardChangeListeners.remove(listener); Loading @@ -205,7 +215,7 @@ public class ShellController { /** * Adds a new user-change listener. The user change callbacks are not made in any * particular order. * particular order, and are not synchronized with transitions. */ public void addUserChangeListener(UserChangeListener listener) { mUserChangeListeners.remove(listener); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java +7 −3 Original line number Diff line number Diff line Loading @@ -157,6 +157,9 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Received remote transition finished callback for (#%d)", info.getDebugId()); unhandleDeath(remote.asBinder(), finishCallback); if (sct != null) { finishTransaction.merge(sct); Loading Loading @@ -223,16 +226,17 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { final RemoteTransition remoteTransition = mRequestedRemotes.get(mergeTarget); if (remoteTransition == null) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Merge into remote: %s", remoteTransition); final IRemoteTransition remote = remoteTransition.getRemoteTransition(); if (remote == null) return; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Requesting merge (#%d) into remote: %s", info.getDebugId(), remoteTransition); IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() { @Override public void onTransitionFinished(WindowContainerTransaction wct, SurfaceControl.Transaction sct) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Merged (#%d) into remote", info.getDebugId()); // We have merged, since we sent the transaction over binder, the one in this // process won't be cleared if the remote applied it. We don't actually know if the // remote applied the transaction, but applying twice will break surfaceflinger Loading