1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings.users;
18
19import android.app.Dialog;
20import android.content.Context;
21import android.content.DialogInterface;
22import android.content.pm.UserInfo;
23import android.os.Bundle;
24import android.os.UserHandle;
25import android.os.UserManager;
26import android.preference.Preference;
27import android.preference.SwitchPreference;
28
29import com.android.internal.logging.MetricsLogger;
30import com.android.settings.R;
31import com.android.settings.SettingsPreferenceFragment;
32
33import java.util.List;
34
35/**
36 * Settings screen for configuring a specific user. It can contain user restrictions
37 * and deletion controls. It is shown when you tap on the settings icon in the
38 * user management (UserSettings) screen.
39 *
40 * Arguments to this fragment must include the userId of the user (in EXTRA_USER_ID) for whom
41 * to display controls, or should contain the EXTRA_USER_GUEST = true.
42 */
43public class UserDetailsSettings extends SettingsPreferenceFragment
44        implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
45
46    private static final String TAG = UserDetailsSettings.class.getSimpleName();
47
48    private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
49    private static final String KEY_REMOVE_USER = "remove_user";
50
51    /** Integer extra containing the userId to manage */
52    static final String EXTRA_USER_ID = "user_id";
53    /** Boolean extra to indicate guest preferences */
54    static final String EXTRA_USER_GUEST = "guest_user";
55
56    private static final int DIALOG_CONFIRM_REMOVE = 1;
57    private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2;
58    private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3;
59
60    private UserManager mUserManager;
61    private SwitchPreference mPhonePref;
62    private Preference mRemoveUserPref;
63
64    private UserInfo mUserInfo;
65    private boolean mGuestUser;
66    private Bundle mDefaultGuestRestrictions;
67
68    @Override
69    protected int getMetricsCategory() {
70        return MetricsLogger.USER_DETAILS;
71    }
72
73    @Override
74    public void onCreate(Bundle icicle) {
75        super.onCreate(icicle);
76
77        final Context context = getActivity();
78        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
79
80        addPreferencesFromResource(R.xml.user_details_settings);
81        mPhonePref = (SwitchPreference) findPreference(KEY_ENABLE_TELEPHONY);
82        mRemoveUserPref = findPreference(KEY_REMOVE_USER);
83
84        mGuestUser = getArguments().getBoolean(EXTRA_USER_GUEST, false);
85
86        if (!mGuestUser) {
87            // Regular user. Get the user id from the caller.
88            final int userId = getArguments().getInt(EXTRA_USER_ID, -1);
89            if (userId == -1) {
90                throw new RuntimeException("Arguments to this fragment must contain the user id");
91            }
92            mUserInfo = mUserManager.getUserInfo(userId);
93            mPhonePref.setChecked(!mUserManager.hasUserRestriction(
94                    UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
95            mRemoveUserPref.setOnPreferenceClickListener(this);
96        } else {
97            // These are not for an existing user, just general Guest settings.
98            removePreference(KEY_REMOVE_USER);
99            // Default title is for calling and SMS. Change to calling-only here
100            mPhonePref.setTitle(R.string.user_enable_calling);
101            mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
102            mPhonePref.setChecked(
103                    !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
104        }
105        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)) {
106            removePreference(KEY_REMOVE_USER);
107        }
108        mPhonePref.setOnPreferenceChangeListener(this);
109    }
110
111    @Override
112    public boolean onPreferenceClick(Preference preference) {
113        if (preference == mRemoveUserPref) {
114            if (UserHandle.myUserId() != UserHandle.USER_OWNER) {
115                throw new RuntimeException("Only the owner can remove a user");
116            }
117            showDialog(DIALOG_CONFIRM_REMOVE);
118            return true;
119        }
120        return false;
121    }
122
123    @Override
124    public boolean onPreferenceChange(Preference preference, Object newValue) {
125        if (Boolean.TRUE.equals(newValue)) {
126            showDialog(mGuestUser? DIALOG_CONFIRM_ENABLE_CALLING : DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS);
127            return false;
128        }
129        enableCallsAndSms(false);
130        return true;
131    }
132
133    void enableCallsAndSms(boolean enabled) {
134        mPhonePref.setChecked(enabled);
135        if (mGuestUser) {
136            mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !enabled);
137            // SMS is always disabled for guest
138            mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
139            mUserManager.setDefaultGuestRestrictions(mDefaultGuestRestrictions);
140            // Update the guest's restrictions, if there is a guest
141            List<UserInfo> users = mUserManager.getUsers(true);
142            for (UserInfo user: users) {
143                if (user.isGuest()) {
144                    UserHandle userHandle = new UserHandle(user.id);
145                    Bundle userRestrictions = mUserManager.getUserRestrictions(userHandle);
146                    userRestrictions.putAll(mDefaultGuestRestrictions);
147                    mUserManager.setUserRestrictions(userRestrictions, userHandle);
148                }
149            }
150        } else {
151            UserHandle userHandle = new UserHandle(mUserInfo.id);
152            mUserManager.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, !enabled,
153                    userHandle);
154            mUserManager.setUserRestriction(UserManager.DISALLOW_SMS, !enabled, userHandle);
155        }
156    }
157
158    @Override
159    public Dialog onCreateDialog(int dialogId) {
160        Context context = getActivity();
161        if (context == null) return null;
162        switch (dialogId) {
163            case DIALOG_CONFIRM_REMOVE:
164                return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id,
165                        new DialogInterface.OnClickListener() {
166                            public void onClick(DialogInterface dialog, int which) {
167                                removeUser();
168                            }
169                        });
170            case DIALOG_CONFIRM_ENABLE_CALLING:
171                return UserDialogs.createEnablePhoneCallsDialog(getActivity(),
172                        new DialogInterface.OnClickListener() {
173                            public void onClick(DialogInterface dialog, int which) {
174                                enableCallsAndSms(true);
175                            }
176                        });
177            case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
178                return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
179                        new DialogInterface.OnClickListener() {
180                            public void onClick(DialogInterface dialog, int which) {
181                                enableCallsAndSms(true);
182                            }
183                        });
184        }
185        throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
186    }
187
188    void removeUser() {
189        mUserManager.removeUser(mUserInfo.id);
190        finishFragment();
191    }
192}
193