1 /*
2  * Copyright (C) 2022 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.combination;
18 
19 import android.content.Context;
20 import android.hardware.biometrics.BiometricAuthenticator;
21 import android.hardware.face.FaceManager;
22 import android.hardware.fingerprint.FingerprintManager;
23 import android.os.UserManager;
24 
25 import androidx.annotation.Nullable;
26 
27 import com.android.settings.R;
28 import com.android.settings.Settings;
29 import com.android.settings.Utils;
30 import com.android.settings.biometrics.ParentalControlsUtils;
31 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
32 import com.android.settingslib.utils.StringUtil;
33 
34 /**
35  * Utilities for combined biometric details shared between Security Settings and Safety Center.
36  */
37 public class CombinedBiometricStatusUtils {
38 
39     private final int mUserId;
40     private final Context mContext;
41     @Nullable
42     FingerprintManager mFingerprintManager;
43     @Nullable
44     FaceManager mFaceManager;
45 
CombinedBiometricStatusUtils(Context context, int userId)46     public CombinedBiometricStatusUtils(Context context, int userId) {
47         mContext = context;
48         mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
49         mFaceManager = Utils.getFaceManagerOrNull(context);
50         mUserId = userId;
51     }
52 
53     /**
54      * Returns whether the combined biometric settings entity should be shown.
55      */
isAvailable()56     public boolean isAvailable() {
57         return Utils.hasFingerprintHardware(mContext) && Utils.hasFaceHardware(mContext);
58     }
59 
60     /**
61      * Returns whether at least one face template or fingerprint has been enrolled.
62      */
hasEnrolled()63     public boolean hasEnrolled() {
64         return hasEnrolledFingerprints() || hasEnrolledFace();
65     }
66 
67     /**
68      * Returns the {@link EnforcedAdmin} in case parental consent is required to change both
69      * face and fingerprint settings.
70      *
71      * @return null if either face or fingerprint settings do not require a parental consent.
72      */
getDisablingAdmin()73     public EnforcedAdmin getDisablingAdmin() {
74         // This controller currently is shown if fingerprint&face exist on the device. If this
75         // changes in the future, the modalities passed into the below will need to be updated.
76 
77         final EnforcedAdmin faceAdmin = ParentalControlsUtils
78                 .parentConsentRequired(mContext, BiometricAuthenticator.TYPE_FACE);
79         final EnforcedAdmin fpAdmin = ParentalControlsUtils
80                 .parentConsentRequired(mContext, BiometricAuthenticator.TYPE_FINGERPRINT);
81 
82         final boolean faceConsentRequired = faceAdmin != null;
83         final boolean fpConsentRequired = fpAdmin != null;
84 
85         // Result is only required if all modalities require consent.
86         // If the admins are non-null, they are actually always the same.
87         return faceConsentRequired && fpConsentRequired ? faceAdmin : null;
88     }
89 
90     /**
91      * Returns the title of combined biometric settings entity.
92      */
getTitle()93     public String getTitle() {
94         UserManager userManager = mContext.getSystemService(UserManager.class);
95         if (userManager != null && userManager.isProfile()) {
96             return mContext.getString(
97                     Utils.isPrivateProfile(mUserId, mContext)
98                             ? R.string.private_space_biometric_unlock_title
99                             : R.string.security_settings_work_biometric_preference_title);
100         } else {
101             return mContext.getString(R.string.security_settings_biometric_preference_title);
102         }
103     }
104 
105     /**
106      * Returns the summary of combined biometric settings entity.
107      */
getSummary()108     public String getSummary() {
109         final int numFingerprintsEnrolled = mFingerprintManager != null
110                 ? mFingerprintManager.getEnrolledFingerprints(mUserId).size() : 0;
111         final boolean faceEnrolled = hasEnrolledFace();
112 
113         if (faceEnrolled && numFingerprintsEnrolled > 1) {
114             return mContext.getString(
115                     R.string.security_settings_biometric_preference_summary_both_fp_multiple);
116         } else if (faceEnrolled && numFingerprintsEnrolled == 1) {
117             return mContext.getString(
118                     R.string.security_settings_biometric_preference_summary_both_fp_single);
119         } else if (faceEnrolled) {
120             return mContext.getString(R.string.security_settings_face_preference_summary);
121         } else if (numFingerprintsEnrolled > 0) {
122             return StringUtil.getIcuPluralsString(mContext, numFingerprintsEnrolled,
123                     R.string.security_settings_fingerprint_preference_summary);
124         } else {
125             return mContext.getString(
126                     R.string.security_settings_biometric_preference_summary_none_enrolled);
127         }
128     }
129 
hasEnrolledFingerprints()130     private boolean hasEnrolledFingerprints() {
131         return mFingerprintManager != null && mFingerprintManager.hasEnrolledFingerprints(mUserId);
132     }
133 
hasEnrolledFace()134     private boolean hasEnrolledFace() {
135         return mFaceManager != null && mFaceManager.hasEnrolledTemplates(mUserId);
136     }
137 
138     /**
139      * Returns the class name of the Settings page corresponding to combined biometric settings
140      * based on the current user.
141      */
getSettingsClassNameBasedOnUser()142     public String getSettingsClassNameBasedOnUser() {
143         UserManager userManager = mContext.getSystemService(UserManager.class);
144         if (userManager != null && userManager.isProfile()) {
145             return getProfileSettingsClassName();
146         } else {
147             return getSettingsClassName();
148         }
149     }
150 
151     /**
152      * Returns the class name of the Settings page corresponding to combined biometric settings.
153      */
getSettingsClassName()154     public String getSettingsClassName() {
155         return Settings.CombinedBiometricSettingsActivity.class.getName();
156     }
157 
158     /**
159      * Returns the class name of the Settings page corresponding to combined biometric settings
160      * for work profile.
161      */
getProfileSettingsClassName()162     public String getProfileSettingsClassName() {
163         return Settings.CombinedBiometricProfileSettingsActivity.class.getName();
164     }
165 
166     /**
167      * Returns the class name of the Settings page corresponding to combined biometric settings for
168      * Private profile.
169      */
getPrivateProfileSettingsClassName()170     public String getPrivateProfileSettingsClassName() {
171         return Settings.PrivateSpaceBiometricSettingsActivity.class.getName();
172     }
173 }
174