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

Commit d626fd31 authored by Adam Bookatz's avatar Adam Bookatz
Browse files

Unify multiuser switcher enabled setting

This does the following:
1. The multiuser switcher (in Settings and SysUI)
is now disabled by default. In order for it to be enabled
one of the following must be true:
  a. the user has explicitly toggled it on in Settings
  b. a new user gets created (via any means)
  c. config_showUserSwitcherByDefault overrides this default

2. Even if a new user is added, if the user had explicitly
*disabled* the switcher, the switcher still won't be enabled.

3. SystemUI and Settings (et al.) all use
UserManager.isUserSwitcherEnabled as the source of
truth in this regard.
No one else reads USER_SWITCHER_ENABLED directly.

4. If the switcher is enabled, then SystemUI will show the
switcher avatar, even if there are no other users on the device,
as long as new users can be created. This way, if the user
has enabled the switcher, the user can use the avatar to add
guest/secondary users (which would not be possible if enabled
status was tied solely to the existence of other users).

Bug: 137943217
Bug: 141372193
Bug: 149973281
Bug: 130270878

Test: manual: Settings > Multiuser doesn't turn on the systemui avatar
Test: manual: Settings > Multiuser is initially disabled
Test: manual: adb shell pm create-user A, does turn on sysui avatar
              even if the user didn't enable, but not if they disabled

Change-Id: Ia440b4db78792da76f94322a563d93db0c68e933
parent 57e977a5
Loading
Loading
Loading
Loading
+34 −12
Original line number Original line Diff line number Diff line
@@ -4032,12 +4032,25 @@ public class UserManager {
    }
    }


    /**
    /**
     * Returns true if the user switcher should be shown, this will be if device supports multi-user
     * Returns true if the user switcher should be shown.
     * and there are at least 2 users available that are not managed profiles.
     * I.e., returns whether the user switcher is enabled and there is something actionable to show.
     * @hide
     *
     * @return true if user switcher should be shown.
     * @return true if user switcher should be shown.
     * @hide
     */
     */
    public boolean isUserSwitcherEnabled() {
    public boolean isUserSwitcherEnabled() {
        return isUserSwitcherEnabled(false);
    }

    /**
     * Returns true if the user switcher should be shown.
     *
     * @param showEvenIfNotActionable value to return if the feature is enabled but there is nothing
     *                                actionable for the user to do anyway
     * @return true if user switcher should be shown.
     * @hide
     */
    public boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable) {
        if (!supportsMultipleUsers()) {
        if (!supportsMultipleUsers()) {
            return false;
            return false;
        }
        }
@@ -4048,13 +4061,24 @@ public class UserManager {
        if (isDeviceInDemoMode(mContext)) {
        if (isDeviceInDemoMode(mContext)) {
            return false;
            return false;
        }
        }
        // If user disabled this feature, don't show switcher
        // Check the Settings.Global.USER_SWITCHER_ENABLED that the user can toggle on/off.
        final boolean userSwitcherEnabled = Settings.Global.getInt(mContext.getContentResolver(),
        final boolean userSwitcherSettingOn = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.USER_SWITCHER_ENABLED, 1) != 0;
                Settings.Global.USER_SWITCHER_ENABLED,
        if (!userSwitcherEnabled) {
                Resources.getSystem().getBoolean(R.bool.config_showUserSwitcherByDefault) ? 1 : 0)
                != 0;
        if (!userSwitcherSettingOn) {
            return false;
            return false;
        }
        }
        List<UserInfo> users = getUsers(true);

        // The feature is enabled. But is it worth showing?
        return showEvenIfNotActionable
                || areThereUsersToWhichToSwitch() // There are switchable users.
                || !hasUserRestriction(UserManager.DISALLOW_ADD_USER); // New users can be added.
    }

    /** Returns whether there are any users (other than the current user) to which to switch. */
    private boolean areThereUsersToWhichToSwitch() {
        final List<UserInfo> users = getUsers(true);
        if (users == null) {
        if (users == null) {
            return false;
            return false;
        }
        }
@@ -4064,9 +4088,7 @@ public class UserManager {
                ++switchableUserCount;
                ++switchableUserCount;
            }
            }
        }
        }
        final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
        return switchableUserCount > 1;
                .getGuestUserDisabled(null);
        return switchableUserCount > 1 || guestEnabled;
    }
    }


    /**
    /**
+3 −0
Original line number Original line Diff line number Diff line
@@ -48,5 +48,8 @@


    <!-- Set to true to enable the user switcher on the keyguard. -->
    <!-- Set to true to enable the user switcher on the keyguard. -->
    <bool name="config_keyguardUserSwitcher">true</bool>
    <bool name="config_keyguardUserSwitcher">true</bool>

    <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
    <bool name="config_showUserSwitcherByDefault">true</bool>
</resources>
</resources>
+3 −0
Original line number Original line Diff line number Diff line
@@ -4444,6 +4444,9 @@
    <!-- Set to true to enable the user switcher on the keyguard. -->
    <!-- Set to true to enable the user switcher on the keyguard. -->
    <bool name="config_keyguardUserSwitcher">false</bool>
    <bool name="config_keyguardUserSwitcher">false</bool>


    <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
    <bool name="config_showUserSwitcherByDefault">false</bool>

    <!-- Set to true to make assistant show in front of the dream/screensaver. -->
    <!-- Set to true to make assistant show in front of the dream/screensaver. -->
    <bool name="config_assistantOnTopOfDream">false</bool>
    <bool name="config_assistantOnTopOfDream">false</bool>


+3 −0
Original line number Original line Diff line number Diff line
@@ -4006,6 +4006,9 @@
  <!-- Set to true to enable the user switcher on the keyguard. -->
  <!-- Set to true to enable the user switcher on the keyguard. -->
  <java-symbol type="bool" name="config_keyguardUserSwitcher" />
  <java-symbol type="bool" name="config_keyguardUserSwitcher" />


  <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
  <java-symbol type="bool" name="config_showUserSwitcherByDefault" />

  <!-- Set to true to make assistant show in front of the dream/screensaver. -->
  <!-- Set to true to make assistant show in front of the dream/screensaver. -->
  <java-symbol type="bool" name="config_assistantOnTopOfDream"/>
  <java-symbol type="bool" name="config_assistantOnTopOfDream"/>


+3 −29
Original line number Original line Diff line number Diff line
@@ -18,10 +18,8 @@ package com.android.systemui.statusbar.phone;


import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.DejankUtils.whitelistIpcs;


import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Context;
import android.os.UserManager;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.view.View;
import android.view.View;
@@ -97,33 +95,9 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
    }
    }


    public boolean isMultiUserEnabled() {
    public boolean isMultiUserEnabled() {
        // Short-circuiting from UserManager. Needs to be extracted because of SystemUI boolean flag
        // qs_show_user_switcher_for_single_user

        // TODO(b/138661450) Move IPC calls to background
        // TODO(b/138661450) Move IPC calls to background
        return whitelistIpcs(() -> {
        return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
            // The default in UserManager is to show the switcher. We want to not show it unless the
                mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
            // user explicitly requests it in Settings
            final boolean userSwitcherEnabled = Settings.Global.getInt(
                    mContext.getContentResolver(),
                    Settings.Global.USER_SWITCHER_ENABLED, 0) != 0;

            if (!userSwitcherEnabled
                    || !UserManager.supportsMultipleUsers()
                    || UserManager.isDeviceInDemoMode(mContext)
                    || mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)) {
                return false;
            }

            final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
                    .getGuestUserDisabled(null);
            return mUserSwitcherController.getSwitchableUserCount() > 1
                    // If we cannot add guests even if they are enabled, do not show
                    || (guestEnabled && !mUserManager.hasUserRestriction(
                    UserManager.DISALLOW_ADD_USER))
                    || mContext.getResources().getBoolean(
                    R.bool.qs_show_user_switcher_for_single_user);
        });
    }
    }


    private void registerListener() {
    private void registerListener() {
@@ -175,7 +149,7 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
    private void refreshContentDescription() {
    private void refreshContentDescription() {
        String currentUser = null;
        String currentUser = null;
        // TODO(b/138661450)
        // TODO(b/138661450)
        if (whitelistIpcs(mUserManager::isUserSwitcherEnabled)
        if (whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled())
                && mUserSwitcherController != null) {
                && mUserSwitcherController != null) {
            currentUser = mUserSwitcherController.getCurrentUserName(mContext);
            currentUser = mUserSwitcherController.getCurrentUserName(mContext);
        }
        }
Loading