Merge "Keeing the device in gesture nav while user setup is pending" into rvc-dev am: 9bc5f9efc2 am: a75e298179

Change-Id: I47e02770ffb4f6bca198853b43113cd793b8e42e
This commit is contained in:
TreeHugger Robot
2020-04-21 18:50:05 +00:00
committed by Automerger Merge Worker
6 changed files with 67 additions and 175 deletions

View File

@@ -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);

View File

@@ -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<NavigationEdgeBackPlugin>, ProtoTraceable<SystemUiTraceProto> {
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);

View File

@@ -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);

View File

@@ -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<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) {
@@ -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<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
@@ -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);
}

View File

@@ -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);

View File

@@ -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);