Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68c30247 authored by Charles Chen's avatar Charles Chen
Browse files

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
parent caf9ae8b
Loading
Loading
Loading
Loading
+154 −135
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
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_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
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_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
@@ -240,7 +241,7 @@ public class DisplayPolicy {
        }
        }
    }
    }


    private final SystemGesturesPointerEventListener mSystemGestures;
    private SystemGesturesPointerEventListener mSystemGestures;


    private volatile int mLidState = LID_ABSENT;
    private volatile int mLidState = LID_ABSENT;
    private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
    private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -382,7 +383,7 @@ public class DisplayPolicy {
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
    private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;


    private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
    private GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;


    private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;
    private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;


@@ -446,7 +447,130 @@ public class DisplayPolicy {


        final Looper looper = UiThread.getHandler().getLooper();
        final Looper looper = UiThread.getHandler().getLooper();
        mHandler = new PolicyHandler(looper);
        mHandler = new PolicyHandler(looper);
        mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,
        mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {

            private Runnable mAppTransitionPending = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionPending(displayId);
                }
            };

            private Runnable mAppTransitionCancelled = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionCancelled(displayId);
                }
            };

            private Runnable mAppTransitionFinished = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionFinished(displayId);
                }
            };

            @Override
            public void onAppTransitionPendingLocked() {
                mHandler.post(mAppTransitionPending);
            }

            @Override
            public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration,
                    long statusBarAnimationStartTime, long statusBarAnimationDuration) {
                mHandler.post(() -> {
                    StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                    if (statusBar != null) {
                        statusBar.appTransitionStarting(mContext.getDisplayId(),
                                statusBarAnimationStartTime, statusBarAnimationDuration);
                    }
                });
                return 0;
            }

            @Override
            public void onAppTransitionCancelledLocked(boolean keyguardGoingAway) {
                mHandler.post(mAppTransitionCancelled);
            }

            @Override
            public void onAppTransitionFinishedLocked(IBinder token) {
                mHandler.post(mAppTransitionFinished);
            }
        };
        displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
        mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
                mService.mVrModeEnabled);

        // TODO(b/180986447): Make it can take screenshot on external display
        mScreenshotHelper = displayContent.isDefaultDisplay
                ? new ScreenshotHelper(mContext) : null;

        if (mDisplayContent.isDefaultDisplay) {
            mHasStatusBar = true;
            mHasNavigationBar = mContext.getResources().getBoolean(R.bool.config_showNavigationBar);

            // Allow a system property to override this. Used by the emulator.
            // See also hasNavigationBar().
            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                mHasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                mHasNavigationBar = true;
            }
        } else {
            mHasStatusBar = false;
            mHasNavigationBar = mDisplayContent.supportsSystemDecorations();
        }

        mRefreshRatePolicy = new RefreshRatePolicy(mService,
                mDisplayContent.getDisplayInfo(),
                mService.mHighRefreshRateDenylist);
    }

    private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) {
        if (mStatusBarAlt != null && mStatusBarAltPosition == pos) {
            requestTransientBars(mStatusBarAlt);
        }
        if (mNavigationBarAlt != null && mNavigationBarAltPosition == pos) {
            requestTransientBars(mNavigationBarAlt);
        }
        if (mClimateBarAlt != null && mClimateBarAltPosition == pos) {
            requestTransientBars(mClimateBarAlt);
        }
        if (mExtraNavBarAlt != null && mExtraNavBarAltPosition == pos) {
            requestTransientBars(mExtraNavBarAlt);
        }
    }

    void 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() {
                    new SystemGesturesPointerEventListener.Callbacks() {
                        @Override
                        @Override
                        public void onSwipeFromTop() {
                        public void onSwipeFromTop() {
@@ -475,9 +599,10 @@ public class DisplayPolicy {
                            synchronized (mLock) {
                            synchronized (mLock) {
                                mDisplayContent.calculateSystemGestureExclusion(
                                mDisplayContent.calculateSystemGestureExclusion(
                                        excludedRegion, null /* outUnrestricted */);
                                        excludedRegion, null /* outUnrestricted */);
                            final boolean excluded =
                                final boolean excluded = mSystemGestures
                                    mSystemGestures.currentGestureStartedInRegion(excludedRegion);
                                        .currentGestureStartedInRegion(excludedRegion);
                            if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_RIGHT
                                if (mNavigationBar != null
                                        && (mNavigationBarPosition == NAV_BAR_RIGHT
                                        || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
                                        || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
                                    requestTransientBars(mNavigationBar);
                                    requestTransientBars(mNavigationBar);
                                }
                                }
@@ -492,9 +617,10 @@ public class DisplayPolicy {
                            synchronized (mLock) {
                            synchronized (mLock) {
                                mDisplayContent.calculateSystemGestureExclusion(
                                mDisplayContent.calculateSystemGestureExclusion(
                                        excludedRegion, null /* outUnrestricted */);
                                        excludedRegion, null /* outUnrestricted */);
                            final boolean excluded =
                                final boolean excluded = mSystemGestures
                                    mSystemGestures.currentGestureStartedInRegion(excludedRegion);
                                        .currentGestureStartedInRegion(excludedRegion);
                            if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_LEFT
                                if (mNavigationBar != null
                                        && (mNavigationBarPosition == NAV_BAR_LEFT
                                        || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
                                        || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
                                    requestTransientBars(mNavigationBar);
                                    requestTransientBars(mNavigationBar);
                                }
                                }
@@ -558,119 +684,13 @@ public class DisplayPolicy {
                            mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                            mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
                        }
                        }
                    });
                    });
        displayContent.registerPointerEventListener(mSystemGestures);
            mDisplayContent.registerPointerEventListener(getSystemGestures());
        mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {
            if (mService.mSystemReady) {

            private Runnable mAppTransitionPending = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionPending(displayId);
                }
            };

            private Runnable mAppTransitionCancelled = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionCancelled(displayId);
                }
            };

            private Runnable mAppTransitionFinished = () -> {
                StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                if (statusBar != null) {
                    statusBar.appTransitionFinished(displayId);
                }
            };

            @Override
            public void onAppTransitionPendingLocked() {
                mHandler.post(mAppTransitionPending);
            }

            @Override
            public int onAppTransitionStartingLocked(boolean keyguardGoingAway, long duration,
                    long statusBarAnimationStartTime, long statusBarAnimationDuration) {
                mHandler.post(() -> {
                    StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
                    if (statusBar != null) {
                        statusBar.appTransitionStarting(mContext.getDisplayId(),
                                statusBarAnimationStartTime, statusBarAnimationDuration);
                    }
                });
                return 0;
            }

            @Override
            public void onAppTransitionCancelledLocked(boolean keyguardGoingAway) {
                mHandler.post(mAppTransitionCancelled);
            }

            @Override
            public void onAppTransitionFinishedLocked(IBinder token) {
                mHandler.post(mAppTransitionFinished);
            }
        };
        displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
        mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
                mService.mVrModeEnabled);

        // TODO: Make it can take screenshot on external display
        mScreenshotHelper = displayContent.isDefaultDisplay
                ? new ScreenshotHelper(mContext) : null;

        if (mDisplayContent.isDefaultDisplay) {
            mHasStatusBar = true;
            mHasNavigationBar = mContext.getResources().getBoolean(R.bool.config_showNavigationBar);

            // Allow a system property to override this. Used by the emulator.
            // See also hasNavigationBar().
            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                mHasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                mHasNavigationBar = true;
            }
        } else {
            mHasStatusBar = false;
            mHasNavigationBar = mDisplayContent.supportsSystemDecorations();
        }

        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) {
        if (mStatusBarAlt != null && mStatusBarAltPosition == pos) {
            requestTransientBars(mStatusBarAlt);
        }
        if (mNavigationBarAlt != null && mNavigationBarAltPosition == pos) {
            requestTransientBars(mNavigationBarAlt);
        }
        if (mClimateBarAlt != null && mClimateBarAltPosition == pos) {
            requestTransientBars(mClimateBarAlt);
        }
        if (mExtraNavBarAlt != null && mExtraNavBarAltPosition == pos) {
            requestTransientBars(mExtraNavBarAlt);
        }
    }

    void systemReady() {
                mSystemGestures.systemReady();
                mSystemGestures.systemReady();
        if (mService.mPointerLocationEnabled) {
            setPointerLocationEnabled(true);
            }
            }
        }
        }
        return mSystemGestures;
    }


    private int getDisplayId() {
    private int getDisplayId() {
        return mDisplayContent.getDisplayId();
        return mDisplayContent.getDisplayId();
@@ -1447,8 +1467,7 @@ public class DisplayPolicy {
    }
    }


    void onDisplayInfoChanged(DisplayInfo info) {
    void onDisplayInfoChanged(DisplayInfo info) {
        mSystemGestures.screenWidth = info.logicalWidth;
        getSystemGestures().onDisplayInfoChanged(info);
        mSystemGestures.screenHeight = info.logicalHeight;
    }
    }


    private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
    private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
@@ -1961,7 +1980,7 @@ public class DisplayPolicy {
    public void onOverlayChangedLw() {
    public void onOverlayChangedLw() {
        updateCurrentUserResources();
        updateCurrentUserResources();
        onConfigurationChanged();
        onConfigurationChanged();
        mSystemGestures.onConfigurationChanged();
        getSystemGestures().onConfigurationChanged();
    }
    }


    /**
    /**
@@ -2032,10 +2051,10 @@ public class DisplayPolicy {
        }
        }


        mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
        mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
        mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
        final GestureNavigationSettingsObserver observer = getGestureNavigationSettingsObserver();
        mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res);
        mLeftGestureInset = observer.getLeftSensitivity(res);
        mNavButtonForcedVisible =
        mRightGestureInset = observer.getRightSensitivity(res);
                mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
        mNavButtonForcedVisible = observer.areNavigationButtonForcedVisible();
        mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
        mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
        mNavigationBarAlwaysShowOnSideGesture =
        mNavigationBarAlwaysShowOnSideGesture =
                res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);
                res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);
@@ -3047,7 +3066,7 @@ public class DisplayPolicy {
    }
    }


    void release() {
    void release() {
        mHandler.post(mGestureNavigationSettingsObserver::unregister);
        mHandler.post(getGestureNavigationSettingsObserver()::unregister);
    }
    }


    @VisibleForTesting
    @VisibleForTesting
+6 −0
Original line number Original line Diff line number Diff line
@@ -126,11 +126,17 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
                Slog.w(TAG, "Cannot create GestureDetector, display removed:" + displayId);
                Slog.w(TAG, "Cannot create GestureDetector, display removed:" + displayId);
                return;
                return;
            }
            }
            onDisplayInfoChanged(info);
            mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {
            mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {
            };
            };
        });
        });
    }
    }


    void onDisplayInfoChanged(DisplayInfo info) {
        screenWidth = info.logicalWidth;
        screenHeight = info.logicalHeight;
    }

    @Override
    @Override
    public void onPointerEvent(MotionEvent event) {
    public void onPointerEvent(MotionEvent event) {
        if (mGestureDetector != null && event.isTouchEvent()) {
        if (mGestureDetector != null && event.isTouchEvent()) {
+12 −0
Original line number Original line Diff line number Diff line
@@ -321,4 +321,16 @@ public class DisplayPolicyTests extends WindowTestsBase {
        assertFalse(navBarSource.getFrame().isEmpty());
        assertFalse(navBarSource.getFrame().isEmpty());
        assertTrue(imeSource.getFrame().contains(navBarSource.getFrame()));
        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();
    }
}
}
+1 −2
Original line number Original line Diff line number Diff line
@@ -538,9 +538,8 @@ class WindowTestsBase extends SystemServiceTestsBase {


    /** Creates a {@link DisplayContent} and adds it to the system. */
    /** Creates a {@link DisplayContent} and adds it to the system. */
    private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
    private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
        final DisplayContent display =
        final DisplayContent dc =
                new TestDisplayContent.Builder(mAtm, info).build();
                new TestDisplayContent.Builder(mAtm, info).build();
        final DisplayContent dc = display.mDisplayContent;
        // this display can show IME.
        // this display can show IME.
        dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
        dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
        return dc;
        return dc;