Merge "1/ Make One handed mode support multiple user switch" into sc-dev

This commit is contained in:
Bill Lin
2021-04-01 02:02:39 +00:00
committed by Android (Google) Code Review
5 changed files with 104 additions and 51 deletions

View File

@@ -89,4 +89,9 @@ public interface OneHanded {
* Receive onConfigurationChanged() events
*/
void onConfigChanged(Configuration newConfig);
/**
* Notifies when user switch complete
*/
void onUserSwitch(int userId);
}

View File

@@ -17,6 +17,7 @@
package com.android.wm.shell.onehanded;
import static android.os.UserHandle.USER_CURRENT;
import static android.os.UserHandle.myUserId;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
@@ -74,6 +75,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private volatile boolean mIsSwipeToNotificationEnabled;
private boolean mTaskChangeToExit;
private boolean mLockedDisabled;
private int mUserId;
private float mOffSetFraction;
private Context mContext;
@@ -141,7 +143,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
if (enabled) {
final int mOneHandedTimeout = mOneHandedSettingsUtil
.getSettingsOneHandedModeTimeout(mContext.getContentResolver());
.getSettingsOneHandedModeTimeout(
mContext.getContentResolver(), mUserId);
final int timeout = mAccessibilityManager
.getRecommendedTimeoutMillis(mOneHandedTimeout * 1000
/* align with A11y timeout millis */,
@@ -149,7 +152,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mTimeoutHandler.setTimeout(timeout / 1000);
} else {
mTimeoutHandler.setTimeout(mOneHandedSettingsUtil
.getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
.getSettingsOneHandedModeTimeout(
mContext.getContentResolver(), mUserId));
}
}
};
@@ -247,12 +251,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
R.fraction.config_one_handed_offset, 1, 1);
final int sysPropPercentageConfig = SystemProperties.getInt(
ONE_HANDED_MODE_OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f));
mUserId = myUserId();
mOffSetFraction = sysPropPercentageConfig / 100.0f;
mIsOneHandedEnabled = mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
context.getContentResolver());
context.getContentResolver(), mUserId);
mIsSwipeToNotificationEnabled =
mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
context.getContentResolver());
context.getContentResolver(), mUserId);
mTimeoutHandler = timeoutHandler;
mEnabledObserver = getObserver(this::onEnabledSettingChanged);
@@ -262,9 +267,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
getObserver(this::onSwipeToNotificationEnabledSettingChanged);
mDisplayController.addDisplayChangingController(mRotationController);
setupCallback();
setupSettingObservers();
registerSettingObservers(mUserId);
setupTimeoutListener();
setupGesturalOverlay();
updateSettings();
@@ -379,27 +383,38 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
}
private void setupSettingObservers() {
private void registerSettingObservers(int newUserId) {
mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
mContext.getContentResolver(), mEnabledObserver);
mContext.getContentResolver(), mEnabledObserver, newUserId);
mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
mContext.getContentResolver(), mTimeoutObserver);
mContext.getContentResolver(), mTimeoutObserver, newUserId);
mOneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
mContext.getContentResolver(), mTaskChangeExitObserver);
mContext.getContentResolver(), mTaskChangeExitObserver, newUserId);
mOneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
mContext.getContentResolver(), mSwipeToNotificationEnabledObserver);
mContext.getContentResolver(), mSwipeToNotificationEnabledObserver, newUserId);
}
private void unregisterSettingObservers() {
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mEnabledObserver);
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mTimeoutObserver);
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mTaskChangeExitObserver);
mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContext.getContentResolver(),
mSwipeToNotificationEnabledObserver);
}
private void updateSettings() {
setOneHandedEnabled(mOneHandedSettingsUtil
.getSettingsOneHandedModeEnabled(mContext.getContentResolver()));
.getSettingsOneHandedModeEnabled(mContext.getContentResolver(), mUserId));
mTimeoutHandler.setTimeout(mOneHandedSettingsUtil
.getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
.getSettingsOneHandedModeTimeout(mContext.getContentResolver(), mUserId));
setTaskChangeToExit(mOneHandedSettingsUtil
.getSettingsTapsAppToExit(mContext.getContentResolver()));
.getSettingsTapsAppToExit(mContext.getContentResolver(), mUserId));
setSwipeToNotificationEnabled(mOneHandedSettingsUtil
.getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
.getSettingsSwipeToNotificationEnabled(mContext.getContentResolver(), mUserId));
}
private void updateDisplayLayout(int displayId) {
@@ -420,7 +435,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
@VisibleForTesting
void onEnabledSettingChanged() {
final boolean enabled = mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
mContext.getContentResolver());
mContext.getContentResolver(), mUserId);
mOneHandedUiEventLogger.writeEvent(enabled
? OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_ENABLED_ON
: OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_ENABLED_OFF);
@@ -430,13 +445,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
// Also checks swipe to notification settings since they all need gesture overlay.
setEnabledGesturalOverlay(
enabled || mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
mContext.getContentResolver()));
mContext.getContentResolver(), mUserId));
}
@VisibleForTesting
void onTimeoutSettingChanged() {
final int newTimeout = mOneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
mContext.getContentResolver());
mContext.getContentResolver(), mUserId);
int metricsId = OneHandedUiEventLogger.OneHandedSettingsTogglesEvent.INVALID.getId();
switch (newTimeout) {
case OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER:
@@ -465,7 +480,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
@VisibleForTesting
void onTaskChangeExitSettingChanged() {
final boolean enabled = mOneHandedSettingsUtil.getSettingsTapsAppToExit(
mContext.getContentResolver());
mContext.getContentResolver(), mUserId);
mOneHandedUiEventLogger.writeEvent(enabled
? OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_ON
: OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_APP_TAPS_EXIT_OFF);
@@ -477,13 +492,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
void onSwipeToNotificationEnabledSettingChanged() {
final boolean enabled =
mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
mContext.getContentResolver());
mContext.getContentResolver(), mUserId);
setSwipeToNotificationEnabled(enabled);
// Also checks one handed mode settings since they all need gesture overlay.
setEnabledGesturalOverlay(
enabled || mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
mContext.getContentResolver()));
mContext.getContentResolver(), mUserId));
}
private void setupTimeoutListener() {
@@ -524,7 +539,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private void setupGesturalOverlay() {
if (!mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
mContext.getContentResolver())) {
mContext.getContentResolver(), mUserId)) {
return;
}
@@ -572,6 +587,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
}
private void onUserSwitch(int newUserId) {
unregisterSettingObservers();
mUserId = newUserId;
registerSettingObservers(newUserId);
updateSettings();
updateOneHandedEnabled();
}
public void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG + "States: ");
@@ -579,6 +602,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
pw.println(mOffSetFraction);
pw.print(innerPrefix + "mLockedDisabled=");
pw.println(mLockedDisabled);
pw.print(innerPrefix + "mUserId=");
pw.println(mUserId);
if (mBackgroundPanelOrganizer != null) {
mBackgroundPanelOrganizer.dump(pw);
@@ -604,7 +629,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mTutorialHandler.dump(pw);
}
mOneHandedSettingsUtil.dump(pw, innerPrefix, mContext.getContentResolver());
mOneHandedSettingsUtil.dump(pw, innerPrefix, mContext.getContentResolver(), mUserId);
if (mOverlayManager != null) {
OverlayInfo info = null;
@@ -703,6 +728,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
OneHandedController.this.onConfigChanged(newConfig);
});
}
@Override
public void onUserSwitch(int userId) {
mMainExecutor.execute(() -> {
OneHandedController.this.onUserSwitch(userId);
});
}
}
/**

View File

@@ -22,6 +22,8 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings;
import androidx.annotation.Nullable;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -62,17 +64,19 @@ public final class OneHandedSettingsUtil {
/**
* Register one handed preference settings observer
*
* @param key Setting key to monitor in observer
* @param resolver ContentResolver of context
* @param observer Observer from caller
* @param key Setting key to monitor in observer
* @param resolver ContentResolver of context
* @param observer Observer from caller
* @param newUserId New user id to be registered
* @return uri key for observing
*/
@Nullable
public Uri registerSettingsKeyObserver(String key, ContentResolver resolver,
ContentObserver observer) {
ContentObserver observer, int newUserId) {
Uri uriKey = null;
uriKey = Settings.Secure.getUriFor(key);
if (resolver != null && uriKey != null) {
resolver.registerContentObserver(uriKey, false, observer);
resolver.registerContentObserver(uriKey, false, observer, newUserId);
}
return uriKey;
}
@@ -80,8 +84,8 @@ public final class OneHandedSettingsUtil {
/**
* Unregister one handed preference settings observer
*
* @param resolver ContentResolver of context
* @param observer preference key change observer
* @param resolver ContentResolver of context
* @param observer preference key change observer
*/
public void unregisterSettingsKeyObserver(ContentResolver resolver,
ContentObserver observer) {
@@ -95,9 +99,9 @@ public final class OneHandedSettingsUtil {
*
* @return enable or disable one handed mode flag.
*/
public boolean getSettingsOneHandedModeEnabled(ContentResolver resolver) {
return Settings.Secure.getInt(resolver,
Settings.Secure.ONE_HANDED_MODE_ENABLED, 0 /* Disabled */) == 1;
public boolean getSettingsOneHandedModeEnabled(ContentResolver resolver, int userId) {
return Settings.Secure.getIntForUser(resolver,
Settings.Secure.ONE_HANDED_MODE_ENABLED, 0 /* Disabled */, userId) == 1;
}
/**
@@ -105,40 +109,44 @@ public final class OneHandedSettingsUtil {
*
* @return enable or disable taps app exit.
*/
public boolean getSettingsTapsAppToExit(ContentResolver resolver) {
return Settings.Secure.getInt(resolver,
Settings.Secure.TAPS_APP_TO_EXIT, 0) == 1;
public boolean getSettingsTapsAppToExit(ContentResolver resolver, int userId) {
return Settings.Secure.getIntForUser(resolver,
Settings.Secure.TAPS_APP_TO_EXIT, 0, userId) == 1;
}
/**
* Query timeout value from Settings provider.
* Default is {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS}
* Query timeout value from Settings provider. Default is
* {@link OneHandedSettingsUtil#ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS}
*
* @return timeout value in seconds.
*/
public @OneHandedTimeout int getSettingsOneHandedModeTimeout(ContentResolver resolver) {
return Settings.Secure.getInt(resolver,
Settings.Secure.ONE_HANDED_MODE_TIMEOUT, ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
public @OneHandedTimeout int getSettingsOneHandedModeTimeout(ContentResolver resolver,
int userId) {
return Settings.Secure.getIntForUser(resolver,
Settings.Secure.ONE_HANDED_MODE_TIMEOUT, ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS,
userId);
}
/**
* Returns whether swipe bottom to notification gesture enabled or not.
*/
public boolean getSettingsSwipeToNotificationEnabled(ContentResolver resolver) {
public boolean getSettingsSwipeToNotificationEnabled(ContentResolver resolver, int userId) {
return Settings.Secure.getInt(resolver,
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 0 /* Default OFF */) == 1;
}
void dump(PrintWriter pw, String prefix, ContentResolver resolver) {
void dump(PrintWriter pw, String prefix, ContentResolver resolver,
int userId) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
pw.println(innerPrefix + TAG);
pw.print(innerPrefix + "isOneHandedModeEnable=");
pw.println(getSettingsOneHandedModeEnabled(resolver));
pw.println(getSettingsOneHandedModeEnabled(resolver, userId));
pw.print(innerPrefix + "oneHandedTimeOut=");
pw.println(getSettingsOneHandedModeTimeout(resolver));
pw.println(getSettingsOneHandedModeTimeout(resolver, userId));
pw.print(innerPrefix + "tapsAppToExit=");
pw.println(getSettingsTapsAppToExit(resolver));
pw.println(getSettingsTapsAppToExit(resolver, userId));
}
public OneHandedSettingsUtil() {
}
}

View File

@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.content.om.IOverlayManager;
import android.graphics.Rect;
import android.os.Handler;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.util.ArrayMap;
import android.view.Display;
@@ -53,6 +54,8 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class OneHandedControllerTest extends OneHandedTestCase {
private int mCurrentUser = UserHandle.myUserId();
Display mDisplay;
DisplayLayout mDisplayLayout;
OneHandedController mSpiedOneHandedController;
@@ -100,13 +103,13 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false);
when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash);
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any())).thenReturn(
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn(
mDefaultEnabled);
when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any())).thenReturn(
when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn(
OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
when(mMockSettingsUitl.getSettingsTapsAppToExit(any())).thenReturn(
when(mMockSettingsUitl.getSettingsTapsAppToExit(any(), anyInt())).thenReturn(
mDefaultTapAppToExitEnabled);
when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any())).thenReturn(
when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
mDefaultSwipeToNotificationEnabled);
when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn(

View File

@@ -296,6 +296,11 @@ public final class WMShell extends SystemUI
}
oneHanded.stopOneHanded();
}
@Override
public void onUserSwitchComplete(int userId) {
oneHanded.onUserSwitch(userId);
}
};
mKeyguardUpdateMonitor.registerCallback(mOneHandedKeyguardCallback);