19e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani/* 29e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * Copyright (C) 2014 The Android Open Source Project 39e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * 49e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 59e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * you may not use this file except in compliance with the License. 69e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * You may obtain a copy of the License at 79e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * 89e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 99e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * 109e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * Unless required by applicable law or agreed to in writing, software 119e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 129e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * See the License for the specific language governing permissions and 149e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * limitations under the License. 159e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani */ 169e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 179e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasanipackage com.android.settings.users; 189e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 199e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.app.Dialog; 209e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.content.Context; 219e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.content.DialogInterface; 229e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.content.pm.UserInfo; 239e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.os.Bundle; 249e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.os.UserHandle; 259e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport android.os.UserManager; 2639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v14.preference.SwitchPreference; 2739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference; 289e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 299d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent; 309e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport com.android.settings.R; 319e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasaniimport com.android.settings.SettingsPreferenceFragment; 329e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils; 339e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 34a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasaniimport java.util.List; 35a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani 369e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani/** 379e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * Settings screen for configuring a specific user. It can contain user restrictions 389e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * and deletion controls. It is shown when you tap on the settings icon in the 399e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * user management (UserSettings) screen. 4051c6dac50ea8874181036f54c3a7e7aa8eb800bdAmith Yamasani * 419e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * Arguments to this fragment must include the userId of the user (in EXTRA_USER_ID) for whom 429e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani * to display controls, or should contain the EXTRA_USER_GUEST = true. 439e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani */ 449e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasanipublic class UserDetailsSettings extends SettingsPreferenceFragment 459e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { 469e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 479e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private static final String TAG = UserDetailsSettings.class.getSimpleName(); 489e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 499e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private static final String KEY_ENABLE_TELEPHONY = "enable_calling"; 509e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private static final String KEY_REMOVE_USER = "remove_user"; 519e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 529e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani /** Integer extra containing the userId to manage */ 539e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani static final String EXTRA_USER_ID = "user_id"; 549e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani /** Boolean extra to indicate guest preferences */ 559e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani static final String EXTRA_USER_GUEST = "guest_user"; 569e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 579e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private static final int DIALOG_CONFIRM_REMOVE = 1; 589e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2; 59dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3; 609e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 619e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private UserManager mUserManager; 629e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private SwitchPreference mPhonePref; 639e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka private Preference mRemoveUserPref; 649e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 659e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private UserInfo mUserInfo; 669e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private boolean mGuestUser; 679e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani private Bundle mDefaultGuestRestrictions; 689e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 699e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani @Override 708a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren protected int getMetricsCategory() { 719d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren return MetricsEvent.USER_DETAILS; 728a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 738a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 748a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 759e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani public void onCreate(Bundle icicle) { 769e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani super.onCreate(icicle); 779e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 789e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani final Context context = getActivity(); 799e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 809e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 819e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani addPreferencesFromResource(R.xml.user_details_settings); 829e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mPhonePref = (SwitchPreference) findPreference(KEY_ENABLE_TELEPHONY); 839e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka mRemoveUserPref = findPreference(KEY_REMOVE_USER); 849e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 859e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mGuestUser = getArguments().getBoolean(EXTRA_USER_GUEST, false); 869e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 879e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani if (!mGuestUser) { 889e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani // Regular user. Get the user id from the caller. 899e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani final int userId = getArguments().getInt(EXTRA_USER_ID, -1); 909e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani if (userId == -1) { 919e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani throw new RuntimeException("Arguments to this fragment must contain the user id"); 929e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 939e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mUserInfo = mUserManager.getUserInfo(userId); 94920c57d499740052f87a15fa1db411b075f943dfAmith Yamasani mPhonePref.setChecked(!mUserManager.hasUserRestriction( 95920c57d499740052f87a15fa1db411b075f943dfAmith Yamasani UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId))); 969e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mRemoveUserPref.setOnPreferenceClickListener(this); 979e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } else { 989e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani // These are not for an existing user, just general Guest settings. 999e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani removePreference(KEY_REMOVE_USER); 1009e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani // Default title is for calling and SMS. Change to calling-only here 1019e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mPhonePref.setTitle(R.string.user_enable_calling); 1029e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mDefaultGuestRestrictions = mUserManager.getDefaultGuestRestrictions(); 1039e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mPhonePref.setChecked( 104920c57d499740052f87a15fa1db411b075f943dfAmith Yamasani !mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)); 1059e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1069e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka if (RestrictedLockUtils.hasBaseUserRestriction(context, 1079e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) { 1089e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka removePreference(KEY_REMOVE_USER); 1099e9e63b7b3b31fcae7242eb07f528487e0913402Sudheer Shanka } 1109e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mPhonePref.setOnPreferenceChangeListener(this); 1119e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1129e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 1139e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani @Override 1149e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani public boolean onPreferenceClick(Preference preference) { 1159e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani if (preference == mRemoveUserPref) { 11632f1fe5b8a9053cf467ae9b304f5e693194fd9bcJulia Reynolds if (!mUserManager.isAdminUser()) { 11744879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen throw new RuntimeException("Only admins can remove a user"); 1189e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1199e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani showDialog(DIALOG_CONFIRM_REMOVE); 1209e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani return true; 1219e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1229e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani return false; 1239e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1249e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 1259e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani @Override 1269e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani public boolean onPreferenceChange(Preference preference, Object newValue) { 127dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov if (Boolean.TRUE.equals(newValue)) { 128b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki showDialog(mGuestUser ? DIALOG_CONFIRM_ENABLE_CALLING 129b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki : DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS); 130dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov return false; 131dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov } 132dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov enableCallsAndSms(false); 133dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov return true; 134dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov } 135dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov 136dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov void enableCallsAndSms(boolean enabled) { 137dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov mPhonePref.setChecked(enabled); 1389e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani if (mGuestUser) { 139dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, !enabled); 140920c57d499740052f87a15fa1db411b075f943dfAmith Yamasani // SMS is always disabled for guest 141920c57d499740052f87a15fa1db411b075f943dfAmith Yamasani mDefaultGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); 1429e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mUserManager.setDefaultGuestRestrictions(mDefaultGuestRestrictions); 143b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki 144a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani // Update the guest's restrictions, if there is a guest 145b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki // TODO: Maybe setDefaultGuestRestrictions() can internally just set the restrictions 146b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki // on any existing guest rather than do it here with multiple Binder calls. 147a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani List<UserInfo> users = mUserManager.getUsers(true); 148a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani for (UserInfo user: users) { 149a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani if (user.isGuest()) { 15037d018e54b8da53f1cdf6782358f9ce358084157Fyodor Kupolov UserHandle userHandle = UserHandle.of(user.id); 151b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki for (String key : mDefaultGuestRestrictions.keySet()) { 152b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki mUserManager.setUserRestriction( 15337d018e54b8da53f1cdf6782358f9ce358084157Fyodor Kupolov key, mDefaultGuestRestrictions.getBoolean(key), userHandle); 154b761ad1c6eefe153eb674d712ab444cee1b7b865Makoto Onuki } 155a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani } 156a766bfa3de1dd87e15c9f0b5bedbdf10735e59ffAmith Yamasani } 1579e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } else { 15837d018e54b8da53f1cdf6782358f9ce358084157Fyodor Kupolov UserHandle userHandle = UserHandle.of(mUserInfo.id); 159dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov mUserManager.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, !enabled, 160dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov userHandle); 161dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov mUserManager.setUserRestriction(UserManager.DISALLOW_SMS, !enabled, userHandle); 1629e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1639e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1649e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 1659e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani @Override 1669e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani public Dialog onCreateDialog(int dialogId) { 1679e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani Context context = getActivity(); 1689e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani if (context == null) return null; 1699e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani switch (dialogId) { 170dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov case DIALOG_CONFIRM_REMOVE: 171dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov return UserDialogs.createRemoveDialog(getActivity(), mUserInfo.id, 1729e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani new DialogInterface.OnClickListener() { 1739e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani public void onClick(DialogInterface dialog, int which) { 1749e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani removeUser(); 1759e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1769e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani }); 1779e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani case DIALOG_CONFIRM_ENABLE_CALLING: 178dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov return UserDialogs.createEnablePhoneCallsDialog(getActivity(), 179dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov new DialogInterface.OnClickListener() { 180dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov public void onClick(DialogInterface dialog, int which) { 181dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov enableCallsAndSms(true); 182dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov } 183dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov }); 184dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS: 185dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(), 186dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov new DialogInterface.OnClickListener() { 187dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov public void onClick(DialogInterface dialog, int which) { 188dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov enableCallsAndSms(true); 189dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov } 190dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov }); 1919e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 192dbbd4fca442dc507cd478f26c5dbd5a94085c4e3Fyodor Kupolov throw new IllegalArgumentException("Unsupported dialogId " + dialogId); 1939e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1949e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani 1959e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani void removeUser() { 1969e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani mUserManager.removeUser(mUserInfo.id); 1979e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani finishFragment(); 1989e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani } 1999e6ac3d25f55303887293e36eb288ef191ffd1bbAmith Yamasani} 200