/* * 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 com.android.car.settings.common.ActionButtonsPreference.ActionButtons; 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. * *

The actions shown depends on the current and selected profile. *

    *
  1. Rename: shown if selected profile is the current profile *
  2. Make admin: shown if current profile is an admin and the selected profile is not *
  3. Manage other profiles: shown if selected profile is the current profile and * there are other profiles *
  4. Add a profile: shown if selected profile is the current profile and * there are no other profiles *
  5. Exit demo: shown if selected profile is the current profile and is a demo *
  6. Delete: shown if the current profile is allowed to remove profiles, is not a demo * profile, and selected profile is not the current profile *
*/ public final class ProfileDetailsActionButtonsPreferenceController extends ProfileDetailsBasePreferenceController { @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); android.car.userlib.UserHelper.grantAdminPermissions(getContext(), profileToMakeAdmin); 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 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(); boolean shouldShowAddProfile = mUserManager.isAdminUser() && mProfileHelper.isCurrentProcessUser(getUserInfo()) && mAddProfileHandler.canAddProfiles(mUserManager) && !areThereOtherProfiles(); boolean shouldShowProfilesButton = isDemoProfile || shouldShowAddProfile || mUserManager.isAdminUser() && mProfileHelper.isCurrentProcessUser(getUserInfo()) && areThereOtherProfiles(); 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) { 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(mRemoveProfileHandler.canRemoveProfile(getUserInfo()) && !mProfileHelper.isCurrentProcessUser(getUserInfo())) .setOnClickListener(v -> mRemoveProfileHandler.showConfirmRemoveProfileDialog()); } @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(); } }