1 /* 2 * Copyright (C) 2021 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 android.car.Car; 20 import android.car.user.CarUserManager; 21 import android.content.Context; 22 import android.os.UserManager; 23 24 import androidx.annotation.VisibleForTesting; 25 import androidx.preference.Preference; 26 27 import com.android.car.settings.R; 28 import com.android.car.settings.common.ConfirmationDialogFragment; 29 import com.android.car.settings.common.ErrorDialog; 30 import com.android.car.settings.common.FragmentController; 31 import com.android.car.settings.common.PreferenceController; 32 33 /** 34 * Consolidates adding profile logic into one handler so we can have consistent logic across various 35 * parts of the Settings app. 36 */ 37 public class AddProfileHandler implements AddNewProfileTask.AddNewProfileListener { 38 39 @VisibleForTesting 40 static final String CONFIRM_CREATE_NEW_PROFILE_DIALOG_TAG = 41 "com.android.car.settings.profiles.ConfirmCreateNewProfileDialog"; 42 43 @VisibleForTesting 44 AddNewProfileTask mAddNewProfileTask; 45 /** Indicates that a task is running. */ 46 private boolean mIsBusy; 47 48 private final Context mContext; 49 private final FragmentController mFragmentController; 50 private final PreferenceController mPreferenceController; 51 private final Car mCar; 52 private CarUserManager mCarUserManager; 53 54 @VisibleForTesting 55 ConfirmationDialogFragment.ConfirmListener mConfirmCreateNewProfileListener; 56 AddProfileHandler(Context context, FragmentController fragmentController, PreferenceController preferenceController)57 public AddProfileHandler(Context context, FragmentController fragmentController, 58 PreferenceController preferenceController) { 59 mContext = context; 60 mFragmentController = fragmentController; 61 mPreferenceController = preferenceController; 62 mCar = Car.createCar(context); 63 mCarUserManager = (CarUserManager) mCar.getCarManager(Car.CAR_USER_SERVICE); 64 65 mConfirmCreateNewProfileListener = arguments -> { 66 mAddNewProfileTask = new AddNewProfileTask(mContext, 67 mCarUserManager, /* addNewProfileListener= */ this); 68 mAddNewProfileTask.execute(mContext.getString(R.string.user_new_user_name)); 69 70 mIsBusy = true; 71 mPreferenceController.refreshUi(); 72 }; 73 } 74 75 /** 76 * Handles operations that should happen in host's onCreateInternal(). 77 * Resets listeners as they can get unregistered with certain configuration changes. 78 */ onCreateInternal()79 public void onCreateInternal() { 80 ConfirmationDialogFragment.resetListeners( 81 (ConfirmationDialogFragment) mFragmentController.findDialogByTag( 82 CONFIRM_CREATE_NEW_PROFILE_DIALOG_TAG), 83 mConfirmCreateNewProfileListener, 84 /* rejectListener= */ null, 85 /* neutralListener= */ null); 86 } 87 88 /** 89 * Handles operations that should happen in host's onStopInternal(). 90 */ onStopInternal()91 public void onStopInternal() { 92 mFragmentController.showProgressBar(false); 93 } 94 95 /** 96 * Handles events that should happen in host's onDestroyInternal(). 97 */ onDestroyInternal()98 public void onDestroyInternal() { 99 if (mAddNewProfileTask != null) { 100 mAddNewProfileTask.cancel(/* mayInterruptIfRunning= */ false); 101 } 102 if (mCar != null) { 103 mCar.disconnect(); 104 } 105 } 106 107 /** 108 * Handles events that should happen in host's updateState(). 109 */ updateState(Preference preference)110 public void updateState(Preference preference) { 111 preference.setEnabled(!mIsBusy); 112 mFragmentController.showProgressBar(mIsBusy); 113 } 114 115 @Override onProfileAddedSuccess()116 public void onProfileAddedSuccess() { 117 mIsBusy = false; 118 mPreferenceController.refreshUi(); 119 } 120 121 @Override onProfileAddedFailure()122 public void onProfileAddedFailure() { 123 mIsBusy = false; 124 mPreferenceController.refreshUi(); 125 // Display failure dialog. 126 mFragmentController.showDialog( 127 ErrorDialog.newInstance(R.string.add_user_error_title), /* tag= */ null); 128 } 129 130 /** 131 * Determines whether the user manager instance has the permission to add profiles 132 * 133 * @param userManager UserManager instance to evaluate 134 * @return whether the user has permissions to add profiles 135 */ canAddProfiles(UserManager userManager)136 public boolean canAddProfiles(UserManager userManager) { 137 return !userManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER); 138 } 139 140 /** 141 * Display dialog to add a profile 142 */ showAddProfileDialog()143 public void showAddProfileDialog() { 144 ConfirmationDialogFragment dialogFragment = 145 ProfilesDialogProvider.getConfirmCreateNewProfileDialogFragment( 146 mContext, mConfirmCreateNewProfileListener, null); 147 148 mFragmentController.showDialog(dialogFragment, CONFIRM_CREATE_NEW_PROFILE_DIALOG_TAG); 149 } 150 151 @VisibleForTesting setCarUserManager(CarUserManager carUserManager)152 void setCarUserManager(CarUserManager carUserManager) { 153 mCarUserManager = carUserManager; 154 } 155 } 156