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 android.hardware.biometrics;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.admin.DevicePolicyManager;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.os.Build;
25 import android.os.UserHandle;
26 import android.provider.Settings;
27 
28 /**
29  * "Base" functionality. For settings-specific functionality (which may rely on this base
30  * functionality), see {@link com.android.settings.biometrics.ParentalControlsUtils}
31  * @hide
32  */
33 public class ParentalControlsUtilsInternal {
34 
35     private static final String TEST_ALWAYS_REQUIRE_CONSENT =
36             "android.hardware.biometrics.ParentalControlsUtilsInternal.always_require_consent";
37 
isTestModeEnabled(@onNull Context context)38     public static boolean isTestModeEnabled(@NonNull Context context) {
39         if (Build.IS_USERDEBUG || Build.IS_ENG) {
40             return Settings.Secure.getInt(context.getContentResolver(),
41                     TEST_ALWAYS_REQUIRE_CONSENT, 0) != 0;
42         }
43         return false;
44     }
45 
parentConsentRequired(@onNull Context context, @NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality, @NonNull UserHandle userHandle)46     public static boolean parentConsentRequired(@NonNull Context context,
47             @NonNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality,
48             @NonNull UserHandle userHandle) {
49         if (isTestModeEnabled(context)) {
50             return true;
51         }
52 
53         return parentConsentRequired(dpm, modality, userHandle);
54     }
55 
56     /**
57      * @return true if parental consent is required in order for biometric sensors to be used.
58      */
parentConsentRequired(@onNull DevicePolicyManager dpm, @BiometricAuthenticator.Modality int modality, @NonNull UserHandle userHandle)59     public static boolean parentConsentRequired(@NonNull DevicePolicyManager dpm,
60             @BiometricAuthenticator.Modality int modality, @NonNull UserHandle userHandle) {
61         final ComponentName cn = getSupervisionComponentName(dpm, userHandle);
62         if (cn == null) {
63             return false;
64         }
65 
66         final int keyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(cn);
67         final boolean dpmFpDisabled = containsFlag(keyguardDisabledFeatures,
68                 DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
69         final boolean dpmFaceDisabled = containsFlag(keyguardDisabledFeatures,
70                 DevicePolicyManager.KEYGUARD_DISABLE_FACE);
71         final boolean dpmIrisDisabled = containsFlag(keyguardDisabledFeatures,
72                 DevicePolicyManager.KEYGUARD_DISABLE_IRIS);
73 
74         final boolean consentRequired;
75         if (containsFlag(modality, BiometricAuthenticator.TYPE_FINGERPRINT) && dpmFpDisabled) {
76             consentRequired = true;
77         } else if (containsFlag(modality, BiometricAuthenticator.TYPE_FACE) && dpmFaceDisabled) {
78             consentRequired = true;
79         } else if (containsFlag(modality, BiometricAuthenticator.TYPE_IRIS) && dpmIrisDisabled) {
80             consentRequired = true;
81         } else {
82             consentRequired = false;
83         }
84 
85         return consentRequired;
86     }
87 
88     @Nullable
getSupervisionComponentName(@onNull DevicePolicyManager dpm, @NonNull UserHandle userHandle)89     public static ComponentName getSupervisionComponentName(@NonNull DevicePolicyManager dpm,
90             @NonNull UserHandle userHandle) {
91         return dpm.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle);
92     }
93 
containsFlag(int haystack, int needle)94     private static boolean containsFlag(int haystack, int needle) {
95         return (haystack & needle) != 0;
96     }
97 }
98