summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Winson Chung <winsonc@google.com> 2020-12-02 22:54:15 -0800
committer Winson Chung <winsonc@google.com> 2021-01-12 10:05:03 -0800
commit5b4318517275d1be027538d62eb8b975ccaf0b7b (patch)
treece36c2a286cf5b9eddf2cd09be7b5123647980cd
parentb898264ff2f58566d02313d1471b2e9bf728c863 (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
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java307
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java217
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java95
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java71
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java16
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java90
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java68
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java14
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java13
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);
}