Migrate SystemGesturePointerEventListener to WindowContext
Previously system context derived display context passed to
SystemGesturePointerEventListener.
After R, it threw IncorrectContextUsageViolation when initialization
because display context is not a UI context.
This CL changes to pass window context to fix the Violation.
Bug: 177650348
Test: atest WmTests
Test: atest DisplayPolicyTests#testDisplayPolicyNoCrash
Change-Id: I0d17327d8a8c14ec626c0dd9ad1a4e8529174598
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5460e36..cee6740 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -67,6 +67,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
@@ -240,7 +241,7 @@
}
}
- private final SystemGesturesPointerEventListener mSystemGestures;
+ private SystemGesturesPointerEventListener mSystemGestures;
private volatile int mLidState = LID_ABSENT;
private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -382,7 +383,7 @@
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
- private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
+ private GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;
@@ -446,119 +447,6 @@
final Looper looper = UiThread.getHandler().getLooper();
mHandler = new PolicyHandler(looper);
- mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,
- new SystemGesturesPointerEventListener.Callbacks() {
- @Override
- public void onSwipeFromTop() {
- synchronized (mLock) {
- if (mStatusBar != null) {
- requestTransientBars(mStatusBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
- }
- }
-
- @Override
- public void onSwipeFromBottom() {
- synchronized (mLock) {
- if (mNavigationBar != null
- && mNavigationBarPosition == NAV_BAR_BOTTOM) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
- }
- }
-
- @Override
- public void onSwipeFromRight() {
- final Region excludedRegion = Region.obtain();
- synchronized (mLock) {
- mDisplayContent.calculateSystemGestureExclusion(
- excludedRegion, null /* outUnrestricted */);
- final boolean excluded =
- mSystemGestures.currentGestureStartedInRegion(excludedRegion);
- if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_RIGHT
- || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT);
- }
- excludedRegion.recycle();
- }
-
- @Override
- public void onSwipeFromLeft() {
- final Region excludedRegion = Region.obtain();
- synchronized (mLock) {
- mDisplayContent.calculateSystemGestureExclusion(
- excludedRegion, null /* outUnrestricted */);
- final boolean excluded =
- mSystemGestures.currentGestureStartedInRegion(excludedRegion);
- if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_LEFT
- || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_LEFT);
- }
- excludedRegion.recycle();
- }
-
- @Override
- public void onFling(int duration) {
- if (mService.mPowerManagerInternal != null) {
- mService.mPowerManagerInternal.setPowerBoost(
- Boost.INTERACTION, duration);
- }
- }
-
- @Override
- public void onDebug() {
- // no-op
- }
-
- private WindowOrientationListener getOrientationListener() {
- final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
- return rotation != null ? rotation.getOrientationListener() : null;
- }
-
- @Override
- public void onDown() {
- final WindowOrientationListener listener = getOrientationListener();
- if (listener != null) {
- listener.onTouchStart();
- }
- }
-
- @Override
- public void onUpOrCancel() {
- final WindowOrientationListener listener = getOrientationListener();
- if (listener != null) {
- listener.onTouchEnd();
- }
- }
-
- @Override
- public void onMouseHoverAtTop() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
- msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
- mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
- }
-
- @Override
- public void onMouseHoverAtBottom() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
- msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
- mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
- }
-
- @Override
- public void onMouseLeaveFromEdge() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- }
- });
- displayContent.registerPointerEventListener(mSystemGestures);
mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {
private Runnable mAppTransitionPending = () -> {
@@ -614,7 +502,7 @@
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
mService.mVrModeEnabled);
- // TODO: Make it can take screenshot on external display
+ // TODO(b/180986447): Make it can take screenshot on external display
mScreenshotHelper = displayContent.isDefaultDisplay
? new ScreenshotHelper(mContext) : null;
@@ -638,16 +526,6 @@
mRefreshRatePolicy = new RefreshRatePolicy(mService,
mDisplayContent.getDisplayInfo(),
mService.mHighRefreshRateDenylist);
-
- mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(mHandler,
- mContext, () -> {
- synchronized (mLock) {
- onConfigurationChanged();
- mSystemGestures.onConfigurationChanged();
- mDisplayContent.updateSystemGestureExclusion();
- }
- });
- mHandler.post(mGestureNavigationSettingsObserver::register);
}
private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) {
@@ -666,12 +544,154 @@
}
void systemReady() {
- mSystemGestures.systemReady();
if (mService.mPointerLocationEnabled) {
setPointerLocationEnabled(true);
}
}
+ @NonNull
+ private GestureNavigationSettingsObserver getGestureNavigationSettingsObserver() {
+ if (mGestureNavigationSettingsObserver == null) {
+ mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(mHandler,
+ mContext, () -> {
+ synchronized (mLock) {
+ onConfigurationChanged();
+ getSystemGestures().onConfigurationChanged();
+ mDisplayContent.updateSystemGestureExclusion();
+ }
+ });
+ mHandler.post(mGestureNavigationSettingsObserver::register);
+ }
+ return mGestureNavigationSettingsObserver;
+ }
+
+ @NonNull
+ private SystemGesturesPointerEventListener getSystemGestures() {
+ if (mSystemGestures == null) {
+ final Context gestureContext = mUiContext.createWindowContext(
+ mDisplayContent.getDisplay(), TYPE_POINTER, null /* options */);
+ mSystemGestures = new SystemGesturesPointerEventListener(gestureContext, mHandler,
+ new SystemGesturesPointerEventListener.Callbacks() {
+ @Override
+ public void onSwipeFromTop() {
+ synchronized (mLock) {
+ if (mStatusBar != null) {
+ requestTransientBars(mStatusBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
+ }
+ }
+
+ @Override
+ public void onSwipeFromBottom() {
+ synchronized (mLock) {
+ if (mNavigationBar != null
+ && mNavigationBarPosition == NAV_BAR_BOTTOM) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
+ }
+ }
+
+ @Override
+ public void onSwipeFromRight() {
+ final Region excludedRegion = Region.obtain();
+ synchronized (mLock) {
+ mDisplayContent.calculateSystemGestureExclusion(
+ excludedRegion, null /* outUnrestricted */);
+ final boolean excluded = mSystemGestures
+ .currentGestureStartedInRegion(excludedRegion);
+ if (mNavigationBar != null
+ && (mNavigationBarPosition == NAV_BAR_RIGHT
+ || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT);
+ }
+ excludedRegion.recycle();
+ }
+
+ @Override
+ public void onSwipeFromLeft() {
+ final Region excludedRegion = Region.obtain();
+ synchronized (mLock) {
+ mDisplayContent.calculateSystemGestureExclusion(
+ excludedRegion, null /* outUnrestricted */);
+ final boolean excluded = mSystemGestures
+ .currentGestureStartedInRegion(excludedRegion);
+ if (mNavigationBar != null
+ && (mNavigationBarPosition == NAV_BAR_LEFT
+ || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_LEFT);
+ }
+ excludedRegion.recycle();
+ }
+
+ @Override
+ public void onFling(int duration) {
+ if (mService.mPowerManagerInternal != null) {
+ mService.mPowerManagerInternal.setPowerBoost(
+ Boost.INTERACTION, duration);
+ }
+ }
+
+ @Override
+ public void onDebug() {
+ // no-op
+ }
+
+ private WindowOrientationListener getOrientationListener() {
+ final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
+ return rotation != null ? rotation.getOrientationListener() : null;
+ }
+
+ @Override
+ public void onDown() {
+ final WindowOrientationListener listener = getOrientationListener();
+ if (listener != null) {
+ listener.onTouchStart();
+ }
+ }
+
+ @Override
+ public void onUpOrCancel() {
+ final WindowOrientationListener listener = getOrientationListener();
+ if (listener != null) {
+ listener.onTouchEnd();
+ }
+ }
+
+ @Override
+ public void onMouseHoverAtTop() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
+ msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
+ mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
+ }
+
+ @Override
+ public void onMouseHoverAtBottom() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
+ msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
+ mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
+ }
+
+ @Override
+ public void onMouseLeaveFromEdge() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ }
+ });
+ mDisplayContent.registerPointerEventListener(getSystemGestures());
+ if (mService.mSystemReady) {
+ mSystemGestures.systemReady();
+ }
+ }
+ return mSystemGestures;
+ }
+
private int getDisplayId() {
return mDisplayContent.getDisplayId();
}
@@ -1447,8 +1467,7 @@
}
void onDisplayInfoChanged(DisplayInfo info) {
- mSystemGestures.screenWidth = info.logicalWidth;
- mSystemGestures.screenHeight = info.logicalHeight;
+ getSystemGestures().onDisplayInfoChanged(info);
}
private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
@@ -1961,7 +1980,7 @@
public void onOverlayChangedLw() {
updateCurrentUserResources();
onConfigurationChanged();
- mSystemGestures.onConfigurationChanged();
+ getSystemGestures().onConfigurationChanged();
}
/**
@@ -2032,10 +2051,10 @@
}
mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
- mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
- mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res);
- mNavButtonForcedVisible =
- mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
+ final GestureNavigationSettingsObserver observer = getGestureNavigationSettingsObserver();
+ mLeftGestureInset = observer.getLeftSensitivity(res);
+ mRightGestureInset = observer.getRightSensitivity(res);
+ mNavButtonForcedVisible = observer.areNavigationButtonForcedVisible();
mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
mNavigationBarAlwaysShowOnSideGesture =
res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);
@@ -3047,7 +3066,7 @@
}
void release() {
- mHandler.post(mGestureNavigationSettingsObserver::unregister);
+ mHandler.post(getGestureNavigationSettingsObserver()::unregister);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
index f3859b4..a98a478 100644
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -126,11 +126,17 @@
Slog.w(TAG, "Cannot create GestureDetector, display removed:" + displayId);
return;
}
+ onDisplayInfoChanged(info);
mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {
};
});
}
+ void onDisplayInfoChanged(DisplayInfo info) {
+ screenWidth = info.logicalWidth;
+ screenHeight = info.logicalHeight;
+ }
+
@Override
public void onPointerEvent(MotionEvent event) {
if (mGestureDetector != null && event.isTouchEvent()) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 2163661..db7054d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -321,4 +321,16 @@
assertFalse(navBarSource.getFrame().isEmpty());
assertTrue(imeSource.getFrame().contains(navBarSource.getFrame()));
}
+
+ @UseTestDisplay
+ @Test
+ public void testDisplayPolicyNotCrash() {
+ final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+
+ // Verify if modules initialized after DisplayContent ctr throws NPE.
+ displayPolicy.onDisplayInfoChanged(mDisplayInfo);
+ displayPolicy.onConfigurationChanged();
+ displayPolicy.onOverlayChangedLw();
+ displayPolicy.release();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index c13d6b1..ebc5c4f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -538,9 +538,8 @@
/** Creates a {@link DisplayContent} and adds it to the system. */
private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
- final DisplayContent display =
+ final DisplayContent dc =
new TestDisplayContent.Builder(mAtm, info).build();
- final DisplayContent dc = display.mDisplayContent;
// this display can show IME.
dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
return dc;