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

Commit 64a1ef6d authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Refine logic about updateHideNavInputEventReceiver" into rvc-dev...

Merge "Merge "Refine logic about updateHideNavInputEventReceiver" into rvc-dev am: 28382c8f" into rvc-dev-plus-aosp
parents 31ab3296 4412fd1b
Loading
Loading
Loading
Loading
+39 −20
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -156,6 +157,7 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InsetsFlags;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.MotionEvent;
@@ -391,7 +393,8 @@ public class DisplayPolicy {
    private boolean mDreamingLockscreen;
    private boolean mAllowLockscreenWhenOn;

    private InputConsumer mInputConsumer = null;
    @VisibleForTesting
    InputConsumer mInputConsumer = null;

    private PointerLocationView mPointerLocationView;

@@ -1372,13 +1375,6 @@ public class DisplayPolicy {
            synchronized (mLock) {
                mForceClearedSystemUiFlags &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
                mDisplayContent.reevaluateStatusBarVisibility();
                if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL && mNavigationBar != null) {
                    final InsetsControlTarget target =
                            mNavigationBar.getControllableInsetProvider().getControlTarget();
                    if (target != null) {
                        target.showInsets(Type.navigationBars(), false /* fromIme */);
                    }
                }
            }
        }
    };
@@ -1406,6 +1402,7 @@ public class DisplayPolicy {
                            if (mInputConsumer == null) {
                                return;
                            }
                            showNavigationBar();
                            // Any user activity always causes us to show the
                            // navigation controls, if they had been hidden.
                            // We also clear the low profile and only content
@@ -1439,6 +1436,16 @@ public class DisplayPolicy {
                finishInputEvent(event, false /* handled */);
            }
        }

        private void showNavigationBar() {
            final InsetsSourceProvider provider = mDisplayContent.getInsetsStateController()
                    .peekSourceProvider(ITYPE_NAVIGATION_BAR);
            final InsetsControlTarget target =
                    provider != null ? provider.getControlTarget() : null;
            if (target != null) {
                target.showInsets(Type.navigationBars(), false /* fromIme */);
            }
        }
    }

    private void simulateLayoutDecorWindow(WindowState win, DisplayFrames displayFrames,
@@ -1500,9 +1507,13 @@ public class DisplayPolicy {
        // drive nav being hidden only by whether it is requested.
        final int sysui = mLastSystemUiFlags;
        final int behavior = mLastBehavior;
        final InsetsSourceProvider provider =
                mDisplayContent.getInsetsStateController().peekSourceProvider(ITYPE_NAVIGATION_BAR);
        boolean navVisible = ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL
                ? (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
                : isNavigationBarRequestedVisible();
                : provider != null
                        ? provider.isClientVisible()
                        : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR);
        boolean navTranslucent = (sysui
                & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0;
        boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0
@@ -1517,7 +1528,7 @@ public class DisplayPolicy {
                && (mNotificationShade.getAttrs().privateFlags
                & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;

        updateHideNavInputEventReceiver(navVisible, navAllowedHidden);
        updateHideNavInputEventReceiver();

        // For purposes of positioning and showing the nav bar, if we have decided that it can't
        // be hidden (because of the screen aspect ratio), then take that into account.
@@ -1539,30 +1550,38 @@ public class DisplayPolicy {
        mLastNotificationShadeForcesShowingNavigation = notificationShadeForcesShowingNavigation;
    }

    boolean isNavigationBarRequestedVisible() {
        final InsetsSourceProvider provider =
                mDisplayContent.getInsetsStateController().peekSourceProvider(ITYPE_NAVIGATION_BAR);
        return provider == null
                ? InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR)
                : provider.isClientVisible();
    }

    void updateHideNavInputEventReceiver(boolean navVisible, boolean navAllowedHidden) {
    void updateHideNavInputEventReceiver() {
        final InsetsSourceProvider provider = mDisplayContent.getInsetsStateController()
                .peekSourceProvider(ITYPE_NAVIGATION_BAR);
        final InsetsControlTarget navControlTarget =
                provider != null ? provider.getControlTarget() : null;
        final WindowState navControllingWin =
                navControlTarget instanceof WindowState ? (WindowState) navControlTarget : null;
        final InsetsState requestedState = navControllingWin != null
                ? navControllingWin.getRequestedInsetsState() : null;
        final InsetsSource navSource = requestedState != null
                ? requestedState.peekSource(ITYPE_NAVIGATION_BAR) : null;
        final boolean navVisible = navSource != null
                ? navSource.isVisible() : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR);
        final boolean showBarsByTouch = navControllingWin != null
                && navControllingWin.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_BARS_BY_TOUCH;
        // When the navigation bar isn't visible, we put up a fake input window to catch all
        // touch events. This way we can detect when the user presses anywhere to bring back the
        // nav bar and ensure the application doesn't see the event.
        if (navVisible || navAllowedHidden) {
        if (navVisible || !showBarsByTouch) {
            if (mInputConsumer != null) {
                mInputConsumer.dismiss();
                mHandler.sendMessage(
                        mHandler.obtainMessage(MSG_DISPOSE_INPUT_CONSUMER, mInputConsumer));
                mInputConsumer = null;
                Slog.v(TAG, INPUT_CONSUMER_NAVIGATION + " dismissed.");
            }
        } else if (mInputConsumer == null && mStatusBar != null && canHideNavigationBar()) {
            mInputConsumer = mDisplayContent.getInputMonitor().createInputConsumer(
                    mHandler.getLooper(),
                    INPUT_CONSUMER_NAVIGATION,
                    HideNavInputEventReceiver::new);
            Slog.v(TAG, INPUT_CONSUMER_NAVIGATION + " created.");
            // As long as mInputConsumer is active, hover events are not dispatched to the app
            // and the pointer icon is likely to become stale. Hide it to avoid confusion.
            InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_NULL);
+2 −9
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;

@@ -95,13 +94,7 @@ class InsetsPolicy {
                || focusedWin != getNavControlTarget(focusedWin)
                || focusedWin.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
                        .isVisible());
        updateHideNavInputEventReceiver();
    }

    private void updateHideNavInputEventReceiver() {
        mPolicy.updateHideNavInputEventReceiver(mPolicy.isNavigationBarRequestedVisible(),
                mFocusedWin != null
                        && mFocusedWin.mAttrs.insetsFlags.behavior != BEHAVIOR_SHOW_BARS_BY_TOUCH);
        mPolicy.updateHideNavInputEventReceiver();
    }

    boolean isHidden(@InternalInsetsType int type) {
@@ -201,7 +194,7 @@ class InsetsPolicy {
        if (windowState == getNavControlTarget(mFocusedWin)) {
            mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
        }
        updateHideNavInputEventReceiver();
        mPolicy.updateHideNavInputEventReceiver();
    }

    /**
+46 −1
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.server.wm;

import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
@@ -29,29 +32,33 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
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_TOAST;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsState;
import android.view.WindowManager;

import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;

import org.junit.Test;
@@ -307,4 +314,42 @@ public class DisplayPolicyTests extends WindowTestsBase {
        win.mHasSurface = true;
        return win;
    }

    @Test
    public void testUpdateHideNavInputEventReceiver() {
        final InsetsPolicy insetsPolicy = mDisplayContent.getInsetsPolicy();
        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
        displayPolicy.addWindowLw(mStatusBarWindow, mStatusBarWindow.mAttrs);
        displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs);
        displayPolicy.addWindowLw(mNotificationShadeWindow, mNotificationShadeWindow.mAttrs);
        spyOn(displayPolicy);
        doReturn(true).when(displayPolicy).hasNavigationBar();

        // App doesn't request to hide navigation bar.
        insetsPolicy.updateBarControlTarget(mAppWindow);
        assertNull(displayPolicy.mInputConsumer);

        // App requests to hide navigation bar.
        final InsetsState requestedState = new InsetsState();
        requestedState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
        mAppWindow.updateRequestedInsetsState(requestedState);
        insetsPolicy.onInsetsModified(mAppWindow, requestedState);
        assertNotNull(displayPolicy.mInputConsumer);

        // App still requests to hide navigation bar, but without BEHAVIOR_SHOW_BARS_BY_TOUCH.
        mAppWindow.mAttrs.insetsFlags.behavior = BEHAVIOR_SHOW_BARS_BY_SWIPE;
        insetsPolicy.updateBarControlTarget(mAppWindow);
        assertNull(displayPolicy.mInputConsumer);

        // App still requests to hide navigation bar, but with BEHAVIOR_SHOW_BARS_BY_TOUCH.
        mAppWindow.mAttrs.insetsFlags.behavior = BEHAVIOR_SHOW_BARS_BY_TOUCH;
        insetsPolicy.updateBarControlTarget(mAppWindow);
        assertNotNull(displayPolicy.mInputConsumer);

        // App still requests to hide navigation bar with BEHAVIOR_SHOW_BARS_BY_TOUCH,
        // but notification shade forcibly shows navigation bar
        mNotificationShadeWindow.mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
        insetsPolicy.updateBarControlTarget(mAppWindow);
        assertNull(displayPolicy.mInputConsumer);
    }
}