• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.profiles;
18 
19 import static com.android.car.settings.common.ActionButtonsPreference.ActionButtons;
20 
21 import android.car.drivingstate.CarUxRestrictions;
22 import android.content.Context;
23 import android.content.pm.UserInfo;
24 import android.os.UserManager;
25 
26 import androidx.annotation.VisibleForTesting;
27 
28 import com.android.car.settings.R;
29 import com.android.car.settings.common.ActionButtonInfo;
30 import com.android.car.settings.common.ActionButtonsPreference;
31 import com.android.car.settings.common.ConfirmationDialogFragment;
32 import com.android.car.settings.common.FragmentController;
33 
34 /**
35  * Displays the action buttons for profile details.
36  *
37  * <p>The actions shown depends on the current and selected profile.
38  * <ol>
39  * <li>Rename: shown if selected profile is the current profile
40  * <li>Make admin: shown if current profile is an admin and the selected profile is not
41  * <li>Manage other profiles: shown if selected profile is the current profile and
42  * there are other profiles
43  * <li>Add a profile: shown if selected profile is the current profile and
44  * there are no other profiles
45  * <li> Exit demo: shown if selected profile is the current profile and is a demo
46  * <li>Delete: shown if the current profile is allowed to remove profiles, is not a demo
47  * profile, and selected profile is not the current profile
48  * </ol>
49  */
50 public final class ProfileDetailsActionButtonsPreferenceController
51         extends ProfileDetailsBasePreferenceController<ActionButtonsPreference> {
52 
53     @VisibleForTesting
54     static final String MAKE_ADMIN_DIALOG_TAG = "MakeAdminDialogFragment";
55 
56     private final ProfileHelper mProfileHelper;
57     private final UserManager mUserManager;
58     private DemoProfileDialogHandler mDemoProfileDialogHandler;
59     private AddProfileHandler mAddProfileHandler;
60 
61     @VisibleForTesting
62     final ConfirmationDialogFragment.ConfirmListener mMakeAdminConfirmListener =
63             arguments -> {
64                 UserInfo profileToMakeAdmin =
65                         (UserInfo) arguments.get(ProfilesDialogProvider.KEY_PROFILE_TO_MAKE_ADMIN);
66                 android.car.userlib.UserHelper.grantAdminPermissions(getContext(),
67                         profileToMakeAdmin);
68                 getFragmentController().goBack();
69             };
70 
71     private final RemoveProfileHandler mRemoveProfileHandler;
72 
ProfileDetailsActionButtonsPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)73     public ProfileDetailsActionButtonsPreferenceController(Context context,
74             String preferenceKey, FragmentController fragmentController,
75             CarUxRestrictions uxRestrictions) {
76         this(context, preferenceKey, fragmentController, uxRestrictions,
77                 ProfileHelper.getInstance(context), UserManager.get(context),
78                 new RemoveProfileHandler(context, ProfileHelper.getInstance(context),
79                         UserManager.get(context), fragmentController));
80     }
81 
82     @VisibleForTesting
ProfileDetailsActionButtonsPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, ProfileHelper profileHelper, UserManager userManager, RemoveProfileHandler removeProfileHandler)83     ProfileDetailsActionButtonsPreferenceController(Context context,
84             String preferenceKey, FragmentController fragmentController,
85             CarUxRestrictions uxRestrictions, ProfileHelper profileHelper, UserManager userManager,
86             RemoveProfileHandler removeProfileHandler) {
87         super(context, preferenceKey, fragmentController, uxRestrictions);
88         mProfileHelper = profileHelper;
89         mUserManager = userManager;
90         mRemoveProfileHandler = removeProfileHandler;
91         mDemoProfileDialogHandler = new DemoProfileDialogHandler(context, fragmentController);
92         mAddProfileHandler = new AddProfileHandler(context, fragmentController, this);
93     }
94 
95     @Override
getPreferenceType()96     protected Class<ActionButtonsPreference> getPreferenceType() {
97         return ActionButtonsPreference.class;
98     }
99 
100     @Override
onCreateInternal()101     protected void onCreateInternal() {
102         super.onCreateInternal();
103 
104         mDemoProfileDialogHandler.onCreateInternal();
105         mAddProfileHandler.onCreateInternal();
106 
107         ConfirmationDialogFragment makeAdminDialog =
108                 (ConfirmationDialogFragment) getFragmentController().findDialogByTag(
109                         MAKE_ADMIN_DIALOG_TAG);
110         ConfirmationDialogFragment.resetListeners(
111                 makeAdminDialog,
112                 mMakeAdminConfirmListener,
113                 /* rejectListener= */ null,
114                 /* neutralListener= */ null);
115 
116         mRemoveProfileHandler.resetListeners();
117     }
118 
119     @Override
onStartInternal()120     protected void onStartInternal() {
121         super.onStartInternal();
122 
123         ActionButtonInfo renameButton = getPreference().getButton(ActionButtons.BUTTON1);
124         ActionButtonInfo makeAdminButton = getPreference().getButton(ActionButtons.BUTTON2);
125         ActionButtonInfo profilesButton = getPreference().getButton(ActionButtons.BUTTON3);
126         ActionButtonInfo deleteButton = getPreference().getButton(ActionButtons.BUTTON4);
127 
128         boolean isDemoProfile = mUserManager.isDemoUser();
129         boolean shouldShowAddProfile = mUserManager.isAdminUser()
130                 && mProfileHelper.isCurrentProcessUser(getUserInfo())
131                 && mAddProfileHandler.canAddProfiles(mUserManager)
132                 && !areThereOtherProfiles();
133         boolean shouldShowProfilesButton = isDemoProfile || shouldShowAddProfile
134                 || mUserManager.isAdminUser() && mProfileHelper.isCurrentProcessUser(getUserInfo())
135                 && areThereOtherProfiles();
136 
137         int profileButtonText;
138         if (shouldShowAddProfile && isDemoProfile) {
139             profileButtonText = R.string.exit_retail_button_text;
140         } else if (shouldShowAddProfile) {
141             profileButtonText = R.string.add_a_profile_button_text;
142         } else {
143             profileButtonText = R.string.manage_other_profiles_button_text;
144         }
145 
146         renameButton
147                 .setText(R.string.bluetooth_rename_button)
148                 .setIcon(R.drawable.ic_edit)
149                 .setVisible(mProfileHelper.isCurrentProcessUser(getUserInfo()))
150                 .setOnClickListener(v -> getFragmentController().launchFragment(
151                         EditProfileNameFragment.newInstance(getUserInfo())));
152 
153         makeAdminButton
154                 .setText(R.string.grant_admin_permissions_button_text)
155                 .setIcon(R.drawable.ic_person)
156                 .setVisible(ProfileUtils.isAdminViewingNonAdmin(mUserManager, getUserInfo()))
157                 .setOnClickListener(v -> showConfirmMakeAdminDialog());
158 
159         profilesButton
160                 .setText(profileButtonText)
161                 .setVisible(shouldShowProfilesButton)
162                 .setOnClickListener(v -> {
163                     if (shouldShowAddProfile && isDemoProfile) {
164                         mDemoProfileDialogHandler.showExitRetailDialog();
165                     } else if (shouldShowAddProfile) {
166                         mAddProfileHandler.showAddProfileDialog();
167                     } else {
168                         getFragmentController().launchFragment(
169                                 new ProfilesListFragment());
170                     }
171                 });
172 
173         if (!isDemoProfile && shouldShowAddProfile) {
174             profilesButton.setIcon(R.drawable.ic_add);
175         } else if (!isDemoProfile && shouldShowProfilesButton) {
176             profilesButton.setIcon(R.drawable.ic_people);
177         }
178 
179         // Do not show delete button if the current profile can't remove the selected profile
180         deleteButton
181                 .setText(R.string.delete_button)
182                 .setIcon(R.drawable.ic_delete)
183                 .setVisible(mRemoveProfileHandler.canRemoveProfile(getUserInfo())
184                         && !mProfileHelper.isCurrentProcessUser(getUserInfo()))
185                 .setOnClickListener(v -> mRemoveProfileHandler.showConfirmRemoveProfileDialog());
186     }
187 
188     @Override
setUserInfo(UserInfo userInfo)189     public void setUserInfo(UserInfo userInfo) {
190         super.setUserInfo(userInfo);
191         mRemoveProfileHandler.setUserInfo(userInfo);
192     }
193 
194     @Override
onStopInternal()195     protected void onStopInternal() {
196         super.onStopInternal();
197         mAddProfileHandler.onStopInternal();
198     }
199 
200     @Override
onDestroyInternal()201     protected void onDestroyInternal() {
202         super.onDestroyInternal();
203         mAddProfileHandler.onDestroyInternal();
204     }
205 
206     @Override
updateState(ActionButtonsPreference preference)207     protected void updateState(ActionButtonsPreference preference) {
208         mAddProfileHandler.updateState(preference);
209     }
210 
showConfirmMakeAdminDialog()211     private void showConfirmMakeAdminDialog() {
212         ConfirmationDialogFragment dialogFragment =
213                 ProfilesDialogProvider.getConfirmGrantAdminDialogFragment(getContext(),
214                         mMakeAdminConfirmListener, /* rejectListener= */ null, getUserInfo());
215 
216         getFragmentController().showDialog(dialogFragment, MAKE_ADMIN_DIALOG_TAG);
217     }
218 
areThereOtherProfiles()219     private boolean areThereOtherProfiles() {
220         UserInfo currUserInfo = mProfileHelper.getCurrentProcessUserInfo();
221         return !mProfileHelper.getAllLivingProfiles(
222                 userInfo -> !userInfo.isGuest() && userInfo.id != currUserInfo.id).isEmpty();
223     }
224 }
225