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 
17 package com.android.settings.users;
18 
19 import android.app.Dialog;
20 import android.content.Context;
21 import android.content.DialogInterface;
22 import android.content.pm.UserInfo;
23 import android.os.Bundle;
24 import android.os.UserHandle;
25 import android.os.UserManager;
26 import android.support.v14.preference.SwitchPreference;
27 import android.support.v7.preference.Preference;
28 
29 import com.android.internal.logging.MetricsProto.MetricsEvent;
30 import com.android.settings.R;
31 import com.android.settings.SettingsPreferenceFragment;
32 import com.android.settingslib.RestrictedLockUtils;
33 
34 import java.util.List;
35 
36 /**
37  * Settings screen for configuring a specific user. It can contain user restrictions
38  * and deletion controls. It is shown when you tap on the settings icon in the
39  * user management (UserSettings) screen.
40  *
41  * Arguments to this fragment must include the userId of the user (in EXTRA_USER_ID) for whom
42  * to display controls, or should contain the EXTRA_USER_GUEST = true.
43  */
44 public class UserDetailsSettings extends SettingsPreferenceFragment
45         implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
46 
47     private static final String TAG = UserDetailsSettings.class.getSimpleName();
48 
49     private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
50     private static final String KEY_REMOVE_USER = "remove_user";
51 
52     /** Integer extra containing the userId to manage */
53     static final String EXTRA_USER_ID = "user_id";
54     /** Boolean extra to indicate guest preferences */
55     static final String EXTRA_USER_GUEST = "guest_user";
56 
57     private static final int DIALOG_CONFIRM_REMOVE = 1;
58     private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2;
59     private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3;
60 
61     private UserManager mUserManager;
62     private SwitchPreference mPhonePref;
63     private Preference mRemoveUserPref;
64 
65     private UserInfo mUserInfo;
66     private boolean mGuestUser;
67     private Bundle mDefaultGuestRestrictions;
68 
69     @Override
getMetricsCategory()70     protected int getMetricsCategory() {
71         return MetricsEvent.USER_DETAILS;
72     }
73 
74     @Override
onCreate(Bundle icicle)75     public void onCreate(Bundle icicle) {
76         super.onCreate(icicle);
77 
78         final Context context = getActivity();
79         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
80 
81         addPreferencesFromResource(R.xml.user_details_settings);
82         mPhonePref = (SwitchPreference) findPreference(KEY_ENABLE_TELEPHONY);
83         mRemoveUserPref = findPreference(KEY_REMOVE_USER);
84 
85         mGuestUser = getArguments().getBoolean(EXTRA_USER_GUEST, false);
86 
87         if (!mGuestUser) {
88             // Regular user. Get the user id from the caller.
89             final int userId = getArguments().getInt(EXTRA_USER_ID, -1);
90             if (userId == -1) {
91                 throw new RuntimeException("Arguments to this fragment must contain the user id");
92             }
93             mUserInfo = mUserManager.getUserInfo(userId);
94             mPhonePref.setChecked(!mUserManager.hasUserRestriction(
95                     UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
96             mRemoveUserPref.setOnPreferenceClickListener(this);
97         } else {
98             // These are not for an existing user, just general Guest settings.
99             removePreference(KEY_REMOVE_USER);
100             // Default title is for calling and SMS. Change to calling-only here
101             mPhonePref.setTitle(R.string.user_enable_calling);
102             mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions();
103             mPhonePref.setChecked(
104                     !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
105         }
106         if (RestrictedLockUtils.hasBaseUserRestriction(context,
107                 UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
108             removePreference(KEY_REMOVE_USER);
109         }
110         mPhonePref.setOnPreferenceChangeListener(this);
111     }
112 
113     @Override
onPreferenceClick(Preference preference)114     public boolean onPreferenceClick(Preference preference) {
115         if (preference == mRemoveUserPref) {
116             if (!mUserManager.isAdminUser()) {
117                 throw new RuntimeException("Only admins can remove a user");
118             }
119             showDialog(DIALOG_CONFIRM_REMOVE);
120             return true;
121         }
122         return false;
123     }
124 
125     @Override
onPreferenceChange(Preference preference, Object newValue)126     public boolean onPreferenceChange(Preference preference, Object newValue) {
127         if (Boolean.TRUE.equals(newValue)) {
128             showDialog(mGuestUser ? DIALOG_CONFIRM_ENABLE_CALLING
129                     : DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS);
130             return false;
131         }
132         enableCallsAndSms(false);
133         return true;
134     }
135 
enableCallsAndSms(boolean enabled)136     void enableCallsAndSms(boolean enabled) {
137         mPhonePref.setChecked(enabled);
138         if (mGuestUser) {
139             mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !enabled);
140             // SMS is always disabled for guest
141             mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
142             mUserManager.setDefaultGuestRestrictions(mDefaultGuestRestrictions);
143 
144             // Update the guest's restrictions, if there is a guest
145             // TODO: Maybe setDefaultGuestRestrictions() can internally just set the restrictions
146             // on any existing guest rather than do it here with multiple Binder calls.
147             List<UserInfo> users = mUserManager.getUsers(true);
148             for (UserInfo user: users) {
149                 if (user.isGuest()) {
150                     UserHandle userHandle = UserHandle.of(user.id);
151                     for (String key : mDefaultGuestRestrictions.keySet()) {
152                         mUserManager.setUserRestriction(
153                                 key, mDefaultGuestRestrictions.getBoolean(key), userHandle);
154                     }
155                 }
156             }
157         } else {
158             UserHandle userHandle = UserHandle.of(mUserInfo.id);
159             mUserManager.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, !enabled,
160                     userHandle);
161             mUserManager.setUserRestriction(UserManager.DISALLOW_SMS, !enabled, userHandle);
162         }
163     }
164 
165     @Override
onCreateDialog(int dialogId)166     public Dialog onCreateDialog(int dialogId) {
167         Context context = getActivity();
168         if (context == null) return null;
169         switch (dialogId) {
170             case DIALOG_CONFIRM_REMOVE:
171                 return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id,
172                         new DialogInterface.OnClickListener() {
173                             public void onClick(DialogInterface dialog, int which) {
174                                 removeUser();
175                             }
176                         });
177             case DIALOG_CONFIRM_ENABLE_CALLING:
178                 return UserDialogs.createEnablePhoneCallsDialog(getActivity(),
179                         new DialogInterface.OnClickListener() {
180                             public void onClick(DialogInterface dialog, int which) {
181                                 enableCallsAndSms(true);
182                             }
183                         });
184             case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
185                 return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
186                         new DialogInterface.OnClickListener() {
187                             public void onClick(DialogInterface dialog, int which) {
188                                 enableCallsAndSms(true);
189                             }
190                         });
191         }
192         throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
193     }
194 
195     void removeUser() {
196         mUserManager.removeUser(mUserInfo.id);
197         finishFragment();
198     }
199 }
200