diff --git a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java index ebfea450af884..56a6db95badcc 100644 --- a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java +++ b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java @@ -46,6 +46,9 @@ public class GestureNavigationSettingsObserver extends ContentObserver { r.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT), false, this, UserHandle.USER_ALL); + r.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), + false, this, UserHandle.USER_ALL); } public void unregister() { @@ -68,6 +71,11 @@ public class GestureNavigationSettingsObserver extends ContentObserver { return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT); } + public boolean areNavigationButtonForcedVisible() { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) == 0; + } + private int getSensitivity(Resources userRes, String side) { final int inset = userRes.getDimensionPixelSize( com.android.internal.R.dimen.config_backGestureInset); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index 7d422e3c15a2c..f9119c7a010fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -53,11 +53,13 @@ import android.view.WindowManagerGlobal; import com.android.internal.policy.GestureNavigationSettingsObserver; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.NavigationEdgeBackPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; @@ -74,7 +76,7 @@ import java.util.concurrent.Executor; /** * Utility class to handle edge swipes for back gesture */ -public class EdgeBackGestureHandler implements DisplayListener, +public class EdgeBackGestureHandler extends CurrentUserTracker implements DisplayListener, PluginListener, ProtoTraceable { private static final String TAG = "EdgeBackGestureHandler"; @@ -165,6 +167,7 @@ public class EdgeBackGestureHandler implements DisplayListener, private boolean mIsGesturalModeEnabled; private boolean mIsEnabled; private boolean mIsNavBarShownTransiently; + private boolean mIsBackGestureAllowed; private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; @@ -200,7 +203,7 @@ public class EdgeBackGestureHandler implements DisplayListener, public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService, SysUiState sysUiFlagContainer, PluginManager pluginManager) { - final Resources res = context.getResources(); + super(Dependency.get(BroadcastDispatcher.class)); mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = context.getMainExecutor(); @@ -216,20 +219,30 @@ public class EdgeBackGestureHandler implements DisplayListener, ViewConfiguration.getLongPressTimeout()); mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver( - mContext.getMainThreadHandler(), mContext, () -> updateCurrentUserResources(res)); + mContext.getMainThreadHandler(), mContext, this::updateCurrentUserResources); - updateCurrentUserResources(res); + updateCurrentUserResources(); sysUiFlagContainer.addCallback(sysUiFlags -> mSysUiFlags = sysUiFlags); } - public void updateCurrentUserResources(Resources res) { + public void updateCurrentUserResources() { + Resources res = Dependency.get(NavigationModeController.class).getCurrentUserContext() + .getResources(); mEdgeWidthLeft = mGestureNavigationSettingsObserver.getLeftSensitivity(res); mEdgeWidthRight = mGestureNavigationSettingsObserver.getRightSensitivity(res); + mIsBackGestureAllowed = + !mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible(); mBottomGestureHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_gesture_height); } + @Override + public void onUserSwitched(int newUserId) { + updateIsEnabled(); + updateCurrentUserResources(); + } + /** * @see NavigationBarView#onAttachedToWindow() */ @@ -243,6 +256,7 @@ public class EdgeBackGestureHandler implements DisplayListener, Settings.Global.getUriFor(FIXED_ROTATION_TRANSFORM_SETTING_NAME), false /* notifyForDescendants */, mFixedRotationObserver, UserHandle.USER_ALL); updateIsEnabled(); + startTracking(); } /** @@ -255,6 +269,7 @@ public class EdgeBackGestureHandler implements DisplayListener, } mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver); updateIsEnabled(); + stopTracking(); } private void setRotationCallbacks(boolean enable) { @@ -269,10 +284,13 @@ public class EdgeBackGestureHandler implements DisplayListener, } } - public void onNavigationModeChanged(int mode, Context currentUserContext) { + /** + * @see NavigationModeController.ModeChangedListener#onNavigationModeChanged + */ + public void onNavigationModeChanged(int mode) { mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode); updateIsEnabled(); - updateCurrentUserResources(currentUserContext.getResources()); + updateCurrentUserResources(); } public void onNavBarTransientStateChanged(boolean isTransient) { @@ -363,6 +381,10 @@ public class EdgeBackGestureHandler implements DisplayListener, updateDisplaySize(); } + public boolean isHandlingGestures() { + return mIsEnabled && mIsBackGestureAllowed; + } + private WindowManager.LayoutParams createLayoutParams() { Resources resources = mContext.getResources(); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( @@ -469,9 +491,9 @@ public class EdgeBackGestureHandler implements DisplayListener, mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset; mLogGesture = false; mInRejectedExclusion = false; - mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags) - && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()) - && !mDisabledForQuickstep; + mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed + && !QuickStepContract.isBackGestureDisabled(mSysUiFlags) + && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()); if (mAllowGesture) { mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge); mEdgeBackPlugin.onMotionEvent(ev); @@ -599,6 +621,7 @@ public class EdgeBackGestureHandler implements DisplayListener, public void dump(PrintWriter pw) { pw.println("EdgeBackGestureHandler:"); pw.println(" mIsEnabled=" + mIsEnabled); + pw.println(" mIsBackGestureAllowed=" + mIsBackGestureAllowed); pw.println(" mAllowGesture=" + mAllowGesture); pw.println(" mDisabledForQuickstep=" + mDisabledForQuickstep); pw.println(" mInRejectedExclusion" + mInRejectedExclusion); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 84aecd4e07593..2978772cac5ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -123,7 +123,7 @@ public class NavigationBarView extends FrameLayout implements private KeyButtonDrawable mRecentIcon; private KeyButtonDrawable mDockedIcon; - private final EdgeBackGestureHandler mEdgeBackGestureHandler; + private EdgeBackGestureHandler mEdgeBackGestureHandler; private final DeadZone mDeadZone; private boolean mDeadZoneConsuming = false; private final NavigationBarTransitions mBarTransitions; @@ -244,7 +244,7 @@ public class NavigationBarView extends FrameLayout implements private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener = info -> { // When the nav bar is in 2-button or 3-button mode, or when IME is visible in fully // gestural mode, the entire nav bar should be touchable. - if (!isGesturalMode(mNavBarMode) || mImeVisible) { + if (!mEdgeBackGestureHandler.isHandlingGestures() || mImeVisible) { info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); return; } @@ -296,8 +296,6 @@ public class NavigationBarView extends FrameLayout implements R.style.RotateButtonCCWStart90, isGesturalMode ? mFloatingRotationButton : rotateSuggestionButton); - final ContextualButton backButton = new ContextualButton(R.id.back, 0); - mConfiguration = new Configuration(); mTmpLastConfiguration = new Configuration(); mConfiguration.updateFrom(context.getResources().getConfiguration()); @@ -305,7 +303,7 @@ public class NavigationBarView extends FrameLayout implements mScreenPinningNotify = new ScreenPinningNotify(mContext); mBarTransitions = new NavigationBarTransitions(this, Dependency.get(CommandQueue.class)); - mButtonDispatchers.put(R.id.back, backButton); + mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back)); mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home)); mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle)); mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps)); @@ -659,7 +657,7 @@ public class NavigationBarView extends FrameLayout implements boolean disableHomeHandle = disableRecent && ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0); - boolean disableBack = !useAltBack && (isGesturalMode(mNavBarMode) + boolean disableBack = !useAltBack && (mEdgeBackGestureHandler.isHandlingGestures() || ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)); // When screen pinning, don't hide back and home when connected service or back and @@ -686,9 +684,9 @@ public class NavigationBarView extends FrameLayout implements } } - getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE); - getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE); - getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE); + getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE); + getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE); + getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE); getHomeHandle().setVisibility(disableHomeHandle ? View.INVISIBLE : View.VISIBLE); } @@ -838,10 +836,9 @@ public class NavigationBarView extends FrameLayout implements @Override public void onNavigationModeChanged(int mode) { - Context curUserCtx = Dependency.get(NavigationModeController.class).getCurrentUserContext(); mNavBarMode = mode; mBarTransitions.onNavigationModeChanged(mNavBarMode); - mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode, curUserCtx); + mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode); mRecentsOnboarding.onNavigationModeChanged(mNavBarMode); getRotateSuggestionButton().onNavigationModeChanged(mNavBarMode); @@ -864,6 +861,7 @@ public class NavigationBarView extends FrameLayout implements @Override public void onFinishInflate() { + super.onFinishInflate(); mNavigationInflaterView = findViewById(R.id.navigation_inflater); mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java index d24ccf343a3ac..6061b1e73d1c1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java @@ -17,9 +17,6 @@ package com.android.systemui.statusbar.phone; import static android.content.Intent.ACTION_OVERLAY_CHANGED; -import static android.content.Intent.ACTION_PREFERRED_ACTIVITY_CHANGED; -import static android.os.UserHandle.USER_CURRENT; -import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY; @@ -38,17 +35,14 @@ import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Secure; import android.util.Log; -import android.util.SparseBooleanArray; import com.android.systemui.Dumpable; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.statusbar.policy.DeviceProvisionedController; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.concurrent.Executor; import javax.inject.Inject; @@ -70,104 +64,34 @@ public class NavigationModeController implements Dumpable { private final Context mContext; private Context mCurrentUserContext; private final IOverlayManager mOverlayManager; - private final DeviceProvisionedController mDeviceProvisionedController; private final Executor mUiBgExecutor; - private SparseBooleanArray mRestoreGesturalNavBarMode = new SparseBooleanArray(); - private ArrayList mListeners = new ArrayList<>(); private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - switch (intent.getAction()) { - case ACTION_OVERLAY_CHANGED: if (DEBUG) { Log.d(TAG, "ACTION_OVERLAY_CHANGED"); } updateCurrentInteractionMode(true /* notify */); - break; - } } }; - private final DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedCallback = - new DeviceProvisionedController.DeviceProvisionedListener() { - @Override - public void onDeviceProvisionedChanged() { - if (DEBUG) { - Log.d(TAG, "onDeviceProvisionedChanged: " - + mDeviceProvisionedController.isDeviceProvisioned()); - } - // Once the device has been provisioned, check if we can restore gestural nav - restoreGesturalNavOverlayIfNecessary(); - } - - @Override - public void onUserSetupChanged() { - if (DEBUG) { - Log.d(TAG, "onUserSetupChanged: " - + mDeviceProvisionedController.isCurrentUserSetup()); - } - // Once the user has been setup, check if we can restore gestural nav - restoreGesturalNavOverlayIfNecessary(); - } - - @Override - public void onUserSwitched() { - if (DEBUG) { - Log.d(TAG, "onUserSwitched: " - + ActivityManagerWrapper.getInstance().getCurrentUserId()); - } - - // Update the nav mode for the current user - updateCurrentInteractionMode(true /* notify */); - - // When switching users, defer enabling the gestural nav overlay until the user - // is all set up - deferGesturalNavOverlayIfNecessary(); - } - }; - @Inject - public NavigationModeController(Context context, - DeviceProvisionedController deviceProvisionedController, - @UiBackground Executor uiBgExecutor) { + public NavigationModeController(Context context, @UiBackground Executor uiBgExecutor) { mContext = context; mCurrentUserContext = context; mOverlayManager = IOverlayManager.Stub.asInterface( ServiceManager.getService(Context.OVERLAY_SERVICE)); mUiBgExecutor = uiBgExecutor; - mDeviceProvisionedController = deviceProvisionedController; - mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback); IntentFilter overlayFilter = new IntentFilter(ACTION_OVERLAY_CHANGED); overlayFilter.addDataScheme("package"); overlayFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, overlayFilter, null, null); - IntentFilter preferredActivityFilter = new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED); - mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, preferredActivityFilter, null, - null); - updateCurrentInteractionMode(false /* notify */); - - // Check if we need to defer enabling gestural nav - deferGesturalNavOverlayIfNecessary(); - } - - private boolean setGestureModeOverlayForMainLauncher() { - if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL) { - // Already in gesture mode - return true; - } - - Log.d(TAG, "Switching system navigation to full-gesture mode:" - + " contextUser=" - + mCurrentUserContext.getUserId()); - - setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT); - return true; } public void updateCurrentInteractionMode(boolean notify) { @@ -176,10 +100,9 @@ public class NavigationModeController implements Dumpable { if (mode == NAV_BAR_MODE_GESTURAL) { switchToDefaultGestureNavOverlayIfNecessary(); } - mUiBgExecutor.execute(() -> { + mUiBgExecutor.execute(() -> Settings.Secure.putString(mCurrentUserContext.getContentResolver(), - Secure.NAVIGATION_MODE, String.valueOf(mode)); - }); + Secure.NAVIGATION_MODE, String.valueOf(mode))); if (DEBUG) { Log.e(TAG, "updateCurrentInteractionMode: mode=" + mode); dumpAssetPaths(mCurrentUserContext); @@ -230,61 +153,11 @@ public class NavigationModeController implements Dumpable { } } - private void deferGesturalNavOverlayIfNecessary() { - final int userId = mDeviceProvisionedController.getCurrentUser(); - mRestoreGesturalNavBarMode.put(userId, false); - if (mDeviceProvisionedController.isDeviceProvisioned() - && mDeviceProvisionedController.isCurrentUserSetup()) { - // User is already setup and device is provisioned, nothing to do - if (DEBUG) { - Log.d(TAG, "deferGesturalNavOverlayIfNecessary: device is provisioned and user is " - + "setup"); - } - return; - } - - ArrayList defaultOverlays = new ArrayList<>(); - try { - defaultOverlays.addAll(Arrays.asList(mOverlayManager.getDefaultOverlayPackages())); - } catch (RemoteException e) { - Log.e(TAG, "deferGesturalNavOverlayIfNecessary: failed to fetch default overlays"); - } - if (!defaultOverlays.contains(NAV_BAR_MODE_GESTURAL_OVERLAY)) { - // No default gesture nav overlay - if (DEBUG) { - Log.d(TAG, "deferGesturalNavOverlayIfNecessary: no default gestural overlay, " - + "default=" + defaultOverlays); - } - return; - } - - // If the default is gestural, force-enable three button mode until the device is - // provisioned - setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT); - mRestoreGesturalNavBarMode.put(userId, true); - - if (DEBUG) { - Log.d(TAG, "deferGesturalNavOverlayIfNecessary: setting to 3 button mode"); - } - } - - private void restoreGesturalNavOverlayIfNecessary() { - if (DEBUG) { - Log.d(TAG, "restoreGesturalNavOverlayIfNecessary: needs restore=" - + mRestoreGesturalNavBarMode); - } - final int userId = mDeviceProvisionedController.getCurrentUser(); - if (mRestoreGesturalNavBarMode.get(userId)) { - // Restore the gestural state if necessary - setGestureModeOverlayForMainLauncher(); - mRestoreGesturalNavBarMode.put(userId, false); - } - } - private void switchToDefaultGestureNavOverlayIfNecessary() { final int userId = mCurrentUserContext.getUserId(); try { - final IOverlayManager om = mOverlayManager; + final IOverlayManager om = IOverlayManager.Stub.asInterface( + ServiceManager.getService(Context.OVERLAY_SERVICE)); final OverlayInfo info = om.getOverlayInfo(NAV_BAR_MODE_GESTURAL_OVERLAY, userId); if (info != null && !info.isEnabled()) { // Enable the default gesture nav overlay, and move the back gesture inset scale to @@ -309,20 +182,6 @@ public class NavigationModeController implements Dumpable { } } - public void setModeOverlay(String overlayPkg, int userId) { - mUiBgExecutor.execute(() -> { - try { - mOverlayManager.setEnabledExclusiveInCategory(overlayPkg, userId); - if (DEBUG) { - Log.d(TAG, "setModeOverlay: overlayPackage=" + overlayPkg - + " userId=" + userId); - } - } catch (SecurityException | IllegalStateException | RemoteException e) { - Log.e(TAG, "Failed to enable overlay " + overlayPkg + " for user " + userId); - } - }); - } - @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("NavigationModeController:"); @@ -334,11 +193,6 @@ public class NavigationModeController implements Dumpable { defaultOverlays = "failed_to_fetch"; } pw.println(" defaultOverlays=" + defaultOverlays); - pw.println(" restoreGesturalNavMode:"); - for (int i = 0; i < mRestoreGesturalNavBarMode.size(); i++) { - pw.println(" userId=" + mRestoreGesturalNavBarMode.keyAt(i) - + " shouldRestore=" + mRestoreGesturalNavBarMode.valueAt(i)); - } dumpAssetPaths(mCurrentUserContext); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java index 27a50027cfe23..14c6e9f9624d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -50,9 +51,11 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { mDependency.injectMockDependency(IWindowManager.class); mDependency.injectMockDependency(AssistManager.class); mDependency.injectMockDependency(OverviewProxyService.class); - mDependency.injectMockDependency(NavigationModeController.class); mDependency.injectMockDependency(StatusBarStateController.class); mDependency.injectMockDependency(KeyguardStateController.class); + doReturn(mContext) + .when(mDependency.injectMockDependency(NavigationModeController.class)) + .getCurrentUserContext(); NavigationBarView navBar = spy(new NavigationBarView(mContext, null)); when(navBar.getCurrentView()).thenReturn(navBar); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 601f8df6af152..8aace212d094c 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -261,6 +261,8 @@ public class DisplayPolicy { @Px private int mRightGestureInset; + private boolean mNavButtonForcedVisible; + StatusBarManagerInternal getStatusBarManagerInternal() { synchronized (mServiceAcquireLock) { if (mStatusBarManagerInternal == null) { @@ -1046,12 +1048,14 @@ public class DisplayPolicy { // calculate inset. if (navigationBarPosition(displayFrames.mDisplayWidth, displayFrames.mDisplayHeight, - displayFrames.mRotation) == NAV_BAR_BOTTOM) { + displayFrames.mRotation) == NAV_BAR_BOTTOM + && !mNavButtonForcedVisible) { + sTmpRect.set(displayFrames.mUnrestricted); sTmpRect.intersectUnchecked(displayFrames.mDisplayCutoutSafe); inOutFrame.top = sTmpRect.bottom - getNavigationBarHeight(displayFrames.mRotation, - mDisplayContent.getConfiguration().uiMode); + mDisplayContent.getConfiguration().uiMode); } }, @@ -2810,6 +2814,8 @@ public class DisplayPolicy { mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode); mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res); mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res); + mNavButtonForcedVisible = + mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible(); mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough); mNavigationBarAlwaysShowOnSideGesture = res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);