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.accounts; 18 19 import static android.app.Activity.RESULT_OK; 20 import static android.os.UserManager.DISALLOW_MODIFY_ACCOUNTS; 21 22 import static com.android.car.settings.enterprise.EnterpriseUtils.hasUserRestrictionByUm; 23 import static com.android.car.settings.enterprise.EnterpriseUtils.isDeviceManaged; 24 25 import android.car.drivingstate.CarUxRestrictions; 26 import android.content.Context; 27 import android.content.Intent; 28 29 import androidx.annotation.Nullable; 30 import androidx.annotation.VisibleForTesting; 31 import androidx.preference.Preference; 32 33 import com.android.car.settings.admin.NewUserDisclaimerActivity; 34 import com.android.car.settings.common.ActivityResultCallback; 35 import com.android.car.settings.common.FragmentController; 36 import com.android.car.settings.common.Logger; 37 import com.android.car.settings.common.PreferenceController; 38 import com.android.car.settings.profiles.ProfileHelper; 39 40 import java.util.Arrays; 41 import java.util.HashSet; 42 import java.util.Set; 43 44 /** 45 * Business Logic for preference starts the add account flow. 46 */ 47 public class AddAccountPreferenceController extends PreferenceController<Preference> 48 implements ActivityResultCallback { 49 public static final int NEW_USER_DISCLAIMER_REQUEST = 1; 50 private static final Logger LOG = new Logger(AddAccountPreferenceController.class); 51 52 private String[] mAuthorities; 53 private String[] mAccountTypes; 54 AddAccountPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)55 public AddAccountPreferenceController(Context context, String preferenceKey, 56 FragmentController fragmentController, 57 CarUxRestrictions uxRestrictions) { 58 super(context, preferenceKey, fragmentController, uxRestrictions); 59 } 60 61 /** Sets the account authorities that are available. */ setAuthorities(String[] authorities)62 public AddAccountPreferenceController setAuthorities(String[] authorities) { 63 mAuthorities = authorities; 64 return this; 65 } 66 67 /** Sets the account authorities that are available. */ setAccountTypes(String[] accountTypes)68 public AddAccountPreferenceController setAccountTypes(String[] accountTypes) { 69 mAccountTypes = accountTypes; 70 return this; 71 } 72 73 @Override getPreferenceType()74 protected Class<Preference> getPreferenceType() { 75 return Preference.class; 76 } 77 78 @Override onCreateInternal()79 protected void onCreateInternal() { 80 super.onCreateInternal(); 81 setClickableWhileDisabled(getPreference(), /* clickable= */ true, p -> { 82 if (!getProfileHelper().isNewUserDisclaimerAcknolwedged(getContext())) { 83 LOG.d("isNewUserDisclaimerAcknolwedged returns false, start activity"); 84 startNewUserDisclaimerActivityForResult(); 85 return; 86 } 87 getProfileHelper() 88 .runClickableWhileDisabled(getContext(), getFragmentController()); 89 }); 90 } 91 92 @Override handlePreferenceClicked(Preference preference)93 protected boolean handlePreferenceClicked(Preference preference) { 94 AccountTypesHelper helper = getAccountTypesHelper(); 95 96 if (mAuthorities != null) { 97 helper.setAuthorities(Arrays.asList(mAuthorities)); 98 } 99 if (mAccountTypes != null) { 100 helper.setAccountTypesFilter( 101 new HashSet<>(Arrays.asList(mAccountTypes))); 102 } 103 launchAddAccount(); 104 return true; 105 } 106 107 @Override processActivityResult(int requestCode, int resultCode, @Nullable Intent data)108 public void processActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 109 if (requestCode == NEW_USER_DISCLAIMER_REQUEST && resultCode == RESULT_OK) { 110 LOG.d("New user disclaimer acknowledged, launching add account."); 111 launchAddAccount(); 112 } else { 113 LOG.e("New user disclaimer failed with result " + resultCode); 114 } 115 } 116 launchAddAccount()117 private void launchAddAccount() { 118 Set<String> authorizedAccountTypes = getAccountTypesHelper().getAuthorizedAccountTypes(); 119 120 // Skip the choose account screen if there is only one account type and the device is not 121 // managed by a device owner. 122 // TODO (b/213894991) add check for profile owner when work profile is supported 123 if (authorizedAccountTypes.size() == 1 && !isDeviceManaged(getContext())) { 124 String accountType = authorizedAccountTypes.iterator().next(); 125 getContext().startActivity( 126 AddAccountActivity.createAddAccountActivityIntent(getContext(), accountType)); 127 } else { 128 getFragmentController().launchFragment(new ChooseAccountFragment()); 129 } 130 } 131 132 @Override getDefaultAvailabilityStatus()133 protected int getDefaultAvailabilityStatus() { 134 if (isDeviceManaged(getContext()) 135 && !getProfileHelper().isNewUserDisclaimerAcknolwedged(getContext())) { 136 return AVAILABLE_FOR_VIEWING; 137 } 138 if (getProfileHelper().canCurrentProcessModifyAccounts()) { 139 return AVAILABLE; 140 } 141 if (getProfileHelper().isDemoOrGuest() 142 || hasUserRestrictionByUm(getContext(), DISALLOW_MODIFY_ACCOUNTS)) { 143 return DISABLED_FOR_PROFILE; 144 } 145 return AVAILABLE_FOR_VIEWING; 146 } 147 startNewUserDisclaimerActivityForResult()148 private void startNewUserDisclaimerActivityForResult() { 149 getFragmentController().startActivityForResult( 150 new Intent(getContext(), NewUserDisclaimerActivity.class), 151 NEW_USER_DISCLAIMER_REQUEST, /* callback= */ this); 152 } 153 154 @VisibleForTesting getProfileHelper()155 ProfileHelper getProfileHelper() { 156 return ProfileHelper.getInstance(getContext()); 157 } 158 159 @VisibleForTesting getAccountTypesHelper()160 AccountTypesHelper getAccountTypesHelper() { 161 return new AccountTypesHelper(getContext()); 162 } 163 } 164