1 /* 2 * Copyright (C) 2018 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.car.settings.users; 18 19 import android.car.user.CarUserManagerHelper; 20 import android.content.pm.UserInfo; 21 import android.os.Bundle; 22 import android.support.annotation.VisibleForTesting; 23 import android.view.View; 24 import android.widget.Button; 25 26 import androidx.car.widget.ListItem; 27 import androidx.car.widget.ListItemProvider; 28 import androidx.car.widget.TextListItem; 29 30 import com.android.car.settings.R; 31 import com.android.car.settings.common.ListItemSettingsFragment; 32 33 import java.util.Arrays; 34 import java.util.List; 35 36 /** 37 * Shows details for a user with the ability to remove user and switch. 38 */ 39 public class UserDetailsFragment extends ListItemSettingsFragment implements 40 ConfirmRemoveUserDialog.ConfirmRemoveUserListener, 41 RemoveUserErrorDialog.RemoveUserErrorListener { 42 public static final String EXTRA_USER_INFO = "extra_user_info"; 43 private static final String ERROR_DIALOG_TAG = "RemoveUserErrorDialogTag"; 44 private static final String CONFIRM_REMOVE_DIALOG_TAG = "ConfirmRemoveUserDialog"; 45 46 private Button mRemoveUserBtn; 47 private Button mSwitchUserBtn; 48 49 private UserInfo mUserInfo; 50 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 51 CarUserManagerHelper mCarUserManagerHelper; 52 private UserIconProvider mUserIconProvider; 53 private ListItemProvider mItemProvider; 54 55 /** 56 * Creates instance of UserDetailsFragment. 57 */ 58 public static UserDetailsFragment newInstance(UserInfo userInfo) { 59 UserDetailsFragment userDetailsFragment = new UserDetailsFragment(); 60 Bundle bundle = ListItemSettingsFragment.getBundle(); 61 bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar_with_button); 62 bundle.putInt(EXTRA_TITLE_ID, R.string.user_details_title); 63 bundle.putParcelable(EXTRA_USER_INFO, userInfo); 64 userDetailsFragment.setArguments(bundle); 65 return userDetailsFragment; 66 } 67 68 @Override 69 public void onCreate(Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 mUserInfo = getArguments().getParcelable(EXTRA_USER_INFO); 72 73 if (savedInstanceState != null) { 74 RemoveUserErrorDialog removeUserErrorDialog = (RemoveUserErrorDialog) 75 getFragmentManager().findFragmentByTag(ERROR_DIALOG_TAG); 76 if (removeUserErrorDialog != null) { 77 removeUserErrorDialog.setRetryListener(this); 78 } 79 80 ConfirmRemoveUserDialog confirmRemoveUserDialog = (ConfirmRemoveUserDialog) 81 getFragmentManager().findFragmentByTag(CONFIRM_REMOVE_DIALOG_TAG); 82 if (confirmRemoveUserDialog != null) { 83 confirmRemoveUserDialog.setConfirmRemoveUserListener(this); 84 } 85 } 86 } 87 88 @Override 89 public void onActivityCreated(Bundle savedInstanceState) { 90 createUserManagerHelper(); 91 mUserIconProvider = new UserIconProvider(mCarUserManagerHelper); 92 mItemProvider = new ListItemProvider.ListProvider(getListItems()); 93 94 // Needs to be called after creation of item provider. 95 super.onActivityCreated(savedInstanceState); 96 97 showActionButtons(); 98 } 99 100 @Override 101 public void onRemoveUserConfirmed() { 102 removeUser(); 103 } 104 105 @Override 106 public void onRetryRemoveUser() { 107 // Retry deleting user. 108 removeUser(); 109 } 110 111 @Override 112 public ListItemProvider getItemProvider() { 113 return mItemProvider; 114 } 115 116 private void removeUser() { 117 if (mCarUserManagerHelper.removeUser( 118 mUserInfo, getContext().getString(R.string.user_guest))) { 119 getActivity().onBackPressed(); 120 } else { 121 // If failed, need to show error dialog for users, can offer retry. 122 RemoveUserErrorDialog removeUserErrorDialog = new RemoveUserErrorDialog(); 123 removeUserErrorDialog.setRetryListener(this); 124 removeUserErrorDialog.show(getFragmentManager(), ERROR_DIALOG_TAG); 125 } 126 } 127 128 private void showActionButtons() { 129 if (mCarUserManagerHelper.isForegroundUser(mUserInfo)) { 130 // Already foreground user, shouldn't show SWITCH button. 131 showRemoveUserButton(); 132 return; 133 } 134 135 showRemoveUserButton(); 136 showSwitchButton(); 137 } 138 139 private void createUserManagerHelper() { 140 // Null check for testing. Don't want to override it if already set by a test. 141 if (mCarUserManagerHelper == null) { 142 mCarUserManagerHelper = new CarUserManagerHelper(getContext()); 143 } 144 } 145 146 private void showRemoveUserButton() { 147 Button removeUserBtn = (Button) getActivity().findViewById(R.id.action_button1); 148 // If the current user is not allowed to remove users, the user trying to be removed 149 // cannot be removed, or the current user is a demo user, do not show delete button. 150 if (!mCarUserManagerHelper.canCurrentProcessRemoveUsers() 151 || !mCarUserManagerHelper.canUserBeRemoved(mUserInfo) 152 || mCarUserManagerHelper.isCurrentProcessDemoUser()) { 153 removeUserBtn.setVisibility(View.GONE); 154 return; 155 } 156 removeUserBtn.setVisibility(View.VISIBLE); 157 removeUserBtn.setText(R.string.delete_button); 158 removeUserBtn.setOnClickListener(v -> { 159 ConfirmRemoveUserDialog dialog = new ConfirmRemoveUserDialog(); 160 dialog.setConfirmRemoveUserListener(this); 161 dialog.show(getFragmentManager(), CONFIRM_REMOVE_DIALOG_TAG); 162 }); 163 } 164 165 private void showSwitchButton() { 166 Button switchUserBtn = (Button) getActivity().findViewById(R.id.action_button2); 167 // If the current process is not allowed to switch to another user, doe not show the switch 168 // button. 169 if (!mCarUserManagerHelper.canCurrentProcessSwitchUsers()) { 170 switchUserBtn.setVisibility(View.GONE); 171 return; 172 } 173 switchUserBtn.setVisibility(View.VISIBLE); 174 switchUserBtn.setText(R.string.user_switch); 175 switchUserBtn.setOnClickListener(v -> { 176 mCarUserManagerHelper.switchToUser(mUserInfo); 177 getActivity().onBackPressed(); 178 }); 179 } 180 181 private List<ListItem> getListItems() { 182 TextListItem item = new TextListItem(getContext()); 183 item.setPrimaryActionIcon(mUserIconProvider.getUserIcon(mUserInfo, getContext()), 184 /* useLargeIcon= */ false); 185 item.setTitle(mUserInfo.name); 186 187 if (!mUserInfo.isInitialized()) { 188 // Indicate that the user has not been initialized yet. 189 item.setBody(getContext().getString(R.string.user_summary_not_set_up)); 190 } 191 192 return Arrays.asList(item); 193 } 194 } 195