1 /*
2  * Copyright (C) 2019 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.systemui.biometrics;
18 
19 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
20 import static android.hardware.biometrics.BiometricManager.Authenticators;
21 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
22 
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.app.admin.DevicePolicyManager;
27 import android.content.Context;
28 import android.content.pm.PackageManager;
29 import android.hardware.biometrics.PromptInfo;
30 import android.hardware.biometrics.SensorPropertiesInternal;
31 import android.os.UserManager;
32 import android.util.DisplayMetrics;
33 import android.view.ViewGroup;
34 import android.view.WindowManager;
35 import android.view.accessibility.AccessibilityEvent;
36 import android.view.accessibility.AccessibilityManager;
37 
38 import com.android.internal.widget.LockPatternUtils;
39 
40 import java.lang.annotation.Retention;
41 import java.lang.annotation.RetentionPolicy;
42 import java.util.List;
43 
44 public class Utils {
45 
46     public static final int CREDENTIAL_PIN = 1;
47     public static final int CREDENTIAL_PATTERN = 2;
48     public static final int CREDENTIAL_PASSWORD = 3;
49 
50     /** Base set of layout flags for fingerprint overlay widgets. */
51     public static final int FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS =
52             WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
53                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
54                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
55                 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
56 
57     @Retention(RetentionPolicy.SOURCE)
58     @IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
59     @interface CredentialType {}
60 
dpToPixels(Context context, float dp)61     static float dpToPixels(Context context, float dp) {
62         return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
63                 / DisplayMetrics.DENSITY_DEFAULT);
64     }
65 
notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view)66     static void notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view) {
67         if (!am.isEnabled()) {
68             return;
69         }
70         AccessibilityEvent event = AccessibilityEvent.obtain();
71         event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
72         event.setContentChangeTypes(CONTENT_CHANGE_TYPE_SUBTREE);
73         view.sendAccessibilityEventUnchecked(event);
74         view.notifySubtreeAccessibilityStateChanged(view, view, CONTENT_CHANGE_TYPE_SUBTREE);
75     }
76 
isDeviceCredentialAllowed(PromptInfo promptInfo)77     static boolean isDeviceCredentialAllowed(PromptInfo promptInfo) {
78         @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
79         return (authenticators & Authenticators.DEVICE_CREDENTIAL) != 0;
80     }
81 
isBiometricAllowed(PromptInfo promptInfo)82     static boolean isBiometricAllowed(PromptInfo promptInfo) {
83         @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
84         return (authenticators & Authenticators.BIOMETRIC_WEAK) != 0;
85     }
86 
getCredentialType(Context context, int userId)87     static @CredentialType int getCredentialType(Context context, int userId) {
88         final LockPatternUtils lpu = new LockPatternUtils(context);
89         switch (lpu.getKeyguardStoredPasswordQuality(userId)) {
90             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
91                 return CREDENTIAL_PATTERN;
92             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
93             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
94                 return CREDENTIAL_PIN;
95             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
96             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
97             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
98             case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
99                 return CREDENTIAL_PASSWORD;
100             default:
101                 return CREDENTIAL_PASSWORD;
102         }
103     }
104 
isManagedProfile(Context context, int userId)105     static boolean isManagedProfile(Context context, int userId) {
106         final UserManager userManager = context.getSystemService(UserManager.class);
107         return userManager.isManagedProfile(userId);
108     }
109 
containsSensorId(@ullable List<? extends SensorPropertiesInternal> properties, int sensorId)110     static boolean containsSensorId(@Nullable List<? extends SensorPropertiesInternal> properties,
111             int sensorId) {
112         if (properties == null) {
113             return false;
114         }
115 
116         for (SensorPropertiesInternal prop : properties) {
117             if (prop.sensorId == sensorId) {
118                 return true;
119             }
120         }
121 
122         return false;
123     }
124 
isSystem(@onNull Context context, @Nullable String clientPackage)125     static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) {
126         final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
127                 == PackageManager.PERMISSION_GRANTED;
128         return hasPermission && "android".equals(clientPackage);
129     }
130 }
131