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

Commit c9a95ef6 authored by Fyodor Kupolov's avatar Fyodor Kupolov
Browse files

Added SearchIndexProvider for UserSettings

It enables customizations for certain cases like whether the user is able to
create restricted profiles or multiuser UI is disabled.

Bug: 21197002
Change-Id: Ia672c0f9bb451877f8debe04438b46cb2b7e9242
parent 3a310719
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ public final class SearchIndexableResources {
        sResMap.put(UserSettings.class.getName(),
                new SearchIndexableResource(
                        Ranking.getRankForClassName(UserSettings.class.getName()),
                        R.xml.user_settings,
                        NO_DATA_RES_ID,
                        UserSettings.class.getName(),
                        R.drawable.ic_settings_multiuser));

+102 −45
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -66,6 +65,9 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.drawable.CircleFramedDrawable;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;

import java.util.ArrayList;
import java.util.Collections;
@@ -83,7 +85,7 @@ import java.util.List;
public class UserSettings extends SettingsPreferenceFragment
        implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
        Preference.OnPreferenceChangeListener,
        EditUserInfoController.OnContentChangedCallback {
        EditUserInfoController.OnContentChangedCallback, Indexable {

    private static final String TAG = "UserSettings";

@@ -131,15 +133,11 @@ public class UserSettings extends SettingsPreferenceFragment
    private int mRemovingUserId = -1;
    private int mAddedUserId = 0;
    private boolean mAddingUser;
    private boolean mEnabled = true;
    private boolean mCanAddUser = true;
    private boolean mCanAddRestrictedProfile = true;
    private UserCapabilities mUserCaps;

    private final Object mUserLock = new Object();
    private UserManager mUserManager;
    private SparseArray<Bitmap> mUserIcons = new SparseArray<Bitmap>();
    private boolean mIsOwner = UserHandle.myUserId() == UserHandle.USER_OWNER;
    private boolean mIsGuest;

    private EditUserInfoController mEditUserInfoController =
            new EditUserInfoController();
@@ -198,16 +196,13 @@ public class UserSettings extends SettingsPreferenceFragment
            mEditUserInfoController.onRestoreInstanceState(icicle);
        }
        final Context context = getActivity();
        mUserCaps = UserCapabilities.create(context);
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        boolean hasMultipleUsers = mUserManager.getUserCount() > 1;
        if ((!UserManager.supportsMultipleUsers())
                || Utils.isMonkeyRunning()) {
            mEnabled = false;
        if (!mUserCaps.mEnabled) {
            return;
        }

        final int myUserId = UserHandle.myUserId();
        mIsGuest = mUserManager.getUserInfo(myUserId).isGuest();

        addPreferencesFromResource(R.xml.user_settings);
        mUserListCategory = (PreferenceGroup) findPreference(KEY_USER_LIST);
@@ -216,25 +211,15 @@ public class UserSettings extends SettingsPreferenceFragment
                null /* delete icon handler */);
        mMePreference.setKey(KEY_USER_ME);
        mMePreference.setOnPreferenceClickListener(this);
        if (mIsOwner) {
        if (mUserCaps.mIsOwner) {
            mMePreference.setSummary(R.string.user_owner);
        }
        mAddUser = findPreference(KEY_ADD_USER);
        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                Context.DEVICE_POLICY_SERVICE);
        // No restricted profiles for tablets with a device owner, or phones.
        if (dpm.getDeviceOwner() != null || Utils.isVoiceCapable(context)) {
            mCanAddRestrictedProfile = false;
        }
        // Determine if add user/profile button should be visible
        if (!mIsOwner || UserManager.getMaxSupportedUsers() < 2
                || !UserManager.supportsMultipleUsers()
                || mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
            mCanAddUser = false;
        } else {
        if (mUserCaps.mCanAddUser) {
            mAddUser.setOnPreferenceClickListener(this);
            // change label to only mention user, if restricted profiles are not supported
            if (!mCanAddRestrictedProfile) {
            if (!mUserCaps.mCanAddRestrictedProfile) {
                mAddUser.setTitle(R.string.user_add_user_menu);
            }
        }
@@ -250,7 +235,7 @@ public class UserSettings extends SettingsPreferenceFragment
    public void onResume() {
        super.onResume();

        if (!mEnabled) return;
        if (!mUserCaps.mEnabled) return;

        loadProfile();
        updateUserList();
@@ -260,7 +245,7 @@ public class UserSettings extends SettingsPreferenceFragment
    public void onDestroy() {
        super.onDestroy();

        if (!mEnabled) return;
        if (!mUserCaps.mEnabled) return;

        getActivity().unregisterReceiver(mUserChangeReceiver);
    }
@@ -283,13 +268,13 @@ public class UserSettings extends SettingsPreferenceFragment
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        int pos = 0;
        UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
        if (!mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) {
        if (!mUserCaps.mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) {
            String nickname = mUserManager.getUserName();
            MenuItem removeThisUser = menu.add(0, MENU_REMOVE_USER, pos++,
                    getResources().getString(R.string.user_remove_user_menu, nickname));
            removeThisUser.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        }
        if (mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
        if (mUserCaps.mIsOwner && !um.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
            MenuItem allowAddOnLockscreen = menu.add(0, MENU_ADD_ON_LOCKSCREEN, pos++,
                    R.string.user_add_on_lockscreen_menu);
            allowAddOnLockscreen.setCheckable(true);
@@ -320,7 +305,7 @@ public class UserSettings extends SettingsPreferenceFragment
     * Loads profile information for the current user.
     */
    private void loadProfile() {
        if (mIsGuest) {
        if (mUserCaps.mIsGuest) {
            // No need to load profile information
            mMePreference.setIcon(getEncircledDefaultIcon());
            mMePreference.setTitle(R.string.user_exit_guest_title);
@@ -451,7 +436,7 @@ public class UserSettings extends SettingsPreferenceFragment
            return;
        }
        UserInfo info = mUserManager.getUserInfo(userId);
        if (info.isRestricted() && mIsOwner) {
        if (info.isRestricted() && mUserCaps.mIsOwner) {
            Bundle extras = new Bundle();
            extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
            extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
@@ -462,7 +447,7 @@ public class UserSettings extends SettingsPreferenceFragment
        } else if (info.id == UserHandle.myUserId()) {
            // Jump to owner info panel
            OwnerInfoSettings.show(this);
        } else if (mIsOwner) {
        } else if (mUserCaps.mIsOwner) {
            Bundle extras = new Bundle();
            extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
            ((SettingsActivity) getActivity()).startPreferencePanel(
@@ -624,7 +609,7 @@ public class UserSettings extends SettingsPreferenceFragment
            }
            case DIALOG_USER_PROFILE_EDITOR: {
                Dialog dlg = mEditUserInfoController.createDialog(
                        (Fragment) this,
                        this,
                        mMePreference.getIcon(),
                        mMePreference.getTitle(),
                        R.string.profile_info_settings_title,
@@ -668,7 +653,7 @@ public class UserSettings extends SettingsPreferenceFragment
            //updateUserList();
            new Thread() {
                public void run() {
                    UserInfo user = null;
                    UserInfo user;
                    // Could take a few seconds
                    if (userType == USER_TYPE_USER) {
                        user = createTrustedUser();
@@ -704,7 +689,7 @@ public class UserSettings extends SettingsPreferenceFragment
     */
    private void exitGuest() {
        // Just to be safe
        if (!mIsGuest) {
        if (!mUserCaps.mIsGuest) {
            return;
        }
        removeThisUser();
@@ -740,8 +725,9 @@ public class UserSettings extends SettingsPreferenceFragment
                //   Secondary user: Delete
                //   Guest: Nothing
                //   Restricted Profile: Settings
                final boolean showSettings = mIsOwner && (voiceCapable || user.isRestricted());
                final boolean showDelete = mIsOwner
                final boolean showSettings = mUserCaps.mIsOwner
                        && (voiceCapable || user.isRestricted());
                final boolean showDelete = mUserCaps.mIsOwner
                        && (!voiceCapable && !user.isRestricted() && !user.isGuest());
                pref = new UserPreference(context, null, user.id,
                        showSettings ? this : null,
@@ -791,7 +777,7 @@ public class UserSettings extends SettingsPreferenceFragment
            // Add a virtual Guest user for guest defaults
            UserPreference pref = new UserPreference(getActivity(), null,
                    UserPreference.USERID_GUEST_DEFAULTS,
                    mIsOwner && voiceCapable? this : null /* settings icon handler */,
                    mUserCaps.mIsOwner && voiceCapable? this : null /* settings icon handler */,
                    null /* delete icon handler */);
            pref.setTitle(R.string.user_guest);
            pref.setIcon(getEncircledDefaultIcon());
@@ -816,7 +802,7 @@ public class UserSettings extends SettingsPreferenceFragment
        // "User & Profiles", otherwise the category is skipped and elements are added directly
        // to preferenceScreen
        PreferenceGroup groupToAddUsers;
        if (mCanAddRestrictedProfile) {
        if (mUserCaps.mCanAddRestrictedProfile) {
            mUserListCategory.removeAll();
            mUserListCategory.setOrder(Preference.DEFAULT_ORDER);
            preferenceScreen.addPreference(mUserListCategory);
@@ -830,7 +816,7 @@ public class UserSettings extends SettingsPreferenceFragment
        }

        // Append Add user to the end of the list
        if (mCanAddUser) {
        if (mUserCaps.mCanAddUser) {
            boolean moreUsers = mUserManager.canAddMoreUsers();
            mAddUser.setEnabled(moreUsers);
            mAddUser.setOrder(Preference.DEFAULT_ORDER);
@@ -839,7 +825,7 @@ public class UserSettings extends SettingsPreferenceFragment
    }

    private boolean shouldShowGuestUserPreference(List<UserInfo> users) {
        boolean showGuestPreference = !mIsGuest;
        boolean showGuestPreference = !mUserCaps.mIsGuest;
        // If user has DISALLOW_ADD_USER don't allow creating a guest either.
        if (showGuestPreference && mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
            showGuestPreference = false;
@@ -856,7 +842,6 @@ public class UserSettings extends SettingsPreferenceFragment


    private void loadIconsAsync(List<Integer> missingIcons) {
        final Resources resources = getResources();
        new AsyncTask<List<Integer>, Void, Void>() {
            @Override
            protected void onPostExecute(Void result) {
@@ -911,7 +896,7 @@ public class UserSettings extends SettingsPreferenceFragment
    @Override
    public boolean onPreferenceClick(Preference pref) {
        if (pref == mMePreference) {
            if (mIsGuest) {
            if (mUserCaps.mIsGuest) {
                showDialog(DIALOG_CONFIRM_EXIT_GUEST);
                return true;
            }
@@ -938,7 +923,7 @@ public class UserSettings extends SettingsPreferenceFragment
        } else if (pref == mAddUser) {
            // If we allow both types, show a picker, otherwise directly go to
            // flow for full user.
            if (mCanAddRestrictedProfile) {
            if (mUserCaps.mCanAddRestrictedProfile) {
                showDialog(DIALOG_CHOOSE_USER_TYPE);
            } else {
                onAddUserClicked(USER_TYPE_USER);
@@ -958,7 +943,7 @@ public class UserSettings extends SettingsPreferenceFragment
        // No guest user. Create one, if there's no restriction.
        // If it is not the primary user, then adding users from lockscreen must be enabled
        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)
                || (!mIsOwner && Settings.Global.getInt(getContentResolver(),
                || (!mUserCaps.mIsOwner && Settings.Global.getInt(getContentResolver(),
                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 1)) {
            Log.i(TAG, "Blocking guest creation because it is restricted");
            return;
@@ -1030,4 +1015,76 @@ public class UserSettings extends SettingsPreferenceFragment
    public void onLabelChanged(CharSequence label) {
        mMePreference.setTitle(label);
    }

    private static class UserCapabilities {
        boolean mEnabled = true;
        boolean mCanAddUser = true;
        boolean mCanAddRestrictedProfile = true;
        boolean mIsOwner = UserHandle.myUserId() == UserHandle.USER_OWNER;
        boolean mIsGuest;

        public static UserCapabilities create(Context context) {
            UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
            UserCapabilities caps = new UserCapabilities();
            if (!UserManager.supportsMultipleUsers() || Utils.isMonkeyRunning()) {
                caps.mEnabled = false;
                return caps;
            }

            if (!caps.mIsOwner || UserManager.getMaxSupportedUsers() < 2
                    || !UserManager.supportsMultipleUsers()
                    || userManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)) {
                caps.mCanAddUser = false;
            }
            DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                    Context.DEVICE_POLICY_SERVICE);
            // No restricted profiles for tablets with a device owner, or phones.
            if (dpm.getDeviceOwner() != null || Utils.isVoiceCapable(context)) {
                caps.mCanAddRestrictedProfile = false;
            }
            final int myUserId = UserHandle.myUserId();
            caps.mIsGuest = userManager.getUserInfo(myUserId).isGuest();
            return caps;
        }

        @Override
        public String toString() {
            return "UserCapabilities{" +
                    "mEnabled=" + mEnabled +
                    ", mCanAddUser=" + mCanAddUser +
                    ", mCanAddRestrictedProfile=" + mCanAddRestrictedProfile +
                    ", mIsOwner=" + mIsOwner +
                    ", mIsGuest=" + mIsGuest +
                    '}';
        }
    }

    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider() {
                @Override
                public List<SearchIndexableRaw> getRawDataToIndex(Context context,
                        boolean enabled) {
                    final List<SearchIndexableRaw> result = new ArrayList<>();
                    final UserCapabilities userCaps = UserCapabilities.create(context);
                    if (!userCaps.mEnabled) {
                        return result;
                    }
                    final Resources res = context.getResources();
                    SearchIndexableRaw data = new SearchIndexableRaw(context);
                    data.title = res.getString(R.string.user_settings_title);
                    data.screenTitle = res.getString(R.string.user_settings_title);
                    result.add(data);

                    if (userCaps.mCanAddUser) {
                        data = new SearchIndexableRaw(context);
                        data.title = res.getString(userCaps.mCanAddRestrictedProfile ?
                                R.string.user_add_user_or_profile_menu
                                : R.string.user_add_user_menu);
                        data.screenTitle = res.getString(R.string.user_settings_title);
                        result.add(data);
                    }
                    return result;
                }
            };

}