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

Commit aa83cc4f authored by Bill Lin's avatar Bill Lin Committed by Automerger Merge Worker
Browse files

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13851605

Change-Id: I855e7ece30235a85b82a5903bee6d2f9d0ebac02
parents 66460cb9 f9d740b0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -89,4 +89,9 @@ public interface OneHanded {
     * Receive onConfigurationChanged() events
     */
    void onConfigChanged(Configuration newConfig);

    /**
     * Notifies when user switch complete
     */
    void onUserSwitch(int userId);
}
+55 −23
Original line number Diff line number Diff line
@@ -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();
@@ -381,27 +385,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) {
@@ -422,7 +437,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);
@@ -432,13 +447,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:
@@ -467,7 +482,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);
@@ -479,13 +494,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() {
@@ -526,7 +541,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>

    private void setupGesturalOverlay() {
        if (!mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
                mContext.getContentResolver())) {
                mContext.getContentResolver(), mUserId)) {
            return;
        }

@@ -574,6 +589,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: ");
@@ -581,6 +604,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);
@@ -606,7 +631,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;
@@ -705,6 +730,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
                OneHandedController.this.onConfigChanged(newConfig);
            });
        }

        @Override
        public void onUserSwitch(int userId) {
            mMainExecutor.execute(() -> {
                OneHandedController.this.onUserSwitch(userId);
            });
        }
    }

    /**
+32 −24
Original line number Diff line number Diff line
@@ -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;
@@ -65,14 +67,16 @@ public final class OneHandedSettingsUtil {
     * @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;
    }
@@ -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() {
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -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(
+5 −0
Original line number Diff line number Diff line
@@ -297,6 +297,11 @@ public final class WMShell extends SystemUI
                }
                oneHanded.stopOneHanded();
            }

            @Override
            public void onUserSwitchComplete(int userId) {
                oneHanded.onUserSwitch(userId);
            }
        };
        mKeyguardUpdateMonitor.registerCallback(mOneHandedKeyguardCallback);