blob: 7f1ad2a3efc1ad6b9c038f2ceca9ef685a1325bd [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.settings.profiles;
import static android.os.UserManager.DISALLOW_ADD_USER;
import static com.android.car.settings.common.ActionButtonsPreference.ActionButtons;
import static com.android.car.settings.enterprise.EnterpriseUtils.hasUserRestrictionByDpm;
import static com.android.car.settings.enterprise.EnterpriseUtils.hasUserRestrictionByUm;
import android.car.drivingstate.CarUxRestrictions;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.UserManager;
import androidx.annotation.VisibleForTesting;
import com.android.car.settings.R;
import com.android.car.settings.common.ActionButtonInfo;
import com.android.car.settings.common.ActionButtonsPreference;
import com.android.car.settings.common.ConfirmationDialogFragment;
import com.android.car.settings.common.FragmentController;
/**
* Displays the action buttons for profile details.
*
* <p>The actions shown depends on the current and selected profile.
* <ol>
* <li>Rename: shown if selected profile is the current profile
* <li>Make admin: shown if current profile is an admin and the selected profile is not
* <li>Manage other profiles: shown if selected profile is the current profile and
* there are other profiles
* <li>Add a profile: shown if selected profile is the current profile and
* there are no other profiles
* <li> Exit demo: shown if selected profile is the current profile and is a demo
* <li>Delete: shown if the current profile is allowed to remove profiles, is not a demo
* profile, and selected profile is not the current profile
* </ol>
*/
public final class ProfileDetailsActionButtonsPreferenceController
extends ProfileDetailsBasePreferenceController<ActionButtonsPreference> {
@VisibleForTesting
static final String MAKE_ADMIN_DIALOG_TAG = "MakeAdminDialogFragment";
private final ProfileHelper mProfileHelper;
private final UserManager mUserManager;
private DemoProfileDialogHandler mDemoProfileDialogHandler;
private AddProfileHandler mAddProfileHandler;
@VisibleForTesting
final ConfirmationDialogFragment.ConfirmListener mMakeAdminConfirmListener =
arguments -> {
UserInfo profileToMakeAdmin =
(UserInfo) arguments.get(ProfilesDialogProvider.KEY_PROFILE_TO_MAKE_ADMIN);
com.android.car.internal.user.UserHelper.grantAdminPermissions(getContext(),
profileToMakeAdmin.getUserHandle());
getFragmentController().goBack();
};
private final RemoveProfileHandler mRemoveProfileHandler;
public ProfileDetailsActionButtonsPreferenceController(Context context,
String preferenceKey, FragmentController fragmentController,
CarUxRestrictions uxRestrictions) {
this(context, preferenceKey, fragmentController, uxRestrictions,
ProfileHelper.getInstance(context), UserManager.get(context),
new RemoveProfileHandler(context, ProfileHelper.getInstance(context),
UserManager.get(context), fragmentController));
}
@VisibleForTesting
ProfileDetailsActionButtonsPreferenceController(Context context,
String preferenceKey, FragmentController fragmentController,
CarUxRestrictions uxRestrictions, ProfileHelper profileHelper, UserManager userManager,
RemoveProfileHandler removeProfileHandler) {
super(context, preferenceKey, fragmentController, uxRestrictions);
mProfileHelper = profileHelper;
mUserManager = userManager;
mRemoveProfileHandler = removeProfileHandler;
mDemoProfileDialogHandler = new DemoProfileDialogHandler(context, fragmentController);
mAddProfileHandler = new AddProfileHandler(context, fragmentController, this);
}
@Override
protected Class<ActionButtonsPreference> getPreferenceType() {
return ActionButtonsPreference.class;
}
@Override
protected void onCreateInternal() {
super.onCreateInternal();
mDemoProfileDialogHandler.onCreateInternal();
mAddProfileHandler.onCreateInternal();
ConfirmationDialogFragment makeAdminDialog =
(ConfirmationDialogFragment) getFragmentController().findDialogByTag(
MAKE_ADMIN_DIALOG_TAG);
ConfirmationDialogFragment.resetListeners(
makeAdminDialog,
mMakeAdminConfirmListener,
/* rejectListener= */ null,
/* neutralListener= */ null);
mRemoveProfileHandler.resetListeners();
}
@Override
protected void onStartInternal() {
super.onStartInternal();
ActionButtonInfo renameButton = getPreference().getButton(ActionButtons.BUTTON1);
ActionButtonInfo makeAdminButton = getPreference().getButton(ActionButtons.BUTTON2);
ActionButtonInfo profilesButton = getPreference().getButton(ActionButtons.BUTTON3);
ActionButtonInfo deleteButton = getPreference().getButton(ActionButtons.BUTTON4);
boolean isDemoProfile = mUserManager.isDemoUser();
// When DISALLOW_ADD_USER is set by device or profile owner, the button should still be
// visible but disabled
boolean shouldShowAddProfile = !(mUserManager.isAdminUser() && areThereOtherProfiles())
&& mProfileHelper.isCurrentProcessUser(getUserInfo())
&& !hasUserRestrictionByUm(getContext(), DISALLOW_ADD_USER);
boolean shouldEnableAddProfile = shouldShowAddProfile
&& !hasUserRestrictionByDpm(getContext(), DISALLOW_ADD_USER);
boolean shouldShowProfilesButton = isDemoProfile || shouldShowAddProfile
|| mUserManager.isAdminUser() && mProfileHelper.isCurrentProcessUser(getUserInfo())
&& areThereOtherProfiles();
int removeProfileAvailabilityStatus = mRemoveProfileHandler.getAvailabilityStatus(
getContext(), getUserInfo(), /* availableForCurrentProcessUser= */ false);
boolean shouldShowDeleteProfile = removeProfileAvailabilityStatus != DISABLED_FOR_PROFILE;
boolean shouldEnableDeleteProfile = removeProfileAvailabilityStatus == AVAILABLE;
int profileButtonText;
if (shouldShowAddProfile && isDemoProfile) {
profileButtonText = R.string.exit_retail_button_text;
} else if (shouldShowAddProfile) {
profileButtonText = R.string.add_a_profile_button_text;
} else {
profileButtonText = R.string.manage_other_profiles_button_text;
}
renameButton
.setText(R.string.bluetooth_rename_button)
.setIcon(R.drawable.ic_edit)
.setVisible(mProfileHelper.isCurrentProcessUser(getUserInfo()))
.setOnClickListener(v -> getFragmentController().launchFragment(
EditProfileNameFragment.newInstance(getUserInfo())));
makeAdminButton
.setText(R.string.grant_admin_permissions_button_text)
.setIcon(R.drawable.ic_person)
.setVisible(ProfileUtils.isAdminViewingNonAdmin(mUserManager, getUserInfo()))
.setOnClickListener(v -> showConfirmMakeAdminDialog());
profilesButton
.setText(profileButtonText)
.setVisible(shouldShowProfilesButton)
.setOnClickListener(v -> {
if (shouldShowAddProfile && isDemoProfile) {
mDemoProfileDialogHandler.showExitRetailDialog();
} else if (shouldShowAddProfile && !shouldEnableAddProfile) {
mAddProfileHandler.runClickableWhileDisabled();
} else if (shouldShowAddProfile) {
mAddProfileHandler.showAddProfileDialog();
} else {
getFragmentController().launchFragment(
new ProfilesListFragment());
}
});
if (!isDemoProfile && shouldShowAddProfile) {
profilesButton.setIcon(R.drawable.ic_add);
} else if (!isDemoProfile && shouldShowProfilesButton) {
profilesButton.setIcon(R.drawable.ic_people);
}
// Do not show delete button if the current profile can't remove the selected profile
deleteButton
.setText(R.string.delete_button)
.setIcon(R.drawable.ic_delete)
.setVisible(shouldShowDeleteProfile)
.setOnClickListener(v -> {
if (shouldEnableDeleteProfile) {
mRemoveProfileHandler.showConfirmRemoveProfileDialog();
} else {
mRemoveProfileHandler.runClickableWhileDisabled();
}
});
}
@Override
public void setUserInfo(UserInfo userInfo) {
super.setUserInfo(userInfo);
mRemoveProfileHandler.setUserInfo(userInfo);
}
@Override
protected void onStopInternal() {
super.onStopInternal();
mAddProfileHandler.onStopInternal();
}
@Override
protected void onDestroyInternal() {
super.onDestroyInternal();
mAddProfileHandler.onDestroyInternal();
}
@Override
protected void updateState(ActionButtonsPreference preference) {
mAddProfileHandler.updateState(preference);
}
private void showConfirmMakeAdminDialog() {
ConfirmationDialogFragment dialogFragment =
ProfilesDialogProvider.getConfirmGrantAdminDialogFragment(getContext(),
mMakeAdminConfirmListener, /* rejectListener= */ null, getUserInfo());
getFragmentController().showDialog(dialogFragment, MAKE_ADMIN_DIALOG_TAG);
}
private boolean areThereOtherProfiles() {
UserInfo currUserInfo = mProfileHelper.getCurrentProcessUserInfo();
return !mProfileHelper.getAllLivingProfiles(
userInfo -> !userInfo.isGuest() && userInfo.id != currUserInfo.id).isEmpty();
}
}