1 /* 2 * Copyright (C) 2018 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.settings.biometrics; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.os.UserHandle; 22 import android.os.UserManager; 23 import android.text.TextUtils; 24 25 import androidx.activity.result.ActivityResultLauncher; 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 import androidx.preference.Preference; 29 30 import com.android.internal.widget.LockPatternUtils; 31 import com.android.settings.Utils; 32 import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils; 33 import com.android.settings.core.BasePreferenceController; 34 import com.android.settings.overlay.FeatureFactory; 35 36 import java.lang.ref.WeakReference; 37 38 public abstract class BiometricStatusPreferenceController extends BasePreferenceController { 39 40 protected final UserManager mUm; 41 protected final LockPatternUtils mLockPatternUtils; 42 43 private final int mUserId = UserHandle.myUserId(); 44 protected final int mProfileChallengeUserId; 45 46 private final BiometricNavigationUtils mBiometricNavigationUtils; 47 private final ActiveUnlockStatusUtils mActiveUnlockStatusUtils; 48 @NonNull private WeakReference<ActivityResultLauncher<Intent>> mLauncherWeakReference = 49 new WeakReference<>(null); 50 51 /** 52 * @return true if the controller should be shown exclusively. 53 */ isDeviceSupported()54 protected abstract boolean isDeviceSupported(); 55 56 /** 57 * @return true if the manager is not null and the hardware is detected. 58 */ isHardwareSupported()59 protected abstract boolean isHardwareSupported(); 60 61 /** 62 * @return the summary text. 63 */ getSummaryText()64 protected abstract String getSummaryText(); 65 66 /** 67 * @return the class name for the settings page. 68 */ getSettingsClassName()69 protected abstract String getSettingsClassName(); 70 BiometricStatusPreferenceController(Context context, String key)71 public BiometricStatusPreferenceController(Context context, String key) { 72 super(context, key); 73 mUm = (UserManager) context.getSystemService(Context.USER_SERVICE); 74 mLockPatternUtils = FeatureFactory.getFeatureFactory() 75 .getSecurityFeatureProvider() 76 .getLockPatternUtils(context); 77 mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId); 78 mBiometricNavigationUtils = new BiometricNavigationUtils(getUserId()); 79 mActiveUnlockStatusUtils = new ActiveUnlockStatusUtils(context); 80 } 81 82 @Override getAvailabilityStatus()83 public int getAvailabilityStatus() { 84 if (mActiveUnlockStatusUtils.isAvailable()) { 85 return getAvailabilityStatusWithWorkProfileCheck(); 86 } 87 if (!isDeviceSupported()) { 88 return UNSUPPORTED_ON_DEVICE; 89 } 90 return getAvailabilityFromUserSupported(); 91 } 92 getAvailabilityFromUserSupported()93 private int getAvailabilityFromUserSupported() { 94 if (isUserSupported()) { 95 return AVAILABLE; 96 } else { 97 return DISABLED_FOR_USER; 98 } 99 } 100 101 // Since this code is flag guarded by mActiveUnlockStatusUtils.isAvailable(), we don't need to 102 // do another check here. getAvailabilityStatusWithWorkProfileCheck()103 private int getAvailabilityStatusWithWorkProfileCheck() { 104 if (!isHardwareSupported()) { 105 // no hardware, never show 106 return UNSUPPORTED_ON_DEVICE; 107 } 108 if (!isDeviceSupported() && isWorkProfileController()) { 109 // hardware supported but work profile, don't show 110 return UNSUPPORTED_ON_DEVICE; 111 } 112 // hardware supported, not work profile, active unlock enabled 113 return getAvailabilityFromUserSupported(); 114 } 115 116 @Override updateState(Preference preference)117 public void updateState(Preference preference) { 118 if (!isAvailable()) { 119 if (preference != null) { 120 preference.setVisible(false); 121 } 122 return; 123 } else { 124 preference.setVisible(true); 125 } 126 preference.setSummary(getSummaryText()); 127 } 128 129 /** 130 * Set ActivityResultLauncher that will be used later during handlePreferenceTreeClick() 131 * 132 * @param preference the preference being compared 133 * @param launcher the ActivityResultLauncher 134 * @return {@code true} if matched preference. 135 */ setPreferenceTreeClickLauncher(@onNull Preference preference, @Nullable ActivityResultLauncher<Intent> launcher)136 public boolean setPreferenceTreeClickLauncher(@NonNull Preference preference, 137 @Nullable ActivityResultLauncher<Intent> launcher) { 138 if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { 139 return false; 140 } 141 142 mLauncherWeakReference = new WeakReference<>(launcher); 143 return true; 144 } 145 146 @Override handlePreferenceTreeClick(Preference preference)147 public boolean handlePreferenceTreeClick(Preference preference) { 148 if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { 149 return super.handlePreferenceTreeClick(preference); 150 } 151 152 return mBiometricNavigationUtils.launchBiometricSettings(preference.getContext(), 153 getSettingsClassName(), preference.getExtras(), mLauncherWeakReference.get()); 154 } 155 getUserId()156 protected int getUserId() { 157 return mUserId; 158 } 159 isUserSupported()160 protected boolean isUserSupported() { 161 return true; 162 } 163 164 /** 165 * Returns true if the controller controls is used for work profile. 166 */ isWorkProfileController()167 protected boolean isWorkProfileController() { 168 return false; 169 } 170 } 171