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 android.hardware.fingerprint;
18 
19 import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
20 import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
21 import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
22 
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.hardware.biometrics.ComponentInfoInternal;
26 import android.hardware.biometrics.SensorLocationInternal;
27 import android.hardware.biometrics.SensorProperties;
28 import android.hardware.biometrics.SensorPropertiesInternal;
29 import android.os.Parcel;
30 
31 import java.util.List;
32 
33 /**
34  * Container for fingerprint sensor properties.
35  * @hide
36  */
37 public class FingerprintSensorPropertiesInternal extends SensorPropertiesInternal {
38     /**
39      * See {@link FingerprintSensorProperties.SensorType}.
40      */
41     public final @FingerprintSensorProperties.SensorType int sensorType;
42 
43     private final List<SensorLocationInternal> mSensorLocations;
44 
FingerprintSensorPropertiesInternal(int sensorId, @SensorProperties.Strength int strength, int maxEnrollmentsPerUser, @NonNull List<ComponentInfoInternal> componentInfo, @FingerprintSensorProperties.SensorType int sensorType, boolean resetLockoutRequiresHardwareAuthToken, @NonNull List<SensorLocationInternal> sensorLocations)45     public FingerprintSensorPropertiesInternal(int sensorId,
46             @SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
47             @NonNull List<ComponentInfoInternal> componentInfo,
48             @FingerprintSensorProperties.SensorType int sensorType,
49             boolean resetLockoutRequiresHardwareAuthToken,
50             @NonNull List<SensorLocationInternal> sensorLocations) {
51         // IBiometricsFingerprint@2.1 handles lockout in the framework, so the challenge is not
52         // required as it can only be generated/attested/verified by TEE components.
53         // IFingerprint@1.0 handles lockout below the HAL, but does not require a challenge. See
54         // the HAL interface for more details.
55         super(sensorId, strength, maxEnrollmentsPerUser, componentInfo,
56             resetLockoutRequiresHardwareAuthToken, false /* resetLockoutRequiresChallenge */);
57         this.sensorType = sensorType;
58         this.mSensorLocations = List.copyOf(sensorLocations);
59     }
60 
61     /**
62      * Initializes SensorProperties with specified values
63      */
FingerprintSensorPropertiesInternal(int sensorId, @SensorProperties.Strength int strength, int maxEnrollmentsPerUser, @NonNull List<ComponentInfoInternal> componentInfo, @FingerprintSensorProperties.SensorType int sensorType, boolean resetLockoutRequiresHardwareAuthToken)64     public FingerprintSensorPropertiesInternal(int sensorId,
65             @SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
66             @NonNull List<ComponentInfoInternal> componentInfo,
67             @FingerprintSensorProperties.SensorType int sensorType,
68             boolean resetLockoutRequiresHardwareAuthToken) {
69         // TODO(b/179175438): Value should be provided from the HAL
70         this(sensorId, strength, maxEnrollmentsPerUser, componentInfo, sensorType,
71                 resetLockoutRequiresHardwareAuthToken, List.of(new SensorLocationInternal(
72                         "" /* displayId */,  540 /* sensorLocationX */, 1636 /* sensorLocationY */,
73                         130 /* sensorRadius */)));
74     }
75 
FingerprintSensorPropertiesInternal(Parcel in)76     protected FingerprintSensorPropertiesInternal(Parcel in) {
77         super(in);
78         sensorType = in.readInt();
79         mSensorLocations = in.createTypedArrayList(SensorLocationInternal.CREATOR);
80     }
81 
82     public static final Creator<FingerprintSensorPropertiesInternal> CREATOR =
83             new Creator<FingerprintSensorPropertiesInternal>() {
84                 @Override
85                 public FingerprintSensorPropertiesInternal createFromParcel(Parcel in) {
86                     return new FingerprintSensorPropertiesInternal(in);
87                 }
88 
89                 @Override
90                 public FingerprintSensorPropertiesInternal[] newArray(int size) {
91                     return new FingerprintSensorPropertiesInternal[size];
92                 }
93             };
94 
95     @Override
describeContents()96     public int describeContents() {
97         return 0;
98     }
99 
100     @Override
writeToParcel(Parcel dest, int flags)101     public void writeToParcel(Parcel dest, int flags) {
102         super.writeToParcel(dest, flags);
103         dest.writeInt(sensorType);
104         dest.writeTypedList(mSensorLocations);
105     }
106 
isAnyUdfpsType()107     public boolean isAnyUdfpsType() {
108         switch (sensorType) {
109             case TYPE_UDFPS_OPTICAL:
110             case TYPE_UDFPS_ULTRASONIC:
111                 return true;
112             default:
113                 return false;
114         }
115     }
116 
117     /**
118      * Returns if sensor type is side-FPS
119      * @return true if sensor is side-fps, false otherwise
120      */
isAnySidefpsType()121     public boolean isAnySidefpsType() {
122         switch (sensorType) {
123             case TYPE_POWER_BUTTON:
124                 return true;
125             default:
126                 return false;
127         }
128     }
129 
130     /**
131      * Get the default location.
132      *
133      * Use this method when the sensor's relationship to the displays on the device do not
134      * matter.
135      * @return
136      */
137     @NonNull
getLocation()138     public SensorLocationInternal getLocation() {
139         final SensorLocationInternal location = getLocation("" /* displayId */);
140         return location != null ? location : SensorLocationInternal.DEFAULT;
141     }
142 
143     /**
144      * Get the location of a sensor relative to a physical display layout.
145      *
146      * @param displayId stable display id
147      * @return location or null if none is specified
148      */
149     @Nullable
getLocation(String displayId)150     public SensorLocationInternal getLocation(String displayId) {
151         for (SensorLocationInternal location : mSensorLocations) {
152             if (location.displayId.equals(displayId)) {
153                 return location;
154             }
155         }
156         return null;
157     }
158 
159     /**
160      * Gets all locations relative to all supported display layouts.
161      * @return supported locations
162      */
163     @NonNull
getAllLocations()164     public List<SensorLocationInternal> getAllLocations() {
165         return mSensorLocations;
166     }
167 
168     @Override
toString()169     public String toString() {
170         return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
171     }
172 }
173