diff options
| author | 2020-12-02 22:54:15 -0800 | |
|---|---|---|
| committer | 2021-01-12 10:05:03 -0800 | |
| commit | 5b4318517275d1be027538d62eb8b975ccaf0b7b (patch) | |
| tree | ce36c2a286cf5b9eddf2cd09be7b5123647980cd | |
| parent | b898264ff2f58566d02313d1471b2e9bf728c863 (diff) | |
3/ Update OneHanded to use shell main thread
- Clean up some usages of handlers and explicit main loopers to use
the shell executors
- Remove the update thread (will eventually move to the shell main thread)
- Make timeout handler non-static (it only has one instance at the moment)
- Post calls from shell back onto the sysui thread
Bug: 161979899
Test: atest WMShellUnitTests
Change-Id: I1db0f0d8e7f83eeb7e4581fb266ffd77aa73fea1
24 files changed, 582 insertions, 610 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java index fa0a75c2d364..4874d3ccae7e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java @@ -18,6 +18,7 @@ package com.android.wm.shell.common; import android.annotation.NonNull; import android.os.Handler; +import android.os.Looper; /** Executor implementation which is backed by a Handler. */ public class HandlerExecutor implements ShellExecutor { @@ -49,4 +50,14 @@ public class HandlerExecutor implements ShellExecutor { public void removeCallbacks(@NonNull Runnable r) { mHandler.removeCallbacks(r); } + + @Override + public boolean hasCallback(Runnable r) { + return mHandler.hasCallbacks(r); + } + + @Override + public Looper getLooper() { + return mHandler.getLooper(); + } } 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 f2c57f71f5b8..d37e628b9a51 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 @@ -16,6 +16,8 @@ package com.android.wm.shell.common; +import android.os.Looper; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -69,4 +71,14 @@ public interface ShellExecutor extends Executor { * See {@link android.os.Handler#removeCallbacks}. */ void removeCallbacks(Runnable r); + + /** + * See {@link android.os.Handler#hasCallbacks(Runnable)}. + */ + boolean hasCallback(Runnable r); + + /** + * Returns the looper that this executor is running on. + */ + Looper getLooper(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java index 146f231a8854..d22abe4dd19b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java @@ -127,7 +127,6 @@ public class OneHandedAnimationController { mSurfaceControlTransactionFactory; private @TransitionDirection int mTransitionDirection; - private int mTransitionOffset; private OneHandedTransitionAnimator(SurfaceControl leash, T startValue, T endValue) { mLeash = leash; @@ -231,11 +230,6 @@ public class OneHandedAnimationController { return this; } - OneHandedTransitionAnimator<T> setTransitionOffset(int offset) { - mTransitionOffset = offset; - return this; - } - T getStartValue() { return mStartValue; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 00605d872e39..48d6a7b40ee1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -26,7 +26,6 @@ import android.content.om.OverlayInfo; import android.database.ContentObserver; import android.graphics.Point; import android.os.Handler; -import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; @@ -41,8 +40,10 @@ import androidx.annotation.VisibleForTesting; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; import java.io.PrintWriter; @@ -51,7 +52,7 @@ import java.util.concurrent.Executor; /** * Manages and manipulates the one handed states, transitions, and gesture for phones. */ -public class OneHandedController implements OneHanded { +public class OneHandedController { private static final String TAG = "OneHandedController"; private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE = @@ -61,8 +62,8 @@ public class OneHandedController implements OneHanded { static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode"; - private boolean mIsOneHandedEnabled; - private boolean mIsSwipeToNotificationEnabled; + private volatile boolean mIsOneHandedEnabled; + private volatile boolean mIsSwipeToNotificationEnabled; private boolean mTaskChangeToExit; private float mOffSetFraction; @@ -73,7 +74,9 @@ public class OneHandedController implements OneHanded { private final OneHandedTouchHandler mTouchHandler; private final OneHandedTutorialHandler mTutorialHandler; private final IOverlayManager mOverlayManager; - private final Handler mMainHandler = new Handler(Looper.getMainLooper()); + private final ShellExecutor mMainExecutor; + private final Handler mMainHandler; + private final OneHandedImpl mImpl = new OneHandedImpl(); private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer; private final AccessibilityManager mAccessibilityManager; @@ -89,83 +92,10 @@ public class OneHandedController implements OneHanded { } }; - private final ContentObserver mEnabledObserver = new ContentObserver(mMainHandler) { - @Override - public void onChange(boolean selfChange) { - final boolean enabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled( - mContext.getContentResolver()); - OneHandedEvents.writeEvent(enabled - ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_ON - : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_OFF); - - setOneHandedEnabled(enabled); - - // Also checks swipe to notification settings since they all need gesture overlay. - setEnabledGesturalOverlay( - enabled || OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( - mContext.getContentResolver())); - } - }; - - private final ContentObserver mTimeoutObserver = new ContentObserver(mMainHandler) { - @Override - public void onChange(boolean selfChange) { - final int newTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout( - mContext.getContentResolver()); - int metricsId = OneHandedEvents.OneHandedSettingsTogglesEvent.INVALID.getId(); - switch (newTimeout) { - case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER: - metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_NEVER; - break; - case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS: - metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4; - break; - case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS: - metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8; - break; - case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS: - metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12; - break; - default: - // do nothing - break; - } - OneHandedEvents.writeEvent(metricsId); - - if (mTimeoutHandler != null) { - mTimeoutHandler.setTimeout(newTimeout); - } - } - }; - - private final ContentObserver mTaskChangeExitObserver = new ContentObserver(mMainHandler) { - @Override - public void onChange(boolean selfChange) { - final boolean enabled = OneHandedSettingsUtil.getSettingsTapsAppToExit( - mContext.getContentResolver()); - OneHandedEvents.writeEvent(enabled - ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON - : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF); - - setTaskChangeToExit(enabled); - } - }; - - private final ContentObserver mSwipeToNotificationEnabledObserver = - new ContentObserver(mMainHandler) { - @Override - public void onChange(boolean selfChange) { - final boolean enabled = - OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( - mContext.getContentResolver()); - setSwipeToNotificationEnabled(enabled); - - // Also checks one handed mode settings since they all need gesture overlay. - setEnabledGesturalOverlay( - enabled || OneHandedSettingsUtil.getSettingsOneHandedModeEnabled( - mContext.getContentResolver())); - } - }; + private final ContentObserver mEnabledObserver; + private final ContentObserver mTimeoutObserver; + private final ContentObserver mTaskChangeExitObserver; + private final ContentObserver mSwipeToNotificationEnabledObserver; private AccessibilityManager.AccessibilityStateChangeListener mAccessibilityStateChangeListener = @@ -188,33 +118,39 @@ public class OneHandedController implements OneHanded { }; /** - * Creates {@link OneHandedController}, returns {@code null} if the feature is not supported. + * Creates {@link OneHanded}, returns {@code null} if the feature is not supported. */ @Nullable - public static OneHandedController create( + public static OneHanded create( Context context, DisplayController displayController, - TaskStackListenerImpl taskStackListener, Executor executor) { + TaskStackListenerImpl taskStackListener, + ShellExecutor mainExecutor, + Handler mainHandler) { if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) { Slog.w(TAG, "Device doesn't support OneHanded feature"); return null; } - OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context); + OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor); + OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context, + mainExecutor); OneHandedAnimationController animationController = new OneHandedAnimationController(context); - OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(); + OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler, + mainExecutor); OneHandedGestureHandler gestureHandler = new OneHandedGestureHandler( - context, displayController); + context, displayController, mainExecutor); OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer = - new OneHandedBackgroundPanelOrganizer(context, displayController, executor); + new OneHandedBackgroundPanelOrganizer(context, displayController, mainExecutor); OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer( - context, displayController, animationController, tutorialHandler, executor, - oneHandedBackgroundPanelOrganizer); + context, displayController, animationController, tutorialHandler, + oneHandedBackgroundPanelOrganizer, mainExecutor); IOverlayManager overlayManager = IOverlayManager.Stub.asInterface( ServiceManager.getService(Context.OVERLAY_SERVICE)); return new OneHandedController(context, displayController, oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler, - gestureHandler, overlayManager, taskStackListener); + gestureHandler, timeoutHandler, overlayManager, taskStackListener, mainExecutor, + mainHandler).mImpl; } @VisibleForTesting @@ -225,8 +161,11 @@ public class OneHandedController implements OneHanded { OneHandedTouchHandler touchHandler, OneHandedTutorialHandler tutorialHandler, OneHandedGestureHandler gestureHandler, + OneHandedTimeoutHandler timeoutHandler, IOverlayManager overlayManager, - TaskStackListenerImpl taskStackListener) { + TaskStackListenerImpl taskStackListener, + ShellExecutor mainExecutor, + Handler mainHandler) { mContext = context; mBackgroundPanelOrganizer = backgroundPanelOrganizer; mDisplayAreaOrganizer = displayAreaOrganizer; @@ -235,6 +174,8 @@ public class OneHandedController implements OneHanded { mTutorialHandler = tutorialHandler; mGestureHandler = gestureHandler; mOverlayManager = overlayManager; + mMainExecutor = mainExecutor; + mMainHandler = mainHandler; final float offsetPercentageConfig = context.getResources().getFraction( R.fraction.config_one_handed_offset, 1, 1); @@ -246,7 +187,13 @@ public class OneHandedController implements OneHanded { mIsSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( context.getContentResolver()); - mTimeoutHandler = OneHandedTimeoutHandler.get(); + mTimeoutHandler = timeoutHandler; + + mEnabledObserver = getObserver(this::onEnabledSettingChanged); + mTimeoutObserver = getObserver(this::onTimeoutSettingChanged); + mTaskChangeExitObserver = getObserver(this::onTaskChangeExitSettingChanged); + mSwipeToNotificationEnabledObserver = + getObserver(this::onSwipeToNotificationEnabledSettingChanged); mDisplayController.addDisplayChangingController(mRotationController); @@ -298,18 +245,8 @@ public class OneHandedController implements OneHanded { updateOneHandedEnabled(); } - @Override - public boolean isOneHandedEnabled() { - return mIsOneHandedEnabled; - } - - @Override - public boolean isSwipeToNotificationEnabled() { - return mIsSwipeToNotificationEnabled; - } - - @Override - public void startOneHanded() { + @VisibleForTesting + void startOneHanded() { if (!mDisplayAreaOrganizer.isInOneHanded()) { final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction); mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); @@ -319,16 +256,15 @@ public class OneHandedController implements OneHanded { } } - @Override - public void stopOneHanded() { + @VisibleForTesting + void stopOneHanded() { if (mDisplayAreaOrganizer.isInOneHanded()) { mDisplayAreaOrganizer.scheduleOffset(0, 0); mTimeoutHandler.removeTimer(); } } - @Override - public void stopOneHanded(int event) { + private void stopOneHanded(int event) { if (!mTaskChangeToExit && event == OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_APP_TAPS_OUT) { //Task change exit not enable, do nothing and return here. return; @@ -341,18 +277,16 @@ public class OneHandedController implements OneHanded { stopOneHanded(); } - @Override - public void setThreeButtonModeEnabled(boolean enabled) { + private void setThreeButtonModeEnabled(boolean enabled) { mGestureHandler.onThreeButtonModeEnabled(enabled); } - @Override - public void registerTransitionCallback(OneHandedTransitionCallback callback) { + @VisibleForTesting + void registerTransitionCallback(OneHandedTransitionCallback callback) { mDisplayAreaOrganizer.registerTransitionCallback(callback); } - @Override - public void registerGestureCallback(OneHandedGestureEventCallback callback) { + private void registerGestureCallback(OneHandedGestureEventCallback callback) { mGestureHandler.setGestureEventListener(callback); } @@ -388,6 +322,80 @@ public class OneHandedController implements OneHanded { .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver())); } + private ContentObserver getObserver(Runnable onChangeRunnable) { + return new ContentObserver(mMainHandler) { + @Override + public void onChange(boolean selfChange) { + onChangeRunnable.run(); + } + }; + } + + private void onEnabledSettingChanged() { + final boolean enabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled( + mContext.getContentResolver()); + OneHandedEvents.writeEvent(enabled + ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_ON + : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_ENABLED_OFF); + + setOneHandedEnabled(enabled); + + // Also checks swipe to notification settings since they all need gesture overlay. + setEnabledGesturalOverlay( + enabled || OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( + mContext.getContentResolver())); + } + + private void onTimeoutSettingChanged() { + final int newTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout( + mContext.getContentResolver()); + int metricsId = OneHandedEvents.OneHandedSettingsTogglesEvent.INVALID.getId(); + switch (newTimeout) { + case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER: + metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_NEVER; + break; + case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS: + metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4; + break; + case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS: + metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8; + break; + case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS: + metricsId = OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12; + break; + default: + // do nothing + break; + } + OneHandedEvents.writeEvent(metricsId); + + if (mTimeoutHandler != null) { + mTimeoutHandler.setTimeout(newTimeout); + } + } + + private void onTaskChangeExitSettingChanged() { + final boolean enabled = OneHandedSettingsUtil.getSettingsTapsAppToExit( + mContext.getContentResolver()); + OneHandedEvents.writeEvent(enabled + ? OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON + : OneHandedEvents.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF); + + setTaskChangeToExit(enabled); + } + + private void onSwipeToNotificationEnabledSettingChanged() { + final boolean enabled = + OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( + mContext.getContentResolver()); + setSwipeToNotificationEnabled(enabled); + + // Also checks one handed mode settings since they all need gesture overlay. + setEnabledGesturalOverlay( + enabled || OneHandedSettingsUtil.getSettingsOneHandedModeEnabled( + mContext.getContentResolver())); + } + private void setupTimeoutListener() { mTimeoutHandler.registerTimeoutListener(timeoutTime -> { stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_TIMEOUT_OUT); @@ -451,8 +459,7 @@ public class OneHandedController implements OneHanded { } } - @Override - public void dump(@NonNull PrintWriter pw) { + private void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG + "states: "); pw.print(innerPrefix + "mOffSetFraction="); @@ -489,4 +496,68 @@ public class OneHandedController implements OneHanded { } } } + + @ExternalThread + private class OneHandedImpl implements OneHanded { + @Override + public boolean isOneHandedEnabled() { + // This is volatile so return directly + return mIsOneHandedEnabled; + } + + @Override + public boolean isSwipeToNotificationEnabled() { + // This is volatile so return directly + return mIsSwipeToNotificationEnabled; + } + + @Override + public void startOneHanded() { + mMainExecutor.execute(() -> { + OneHandedController.this.startOneHanded(); + }); + } + + @Override + public void stopOneHanded() { + mMainExecutor.execute(() -> { + OneHandedController.this.stopOneHanded(); + }); + } + + @Override + public void stopOneHanded(int event) { + mMainExecutor.execute(() -> { + OneHandedController.this.stopOneHanded(event); + }); + } + + @Override + public void setThreeButtonModeEnabled(boolean enabled) { + mMainExecutor.execute(() -> { + OneHandedController.this.setThreeButtonModeEnabled(enabled); + }); + } + + @Override + public void registerTransitionCallback(OneHandedTransitionCallback callback) { + mMainExecutor.execute(() -> { + OneHandedController.this.registerTransitionCallback(callback); + }); + } + + @Override + public void registerGestureCallback(OneHandedGestureEventCallback callback) { + mMainExecutor.execute(() -> { + OneHandedController.this.registerGestureCallback(callback); + }); + } + + @Override + public void dump(@NonNull PrintWriter pw) { + mMainExecutor.execute(() -> { + OneHandedController.this.dump(pw); + }); + } + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index 7873318fc82d..d2d5591100d4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -24,8 +24,6 @@ import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSI import android.content.Context; import android.graphics.Point; import android.graphics.Rect; -import android.os.Handler; -import android.os.Looper; import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Log; @@ -39,9 +37,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import com.android.internal.os.SomeArgs; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; import java.util.ArrayList; @@ -64,17 +62,9 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION = "persist.debug.one_handed_translate_animation_duration"; - @VisibleForTesting - static final int MSG_RESET_IMMEDIATE = 1; - @VisibleForTesting - static final int MSG_OFFSET_ANIMATE = 2; - @VisibleForTesting - static final int MSG_OFFSET_FINISH = 3; - private final Rect mLastVisualDisplayBounds = new Rect(); private final Rect mDefaultDisplayBounds = new Rect(); - private Handler mUpdateHandler; private boolean mIsInOneHanded; private int mEnterExitAnimationDurationMs; @@ -101,8 +91,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { OneHandedAnimationController.OneHandedTransitionAnimator animator) { mAnimationController.removeAnimator(animator.getLeash()); if (mAnimationController.isAnimatorsConsumed()) { - mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_OFFSET_FINISH, - obtainArgsFromAnimator(animator))); + finishOffset(animator.getDestinationOffset(), + animator.getTransitionDirection()); } } @@ -111,52 +101,22 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { OneHandedAnimationController.OneHandedTransitionAnimator animator) { mAnimationController.removeAnimator(animator.getLeash()); if (mAnimationController.isAnimatorsConsumed()) { - mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_OFFSET_FINISH, - obtainArgsFromAnimator(animator))); + finishOffset(animator.getDestinationOffset(), + animator.getTransitionDirection()); } } }; - @SuppressWarnings("unchecked") - private Handler.Callback mUpdateCallback = (msg) -> { - SomeArgs args = (SomeArgs) msg.obj; - final Rect currentBounds = args.arg1 != null ? (Rect) args.arg1 : mDefaultDisplayBounds; - final WindowContainerTransaction wctFromRotate = (WindowContainerTransaction) args.arg2; - final int yOffset = args.argi2; - final int direction = args.argi3; - - switch (msg.what) { - case MSG_RESET_IMMEDIATE: - resetWindowsOffset(wctFromRotate); - mDefaultDisplayBounds.set(currentBounds); - mLastVisualDisplayBounds.set(currentBounds); - finishOffset(0, TRANSITION_DIRECTION_EXIT); - break; - case MSG_OFFSET_ANIMATE: - final Rect toBounds = new Rect(mDefaultDisplayBounds.left, - mDefaultDisplayBounds.top + yOffset, - mDefaultDisplayBounds.right, - mDefaultDisplayBounds.bottom + yOffset); - offsetWindows(currentBounds, toBounds, direction, mEnterExitAnimationDurationMs); - break; - case MSG_OFFSET_FINISH: - finishOffset(yOffset, direction); - break; - } - args.recycle(); - return true; - }; - /** * Constructor of OneHandedDisplayAreaOrganizer */ public OneHandedDisplayAreaOrganizer(Context context, DisplayController displayController, OneHandedAnimationController animationController, - OneHandedTutorialHandler tutorialHandler, Executor executor, - OneHandedBackgroundPanelOrganizer oneHandedBackgroundGradientOrganizer) { - super(executor); - mUpdateHandler = new Handler(OneHandedThread.get().getLooper(), mUpdateCallback); + OneHandedTutorialHandler tutorialHandler, + OneHandedBackgroundPanelOrganizer oneHandedBackgroundGradientOrganizer, + ShellExecutor mainExecutor) { + super(mainExecutor); mAnimationController = animationController; mDisplayController = displayController; mDefaultDisplayBounds.set(getDisplayBounds()); @@ -176,12 +136,10 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { @NonNull SurfaceControl leash) { Objects.requireNonNull(displayAreaInfo, "displayAreaInfo must not be null"); Objects.requireNonNull(leash, "leash must not be null"); - synchronized (this) { - if (mDisplayAreaMap.get(displayAreaInfo) == null) { - // mDefaultDisplayBounds may out of date after removeDisplayChangingController() - mDefaultDisplayBounds.set(getDisplayBounds()); - mDisplayAreaMap.put(displayAreaInfo, leash); - } + if (mDisplayAreaMap.get(displayAreaInfo) == null) { + // mDefaultDisplayBounds may out of date after removeDisplayChangingController() + mDefaultDisplayBounds.set(getDisplayBounds()); + mDisplayAreaMap.put(displayAreaInfo, leash); } } @@ -189,13 +147,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) { Objects.requireNonNull(displayAreaInfo, "Requires valid displayArea, and displayArea must not be null"); - synchronized (this) { - if (!mDisplayAreaMap.containsKey(displayAreaInfo)) { - Log.w(TAG, "Unrecognized token: " + displayAreaInfo.token); - return; - } - mDisplayAreaMap.remove(displayAreaInfo); + if (!mDisplayAreaMap.containsKey(displayAreaInfo)) { + Log.w(TAG, "Unrecognized token: " + displayAreaInfo.token); + return; } + mDisplayAreaMap.remove(displayAreaInfo); } @Override @@ -212,7 +168,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { @Override public void unregisterOrganizer() { super.unregisterOrganizer(); - mUpdateHandler.post(() -> resetWindowsOffset(null)); + resetWindowsOffset(null); } /** @@ -230,14 +186,10 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { final boolean isOrientationDiff = Math.abs(fromRotation - toRotation) % 2 == 1; if (isOrientationDiff) { - newBounds.set(newBounds.left, newBounds.top, newBounds.bottom, newBounds.right); - SomeArgs args = SomeArgs.obtain(); - args.arg1 = newBounds; - args.arg2 = wct; - args.argi1 = 0 /* xOffset */; - args.argi2 = 0 /* yOffset */; - args.argi3 = TRANSITION_DIRECTION_EXIT; - mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_RESET_IMMEDIATE, args)); + resetWindowsOffset(wct); + mDefaultDisplayBounds.set(newBounds); + mLastVisualDisplayBounds.set(newBounds); + finishOffset(0, TRANSITION_DIRECTION_EXIT); } } @@ -246,79 +198,65 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { * Directly perform manipulation/offset on the leash. */ public void scheduleOffset(int xOffset, int yOffset) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = getLastVisualDisplayBounds(); - args.argi1 = xOffset; - args.argi2 = yOffset; - args.argi3 = yOffset > 0 ? TRANSITION_DIRECTION_TRIGGER : TRANSITION_DIRECTION_EXIT; - mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_OFFSET_ANIMATE, args)); - } - - private void offsetWindows(Rect fromBounds, Rect toBounds, int direction, int durationMs) { - if (Looper.myLooper() != mUpdateHandler.getLooper()) { - throw new RuntimeException("Callers should call scheduleOffset() instead of this " - + "directly"); - } - synchronized (this) { - final WindowContainerTransaction wct = new WindowContainerTransaction(); - mDisplayAreaMap.forEach( - (key, leash) -> { - animateWindows(leash, fromBounds, toBounds, direction, durationMs); - wct.setBounds(key.token, toBounds); - }); - applyTransaction(wct); - } + final Rect toBounds = new Rect(mDefaultDisplayBounds.left, + mDefaultDisplayBounds.top + yOffset, + mDefaultDisplayBounds.right, + mDefaultDisplayBounds.bottom + yOffset); + final Rect fromBounds = getLastVisualDisplayBounds() != null + ? getLastVisualDisplayBounds() + : mDefaultDisplayBounds; + final int direction = yOffset > 0 + ? TRANSITION_DIRECTION_TRIGGER + : TRANSITION_DIRECTION_EXIT; + + final WindowContainerTransaction wct = new WindowContainerTransaction(); + mDisplayAreaMap.forEach( + (key, leash) -> { + animateWindows(leash, fromBounds, toBounds, direction, + mEnterExitAnimationDurationMs); + wct.setBounds(key.token, toBounds); + }); + applyTransaction(wct); } private void resetWindowsOffset(WindowContainerTransaction wct) { - synchronized (this) { - final SurfaceControl.Transaction tx = - mSurfaceControlTransactionFactory.getTransaction(); - mDisplayAreaMap.forEach( - (key, leash) -> { - final OneHandedAnimationController.OneHandedTransitionAnimator animator = - mAnimationController.getAnimatorMap().remove(leash); - if (animator != null && animator.isRunning()) { - animator.cancel(); - } - tx.setPosition(leash, 0, 0) - .setWindowCrop(leash, -1/* reset */, -1/* reset */); - // DisplayRotationController will applyTransaction() after finish rotating - if (wct != null) { - wct.setBounds(key.token, null/* reset */); - } - }); - tx.apply(); - } + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + mDisplayAreaMap.forEach( + (key, leash) -> { + final OneHandedAnimationController.OneHandedTransitionAnimator animator = + mAnimationController.getAnimatorMap().remove(leash); + if (animator != null && animator.isRunning()) { + animator.cancel(); + } + tx.setPosition(leash, 0, 0) + .setWindowCrop(leash, -1/* reset */, -1/* reset */); + // DisplayRotationController will applyTransaction() after finish rotating + if (wct != null) { + wct.setBounds(key.token, null/* reset */); + } + }); + tx.apply(); } private void animateWindows(SurfaceControl leash, Rect fromBounds, Rect toBounds, @OneHandedAnimationController.TransitionDirection int direction, int durationMs) { - if (Looper.myLooper() != mUpdateHandler.getLooper()) { - throw new RuntimeException("Callers should call scheduleOffset() instead of " - + "this directly"); + final OneHandedAnimationController.OneHandedTransitionAnimator animator = + mAnimationController.getAnimator(leash, fromBounds, toBounds); + if (animator != null) { + animator.setTransitionDirection(direction) + .addOneHandedAnimationCallback(mOneHandedAnimationCallback) + .addOneHandedAnimationCallback(mTutorialHandler.getAnimationCallback()) + .addOneHandedAnimationCallback( + mBackgroundPanelOrganizer.getOneHandedAnimationCallback()) + .setDuration(durationMs) + .start(); } - mUpdateHandler.post(() -> { - final OneHandedAnimationController.OneHandedTransitionAnimator animator = - mAnimationController.getAnimator(leash, fromBounds, toBounds); - if (animator != null) { - animator.setTransitionDirection(direction) - .addOneHandedAnimationCallback(mOneHandedAnimationCallback) - .addOneHandedAnimationCallback(mTutorialHandler.getAnimationCallback()) - .addOneHandedAnimationCallback( - mBackgroundPanelOrganizer.getOneHandedAnimationCallback()) - .setDuration(durationMs) - .start(); - } - }); } - private void finishOffset(int offset, + @VisibleForTesting + void finishOffset(int offset, @OneHandedAnimationController.TransitionDirection int direction) { - if (Looper.myLooper() != mUpdateHandler.getLooper()) { - throw new RuntimeException( - "Callers should call scheduleOffset() instead of this directly."); - } // Only finishOffset() can update mIsInOneHanded to ensure the state is handle in sequence, // the flag *MUST* be updated before dispatch mTransitionCallbacks mIsInOneHanded = (offset > 0 || direction == TRANSITION_DIRECTION_TRIGGER); @@ -361,11 +299,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { return new Rect(0, 0, realSize.x, realSize.y); } - @VisibleForTesting - void setUpdateHandler(Handler updateHandler) { - mUpdateHandler = updateHandler; - } - /** * Register transition callback */ @@ -373,16 +306,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { mTransitionCallbacks.add(callback); } - private SomeArgs obtainArgsFromAnimator( - OneHandedAnimationController.OneHandedTransitionAnimator animator) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = animator.getDestinationBounds(); - args.argi1 = 0 /* xOffset */; - args.argi2 = animator.getDestinationOffset(); - args.argi3 = animator.getTransitionDirection(); - return args; - } - void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG + "states: "); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java index aa4ec1788a88..1ed121f35a59 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java @@ -41,6 +41,7 @@ import androidx.annotation.VisibleForTesting; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; /** * The class manage swipe up and down gesture for 3-Button mode navigation, @@ -70,7 +71,8 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, InputMonitor mInputMonitor; @VisibleForTesting InputEventReceiver mInputEventReceiver; - private DisplayController mDisplayController; + private final DisplayController mDisplayController; + private final ShellExecutor mMainExecutor; @VisibleForTesting @Nullable OneHandedGestureEventCallback mGestureEventCallback; @@ -84,8 +86,10 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, * @param context {@link Context} * @param displayController {@link DisplayController} */ - public OneHandedGestureHandler(Context context, DisplayController displayController) { + public OneHandedGestureHandler(Context context, DisplayController displayController, + ShellExecutor mainExecutor) { mDisplayController = displayController; + mMainExecutor = mainExecutor; displayController.addDisplayChangingController(this); mNavGestureHeight = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_gesture_larger_height); @@ -93,6 +97,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, R.dimen.gestures_onehanded_drag_threshold); final float slop = ViewConfiguration.get(context).getScaledTouchSlop(); mSquaredSlop = slop * slop; + updateIsEnabled(); } @@ -217,7 +222,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, mInputMonitor = InputManager.getInstance().monitorGestureInput( "onehanded-gesture-offset", DEFAULT_DISPLAY); mInputEventReceiver = new EventReceiver( - mInputMonitor.getInputChannel(), Looper.getMainLooper()); + mInputMonitor.getInputChannel(), mMainExecutor.getLooper()); } } @@ -233,6 +238,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, mRotation = toRotation; } + // TODO: Use BatchedInputEventReceiver private class EventReceiver extends InputEventReceiver { EventReceiver(InputChannel channel, Looper looper) { super(channel, looper); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java deleted file mode 100644 index 24d33ede5d63..000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2020 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.onehanded; - -import android.os.Handler; -import android.os.HandlerThread; - -/** - * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton - * foreground thread for each process for updating one handed. - */ -public class OneHandedThread extends HandlerThread { - private static OneHandedThread sInstance; - private static Handler sHandler; - - private OneHandedThread() { - super("OneHanded"); - } - - private static void ensureThreadLocked() { - if (sInstance == null) { - sInstance = new OneHandedThread(); - sInstance.start(); - sHandler = new Handler(sInstance.getLooper()); - } - } - - /** - * @return the static update thread instance - */ - public static OneHandedThread get() { - synchronized (OneHandedThread.class) { - ensureThreadLocked(); - return sInstance; - } - } - - /** - * @return the static update thread handler instance - */ - public static Handler getHandler() { - synchronized (OneHandedThread.class) { - ensureThreadLocked(); - return sHandler; - } - } - -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java index 9c97cd7db71f..4a98941b7410 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java @@ -19,12 +19,12 @@ package com.android.wm.shell.onehanded; import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; import android.os.Handler; -import android.os.Looper; -import android.os.Message; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.android.wm.shell.common.ShellExecutor; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -35,18 +35,15 @@ import java.util.concurrent.TimeUnit; */ public class OneHandedTimeoutHandler { private static final String TAG = "OneHandedTimeoutHandler"; - private static boolean sIsDragging = false; + + private final ShellExecutor mMainExecutor; + // Default timeout is ONE_HANDED_TIMEOUT_MEDIUM - private static @OneHandedSettingsUtil.OneHandedTimeout int sTimeout = + private @OneHandedSettingsUtil.OneHandedTimeout int mTimeout = ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; - private static long sTimeoutMs = TimeUnit.SECONDS.toMillis(sTimeout); - private static OneHandedTimeoutHandler sInstance; - private static List<TimeoutListener> sListeners = new ArrayList<>(); - - @VisibleForTesting - static final int ONE_HANDED_TIMEOUT_STOP_MSG = 1; - @VisibleForTesting - static Handler sHandler; + private long mTimeoutMs = TimeUnit.SECONDS.toMillis(mTimeout); + private final Runnable mTimeoutRunnable = this::onStop; + private List<TimeoutListener> mListeners = new ArrayList<>(); /** * Get the current config of timeout @@ -54,7 +51,7 @@ public class OneHandedTimeoutHandler { * @return timeout of current config */ public @OneHandedSettingsUtil.OneHandedTimeout int getTimeout() { - return sTimeout; + return mTimeout; } /** @@ -69,32 +66,36 @@ public class OneHandedTimeoutHandler { void onTimeout(int timeoutTime); } + public OneHandedTimeoutHandler(ShellExecutor mainExecutor) { + mMainExecutor = mainExecutor; + } + /** * Set the specific timeout of {@link OneHandedSettingsUtil.OneHandedTimeout} */ - public static void setTimeout(@OneHandedSettingsUtil.OneHandedTimeout int timeout) { - sTimeout = timeout; - sTimeoutMs = TimeUnit.SECONDS.toMillis(sTimeout); + public void setTimeout(@OneHandedSettingsUtil.OneHandedTimeout int timeout) { + mTimeout = timeout; + mTimeoutMs = TimeUnit.SECONDS.toMillis(mTimeout); resetTimer(); } /** * Reset the timer when one handed trigger or user is operating in some conditions */ - public static void removeTimer() { - sHandler.removeMessages(ONE_HANDED_TIMEOUT_STOP_MSG); + public void removeTimer() { + mMainExecutor.removeCallbacks(mTimeoutRunnable); } /** * Reset the timer when one handed trigger or user is operating in some conditions */ - public static void resetTimer() { + public void resetTimer() { removeTimer(); - if (sTimeout == OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER) { + if (mTimeout == OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER) { return; } - if (sTimeout != OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER) { - sHandler.sendEmptyMessageDelayed(ONE_HANDED_TIMEOUT_STOP_MSG, sTimeoutMs); + if (mTimeout != OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER) { + mMainExecutor.executeDelayed(mTimeoutRunnable, mTimeoutMs); } } @@ -103,47 +104,19 @@ public class OneHandedTimeoutHandler { * * @param listener the listener be sent events when times up */ - public static void registerTimeoutListener(TimeoutListener listener) { - sListeners.add(listener); + public void registerTimeoutListener(TimeoutListener listener) { + mListeners.add(listener); } - /** - * Private constructor due to Singleton pattern - */ - private OneHandedTimeoutHandler() { - } - - /** - * Singleton pattern to get {@link OneHandedTimeoutHandler} instance - * - * @return the static update thread instance - */ - public static OneHandedTimeoutHandler get() { - synchronized (OneHandedTimeoutHandler.class) { - if (sInstance == null) { - sInstance = new OneHandedTimeoutHandler(); - } - if (sHandler == null) { - sHandler = new Handler(Looper.myLooper()) { - @Override - public void handleMessage(Message msg) { - if (msg.what == ONE_HANDED_TIMEOUT_STOP_MSG) { - onStop(); - } - } - }; - if (sTimeout != OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER) { - sHandler.sendEmptyMessageDelayed(ONE_HANDED_TIMEOUT_STOP_MSG, sTimeoutMs); - } - } - return sInstance; - } + @VisibleForTesting + boolean hasScheduledTimeout() { + return mMainExecutor.hasCallback(mTimeoutRunnable); } - private static void onStop() { - for (int i = sListeners.size() - 1; i >= 0; i--) { - final TimeoutListener listener = sListeners.get(i); - listener.onTimeout(sTimeout); + private void onStop() { + for (int i = mListeners.size() - 1; i >= 0; i--) { + final TimeoutListener listener = mListeners.get(i); + listener.onTimeout(mTimeout); } } @@ -151,9 +124,9 @@ public class OneHandedTimeoutHandler { final String innerPrefix = " "; pw.println(TAG + "states: "); pw.print(innerPrefix + "sTimeout="); - pw.println(sTimeout); + pw.println(mTimeout); pw.print(innerPrefix + "sListeners="); - pw.println(sListeners); + pw.println(mListeners); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java index 721382d52717..60709bef4daf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java @@ -30,6 +30,8 @@ import android.view.MotionEvent; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.android.wm.shell.common.ShellExecutor; + import java.io.PrintWriter; /** @@ -41,7 +43,8 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { private static final String TAG = "OneHandedTouchHandler"; private final Rect mLastUpdatedBounds = new Rect(); - private OneHandedTimeoutHandler mTimeoutHandler; + private final OneHandedTimeoutHandler mTimeoutHandler; + private final ShellExecutor mMainExecutor; @VisibleForTesting InputMonitor mInputMonitor; @@ -54,8 +57,10 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { private boolean mIsOnStopTransitioning; private boolean mIsInOutsideRegion; - public OneHandedTouchHandler() { - mTimeoutHandler = OneHandedTimeoutHandler.get(); + public OneHandedTouchHandler(OneHandedTimeoutHandler timeoutHandler, + ShellExecutor mainExecutor) { + mTimeoutHandler = timeoutHandler; + mMainExecutor = mainExecutor; updateIsEnabled(); } @@ -128,7 +133,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { mInputMonitor = InputManager.getInstance().monitorGestureInput( "onehanded-touch", DEFAULT_DISPLAY); mInputEventReceiver = new EventReceiver( - mInputMonitor.getInputChannel(), Looper.getMainLooper()); + mInputMonitor.getInputChannel(), mMainExecutor.getLooper()); } } @@ -150,6 +155,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { pw.println(mLastUpdatedBounds); } + // TODO: Use BatchedInputEventReceiver private class EventReceiver extends InputEventReceiver { EventReceiver(InputChannel channel, Looper looper) { super(channel, looper); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java index a944e3bc50cf..492130bebb30 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java @@ -21,7 +21,6 @@ import android.content.Context; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; -import android.os.Handler; import android.os.SystemProperties; import android.provider.Settings; import android.view.Gravity; @@ -36,6 +35,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import com.android.wm.shell.R; +import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; @@ -57,7 +57,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { private View mTutorialView; private Point mDisplaySize = new Point(); - private Handler mUpdateHandler; private ContentResolver mContentResolver; private boolean mCanShowTutorial; private String mStartOneHandedDescription; @@ -82,69 +81,67 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { private final OneHandedAnimationCallback mAnimationCallback = new OneHandedAnimationCallback() { @Override public void onTutorialAnimationUpdate(int offset) { - mUpdateHandler.post(() -> onAnimationUpdate(offset)); + onAnimationUpdate(offset); } @Override public void onOneHandedAnimationStart( OneHandedAnimationController.OneHandedTransitionAnimator animator) { - mUpdateHandler.post(() -> { - final Rect startValue = (Rect) animator.getStartValue(); - if (mTriggerState == ONE_HANDED_TRIGGER_STATE.UNSET) { - mTriggerState = (startValue.top == 0) - ? ONE_HANDED_TRIGGER_STATE.ENTERING : ONE_HANDED_TRIGGER_STATE.EXITING; - if (mCanShowTutorial && mTriggerState == ONE_HANDED_TRIGGER_STATE.ENTERING) { - createTutorialTarget(); - } + final Rect startValue = (Rect) animator.getStartValue(); + if (mTriggerState == ONE_HANDED_TRIGGER_STATE.UNSET) { + mTriggerState = (startValue.top == 0) + ? ONE_HANDED_TRIGGER_STATE.ENTERING : ONE_HANDED_TRIGGER_STATE.EXITING; + if (mCanShowTutorial && mTriggerState == ONE_HANDED_TRIGGER_STATE.ENTERING) { + createTutorialTarget(); } - }); + } } }; - public OneHandedTutorialHandler(Context context) { + public OneHandedTutorialHandler(Context context, ShellExecutor mainExecutor) { context.getDisplay().getRealSize(mDisplaySize); mPackageName = context.getPackageName(); mContentResolver = context.getContentResolver(); - mUpdateHandler = new Handler(); mWindowManager = context.getSystemService(WindowManager.class); mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); - mTargetViewContainer = new FrameLayout(context); - mTargetViewContainer.setClipChildren(false); + + mStartOneHandedDescription = context.getResources().getString( + R.string.accessibility_action_start_one_handed); + mStopOneHandedDescription = context.getResources().getString( + R.string.accessibility_action_stop_one_handed); + mCanShowTutorial = (Settings.Secure.getInt(mContentResolver, + Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT) + ? false : true; final float offsetPercentageConfig = context.getResources().getFraction( R.fraction.config_one_handed_offset, 1, 1); final int sysPropPercentageConfig = SystemProperties.getInt( ONE_HANDED_MODE_OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f)); mTutorialAreaHeight = Math.round(mDisplaySize.y * (sysPropPercentageConfig / 100.0f)); - mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null); - mTargetViewContainer.addView(mTutorialView); - mCanShowTutorial = (Settings.Secure.getInt(mContentResolver, - Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT) - ? false : true; - mStartOneHandedDescription = context.getResources().getString( - R.string.accessibility_action_start_one_handed); - mStopOneHandedDescription = context.getResources().getString( - R.string.accessibility_action_stop_one_handed); + + mainExecutor.execute(() -> { + mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, + null); + mTargetViewContainer = new FrameLayout(context); + mTargetViewContainer.setClipChildren(false); + mTargetViewContainer.addView(mTutorialView); + }); } @Override public void onStartFinished(Rect bounds) { - mUpdateHandler.post(() -> { - updateFinished(View.VISIBLE, 0f); - updateTutorialCount(); - announcementForScreenReader(true); - mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET; - }); + updateFinished(View.VISIBLE, 0f); + updateTutorialCount(); + announcementForScreenReader(true); + mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET; } @Override public void onStopFinished(Rect bounds) { - mUpdateHandler.post(() -> { - updateFinished(View.INVISIBLE, -mTargetViewContainer.getHeight()); - announcementForScreenReader(false); - removeTutorialFromWindowManager(); - mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET; - }); + updateFinished(View.INVISIBLE, -mTargetViewContainer.getHeight()); + announcementForScreenReader(false); + removeTutorialFromWindowManager(); + mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET; } private void updateFinished(int visible, float finalPosition) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java index 7194fc70025c..3b65899364cd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java @@ -53,7 +53,7 @@ public class PipAccessibilityInteractionConnection { private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList; private final Context mContext; - private final ShellExecutor mShellMainExcutor; + private final ShellExecutor mMainExcutor; private final @NonNull PipBoundsState mPipBoundsState; private final PipMotionHelper mMotionHelper; private final PipTaskOrganizer mTaskOrganizer; @@ -72,9 +72,9 @@ public class PipAccessibilityInteractionConnection { @NonNull PipBoundsState pipBoundsState, PipMotionHelper motionHelper, PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm, AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback, - ShellExecutor shellMainExcutor) { + ShellExecutor mainExcutor) { mContext = context; - mShellMainExcutor = shellMainExcutor; + mMainExcutor = mainExcutor; mPipBoundsState = pipBoundsState; mMotionHelper = motionHelper; mTaskOrganizer = taskOrganizer; @@ -271,7 +271,7 @@ public class PipAccessibilityInteractionConnection { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec, Bundle arguments) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this .findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid, @@ -285,7 +285,7 @@ public class PipAccessibilityInteractionConnection { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByViewId( accessibilityNodeId, viewId, bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid, spec); @@ -298,7 +298,7 @@ public class PipAccessibilityInteractionConnection { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByText( accessibilityNodeId, text, bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid, spec); @@ -310,7 +310,7 @@ public class PipAccessibilityInteractionConnection { int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this.findFocus(accessibilityNodeId, focusType, bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid, spec); @@ -322,7 +322,7 @@ public class PipAccessibilityInteractionConnection { int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this.focusSearch(accessibilityNodeId, direction, bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid, @@ -335,7 +335,7 @@ public class PipAccessibilityInteractionConnection { Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid) throws RemoteException { - mShellMainExcutor.execute(() -> { + mMainExcutor.execute(() -> { PipAccessibilityInteractionConnection.this.performAccessibilityAction( accessibilityNodeId, action, arguments, interactionId, callback, flags, interrogatingPid, interrogatingTid); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java index a8a3a9fd7da2..17fc0578dd2b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java @@ -25,6 +25,8 @@ import android.view.SurfaceControl; 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; @@ -49,11 +51,14 @@ public class OneHandedAnimationControllerTest extends OneHandedTestCase { @Mock private SurfaceControl mMockLeash; + @Mock + private ShellExecutor mMainExecutor; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mTutorialHandler = new OneHandedTutorialHandler(mContext); + mTutorialHandler = new OneHandedTutorialHandler(mContext, mMainExecutor); mOneHandedAnimationController = new OneHandedAnimationController(mContext); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 20184bfd5541..16d13f40f840 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.om.IOverlayManager; +import android.os.Handler; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -33,6 +34,7 @@ import android.view.Display; import androidx.test.filters.SmallTest; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerImpl; import org.junit.Before; @@ -45,7 +47,6 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedControllerTest extends OneHandedTestCase { Display mDisplay; OneHandedController mOneHandedController; @@ -69,11 +70,16 @@ public class OneHandedControllerTest extends OneHandedTestCase { IOverlayManager mMockOverlayManager; @Mock TaskStackListenerImpl mMockTaskStackListener; + @Mock + ShellExecutor mMockShellMainExecutor; + @Mock + Handler mMockShellMainHandler; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mDisplay = mContext.getDisplay(); + mTimeoutHandler = Mockito.spy(new OneHandedTimeoutHandler(mMockShellMainExecutor)); OneHandedController oneHandedController = new OneHandedController( mContext, mMockDisplayController, @@ -82,10 +88,12 @@ public class OneHandedControllerTest extends OneHandedTestCase { mMockTouchHandler, mMockTutorialHandler, mMockGestureHandler, + mTimeoutHandler, mMockOverlayManager, - mMockTaskStackListener); + mMockTaskStackListener, + mMockShellMainExecutor, + mMockShellMainHandler); mOneHandedController = Mockito.spy(oneHandedController); - mTimeoutHandler = Mockito.spy(OneHandedTimeoutHandler.get()); when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); @@ -97,7 +105,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mContext); OneHandedDisplayAreaOrganizer displayAreaOrganizer = new OneHandedDisplayAreaOrganizer( mContext, mMockDisplayController, animationController, mMockTutorialHandler, - Runnable::run, mMockBackgroundOrganizer); + mMockBackgroundOrganizer, mMockShellMainExecutor); assertThat(displayAreaOrganizer.isInOneHanded()).isFalse(); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java index 3d9fad9097f8..6cfd0c43724c 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java @@ -44,6 +44,7 @@ import android.window.WindowContainerTransaction; import androidx.test.filters.SmallTest; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import org.junit.Before; import org.junit.Test; @@ -53,7 +54,6 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { static final int DISPLAY_WIDTH = 1000; static final int DISPLAY_HEIGHT = 1000; @@ -82,9 +82,8 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { WindowContainerTransaction mMockWindowContainerTransaction; @Mock OneHandedBackgroundPanelOrganizer mMockBackgroundOrganizer; - - Handler mSpyUpdateHandler; - Handler.Callback mUpdateCallback = (msg) -> false; + @Mock + ShellExecutor mMockShellMainExecutor; @Before public void setUp() throws Exception { @@ -110,19 +109,17 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { when(mMockLeash.getWidth()).thenReturn(DISPLAY_WIDTH); when(mMockLeash.getHeight()).thenReturn(DISPLAY_HEIGHT); - mDisplayAreaOrganizer = new OneHandedDisplayAreaOrganizer(mContext, + mDisplayAreaOrganizer = spy(new OneHandedDisplayAreaOrganizer(mContext, mMockDisplayController, mMockAnimationController, mTutorialHandler, - Runnable::run, mMockBackgroundOrganizer); - mSpyUpdateHandler = spy(new Handler(OneHandedThread.get().getLooper(), mUpdateCallback)); - mDisplayAreaOrganizer.setUpdateHandler(mSpyUpdateHandler); + mMockBackgroundOrganizer, + mMockShellMainExecutor)); } @Test public void testOnDisplayAreaAppeared() { mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash); - mTestableLooper.processAllMessages(); verify(mMockAnimationController, never()).getAnimator(any(), any(), any()); } @@ -130,31 +127,18 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { @Test public void testOnDisplayAreaVanished() { mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash); - mTestableLooper.processAllMessages(); mDisplayAreaOrganizer.onDisplayAreaVanished(mDisplayAreaInfo); assertThat(mDisplayAreaOrganizer.mDisplayAreaMap).isEmpty(); } @Test - public void testScheduleOffset() { - final int xOffSet = 0; - final int yOffSet = 100; - mDisplayAreaOrganizer.scheduleOffset(xOffSet, yOffSet); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); - } - - @Test public void testRotation_portrait_0_to_landscape_90() { when(mMockLeash.isValid()).thenReturn(false); // Rotate 0 -> 90 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_90, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -163,9 +147,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 0 -> 270 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_270, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -174,9 +156,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 180 -> 90 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_90, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -185,9 +165,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 180 -> 270 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_270, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -196,9 +174,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 90 -> 0 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_0, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -207,9 +183,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 90 -> 180 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_180, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -218,9 +192,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 270 -> 0 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_0, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -229,9 +201,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 270 -> 180 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_180, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler).sendMessage(any()); + verify(mDisplayAreaOrganizer).finishOffset(anyInt(), anyInt()); } @Test @@ -240,9 +210,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 0 -> 0 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_0, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -251,9 +219,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 0 -> 180 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_180, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -262,9 +228,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 180 -> 180 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_180, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -273,9 +237,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 180 -> 0 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_0, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -284,9 +246,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 90 -> 90 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_90, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -295,9 +255,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 90 -> 270 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_270, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -306,9 +264,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 270 -> 270 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_270, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } @Test @@ -317,8 +273,6 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { // Rotate 270 -> 90 mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_90, mMockWindowContainerTransaction); - mTestableLooper.processAllMessages(); - - verify(mSpyUpdateHandler, never()).sendMessage(any()); + verify(mDisplayAreaOrganizer, never()).finishOffset(anyInt(), anyInt()); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java index fb417c8ca5e8..e5f2ff717e37 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java @@ -26,6 +26,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import org.junit.Before; import org.junit.Ignore; @@ -36,17 +37,20 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedGestureHandlerTest extends OneHandedTestCase { OneHandedTutorialHandler mTutorialHandler; OneHandedGestureHandler mGestureHandler; @Mock DisplayController mMockDisplayController; + @Mock + ShellExecutor mMockShellMainExecutor; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mTutorialHandler = new OneHandedTutorialHandler(mContext); - mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController); + mTutorialHandler = new OneHandedTutorialHandler(mContext, mMockShellMainExecutor); + mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController, + mMockShellMainExecutor); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java index 7c11138a47aa..f8c9d535ba94 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java @@ -38,7 +38,6 @@ import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedSettingsUtilTest extends OneHandedTestCase { ContentResolver mContentResolver; ContentObserver mContentObserver; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java index e2b70c3bcc70..9219f15afc7f 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java @@ -20,43 +20,46 @@ import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TI import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER; import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS; -import static com.android.wm.shell.onehanded.OneHandedTimeoutHandler.ONE_HANDED_TIMEOUT_STOP_MSG; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; +import android.os.Looper; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; 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; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; + @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedTimeoutHandlerTest extends OneHandedTestCase { - OneHandedTimeoutHandler mTimeoutHandler; + private OneHandedTimeoutHandler mTimeoutHandler; + private ShellExecutor mMainExecutor; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mTimeoutHandler = Mockito.spy(OneHandedTimeoutHandler.get()); - } - - @Test - public void testTimeoutHandler_isNotNull() { - assertThat(OneHandedTimeoutHandler.get()).isNotNull(); + mMainExecutor = new TestShellExecutor(); + mTimeoutHandler = Mockito.spy(new OneHandedTimeoutHandler(mMainExecutor)); } @Test public void testTimeoutHandler_getTimeout_defaultMedium() { - assertThat(OneHandedTimeoutHandler.get().getTimeout()).isEqualTo( + assertThat(mTimeoutHandler.getTimeout()).isEqualTo( ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); } @@ -64,28 +67,29 @@ public class OneHandedTimeoutHandlerTest extends OneHandedTestCase { public void testTimeoutHandler_setNewTime_resetTimer() { mTimeoutHandler.setTimeout(ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); verify(mTimeoutHandler).resetTimer(); - assertThat(mTimeoutHandler.sHandler.hasMessages(ONE_HANDED_TIMEOUT_STOP_MSG)).isNotNull(); + assertTrue(mTimeoutHandler.hasScheduledTimeout()); } @Test public void testSetTimeoutNever_neverResetTimer() { mTimeoutHandler.setTimeout(ONE_HANDED_TIMEOUT_NEVER); - assertThat(!mTimeoutHandler.sHandler.hasMessages(ONE_HANDED_TIMEOUT_STOP_MSG)).isNotNull(); + assertFalse(mTimeoutHandler.hasScheduledTimeout()); } @Test public void testSetTimeoutShort() { mTimeoutHandler.setTimeout(ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS); verify(mTimeoutHandler).resetTimer(); - assertThat(mTimeoutHandler.sHandler.hasMessages(ONE_HANDED_TIMEOUT_STOP_MSG)).isNotNull(); + assertThat(mTimeoutHandler.getTimeout()).isEqualTo(ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS); + assertTrue(mTimeoutHandler.hasScheduledTimeout()); } @Test public void testSetTimeoutMedium() { mTimeoutHandler.setTimeout(ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); verify(mTimeoutHandler).resetTimer(); - assertThat(mTimeoutHandler.sHandler.hasMessages( - ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS)).isNotNull(); + assertThat(mTimeoutHandler.getTimeout()).isEqualTo(ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); + assertTrue(mTimeoutHandler.hasScheduledTimeout()); } @Test @@ -96,10 +100,38 @@ public class OneHandedTimeoutHandlerTest extends OneHandedTestCase { @Test public void testDragging_shouldRemoveAndSendEmptyMessageDelay() { - final boolean isDragging = true; mTimeoutHandler.setTimeout(ONE_HANDED_TIMEOUT_LONG_IN_SECONDS); mTimeoutHandler.resetTimer(); - TestableLooper.get(this).processAllMessages(); - assertThat(mTimeoutHandler.sHandler.hasMessages(ONE_HANDED_TIMEOUT_STOP_MSG)).isNotNull(); + assertTrue(mTimeoutHandler.hasScheduledTimeout()); + } + + private class TestShellExecutor implements ShellExecutor { + private ArrayList<Runnable> mExecuted = new ArrayList<>(); + private ArrayList<Runnable> mDelayed = new ArrayList<>(); + + @Override + public void execute(Runnable runnable) { + mExecuted.add(runnable); + } + + @Override + public void executeDelayed(Runnable r, long delayMillis) { + mDelayed.add(r); + } + + @Override + public void removeCallbacks(Runnable r) { + mDelayed.remove(r); + } + + @Override + public boolean hasCallback(Runnable r) { + return mDelayed.contains(r); + } + + @Override + public Looper getLooper() { + return Looper.myLooper(); + } } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java index c69e385b2602..d3b02caf8b65 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java @@ -23,22 +23,30 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; +import com.android.wm.shell.common.ShellExecutor; + import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedTouchHandlerTest extends OneHandedTestCase { - OneHandedTouchHandler mTouchHandler; + private OneHandedTouchHandler mTouchHandler; + + @Mock + private OneHandedTimeoutHandler mTimeoutHandler; + + @Mock + private ShellExecutor mMainExecutor; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mTouchHandler = new OneHandedTouchHandler(); + mTouchHandler = new OneHandedTouchHandler(mTimeoutHandler, mMainExecutor); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java index b187dc981bf8..c451b8b2d2d7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java @@ -19,12 +19,14 @@ package com.android.wm.shell.onehanded; import static org.mockito.Mockito.verify; import android.content.om.IOverlayManager; +import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerImpl; import org.junit.Before; @@ -35,12 +37,12 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Mock OneHandedTouchHandler mTouchHandler; OneHandedTutorialHandler mTutorialHandler; OneHandedGestureHandler mGestureHandler; + OneHandedTimeoutHandler mTimeoutHandler; OneHandedController mOneHandedController; @Mock DisplayController mMockDisplayController; @@ -52,12 +54,18 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { IOverlayManager mMockOverlayManager; @Mock TaskStackListenerImpl mMockTaskStackListener; + @Mock + ShellExecutor mMockShellMainExecutor; + @Mock + Handler mMockShellMainHandler; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mTutorialHandler = new OneHandedTutorialHandler(mContext); - mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController); + mTutorialHandler = new OneHandedTutorialHandler(mContext, mMockShellMainExecutor); + mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor); + mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController, + mMockShellMainExecutor); mOneHandedController = new OneHandedController( getContext(), mMockDisplayController, @@ -66,8 +74,11 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { mTouchHandler, mTutorialHandler, mGestureHandler, + mTimeoutHandler, mMockOverlayManager, - mMockTaskStackListener); + mMockTaskStackListener, + mMockShellMainExecutor, + mMockShellMainHandler); } @Test diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java index e20cd44974bb..f0ccc6d15661 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java @@ -45,9 +45,9 @@ public class TvWMShellModule { @WMSingleton @Provides static DisplayImeController provideDisplayImeController(IWindowManager wmService, - DisplayController displayController, @ShellMainThread ShellExecutor shellMainExecutor, + DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, TransactionPool transactionPool) { - return new DisplayImeController(wmService, displayController, shellMainExecutor, + return new DisplayImeController(wmService, displayController, mainExecutor, transactionPool); } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 08194291ce2f..715b0a25e461 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -43,6 +43,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.Dependency; import com.android.systemui.SystemUI; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationModeController; @@ -67,6 +68,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; import java.util.Optional; +import java.util.concurrent.Executor; import javax.inject.Inject; @@ -86,18 +88,21 @@ public final class WMShell extends SystemUI | SYSUI_STATE_BUBBLES_EXPANDED | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; + // Shell interfaces + private final Optional<Pip> mPipOptional; + private final Optional<LegacySplitScreen> mSplitScreenOptional; + private final Optional<OneHanded> mOneHandedOptional; + private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional; + private final Optional<ShellCommandHandler> mShellCommandHandler; + private final CommandQueue mCommandQueue; private final ConfigurationController mConfigurationController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final NavigationModeController mNavigationModeController; private final ScreenLifecycle mScreenLifecycle; private final SysUiState mSysUiState; - private final Optional<Pip> mPipOptional; - private final Optional<LegacySplitScreen> mSplitScreenOptional; - private final Optional<OneHanded> mOneHandedOptional; - private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional; private final ProtoTracer mProtoTracer; - private final Optional<ShellCommandHandler> mShellCommandHandler; + private final Executor mSysUiMainExecutor; private boolean mIsSysUiStateValid; private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback; @@ -105,18 +110,20 @@ public final class WMShell extends SystemUI private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback; @Inject - public WMShell(Context context, CommandQueue commandQueue, + public WMShell(Context context, + Optional<Pip> pipOptional, + Optional<LegacySplitScreen> splitScreenOptional, + Optional<OneHanded> oneHandedOptional, + Optional<HideDisplayCutout> hideDisplayCutoutOptional, + Optional<ShellCommandHandler> shellCommandHandler, + CommandQueue commandQueue, ConfigurationController configurationController, KeyguardUpdateMonitor keyguardUpdateMonitor, NavigationModeController navigationModeController, ScreenLifecycle screenLifecycle, SysUiState sysUiState, - Optional<Pip> pipOptional, - Optional<LegacySplitScreen> splitScreenOptional, - Optional<OneHanded> oneHandedOptional, - Optional<HideDisplayCutout> hideDisplayCutoutOptional, ProtoTracer protoTracer, - Optional<ShellCommandHandler> shellCommandHandler) { + @Main Executor sysUiMainExecutor) { super(context); mCommandQueue = commandQueue; mConfigurationController = configurationController; @@ -129,12 +136,13 @@ public final class WMShell extends SystemUI mOneHandedOptional = oneHandedOptional; mHideDisplayCutoutOptional = hideDisplayCutoutOptional; mProtoTracer = protoTracer; - mProtoTracer.add(this); mShellCommandHandler = shellCommandHandler; + mSysUiMainExecutor = sysUiMainExecutor; } @Override public void start() { + mProtoTracer.add(this); mCommandQueue.addCallback(this); mPipOptional.ifPresent(this::initPip); mSplitScreenOptional.ifPresent(this::initSplitScreen); @@ -213,34 +221,43 @@ public final class WMShell extends SystemUI oneHanded.registerTransitionCallback(new OneHandedTransitionCallback() { @Override public void onStartFinished(Rect bounds) { - mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, - true).commitUpdate(DEFAULT_DISPLAY); + mSysUiMainExecutor.execute(() -> { + mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, + true).commitUpdate(DEFAULT_DISPLAY); + }); } @Override public void onStopFinished(Rect bounds) { - mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, - false).commitUpdate(DEFAULT_DISPLAY); + mSysUiMainExecutor.execute(() -> { + mSysUiState.setFlag(SYSUI_STATE_ONE_HANDED_ACTIVE, + false).commitUpdate(DEFAULT_DISPLAY); + }); } }); oneHanded.registerGestureCallback(new OneHandedGestureEventCallback() { @Override public void onStart() { - if (oneHanded.isOneHandedEnabled()) { - oneHanded.startOneHanded(); - } else if (oneHanded.isSwipeToNotificationEnabled()) { - mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN); - } + mSysUiMainExecutor.execute(() -> { + if (oneHanded.isOneHandedEnabled()) { + oneHanded.startOneHanded(); + } else if (oneHanded.isSwipeToNotificationEnabled()) { + mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN); + } + }); } @Override public void onStop() { - if (oneHanded.isOneHandedEnabled()) { - oneHanded.stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT); - } else if (oneHanded.isSwipeToNotificationEnabled()) { - mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP); - } + mSysUiMainExecutor.execute(() -> { + if (oneHanded.isOneHandedEnabled()) { + oneHanded.stopOneHanded( + OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT); + } else if (oneHanded.isSwipeToNotificationEnabled()) { + mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP); + } + }); } }); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index 572b15d5215a..bcb4386c2ceb 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -110,9 +110,9 @@ public abstract class WMShellBaseModule { @ShellMainThread public static Handler provideShellMainHandler(@Main Handler sysuiMainHandler) { if (ENABLE_SHELL_MAIN_THREAD) { - HandlerThread shellMainThread = new HandlerThread("wmshell.main"); - shellMainThread.start(); - return shellMainThread.getThreadHandler(); + HandlerThread mainThread = new HandlerThread("wmshell.main"); + mainThread.start(); + return mainThread.getThreadHandler(); } return sysuiMainHandler; } @@ -123,10 +123,10 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides @ShellMainThread - public static ShellExecutor provideShellMainExecutor(@ShellMainThread Handler shellMainHandler, + public static ShellExecutor provideShellMainExecutor(@ShellMainThread Handler mainHandler, @Main ShellExecutor sysuiMainExecutor) { if (ENABLE_SHELL_MAIN_THREAD) { - return new HandlerExecutor(shellMainHandler); + return new HandlerExecutor(mainHandler); } return sysuiMainExecutor; } @@ -177,7 +177,7 @@ public abstract class WMShellBaseModule { Optional<AppPairs> appPairsOptional, FullscreenTaskListener fullscreenTaskListener, Transitions transitions, - @ShellMainThread ShellExecutor shellMainExecutor) { + @ShellMainThread ShellExecutor mainExecutor) { return ShellInitImpl.create(displayImeController, dragAndDropController, shellTaskOrganizer, @@ -185,7 +185,7 @@ public abstract class WMShellBaseModule { appPairsOptional, fullscreenTaskListener, transitions, - shellMainExecutor); + mainExecutor); } /** @@ -201,10 +201,10 @@ public abstract class WMShellBaseModule { Optional<OneHanded> oneHandedOptional, Optional<HideDisplayCutout> hideDisplayCutout, Optional<AppPairs> appPairsOptional, - @ShellMainThread ShellExecutor shellMainExecutor) { + @ShellMainThread ShellExecutor mainExecutor) { return Optional.of(ShellCommandHandlerImpl.create(shellTaskOrganizer, legacySplitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout, - appPairsOptional, shellMainExecutor)); + appPairsOptional, mainExecutor)); } @WMSingleton @@ -216,8 +216,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static DisplayController provideDisplayController(Context context, - IWindowManager wmService, @ShellMainThread ShellExecutor shellMainExecutor) { - return new DisplayController(context, wmService, shellMainExecutor); + IWindowManager wmService, @ShellMainThread ShellExecutor mainExecutor) { + return new DisplayController(context, wmService, mainExecutor); } @WMSingleton @@ -236,8 +236,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static WindowManagerShellWrapper provideWindowManagerShellWrapper( - @ShellMainThread ShellExecutor shellMainExecutor) { - return new WindowManagerShellWrapper(shellMainExecutor); + @ShellMainThread ShellExecutor mainExecutor) { + return new WindowManagerShellWrapper(mainExecutor); } @WMSingleton @@ -277,8 +277,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static SyncTransactionQueue provideSyncTransactionQueue(TransactionPool pool, - @ShellMainThread ShellExecutor shellMainExecutor) { - return new SyncTransactionQueue(pool, shellMainExecutor); + @ShellMainThread ShellExecutor mainExecutor) { + return new SyncTransactionQueue(pool, mainExecutor); } @WMSingleton @@ -299,8 +299,8 @@ public abstract class WMShellBaseModule { @WMSingleton @Provides static TaskStackListenerImpl providerTaskStackListenerImpl( - @ShellMainThread Handler shellMainHandler) { - return new TaskStackListenerImpl(shellMainHandler); + @ShellMainThread Handler mainHandler) { + return new TaskStackListenerImpl(mainHandler); } @BindsOptionalOf @@ -319,20 +319,22 @@ public abstract class WMShellBaseModule { LauncherApps launcherApps, UiEventLogger uiEventLogger, ShellTaskOrganizer organizer, - @ShellMainThread ShellExecutor shellMainExecutor) { + @ShellMainThread ShellExecutor mainExecutor) { return Optional.of(BubbleController.create(context, null /* synchronizer */, floatingContentCoordinator, statusBarService, windowManager, windowManagerShellWrapper, launcherApps, uiEventLogger, organizer, - shellMainExecutor)); + mainExecutor)); } + // Needs the shell main handler for ContentObserver callbacks @WMSingleton @Provides static Optional<OneHanded> provideOneHandedController(Context context, DisplayController displayController, TaskStackListenerImpl taskStackListener, - @ShellMainThread ShellExecutor mainExecutor) { + @ShellMainThread ShellExecutor mainExecutor, + @ShellMainThread Handler mainHandler) { return Optional.ofNullable(OneHandedController.create(context, displayController, - taskStackListener, mainExecutor)); + taskStackListener, mainExecutor, mainHandler)); } @WMSingleton diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index e635e1708841..88f6e1ffac0c 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -62,9 +62,9 @@ public class WMShellModule { @WMSingleton @Provides static DisplayImeController provideDisplayImeController(IWindowManager wmService, - DisplayController displayController, @ShellMainThread ShellExecutor shellMainExecutor, + DisplayController displayController, @ShellMainThread ShellExecutor mainExecutor, TransactionPool transactionPool) { - return new DisplayImeController(wmService, displayController, shellMainExecutor, + return new DisplayImeController(wmService, displayController, mainExecutor, transactionPool); } @@ -96,11 +96,11 @@ public class WMShellModule { PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper, TaskStackListenerImpl taskStackListener, - @ShellMainThread ShellExecutor shellMainExecutor) { + @ShellMainThread ShellExecutor mainExecutor) { return Optional.ofNullable(PipController.create(context, displayController, pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTouchHandler, - windowManagerShellWrapper, taskStackListener, shellMainExecutor)); + windowManagerShellWrapper, taskStackListener, mainExecutor)); } @WMSingleton @@ -131,10 +131,10 @@ public class WMShellModule { PipTaskOrganizer pipTaskOrganizer, FloatingContentCoordinator floatingContentCoordinator, PipUiEventLogger pipUiEventLogger, - @ShellMainThread ShellExecutor shellMainExecutor) { + @ShellMainThread ShellExecutor mainExecutor) { return new PipTouchHandler(context, menuPhoneController, pipBoundsAlgorithm, pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger, - shellMainExecutor); + mainExecutor); } @WMSingleton diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 31bf7120900f..446d3f2f72a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.tracing.ProtoTracer; import com.android.wm.shell.ShellCommandHandler; +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; @@ -63,22 +64,22 @@ public class WMShellTest extends SysuiTestCase { @Mock SysUiState mSysUiState; @Mock Pip mPip; @Mock PipTouchHandler mPipTouchHandler; - @Mock - LegacySplitScreen mLegacySplitScreen; + @Mock LegacySplitScreen mLegacySplitScreen; @Mock OneHanded mOneHanded; @Mock HideDisplayCutout mHideDisplayCutout; @Mock ProtoTracer mProtoTracer; @Mock ShellCommandHandler mShellCommandHandler; + @Mock ShellExecutor mSysUiMainExecutor; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mWMShell = new WMShell(mContext, mCommandQueue, mConfigurationController, + mWMShell = new WMShell(mContext, Optional.of(mPip), Optional.of(mLegacySplitScreen), + Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), + Optional.of(mShellCommandHandler), mCommandQueue, mConfigurationController, mKeyguardUpdateMonitor, mNavigationModeController, - mScreenLifecycle, mSysUiState, Optional.of(mPip), Optional.of(mLegacySplitScreen), - Optional.of(mOneHanded), Optional.of(mHideDisplayCutout), mProtoTracer, - Optional.of(mShellCommandHandler)); + mScreenLifecycle, mSysUiState, mProtoTracer, mSysUiMainExecutor); when(mPip.getPipTouchHandler()).thenReturn(mPipTouchHandler); } |