diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java index 2f2168f535538..aa82339a436a8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java @@ -16,113 +16,32 @@ package com.android.wm.shell; +import android.util.Slog; + import com.android.wm.shell.apppairs.AppPairs; -import com.android.wm.shell.common.annotations.ExternalThread; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout; +import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.pip.Pip; -import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import java.io.PrintWriter; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** * An entry point into the shell for dumping shell internal state and running adb commands. * * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}. */ -public final class ShellCommandHandler { +public interface ShellCommandHandler { + /** + * Dumps the shell state. + */ + void dump(PrintWriter pw); - private final Optional mLegacySplitScreenOptional; - private final Optional mPipOptional; - private final Optional mOneHandedOptional; - private final Optional mHideDisplayCutout; - private final ShellTaskOrganizer mShellTaskOrganizer; - private final Optional mAppPairsOptional; - - public ShellCommandHandler( - ShellTaskOrganizer shellTaskOrganizer, - Optional legacySplitScreenOptional, - Optional pipOptional, - Optional oneHandedOptional, - Optional hideDisplayCutout, - Optional appPairsOptional) { - mShellTaskOrganizer = shellTaskOrganizer; - mLegacySplitScreenOptional = legacySplitScreenOptional; - mPipOptional = pipOptional; - mOneHandedOptional = oneHandedOptional; - mHideDisplayCutout = hideDisplayCutout; - mAppPairsOptional = appPairsOptional; - } - - /** Dumps WM Shell internal state. */ - @ExternalThread - public void dump(PrintWriter pw) { - mShellTaskOrganizer.dump(pw, ""); - pw.println(); - pw.println(); - mPipOptional.ifPresent(pip -> pip.dump(pw)); - mLegacySplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw)); - mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw)); - mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw)); - pw.println(); - pw.println(); - mAppPairsOptional.ifPresent(appPairs -> appPairs.dump(pw, "")); - } - - - /** Returns {@code true} if command was found and executed. */ - @ExternalThread - public boolean handleCommand(String[] args, PrintWriter pw) { - if (args.length < 2) { - // Argument at position 0 is "WMShell". - return false; - } - switch (args[1]) { - case "pair": - return runPair(args, pw); - case "unpair": - return runUnpair(args, pw); - case "help": - return runHelp(pw); - default: - return false; - } - } - - - private boolean runPair(String[] args, PrintWriter pw) { - if (args.length < 4) { - // First two arguments are "WMShell" and command name. - pw.println("Error: two task ids should be provided as arguments"); - return false; - } - final int taskId1 = new Integer(args[2]); - final int taskId2 = new Integer(args[3]); - mAppPairsOptional.ifPresent(appPairs -> appPairs.pair(taskId1, taskId2)); - return true; - } - - private boolean runUnpair(String[] args, PrintWriter pw) { - if (args.length < 3) { - // First two arguments are "WMShell" and command name. - pw.println("Error: task id should be provided as an argument"); - return false; - } - final int taskId = new Integer(args[2]); - mAppPairsOptional.ifPresent(appPairs -> appPairs.unpair(taskId)); - return true; - } - - private boolean runHelp(PrintWriter pw) { - pw.println("Window Manager Shell commands:"); - pw.println(" help"); - pw.println(" Print this help text."); - pw.println(" "); - pw.println(" Dump Window Manager Shell internal state"); - pw.println(" pair "); - pw.println(" unpair "); - pw.println(" Pairs/unpairs tasks with given ids."); - return true; - } + /** + * Handles a shell command. + */ + boolean handleCommand(final String[] args, PrintWriter pw); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java new file mode 100644 index 0000000000000..f213af752d55a --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2019 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.wm.shell; + +import android.util.Slog; + +import com.android.wm.shell.apppairs.AppPairs; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout; +import com.android.wm.shell.onehanded.OneHanded; +import com.android.wm.shell.pip.Pip; +import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; + +import java.io.PrintWriter; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * An entry point into the shell for dumping shell internal state and running adb commands. + * + * Use with {@code adb shell dumpsys activity service SystemUIService WMShell ...}. + */ +public final class ShellCommandHandlerImpl { + private static final String TAG = ShellCommandHandlerImpl.class.getSimpleName(); + + private final Optional mLegacySplitScreenOptional; + private final Optional mPipOptional; + private final Optional mOneHandedOptional; + private final Optional mHideDisplayCutout; + private final ShellTaskOrganizer mShellTaskOrganizer; + private final Optional mAppPairsOptional; + private final ShellExecutor mMainExecutor; + private final HandlerImpl mImpl = new HandlerImpl(); + + public static ShellCommandHandler create( + ShellTaskOrganizer shellTaskOrganizer, + Optional legacySplitScreenOptional, + Optional pipOptional, + Optional oneHandedOptional, + Optional hideDisplayCutout, + Optional appPairsOptional, + ShellExecutor mainExecutor) { + return new ShellCommandHandlerImpl(shellTaskOrganizer, legacySplitScreenOptional, + pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional, + mainExecutor).mImpl; + } + + private ShellCommandHandlerImpl( + ShellTaskOrganizer shellTaskOrganizer, + Optional legacySplitScreenOptional, + Optional pipOptional, + Optional oneHandedOptional, + Optional hideDisplayCutout, + Optional appPairsOptional, + ShellExecutor mainExecutor) { + mShellTaskOrganizer = shellTaskOrganizer; + mLegacySplitScreenOptional = legacySplitScreenOptional; + mPipOptional = pipOptional; + mOneHandedOptional = oneHandedOptional; + mHideDisplayCutout = hideDisplayCutout; + mAppPairsOptional = appPairsOptional; + mMainExecutor = mainExecutor; + } + + /** Dumps WM Shell internal state. */ + private void dump(PrintWriter pw) { + mShellTaskOrganizer.dump(pw, ""); + pw.println(); + pw.println(); + mPipOptional.ifPresent(pip -> pip.dump(pw)); + mLegacySplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw)); + mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw)); + mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw)); + pw.println(); + pw.println(); + mAppPairsOptional.ifPresent(appPairs -> appPairs.dump(pw, "")); + } + + + /** Returns {@code true} if command was found and executed. */ + private boolean handleCommand(final String[] args, PrintWriter pw) { + if (args.length < 2) { + // Argument at position 0 is "WMShell". + return false; + } + switch (args[1]) { + case "pair": + return runPair(args, pw); + case "unpair": + return runUnpair(args, pw); + case "help": + return runHelp(pw); + default: + return false; + } + } + + + private boolean runPair(String[] args, PrintWriter pw) { + if (args.length < 4) { + // First two arguments are "WMShell" and command name. + pw.println("Error: two task ids should be provided as arguments"); + return false; + } + final int taskId1 = new Integer(args[2]); + final int taskId2 = new Integer(args[3]); + mAppPairsOptional.ifPresent(appPairs -> appPairs.pair(taskId1, taskId2)); + return true; + } + + private boolean runUnpair(String[] args, PrintWriter pw) { + if (args.length < 3) { + // First two arguments are "WMShell" and command name. + pw.println("Error: task id should be provided as an argument"); + return false; + } + final int taskId = new Integer(args[2]); + mAppPairsOptional.ifPresent(appPairs -> appPairs.unpair(taskId)); + return true; + } + + private boolean runHelp(PrintWriter pw) { + pw.println("Window Manager Shell commands:"); + pw.println(" help"); + pw.println(" Print this help text."); + pw.println(" "); + pw.println(" Dump Window Manager Shell internal state"); + pw.println(" pair "); + pw.println(" unpair "); + pw.println(" Pairs/unpairs tasks with given ids."); + return true; + } + + private class HandlerImpl implements ShellCommandHandler { + @Override + public void dump(PrintWriter pw) { + try { + mMainExecutor.executeBlocking(() -> ShellCommandHandlerImpl.this.dump(pw)); + } catch (InterruptedException e) { + throw new RuntimeException("Failed to dump the Shell in 2s", e); + } + } + + @Override + public boolean handleCommand(String[] args, PrintWriter pw) { + try { + boolean[] result = new boolean[1]; + mMainExecutor.executeBlocking(() -> { + result[0] = ShellCommandHandlerImpl.this.handleCommand(args, pw); + }); + return result[0]; + } catch (InterruptedException e) { + throw new RuntimeException("Failed to handle Shell command in 2s", e); + } + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java index f4c617e601fc0..d7010b1747444 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java @@ -16,61 +16,15 @@ package com.android.wm.shell; -import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; - -import com.android.wm.shell.apppairs.AppPairs; -import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.annotations.ExternalThread; -import com.android.wm.shell.draganddrop.DragAndDropController; -import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; - -import java.util.Optional; /** * An entry point into the shell for initializing shell internal state. */ -public class ShellInit { - - private final DisplayImeController mDisplayImeController; - private final DragAndDropController mDragAndDropController; - private final ShellTaskOrganizer mShellTaskOrganizer; - private final Optional mLegacySplitScreenOptional; - private final Optional mAppPairsOptional; - private final FullscreenTaskListener mFullscreenTaskListener; - private final Transitions mTransitions; - - public ShellInit(DisplayImeController displayImeController, - DragAndDropController dragAndDropController, - ShellTaskOrganizer shellTaskOrganizer, - Optional legacySplitScreenOptional, - Optional appPairsOptional, - FullscreenTaskListener fullscreenTaskListener, - Transitions transitions) { - mDisplayImeController = displayImeController; - mDragAndDropController = dragAndDropController; - mShellTaskOrganizer = shellTaskOrganizer; - mLegacySplitScreenOptional = legacySplitScreenOptional; - mAppPairsOptional = appPairsOptional; - mFullscreenTaskListener = fullscreenTaskListener; - mTransitions = transitions; - } - - @ExternalThread - public void init() { - // Start listening for display changes - mDisplayImeController.startMonitorDisplays(); - - mShellTaskOrganizer.addListenerForType( - mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN); - // Register the shell organizer - mShellTaskOrganizer.registerOrganizer(); - - mAppPairsOptional.ifPresent(AppPairs::onOrganizerRegistered); - // Bind the splitscreen impl to the drag drop controller - mDragAndDropController.setSplitScreenController(mLegacySplitScreenOptional); - - if (Transitions.ENABLE_SHELL_TRANSITIONS) { - mTransitions.register(mShellTaskOrganizer); - } - } +@ExternalThread +public interface ShellInit { + /** + * Initializes the shell state. + */ + void init(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java new file mode 100644 index 0000000000000..00567618ef06d --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2019 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.wm.shell; + +import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN; + +import com.android.wm.shell.apppairs.AppPairs; +import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.annotations.ExternalThread; +import com.android.wm.shell.draganddrop.DragAndDropController; +import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * The entry point implementation into the shell for initializing shell internal state. + */ +public class ShellInitImpl { + private static final String TAG = ShellInitImpl.class.getSimpleName(); + + private final DisplayImeController mDisplayImeController; + private final DragAndDropController mDragAndDropController; + private final ShellTaskOrganizer mShellTaskOrganizer; + private final Optional mLegacySplitScreenOptional; + private final Optional mAppPairsOptional; + private final FullscreenTaskListener mFullscreenTaskListener; + private final ShellExecutor mMainExecutor; + + private final InitImpl mImpl = new InitImpl(); + + public static ShellInit create(DisplayImeController displayImeController, + DragAndDropController dragAndDropController, + ShellTaskOrganizer shellTaskOrganizer, + Optional legacySplitScreenOptional, + Optional appPairsOptional, + FullscreenTaskListener fullscreenTaskListener, + ShellExecutor mainExecutor) { + return new ShellInitImpl(displayImeController, + dragAndDropController, + shellTaskOrganizer, + legacySplitScreenOptional, + appPairsOptional, + fullscreenTaskListener, + mainExecutor).mImpl; + } + + private ShellInitImpl(DisplayImeController displayImeController, + DragAndDropController dragAndDropController, + ShellTaskOrganizer shellTaskOrganizer, + Optional legacySplitScreenOptional, + Optional appPairsOptional, + FullscreenTaskListener fullscreenTaskListener, + ShellExecutor mainExecutor) { + mDisplayImeController = displayImeController; + mDragAndDropController = dragAndDropController; + mShellTaskOrganizer = shellTaskOrganizer; + mLegacySplitScreenOptional = legacySplitScreenOptional; + mAppPairsOptional = appPairsOptional; + mFullscreenTaskListener = fullscreenTaskListener; + mMainExecutor = mainExecutor; + } + + private void init() { + // Start listening for display changes + mDisplayImeController.startMonitorDisplays(); + + mShellTaskOrganizer.addListenerForType( + mFullscreenTaskListener, TASK_LISTENER_TYPE_FULLSCREEN); + // Register the shell organizer + mShellTaskOrganizer.registerOrganizer(); + + mAppPairsOptional.ifPresent(AppPairs::onOrganizerRegistered); + + // Bind the splitscreen impl to the drag drop controller + mDragAndDropController.initialize(mLegacySplitScreenOptional); + } + + @ExternalThread + private class InitImpl implements ShellInit { + @Override + public void init() { + try { + mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init()); + } catch (InterruptedException e) { + throw new RuntimeException("Failed to initialize the Shell in 2s", e); + } + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java index 834de3f15b1da..abd92577c1d41 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java @@ -37,8 +37,8 @@ public class WindowManagerShellWrapper { */ private final PinnedStackListenerForwarder mPinnedStackListenerForwarder; - public WindowManagerShellWrapper(ShellExecutor shellMainExecutor) { - mPinnedStackListenerForwarder = new PinnedStackListenerForwarder(shellMainExecutor); + public WindowManagerShellWrapper(ShellExecutor mainExecutor) { + mPinnedStackListenerForwarder = new PinnedStackListenerForwarder(mainExecutor); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index 40b41e11c8aa4..9419b9c6d3444 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -45,7 +45,6 @@ import android.graphics.PixelFormat; import android.graphics.PointF; import android.os.Binder; import android.os.Bundle; -import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; @@ -68,6 +67,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PinnedStackListenerForwarder; import java.io.FileDescriptor; @@ -106,7 +106,6 @@ public class BubbleController implements Bubbles { private final FloatingContentCoordinator mFloatingContentCoordinator; private final BubbleDataRepository mDataRepository; private BubbleLogger mLogger; - private final Handler mMainHandler; private BubbleData mBubbleData; private View mBubbleScrim; @Nullable private BubbleStackView mStackView; @@ -138,7 +137,7 @@ public class BubbleController implements Bubbles { private WindowManager mWindowManager; // Used to post to main UI thread - private Handler mHandler = new Handler(); + private final ShellExecutor mMainExecutor; /** LayoutParams used to add the BubbleStackView to the window manager. */ private WindowManager.LayoutParams mWmLayoutParams; @@ -186,15 +185,15 @@ public class BubbleController implements Bubbles { WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps, UiEventLogger uiEventLogger, - Handler mainHandler, - ShellTaskOrganizer organizer) { + ShellTaskOrganizer organizer, + ShellExecutor mainExecutor) { BubbleLogger logger = new BubbleLogger(uiEventLogger); BubblePositioner positioner = new BubblePositioner(context, windowManager); BubbleData data = new BubbleData(context, logger, positioner); return new BubbleController(context, data, synchronizer, floatingContentCoordinator, new BubbleDataRepository(context, launcherApps), statusBarService, windowManager, windowManagerShellWrapper, launcherApps, - logger, mainHandler, organizer, positioner); + logger, organizer, positioner, mainExecutor); } /** @@ -211,14 +210,14 @@ public class BubbleController implements Bubbles { WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps, BubbleLogger bubbleLogger, - Handler mainHandler, ShellTaskOrganizer organizer, - BubblePositioner positioner) { + BubblePositioner positioner, + ShellExecutor mainExecutor) { mContext = context; mFloatingContentCoordinator = floatingContentCoordinator; mDataRepository = dataRepository; mLogger = bubbleLogger; - mMainHandler = mainHandler; + mMainExecutor = mainExecutor; mBubblePositioner = positioner; mBubbleData = data; @@ -241,7 +240,7 @@ public class BubbleController implements Bubbles { bubble.setPendingIntentCanceled(); return; } - mHandler.post(() -> removeBubble(bubble.getKey(), DISMISS_INVALID_INTENT)); + mMainExecutor.execute(() -> removeBubble(bubble.getKey(), DISMISS_INVALID_INTENT)); }); try { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java index cb4584c41184c..3a7b534f3c177 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java @@ -16,7 +16,6 @@ package com.android.wm.shell.common; -import android.os.Handler; import android.os.RemoteException; import android.view.IDisplayWindowRotationCallback; import android.view.IDisplayWindowRotationController; @@ -37,7 +36,7 @@ import java.util.ArrayList; */ public class DisplayChangeController { - private final Handler mHandler; + private final ShellExecutor mMainExecutor; private final IWindowManager mWmService; private final IDisplayWindowRotationController mControllerImpl; @@ -45,8 +44,8 @@ public class DisplayChangeController { new ArrayList<>(); private final ArrayList mTmpListeners = new ArrayList<>(); - public DisplayChangeController(Handler mainHandler, IWindowManager wmService) { - mHandler = mainHandler; + public DisplayChangeController(IWindowManager wmService, ShellExecutor mainExecutor) { + mMainExecutor = mainExecutor; mWmService = wmService; mControllerImpl = new DisplayWindowRotationControllerImpl(); try { @@ -97,7 +96,7 @@ public class DisplayChangeController { @Override public void onRotateDisplay(int displayId, final int fromRotation, final int toRotation, IDisplayWindowRotationCallback callback) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayChangeController.this.onRotateDisplay(displayId, fromRotation, toRotation, callback); }); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java index a413c052cb6c4..ba9ba5e5883ac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java @@ -20,7 +20,6 @@ import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.hardware.display.DisplayManager; -import android.os.Handler; import android.os.RemoteException; import android.util.Slog; import android.util.SparseArray; @@ -44,7 +43,7 @@ import java.util.ArrayList; public class DisplayController { private static final String TAG = "DisplayController"; - private final Handler mHandler; + private final ShellExecutor mMainExecutor; private final Context mContext; private final IWindowManager mWmService; private final DisplayChangeController mChangeController; @@ -61,12 +60,12 @@ public class DisplayController { return displayManager.getDisplay(displayId); } - public DisplayController(Context context, Handler handler, - IWindowManager wmService) { - mHandler = handler; + public DisplayController(Context context, IWindowManager wmService, + ShellExecutor mainExecutor) { + mMainExecutor = mainExecutor; mContext = context; mWmService = wmService; - mChangeController = new DisplayChangeController(mHandler, mWmService); + mChangeController = new DisplayChangeController(mWmService, mainExecutor); mDisplayContainerListener = new DisplayWindowListenerImpl(); try { mWmService.registerDisplayWindowListener(mDisplayContainerListener); @@ -229,35 +228,35 @@ public class DisplayController { private class DisplayWindowListenerImpl extends IDisplayWindowListener.Stub { @Override public void onDisplayAdded(int displayId) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayController.this.onDisplayAdded(displayId); }); } @Override public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayController.this.onDisplayConfigurationChanged(displayId, newConfig); }); } @Override public void onDisplayRemoved(int displayId) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayController.this.onDisplayRemoved(displayId); }); } @Override public void onFixedRotationStarted(int displayId, int newRotation) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayController.this.onFixedRotationStarted(displayId, newRotation); }); } @Override public void onFixedRotationFinished(int displayId) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { DisplayController.this.onFixedRotationFinished(displayId); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index 3fbd7ed0ec5d8..39441281f670a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -40,10 +40,12 @@ import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import androidx.annotation.BinderThread; +import androidx.annotation.VisibleForTesting; import com.android.internal.view.IInputMethodManager; import java.util.ArrayList; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -64,7 +66,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged private static final int FLOATING_IME_BOTTOM_INSET = -80; protected final IWindowManager mWmService; - protected final Executor mExecutor; + protected final Executor mMainExecutor; private final TransactionPool mTransactionPool; private final DisplayController mDisplayController; private final SparseArray mImePerDisplay = new SparseArray<>(); @@ -73,10 +75,10 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged public DisplayImeController(IWindowManager wmService, DisplayController displayController, Executor mainExecutor, TransactionPool transactionPool) { - mExecutor = mainExecutor; mWmService = wmService; - mTransactionPool = transactionPool; mDisplayController = displayController; + mMainExecutor = mainExecutor; + mTransactionPool = transactionPool; } /** Starts monitor displays changes and set insets controller for each displays. */ @@ -90,11 +92,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged // WM will defer IME inset handling to it in multi-window scenarious. PerDisplay pd = new PerDisplay(displayId, mDisplayController.getDisplayLayout(displayId).rotation()); - try { - mWmService.setDisplayWindowInsetsController(displayId, pd); - } catch (RemoteException e) { - Slog.w(TAG, "Unable to set insets controller on display " + displayId); - } + pd.register(); mImePerDisplay.put(displayId, pd); } @@ -182,9 +180,11 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } /** An implementation of {@link IDisplayWindowInsetsController} for a given display id. */ - public class PerDisplay extends IDisplayWindowInsetsController.Stub { + public class PerDisplay { final int mDisplayId; final InsetsState mInsetsState = new InsetsState(); + protected final DisplayWindowInsetsControllerImpl mInsetsControllerImpl = + new DisplayWindowInsetsControllerImpl(); InsetsSourceControl mImeSourceControl = null; int mAnimationDirection = DIRECTION_NONE; ValueAnimator mAnimation = null; @@ -198,10 +198,16 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged mRotation = initialRotation; } - @BinderThread - @Override - public void insetsChanged(InsetsState insetsState) { - mExecutor.execute(() -> { + public void register() { + try { + mWmService.setDisplayWindowInsetsController(mDisplayId, mInsetsControllerImpl); + } catch (RemoteException e) { + Slog.w(TAG, "Unable to set insets controller on display " + mDisplayId); + } + } + + protected void insetsChanged(InsetsState insetsState) { + mMainExecutor.execute(() -> { if (mInsetsState.equals(insetsState)) { return; } @@ -220,9 +226,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged }); } - @BinderThread - @Override - public void insetsControlChanged(InsetsState insetsState, + @VisibleForTesting + protected void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls) { insetsChanged(insetsState); if (activeControls != null) { @@ -231,7 +236,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged continue; } if (activeControl.getType() == InsetsState.ITYPE_IME) { - mExecutor.execute(() -> { + mMainExecutor.execute(() -> { final Point lastSurfacePosition = mImeSourceControl != null ? mImeSourceControl.getSurfacePosition() : null; final boolean positionChanged = @@ -271,30 +276,25 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } } - @BinderThread - @Override - public void showInsets(int types, boolean fromIme) { + protected void showInsets(int types, boolean fromIme) { if ((types & WindowInsets.Type.ime()) == 0) { return; } if (DEBUG) Slog.d(TAG, "Got showInsets for ime"); - mExecutor.execute(() -> startAnimation(true /* show */, false /* forceRestart */)); + mMainExecutor.execute(() -> startAnimation(true /* show */, false /* forceRestart */)); } - @BinderThread - @Override - public void hideInsets(int types, boolean fromIme) { + + protected void hideInsets(int types, boolean fromIme) { if ((types & WindowInsets.Type.ime()) == 0) { return; } if (DEBUG) Slog.d(TAG, "Got hideInsets for ime"); - mExecutor.execute(() -> startAnimation(false /* show */, false /* forceRestart */)); + mMainExecutor.execute(() -> startAnimation(false /* show */, false /* forceRestart */)); } - @BinderThread - @Override public void topFocusedWindowChanged(String packageName) { - // no-op + // Do nothing } /** @@ -457,6 +457,47 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged setVisibleDirectly(true /* visible */); } } + + @VisibleForTesting + @BinderThread + public class DisplayWindowInsetsControllerImpl + extends IDisplayWindowInsetsController.Stub { + @Override + public void topFocusedWindowChanged(String packageName) throws RemoteException { + mMainExecutor.execute(() -> { + PerDisplay.this.topFocusedWindowChanged(packageName); + }); + } + + @Override + public void insetsChanged(InsetsState insetsState) throws RemoteException { + mMainExecutor.execute(() -> { + PerDisplay.this.insetsChanged(insetsState); + }); + } + + @Override + public void insetsControlChanged(InsetsState insetsState, + InsetsSourceControl[] activeControls) throws RemoteException { + mMainExecutor.execute(() -> { + PerDisplay.this.insetsControlChanged(insetsState, activeControls); + }); + } + + @Override + public void showInsets(int types, boolean fromIme) throws RemoteException { + mMainExecutor.execute(() -> { + PerDisplay.this.showInsets(types, fromIme); + }); + } + + @Override + public void hideInsets(int types, boolean fromIme) throws RemoteException { + mMainExecutor.execute(() -> { + PerDisplay.this.hideInsets(types, fromIme); + }); + } + } } void removeImeSurface() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java index 22b831b7565e0..f2c57f71f5b8e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java @@ -50,6 +50,16 @@ public interface ShellExecutor extends Executor { latch.await(waitTimeout, waitTimeUnit); } + /** + * Convenience method to execute the blocking call with a default timeout. + * + * @throws InterruptedException if runnable does not return in the time specified by + * {@param waitTimeout} + */ + default void executeBlocking(Runnable runnable) throws InterruptedException { + executeBlocking(runnable, 2, TimeUnit.SECONDS); + } + /** * See {@link android.os.Handler#postDelayed(Runnable, long)}. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java index 7321dc88770d1..33beab5ee3f13 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java @@ -16,16 +16,14 @@ package com.android.wm.shell.common; +import android.annotation.BinderThread; import android.annotation.NonNull; -import android.os.Handler; import android.util.Slog; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import android.window.WindowOrganizer; -import androidx.annotation.BinderThread; - import com.android.wm.shell.common.annotations.ShellMainThread; import java.util.ArrayList; @@ -41,7 +39,7 @@ public final class SyncTransactionQueue { private static final int REPLY_TIMEOUT = 5300; private final TransactionPool mTransactionPool; - private final Handler mHandler; + private final ShellExecutor mMainExecutor; // Sync Transactions currently don't support nesting or interleaving properly, so // queue up transactions to run them serially. @@ -59,9 +57,9 @@ public final class SyncTransactionQueue { } }; - public SyncTransactionQueue(TransactionPool pool, Handler handler) { + public SyncTransactionQueue(TransactionPool pool, ShellExecutor mainExecutor) { mTransactionPool = pool; - mHandler = handler; + mMainExecutor = mainExecutor; } /** @@ -152,14 +150,14 @@ public final class SyncTransactionQueue { if (DEBUG) Slog.d(TAG, "Sending sync transaction: " + mWCT); mId = new WindowOrganizer().applySyncTransaction(mWCT, this); if (DEBUG) Slog.d(TAG, " Sent sync transaction. Got id=" + mId); - mHandler.postDelayed(mOnReplyTimeout, REPLY_TIMEOUT); + mMainExecutor.executeDelayed(mOnReplyTimeout, REPLY_TIMEOUT); } @BinderThread @Override public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) { - mHandler.post(() -> { + mMainExecutor.execute(() -> { synchronized (mQueue) { if (mId != id) { Slog.e(TAG, "Got an unexpected onTransactionReady. Expected " @@ -167,7 +165,7 @@ public final class SyncTransactionQueue { return; } mInFlight = null; - mHandler.removeCallbacks(mOnReplyTimeout); + mMainExecutor.removeCallbacks(mOnReplyTimeout); if (DEBUG) Slog.d(TAG, "onTransactionReady id=" + mId); mQueue.remove(this); onTransactionReceived(t); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java index 718f7a04508ee..db34248d491b6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java @@ -71,11 +71,11 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. private final IActivityTaskManager mActivityTaskManager; // NOTE: In this case we do want to use a handler since we rely on the message system to // efficiently dedupe sequential calls - private Handler mHandler; + private Handler mMainHandler; - public TaskStackListenerImpl(Handler handler) { + public TaskStackListenerImpl(Handler mainHandler) { mActivityTaskManager = ActivityTaskManager.getService(); - mHandler = new Handler(handler.getLooper(), this); + mMainHandler = new Handler(mainHandler.getLooper(), this); } @VisibleForTesting @@ -84,8 +84,8 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. } @VisibleForTesting - void setHandler(Handler handler) { - mHandler = handler; + void setHandler(Handler mainHandler) { + mMainHandler = mainHandler; } public void addListener(TaskStackListenerCallback listener) { @@ -124,13 +124,13 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. @Override public void onRecentTaskListUpdated() { - mHandler.obtainMessage(ON_TASK_LIST_UPDATED).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_LIST_UPDATED).sendToTarget(); } @Override public void onRecentTaskListFrozenChanged(boolean frozen) { - mHandler.obtainMessage(ON_TASK_LIST_FROZEN_UNFROZEN, frozen ? 1 : 0, 0 /* unused */) - .sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_LIST_FROZEN_UNFROZEN, frozen ? 1 : 0, + 0 /* unused */).sendToTarget(); } @Override @@ -147,48 +147,50 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. } mTmpListeners.clear(); - mHandler.removeMessages(ON_TASK_STACK_CHANGED); - mHandler.sendEmptyMessage(ON_TASK_STACK_CHANGED); + mMainHandler.removeMessages(ON_TASK_STACK_CHANGED); + mMainHandler.sendEmptyMessage(ON_TASK_STACK_CHANGED); } @Override public void onTaskProfileLocked(int taskId, int userId) { - mHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget(); } @Override public void onTaskDisplayChanged(int taskId, int newDisplayId) { - mHandler.obtainMessage(ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_DISPLAY_CHANGED, taskId, + newDisplayId).sendToTarget(); } @Override public void onTaskCreated(int taskId, ComponentName componentName) { - mHandler.obtainMessage(ON_TASK_CREATED, taskId, 0, componentName).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_CREATED, taskId, 0, componentName).sendToTarget(); } @Override public void onTaskRemoved(int taskId) { - mHandler.obtainMessage(ON_TASK_REMOVED, taskId, 0).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_REMOVED, taskId, 0).sendToTarget(); } @Override public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) { - mHandler.obtainMessage(ON_TASK_MOVED_TO_FRONT, taskInfo).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_MOVED_TO_FRONT, taskInfo).sendToTarget(); } @Override public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) { - mHandler.obtainMessage(ON_TASK_DESCRIPTION_CHANGED, taskInfo).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_DESCRIPTION_CHANGED, taskInfo).sendToTarget(); } @Override public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { - mHandler.obtainMessage(ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget(); + mMainHandler.obtainMessage(ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot) + .sendToTarget(); } @Override public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { - mHandler.obtainMessage(ON_BACK_PRESSED_ON_TASK_ROOT, taskInfo).sendToTarget(); + mMainHandler.obtainMessage(ON_BACK_PRESSED_ON_TASK_ROOT, taskInfo).sendToTarget(); } @Override @@ -198,44 +200,44 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. args.argi1 = userId; args.argi2 = taskId; args.argi3 = stackId; - mHandler.removeMessages(ON_ACTIVITY_PINNED); - mHandler.obtainMessage(ON_ACTIVITY_PINNED, args).sendToTarget(); + mMainHandler.removeMessages(ON_ACTIVITY_PINNED); + mMainHandler.obtainMessage(ON_ACTIVITY_PINNED, args).sendToTarget(); } @Override public void onActivityUnpinned() { - mHandler.removeMessages(ON_ACTIVITY_UNPINNED); - mHandler.sendEmptyMessage(ON_ACTIVITY_UNPINNED); + mMainHandler.removeMessages(ON_ACTIVITY_UNPINNED); + mMainHandler.sendEmptyMessage(ON_ACTIVITY_UNPINNED); } @Override - public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, - boolean clearedTask, boolean wasVisible) { + public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, + boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { final SomeArgs args = SomeArgs.obtain(); args.arg1 = task; args.argi1 = homeTaskVisible ? 1 : 0; args.argi2 = clearedTask ? 1 : 0; args.argi3 = wasVisible ? 1 : 0; - mHandler.removeMessages(ON_ACTIVITY_RESTART_ATTEMPT); - mHandler.obtainMessage(ON_ACTIVITY_RESTART_ATTEMPT, args).sendToTarget(); + mMainHandler.removeMessages(ON_ACTIVITY_RESTART_ATTEMPT); + mMainHandler.obtainMessage(ON_ACTIVITY_RESTART_ATTEMPT, args).sendToTarget(); } @Override public void onActivityForcedResizable(String packageName, int taskId, int reason) { - mHandler.obtainMessage(ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName) + mMainHandler.obtainMessage(ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName) .sendToTarget(); } @Override public void onActivityDismissingDockedStack() { - mHandler.sendEmptyMessage(ON_ACTIVITY_DISMISSING_DOCKED_STACK); + mMainHandler.sendEmptyMessage(ON_ACTIVITY_DISMISSING_DOCKED_STACK); } @Override public void onActivityLaunchOnSecondaryDisplayFailed( ActivityManager.RunningTaskInfo taskInfo, int requestedDisplayId) { - mHandler.obtainMessage(ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED, + mMainHandler.obtainMessage(ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED, requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget(); @@ -245,25 +247,25 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler. public void onActivityLaunchOnSecondaryDisplayRerouted( ActivityManager.RunningTaskInfo taskInfo, int requestedDisplayId) { - mHandler.obtainMessage(ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED, + mMainHandler.obtainMessage(ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED, requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget(); } @Override public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { - mHandler.obtainMessage(ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE, taskId, + mMainHandler.obtainMessage(ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE, taskId, requestedOrientation).sendToTarget(); } @Override public void onActivityRotation(int displayId) { - mHandler.obtainMessage(ON_ACTIVITY_ROTATION, displayId, 0 /* unused */) + mMainHandler.obtainMessage(ON_ACTIVITY_ROTATION, displayId, 0 /* unused */) .sendToTarget(); } @Override public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) { - mHandler.obtainMessage(ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED, displayId, + mMainHandler.obtainMessage(ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED, displayId, 0 /* unused */, activityToken).sendToTarget(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java index 8ae66790eb3b2..c8b4e10d4bb62 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java @@ -74,11 +74,11 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange public DragAndDropController(Context context, DisplayController displayController) { mContext = context; mDisplayController = displayController; - mDisplayController.addDisplayWindowListener(this); } - public void setSplitScreenController(Optional splitscreen) { + public void initialize(Optional splitscreen) { mLegacySplitScreen = splitscreen.orElse(null); + mDisplayController.addDisplayWindowListener(this); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java index b92846fcaf94c..a89100526b8b7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutController.java @@ -25,6 +25,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; import java.util.concurrent.Executor; @@ -37,12 +38,15 @@ public class HideDisplayCutoutController implements HideDisplayCutout { private final Context mContext; private final HideDisplayCutoutOrganizer mOrganizer; + private final ShellExecutor mMainExecutor; @VisibleForTesting boolean mEnabled; - HideDisplayCutoutController(Context context, HideDisplayCutoutOrganizer organizer) { + HideDisplayCutoutController(Context context, HideDisplayCutoutOrganizer organizer, + ShellExecutor mainExecutor) { mContext = context; mOrganizer = organizer; + mMainExecutor = mainExecutor; updateStatus(); } @@ -52,7 +56,7 @@ public class HideDisplayCutoutController implements HideDisplayCutout { */ @Nullable public static HideDisplayCutoutController create( - Context context, DisplayController displayController, Executor executor) { + Context context, DisplayController displayController, ShellExecutor mainExecutor) { // The SystemProperty is set for devices that support this feature and is used to control // whether to create the HideDisplayCutout instance. // It's defined in the device.mk (e.g. device/google/crosshatch/device.mk). @@ -61,8 +65,8 @@ public class HideDisplayCutoutController implements HideDisplayCutout { } HideDisplayCutoutOrganizer organizer = - new HideDisplayCutoutOrganizer(context, displayController, executor); - return new HideDisplayCutoutController(context, organizer); + new HideDisplayCutoutOrganizer(context, displayController, mainExecutor); + return new HideDisplayCutoutController(context, organizer, mainExecutor); } @VisibleForTesting diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java index 51a35d8514de1..53dd391a01af0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java @@ -42,6 +42,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.R; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; import java.util.List; @@ -90,8 +91,8 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { }; HideDisplayCutoutOrganizer(Context context, DisplayController displayController, - Executor executor) { - super(executor); + ShellExecutor mainExecutor) { + super(mainExecutor); mContext = context; mDisplayController = displayController; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java index 2c0cf59384742..7ce9014fc9baf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java @@ -24,7 +24,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.Nullable; import android.graphics.Rect; -import android.os.Handler; import android.util.Slog; import android.view.Choreographer; import android.view.SurfaceControl; @@ -33,6 +32,7 @@ import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TransactionPool; class DividerImeController implements DisplayImeController.ImePositionProcessor { @@ -43,7 +43,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor private final LegacySplitScreenTaskListener mSplits; private final TransactionPool mTransactionPool; - private final Handler mHandler; + private final ShellExecutor mMainExecutor; private final TaskOrganizer mTaskOrganizer; /** @@ -94,10 +94,10 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor private boolean mAdjustedWhileHidden = false; DividerImeController(LegacySplitScreenTaskListener splits, TransactionPool pool, - Handler handler, TaskOrganizer taskOrganizer) { + ShellExecutor mainExecutor, TaskOrganizer taskOrganizer) { mSplits = splits; mTransactionPool = pool; - mHandler = handler; + mMainExecutor = mainExecutor; mTaskOrganizer = taskOrganizer; } @@ -377,7 +377,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor /** Completely aborts/resets adjustment state */ public void pause(int displayId) { if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState()); - mHandler.post(() -> { + mMainExecutor.execute(() -> { if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState()); if (mPaused) { return; @@ -396,7 +396,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor public void resume(int displayId) { if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState()); - mHandler.post(() -> { + mMainExecutor.execute(() -> { if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState()); if (!mPaused) { return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java index ee5c9bce12891..139544f951ce0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java @@ -22,12 +22,12 @@ import static com.android.wm.shell.legacysplitscreen.ForcedResizableInfoActivity import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; -import android.os.Handler; import android.os.UserHandle; import android.util.ArraySet; import android.widget.Toast; import com.android.wm.shell.R; +import com.android.wm.shell.common.ShellExecutor; import java.util.function.Consumer; @@ -40,7 +40,7 @@ final class ForcedResizableInfoActivityController implements DividerView.Divider private static final int TIMEOUT = 1000; private final Context mContext; - private final Handler mHandler = new Handler(); + private final ShellExecutor mMainExecutor; private final ArraySet mPendingTasks = new ArraySet<>(); private final ArraySet mPackagesShownInSession = new ArraySet<>(); private boolean mDividerDragging; @@ -69,15 +69,17 @@ final class ForcedResizableInfoActivityController implements DividerView.Divider } ForcedResizableInfoActivityController(Context context, - LegacySplitScreenController splitScreenController) { + LegacySplitScreenController splitScreenController, + ShellExecutor mainExecutor) { mContext = context; + mMainExecutor = mainExecutor; splitScreenController.registerInSplitScreenListener(mDockedStackExistsListener); } @Override public void onDraggingStart() { mDividerDragging = true; - mHandler.removeCallbacks(mTimeoutRunnable); + mMainExecutor.removeCallbacks(mTimeoutRunnable); } @Override @@ -111,7 +113,7 @@ final class ForcedResizableInfoActivityController implements DividerView.Divider } private void showPending() { - mHandler.removeCallbacks(mTimeoutRunnable); + mMainExecutor.removeCallbacks(mTimeoutRunnable); for (int i = mPendingTasks.size() - 1; i >= 0; i--) { PendingTaskRecord pendingRecord = mPendingTasks.valueAt(i); Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class); @@ -127,8 +129,8 @@ final class ForcedResizableInfoActivityController implements DividerView.Divider } private void postTimeout() { - mHandler.removeCallbacks(mTimeoutRunnable); - mHandler.postDelayed(mTimeoutRunnable, TIMEOUT); + mMainExecutor.removeCallbacks(mTimeoutRunnable); + mMainExecutor.executeDelayed(mTimeoutRunnable, TIMEOUT); } private boolean debounce(String packageName) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java index 789bd1a90731f..9e1f0a2ed4935 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java @@ -30,7 +30,6 @@ import android.app.ActivityTaskManager; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; -import android.os.Handler; import android.os.RemoteException; import android.provider.Settings; import android.util.Slog; @@ -49,6 +48,7 @@ import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TaskStackListenerCallback; @@ -80,7 +80,7 @@ public class LegacySplitScreenController implements LegacySplitScreen, private final DividerImeController mImePositionProcessor; private final DividerState mDividerState = new DividerState(); private final ForcedResizableInfoActivityController mForcedResizableController; - private final Handler mHandler; + private final ShellExecutor mMainExecutor; private final LegacySplitScreenTaskListener mSplits; private final SystemWindows mSystemWindows; final TransactionPool mTransactionPool; @@ -112,21 +112,23 @@ public class LegacySplitScreenController implements LegacySplitScreen, public LegacySplitScreenController(Context context, DisplayController displayController, SystemWindows systemWindows, - DisplayImeController imeController, Handler handler, TransactionPool transactionPool, + DisplayImeController imeController, TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, - TaskStackListenerImpl taskStackListener, Transitions transitions) { + TaskStackListenerImpl taskStackListener, Transitions transitions, + ShellExecutor mainExecutor) { mContext = context; mDisplayController = displayController; mSystemWindows = systemWindows; mImeController = imeController; - mHandler = handler; - mForcedResizableController = new ForcedResizableInfoActivityController(context, this); + mMainExecutor = mainExecutor; + mForcedResizableController = new ForcedResizableInfoActivityController(context, this, + mainExecutor); mTransactionPool = transactionPool; mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer); mTaskOrganizer = shellTaskOrganizer; mSplits = new LegacySplitScreenTaskListener(this, shellTaskOrganizer, transitions, syncQueue); - mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler, + mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mMainExecutor, shellTaskOrganizer); mRotationController = (display, fromRotation, toRotation, wct) -> { @@ -271,11 +273,6 @@ public class LegacySplitScreenController implements LegacySplitScreen, } } - /** Posts task to handler dealing with divider. */ - void post(Runnable task) { - mHandler.post(task); - } - @Override public DividerView getDividerView() { return mView; @@ -345,7 +342,7 @@ public class LegacySplitScreenController implements LegacySplitScreen, } void onTaskVanished() { - mHandler.post(this::removeDivider); + removeDivider(); } private void updateVisibility(final boolean visible) { @@ -379,7 +376,7 @@ public class LegacySplitScreenController implements LegacySplitScreen, @Override public void setMinimized(final boolean minimized) { if (DEBUG) Slog.d(TAG, "posting ext setMinimized " + minimized + " vis:" + mVisible); - mHandler.post(() -> { + mMainExecutor.execute(() -> { if (DEBUG) Slog.d(TAG, "run posted ext setMinimized " + minimized + " vis:" + mVisible); if (!mVisible) { return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java index 8c624cdb10639..3ed070b40816d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java @@ -204,7 +204,7 @@ class LegacySplitScreenTaskListener implements ShellTaskOrganizer.TaskListener { return; } - mSplitScreenController.post(() -> handleTaskInfoChanged(taskInfo)); + handleTaskInfoChanged(taskInfo); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java index d59aec2cc4461..8f8ec475a85cc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java @@ -38,11 +38,11 @@ import java.util.ArrayList; public class PinnedStackListenerForwarder { private final IPinnedStackListener mListenerImpl = new PinnedStackListenerImpl(); - private final ShellExecutor mShellMainExecutor; + private final ShellExecutor mMainExecutor; private final ArrayList mListeners = new ArrayList<>(); - public PinnedStackListenerForwarder(ShellExecutor shellMainExecutor) { - mShellMainExecutor = shellMainExecutor; + public PinnedStackListenerForwarder(ShellExecutor mainExecutor) { + mMainExecutor = mainExecutor; } /** Adds a listener to receive updates from the WindowManagerService. */ @@ -94,35 +94,35 @@ public class PinnedStackListenerForwarder { private class PinnedStackListenerImpl extends IPinnedStackListener.Stub { @Override public void onMovementBoundsChanged(boolean fromImeAdjustment) { - mShellMainExecutor.execute(() -> { + mMainExecutor.execute(() -> { PinnedStackListenerForwarder.this.onMovementBoundsChanged(fromImeAdjustment); }); } @Override public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { - mShellMainExecutor.execute(() -> { + mMainExecutor.execute(() -> { PinnedStackListenerForwarder.this.onImeVisibilityChanged(imeVisible, imeHeight); }); } @Override public void onActionsChanged(ParceledListSlice actions) { - mShellMainExecutor.execute(() -> { + mMainExecutor.execute(() -> { PinnedStackListenerForwarder.this.onActionsChanged(actions); }); } @Override public void onActivityHidden(ComponentName componentName) { - mShellMainExecutor.execute(() -> { + mMainExecutor.execute(() -> { PinnedStackListenerForwarder.this.onActivityHidden(componentName); }); } @Override public void onAspectRatioChanged(float aspectRatio) { - mShellMainExecutor.execute(() -> { + mMainExecutor.execute(() -> { PinnedStackListenerForwarder.this.onAspectRatioChanged(aspectRatio); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index 33439a412b4d5..6b6bf5e4a7761 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -155,7 +155,7 @@ public class PipTouchHandler { PipTaskOrganizer pipTaskOrganizer, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, - ShellExecutor shellMainExecutor) { + ShellExecutor mainExecutor) { // Initialize the Pip input consumer mContext = context; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); @@ -186,7 +186,7 @@ public class PipTouchHandler { mFloatingContentCoordinator = floatingContentCoordinator; mConnection = new PipAccessibilityInteractionConnection(mContext, pipBoundsState, mMotionHelper, pipTaskOrganizer, mPipBoundsAlgorithm.getSnapAlgorithm(), - this::onAccessibilityShowMenu, this::updateMovementBounds, shellMainExecutor); + this::onAccessibilityShowMenu, this::updateMovementBounds, mainExecutor); mPipUiEventLogger = pipUiEventLogger; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java index 595440f8d52db..f10dc16fae5c9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutControllerTest.java @@ -27,6 +27,8 @@ import android.testing.TestableLooper; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; +import com.android.wm.shell.common.ShellExecutor; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,12 +46,14 @@ public class HideDisplayCutoutControllerTest { private HideDisplayCutoutController mHideDisplayCutoutController; @Mock private HideDisplayCutoutOrganizer mMockDisplayAreaOrganizer; + @Mock + private ShellExecutor mMockMainExecutor; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mHideDisplayCutoutController = new HideDisplayCutoutController( - mContext, mMockDisplayAreaOrganizer); + mContext, mMockDisplayAreaOrganizer, mMockMainExecutor); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java index e0c835b6dc6ce..9637570454530 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java @@ -50,6 +50,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import org.junit.Before; import org.junit.Test; @@ -72,6 +73,9 @@ public class HideDisplayCutoutOrganizerTest { private DisplayController mMockDisplayController; private HideDisplayCutoutOrganizer mOrganizer; + @Mock + private ShellExecutor mMockMainExecutor; + private DisplayAreaInfo mDisplayAreaInfo; private SurfaceControl mLeash; @@ -93,7 +97,7 @@ public class HideDisplayCutoutOrganizerTest { when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer( - mContext, mMockDisplayController, Runnable::run); + mContext, mMockDisplayController, mMockMainExecutor); mOrganizer = Mockito.spy(organizer); doNothing().when(mOrganizer).unregisterOrganizer(); doNothing().when(mOrganizer).applyBoundsAndOffsets(any(), any(), any(), any()); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java index 4efaebf96c2bd..b4cfbc281d611 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java @@ -73,7 +73,7 @@ public class PipTouchHandlerTest extends ShellTestCase { private PipUiEventLogger mPipUiEventLogger; @Mock - private ShellExecutor mShellMainExecutor; + private ShellExecutor mMainExecutor; private PipBoundsState mPipBoundsState; private PipBoundsAlgorithm mPipBoundsAlgorithm; @@ -98,7 +98,7 @@ public class PipTouchHandlerTest extends ShellTestCase { mPipSnapAlgorithm = new PipSnapAlgorithm(); mPipTouchHandler = new PipTouchHandler(mContext, mPhonePipMenuController, mPipBoundsAlgorithm, mPipBoundsState, mPipTaskOrganizer, - mFloatingContentCoordinator, mPipUiEventLogger, mShellMainExecutor); + mFloatingContentCoordinator, mPipUiEventLogger, mMainExecutor); mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper()); mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler()); mPipTouchHandler.setPipMotionHelper(mMotionHelper); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java index 1049548c382c4..1d3f26e730806 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java @@ -17,24 +17,22 @@ package com.android.systemui.wmshell; import android.content.Context; -import android.os.Handler; import android.view.IWindowManager; import com.android.systemui.dagger.WMSingleton; -import com.android.systemui.dagger.qualifiers.Main; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.Transitions; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController; -import java.util.concurrent.Executor; - import dagger.Module; import dagger.Provides; @@ -47,9 +45,9 @@ public class TvWMShellModule { @WMSingleton @Provides static DisplayImeController provideDisplayImeController(IWindowManager wmService, - DisplayController displayController, @Main Executor mainExecutor, + DisplayController displayController, @ShellMainThread ShellExecutor shellMainExecutor, TransactionPool transactionPool) { - return new DisplayImeController(wmService, displayController, mainExecutor, + return new DisplayImeController(wmService, displayController, shellMainExecutor, transactionPool); } @@ -57,12 +55,12 @@ public class TvWMShellModule { @Provides static LegacySplitScreen provideSplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, - DisplayImeController displayImeController, @Main Handler handler, - TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, - SyncTransactionQueue syncQueue, TaskStackListenerImpl taskStackListener, - Transitions transitions) { + DisplayImeController displayImeController, TransactionPool transactionPool, + ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, + TaskStackListenerImpl taskStackListener, Transitions transitions, + @ShellMainThread ShellExecutor mainExecutor) { return new LegacySplitScreenController(context, displayController, systemWindows, - displayImeController, handler, transactionPool, shellTaskOrganizer, syncQueue, - taskStackListener, transitions); + displayImeController, transactionPool, shellTaskOrganizer, syncQueue, + taskStackListener, transitions, mainExecutor); } } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 88cbddd4f0881..b46751dd0056a 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -36,7 +36,9 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.wm.shell.FullscreenTaskListener; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellCommandHandler; +import com.android.wm.shell.ShellCommandHandlerImpl; import com.android.wm.shell.ShellInit; +import com.android.wm.shell.ShellInitImpl; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.Transitions; import com.android.wm.shell.WindowManagerShellWrapper; @@ -158,7 +160,7 @@ public abstract class WMShellBaseModule { // Choreographer.getSfInstance() which returns a thread-local Choreographer instance // that uses the SF vsync handler.setProvider(new SfVsyncFrameCallbackProvider()); - }, 1, TimeUnit.SECONDS); + }); return handler; } catch (InterruptedException e) { throw new RuntimeException("Failed to initialize SfVsync animation handler in 1s", e); @@ -173,14 +175,14 @@ public abstract class WMShellBaseModule { Optional legacySplitScreenOptional, Optional appPairsOptional, FullscreenTaskListener fullscreenTaskListener, - Transitions transitions) { - return new ShellInit(displayImeController, + @ShellMainThread ShellExecutor shellMainExecutor) { + return ShellInitImpl.create(displayImeController, dragAndDropController, shellTaskOrganizer, legacySplitScreenOptional, appPairsOptional, fullscreenTaskListener, - transitions); + shellMainExecutor); } /** @@ -195,9 +197,11 @@ public abstract class WMShellBaseModule { Optional pipOptional, Optional oneHandedOptional, Optional hideDisplayCutout, - Optional appPairsOptional) { - return Optional.of(new ShellCommandHandler(shellTaskOrganizer, legacySplitScreenOptional, - pipOptional, oneHandedOptional, hideDisplayCutout, appPairsOptional)); + Optional appPairsOptional, + @ShellMainThread ShellExecutor shellMainExecutor) { + return Optional.of(ShellCommandHandlerImpl.create(shellTaskOrganizer, + legacySplitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout, + appPairsOptional, shellMainExecutor)); } @WMSingleton @@ -208,9 +212,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static DisplayController provideDisplayController(Context context, @Main Handler handler, - IWindowManager wmService) { - return new DisplayController(context, handler, wmService); + static DisplayController provideDisplayController(Context context, + IWindowManager wmService, @ShellMainThread ShellExecutor shellMainExecutor) { + return new DisplayController(context, wmService, shellMainExecutor); } @WMSingleton @@ -269,9 +273,9 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides - static SyncTransactionQueue provideSyncTransactionQueue(@Main Handler handler, - TransactionPool pool) { - return new SyncTransactionQueue(pool, handler); + static SyncTransactionQueue provideSyncTransactionQueue(TransactionPool pool, + @ShellMainThread ShellExecutor shellMainExecutor) { + return new SyncTransactionQueue(pool, shellMainExecutor); } @WMSingleton @@ -288,10 +292,12 @@ public abstract class WMShellBaseModule { return new RootTaskDisplayAreaOrganizer(mainExecutor, context); } + // We currently dedupe multiple messages, so we use the shell main handler directly @WMSingleton @Provides - static TaskStackListenerImpl providerTaskStackListenerImpl(@Main Handler handler) { - return new TaskStackListenerImpl(handler); + static TaskStackListenerImpl providerTaskStackListenerImpl( + @ShellMainThread Handler shellMainHandler) { + return new TaskStackListenerImpl(shellMainHandler); } @BindsOptionalOf @@ -309,11 +315,12 @@ public abstract class WMShellBaseModule { WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps, UiEventLogger uiEventLogger, - @Main Handler mainHandler, - ShellTaskOrganizer organizer) { + ShellTaskOrganizer organizer, + @ShellMainThread ShellExecutor shellMainExecutor) { return Optional.of(BubbleController.create(context, null /* synchronizer */, floatingContentCoordinator, statusBarService, windowManager, - windowManagerShellWrapper, launcherApps, uiEventLogger, mainHandler, organizer)); + windowManagerShellWrapper, launcherApps, uiEventLogger, organizer, + shellMainExecutor)); } @WMSingleton diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index 9ec7657c5dd51..509419e5d11c8 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -65,9 +65,9 @@ public class WMShellModule { @WMSingleton @Provides static DisplayImeController provideDisplayImeController(IWindowManager wmService, - DisplayController displayController, @Main Executor mainExecutor, + DisplayController displayController, @ShellMainThread ShellExecutor shellMainExecutor, TransactionPool transactionPool) { - return new DisplayImeController(wmService, displayController, mainExecutor, + return new DisplayImeController(wmService, displayController, shellMainExecutor, transactionPool); } @@ -75,13 +75,13 @@ public class WMShellModule { @Provides static LegacySplitScreen provideLegacySplitScreen(Context context, DisplayController displayController, SystemWindows systemWindows, - DisplayImeController displayImeController, @Main Handler handler, - TransactionPool transactionPool, ShellTaskOrganizer shellTaskOrganizer, - SyncTransactionQueue syncQueue, TaskStackListenerImpl taskStackListener, - Transitions transitions) { + DisplayImeController displayImeController, TransactionPool transactionPool, + ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue, + TaskStackListenerImpl taskStackListener, Transitions transitions, + @ShellMainThread ShellExecutor mainExecutor) { return new LegacySplitScreenController(context, displayController, systemWindows, - displayImeController, handler, transactionPool, shellTaskOrganizer, syncQueue, - taskStackListener, transitions); + displayImeController, transactionPool, shellTaskOrganizer, syncQueue, + taskStackListener, transitions, mainExecutor); } @WMSingleton diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 230aeab4183c5..eaef4556bf4d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -100,6 +100,7 @@ import com.android.wm.shell.bubbles.BubbleOverflow; import com.android.wm.shell.bubbles.BubbleStackView; import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; import com.google.common.collect.ImmutableList; @@ -278,9 +279,9 @@ public class BubblesTest extends SysuiTestCase { mWindowManagerShellWrapper, mLauncherApps, mBubbleLogger, - mock(Handler.class), mock(ShellTaskOrganizer.class), - mPositioner); + mPositioner, + mock(ShellExecutor.class)); mBubbleController.setExpandListener(mBubbleExpandListener); mBubblesManager = new BubblesManager( diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java index bbcc30abe3157..51092c131bfe7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java @@ -93,6 +93,7 @@ import com.android.wm.shell.bubbles.BubbleOverflow; import com.android.wm.shell.bubbles.BubbleStackView; import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; import org.junit.Before; import org.junit.Ignore; @@ -246,9 +247,9 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase { mWindowManagerShellWrapper, mLauncherApps, mBubbleLogger, - mock(Handler.class), mock(ShellTaskOrganizer.class), - mPositioner); + mPositioner, + mock(ShellExecutor.class)); mBubbleController.setExpandListener(mBubbleExpandListener); mBubblesManager = new BubblesManager( diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java index fd39b6e5b1c86..3f918e8b86339 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java @@ -30,6 +30,7 @@ import com.android.wm.shell.bubbles.BubbleDataRepository; import com.android.wm.shell.bubbles.BubbleLogger; import com.android.wm.shell.bubbles.BubblePositioner; import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; /** * Testable BubbleController subclass that immediately synchronizes surfaces. @@ -46,12 +47,12 @@ public class TestableBubbleController extends BubbleController { WindowManagerShellWrapper windowManagerShellWrapper, LauncherApps launcherApps, BubbleLogger bubbleLogger, - Handler mainHandler, ShellTaskOrganizer shellTaskOrganizer, - BubblePositioner positioner) { + BubblePositioner positioner, + ShellExecutor shellMainExecutor) { super(context, data, Runnable::run, floatingContentCoordinator, dataRepository, statusBarService, windowManager, windowManagerShellWrapper, launcherApps, - bubbleLogger, mainHandler, shellTaskOrganizer, positioner); + bubbleLogger, shellTaskOrganizer, positioner, shellMainExecutor); setInflateSynchronously(true); } }