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

Commit 2c74acae authored by Tiger Huang's avatar Tiger Huang Committed by Automerger Merge Worker
Browse files

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

Merge "Refine logic about updateHideNavInputEventReceiver" into rvc-dev am: 28382c8f am: 3b88d3be

Change-Id: I51481a525d7a0bbe85ad2c9185e4929707e5aefe
parents 11ec4173 3b88d3be
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);
    }
}