Loading core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java +8 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +33 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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<NavigationEdgeBackPlugin>, ProtoTraceable<SystemUiTraceProto> { private static final String TAG = "EdgeBackGestureHandler"; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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() */ Loading @@ -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(); } /** Loading @@ -255,6 +269,7 @@ public class EdgeBackGestureHandler implements DisplayListener, } mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver); updateIsEnabled(); stopTracking(); } private void setRotationCallbacks(boolean enable) { Loading @@ -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) { Loading Loading @@ -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( Loading Loading @@ -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); Loading Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +9 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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()); Loading @@ -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)); Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java +5 −151 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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<ModeChangedListener> 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) { Loading @@ -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); Loading Loading @@ -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<String> 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 Loading @@ -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:"); Loading @@ -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); } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading
core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java +8 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +33 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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<NavigationEdgeBackPlugin>, ProtoTraceable<SystemUiTraceProto> { private static final String TAG = "EdgeBackGestureHandler"; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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() */ Loading @@ -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(); } /** Loading @@ -255,6 +269,7 @@ public class EdgeBackGestureHandler implements DisplayListener, } mContext.getContentResolver().unregisterContentObserver(mFixedRotationObserver); updateIsEnabled(); stopTracking(); } private void setRotationCallbacks(boolean enable) { Loading @@ -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) { Loading Loading @@ -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( Loading Loading @@ -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); Loading Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +9 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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()); Loading @@ -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)); Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java +5 −151 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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<ModeChangedListener> 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) { Loading @@ -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); Loading Loading @@ -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<String> 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 Loading @@ -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:"); Loading @@ -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); } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading