Merge "Add biometric component info and face type into SensorPropertiesInternal" into sc-dev am: 82a38b099e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13793823

Change-Id: I32943a83c6da27d83702cc85b69b00dc48fa44c7
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 7e19fc3..4a1243d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1053,6 +1053,7 @@
   }
 
   public class SensorProperties {
+    method @NonNull public java.util.List<android.hardware.biometrics.SensorProperties.ComponentInfo> getComponentInfo();
     method public int getSensorId();
     method public int getSensorStrength();
     field public static final int STRENGTH_CONVENIENCE = 0; // 0x0
@@ -1060,6 +1061,14 @@
     field public static final int STRENGTH_WEAK = 1; // 0x1
   }
 
+  public static final class SensorProperties.ComponentInfo {
+    method @NonNull public String getComponentId();
+    method @NonNull public String getFirmwareVersion();
+    method @NonNull public String getHardwareVersion();
+    method @NonNull public String getSerialNumber();
+    method @NonNull public String getSoftwareVersion();
+  }
+
 }
 
 package android.hardware.camera2 {
diff --git a/core/java/android/hardware/biometrics/ComponentInfoInternal.aidl b/core/java/android/hardware/biometrics/ComponentInfoInternal.aidl
new file mode 100644
index 0000000..0c780cc
--- /dev/null
+++ b/core/java/android/hardware/biometrics/ComponentInfoInternal.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.biometrics;
+
+parcelable ComponentInfoInternal;
\ No newline at end of file
diff --git a/core/java/android/hardware/biometrics/ComponentInfoInternal.java b/core/java/android/hardware/biometrics/ComponentInfoInternal.java
new file mode 100644
index 0000000..fa34e0b
--- /dev/null
+++ b/core/java/android/hardware/biometrics/ComponentInfoInternal.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The internal class for storing the component info for a subsystem of the biometric sensor,
+ * as defined in {@link android.hardware.biometrics.common.ComponentInfo}.
+ * @hide
+ */
+public class ComponentInfoInternal implements Parcelable {
+
+    public final String componentId;
+    public final String hardwareVersion;
+    public final String firmwareVersion;
+    public final String serialNumber;
+    public final String softwareVersion;
+
+    /**
+     * Constructs a {@link ComponentInfoInternal} from another instance.
+     * @hide
+     */
+    public static ComponentInfoInternal from(@NonNull ComponentInfoInternal comp) {
+        return new ComponentInfoInternal(comp.componentId, comp.hardwareVersion,
+                comp.firmwareVersion, comp.serialNumber, comp.softwareVersion);
+    }
+
+    /**
+     * @hide
+     */
+    public ComponentInfoInternal(String componentId, String hardwareVersion,
+            String firmwareVersion, String serialNumber, String softwareVersion) {
+        this.componentId = componentId;
+        this.hardwareVersion = hardwareVersion;
+        this.firmwareVersion = firmwareVersion;
+        this.serialNumber = serialNumber;
+        this.softwareVersion = softwareVersion;
+    }
+
+    protected ComponentInfoInternal(Parcel in) {
+        componentId = in.readString();
+        hardwareVersion = in.readString();
+        firmwareVersion = in.readString();
+        serialNumber = in.readString();
+        softwareVersion = in.readString();
+    }
+
+    public static final Creator<ComponentInfoInternal> CREATOR =
+            new Creator<ComponentInfoInternal>() {
+        @Override
+        public ComponentInfoInternal createFromParcel(Parcel in) {
+            return new ComponentInfoInternal(in);
+        }
+
+        @Override
+        public ComponentInfoInternal[] newArray(int size) {
+            return new ComponentInfoInternal[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(componentId);
+        dest.writeString(hardwareVersion);
+        dest.writeString(firmwareVersion);
+        dest.writeString(serialNumber);
+        dest.writeString(softwareVersion);
+    }
+
+    @Override
+    public String toString() {
+        return "ComponentId: " + componentId
+                + ", HardwareVersion: " + hardwareVersion
+                + ", FirmwareVersion: " + firmwareVersion
+                + ", SerialNumber " + serialNumber
+                + ", SoftwareVersion: " + softwareVersion;
+    }
+}
diff --git a/core/java/android/hardware/biometrics/SensorProperties.java b/core/java/android/hardware/biometrics/SensorProperties.java
index 360f138..3b9cad4 100644
--- a/core/java/android/hardware/biometrics/SensorProperties.java
+++ b/core/java/android/hardware/biometrics/SensorProperties.java
@@ -17,10 +17,13 @@
 package android.hardware.biometrics;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.TestApi;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * The base class containing all modality-agnostic information.
@@ -56,15 +59,93 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface Strength {}
 
+    /**
+     * A class storing the component info for a subsystem of the sensor.
+     */
+    public static final class ComponentInfo {
+        @NonNull private final String mComponentId;
+        @NonNull private final String mHardwareVersion;
+        @NonNull private final String mFirmwareVersion;
+        @NonNull private final String mSerialNumber;
+        @NonNull private final String mSoftwareVersion;
+
+        /**
+         * @hide
+         */
+        public ComponentInfo(@NonNull String componentId, @NonNull String hardwareVersion,
+                @NonNull String firmwareVersion, @NonNull String serialNumber,
+                @NonNull String softwareVersion) {
+            mComponentId = componentId;
+            mHardwareVersion = hardwareVersion;
+            mFirmwareVersion = firmwareVersion;
+            mSerialNumber = serialNumber;
+            mSoftwareVersion = softwareVersion;
+        }
+
+        /**
+         * @return The unique identifier for the subsystem.
+         */
+        @NonNull
+        public String getComponentId() {
+            return mComponentId;
+        }
+
+        /**
+         * @return The hardware version for the subsystem. For example, <vendor>/<model>/<revision>.
+         */
+        @NonNull
+        public String getHardwareVersion() {
+            return mHardwareVersion;
+        }
+
+        /**
+         * @return The firmware version for the subsystem.
+         */
+        @NonNull
+        public String getFirmwareVersion() {
+            return mFirmwareVersion;
+        }
+
+        /**
+         * @return The serial number for the subsystem.
+         */
+        @NonNull
+        public String getSerialNumber() {
+            return mSerialNumber;
+        }
+
+        /**
+         * @return The software version for the subsystem.
+         * For example, <vendor>/<version>/<revision>.
+         */
+        @NonNull
+        public String getSoftwareVersion() {
+            return mSoftwareVersion;
+        }
+
+        /**
+         * Constructs a {@link ComponentInfo} from the internal parcelable representation.
+         * @hide
+         */
+        public static ComponentInfo from(ComponentInfoInternal internalComp) {
+            return new ComponentInfo(internalComp.componentId, internalComp.hardwareVersion,
+                    internalComp.firmwareVersion, internalComp.serialNumber,
+                    internalComp.softwareVersion);
+        }
+    }
+
     private final int mSensorId;
     @Strength private final int mSensorStrength;
+    private final List<ComponentInfo> mComponentInfo;
 
     /**
      * @hide
      */
-    public SensorProperties(int sensorId, @Strength int sensorStrength) {
+    public SensorProperties(int sensorId, @Strength int sensorStrength,
+            List<ComponentInfo> componentInfo) {
         mSensorId = sensorId;
         mSensorStrength = sensorStrength;
+        mComponentInfo = componentInfo;
     }
 
     /**
@@ -83,10 +164,23 @@
     }
 
     /**
+     * @return The sensor's component info.
+     */
+    @NonNull
+    public List<ComponentInfo> getComponentInfo() {
+        return mComponentInfo;
+    }
+
+    /**
      * Constructs a {@link SensorProperties} from the internal parcelable representation.
      * @hide
      */
     public static SensorProperties from(SensorPropertiesInternal internalProp) {
-        return new SensorProperties(internalProp.sensorId, internalProp.sensorStrength);
+        final List<ComponentInfo> componentInfo = new ArrayList<>();
+        for (ComponentInfoInternal internalComp : internalProp.componentInfo) {
+            componentInfo.add(ComponentInfo.from(internalComp));
+        }
+        return new SensorProperties(internalProp.sensorId, internalProp.sensorStrength,
+                componentInfo);
     }
 }
diff --git a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
index 909f456..eda0ded 100644
--- a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
+++ b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
@@ -20,6 +20,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * The base class containing all modality-agnostic information. This is a superset of the
  * {@link android.hardware.biometrics.common.CommonProps}, and provides backwards-compatible
@@ -31,21 +34,23 @@
     public final int sensorId;
     @SensorProperties.Strength public final int sensorStrength;
     public final int maxEnrollmentsPerUser;
+    public final List<ComponentInfoInternal> componentInfo;
     public final boolean resetLockoutRequiresHardwareAuthToken;
     public final boolean resetLockoutRequiresChallenge;
 
     public static SensorPropertiesInternal from(@NonNull SensorPropertiesInternal prop) {
         return new SensorPropertiesInternal(prop.sensorId, prop.sensorStrength,
-                prop.maxEnrollmentsPerUser, prop.resetLockoutRequiresHardwareAuthToken,
-                prop.resetLockoutRequiresChallenge);
+                prop.maxEnrollmentsPerUser, prop.componentInfo,
+                prop.resetLockoutRequiresHardwareAuthToken, prop.resetLockoutRequiresChallenge);
     }
 
     protected SensorPropertiesInternal(int sensorId, @SensorProperties.Strength int sensorStrength,
-            int maxEnrollmentsPerUser, boolean resetLockoutRequiresHardwareAuthToken,
-            boolean resetLockoutRequiresChallenge) {
+            int maxEnrollmentsPerUser, @NonNull List<ComponentInfoInternal> componentInfo,
+            boolean resetLockoutRequiresHardwareAuthToken, boolean resetLockoutRequiresChallenge) {
         this.sensorId = sensorId;
         this.sensorStrength = sensorStrength;
         this.maxEnrollmentsPerUser = maxEnrollmentsPerUser;
+        this.componentInfo = componentInfo;
         this.resetLockoutRequiresHardwareAuthToken = resetLockoutRequiresHardwareAuthToken;
         this.resetLockoutRequiresChallenge = resetLockoutRequiresChallenge;
     }
@@ -54,6 +59,8 @@
         sensorId = in.readInt();
         sensorStrength = in.readInt();
         maxEnrollmentsPerUser = in.readInt();
+        componentInfo = new ArrayList<>();
+        in.readList(componentInfo, ComponentInfoInternal.class.getClassLoader());
         resetLockoutRequiresHardwareAuthToken = in.readBoolean();
         resetLockoutRequiresChallenge = in.readBoolean();
     }
@@ -81,13 +88,23 @@
         dest.writeInt(sensorId);
         dest.writeInt(sensorStrength);
         dest.writeInt(maxEnrollmentsPerUser);
+        dest.writeList(componentInfo);
         dest.writeBoolean(resetLockoutRequiresHardwareAuthToken);
         dest.writeBoolean(resetLockoutRequiresChallenge);
     }
 
     @Override
     public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("[ ");
+        for (ComponentInfoInternal info : componentInfo) {
+            sb.append("[").append(info.toString());
+            sb.append("] ");
+        }
+        sb.append("]");
+
         return "ID: " + sensorId + ", Strength: " + sensorStrength
-                + ", MaxEnrollmentsPerUser: " + maxEnrollmentsPerUser;
+                + ", MaxEnrollmentsPerUser: " + maxEnrollmentsPerUser
+                + ", ComponentInfo: " + sb.toString();
     }
 }
diff --git a/core/java/android/hardware/face/FaceSensorProperties.java b/core/java/android/hardware/face/FaceSensorProperties.java
index e61d931..6ddea50 100644
--- a/core/java/android/hardware/face/FaceSensorProperties.java
+++ b/core/java/android/hardware/face/FaceSensorProperties.java
@@ -16,25 +16,75 @@
 
 package android.hardware.face;
 
+import android.annotation.IntDef;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.SensorProperties;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Container for face sensor properties.
  * @hide
  */
 public class FaceSensorProperties extends SensorProperties {
+    /**
+     * @hide
+     */
+    public static final int TYPE_UNKNOWN = 0;
+
+    /**
+     * @hide
+     */
+    public static final int TYPE_RGB = 1;
+
+    /**
+     * @hide
+     */
+    public static final int TYPE_IR = 2;
+
+    /**
+     * @hide
+     */
+    @IntDef({TYPE_UNKNOWN,
+            TYPE_RGB,
+            TYPE_IR})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SensorType {}
+
+    @FaceSensorProperties.SensorType
+    final int mSensorType;
 
     /**
      * @hide
      */
     public static FaceSensorProperties from(FaceSensorPropertiesInternal internalProp) {
-        return new FaceSensorProperties(internalProp.sensorId, internalProp.sensorStrength);
+        final List<ComponentInfo> componentInfo = new ArrayList<>();
+        for (ComponentInfoInternal internalComp : internalProp.componentInfo) {
+            componentInfo.add(ComponentInfo.from(internalComp));
+        }
+        return new FaceSensorProperties(internalProp.sensorId,
+                internalProp.sensorStrength,
+                componentInfo,
+                internalProp.sensorType);
     }
     /**
      * @hide
      */
-    public FaceSensorProperties(int sensorId, int sensorStrength) {
-        super(sensorId, sensorStrength);
+    public FaceSensorProperties(int sensorId, int sensorStrength,
+            List<ComponentInfo> componentInfo, @FaceSensorProperties.SensorType int sensorType) {
+        super(sensorId, sensorStrength, componentInfo);
+        mSensorType = sensorType;
     }
 
+    /**
+     * @hide
+     * @return The sensor's type.
+     */
+    @FaceSensorProperties.SensorType
+    public int getSensorType() {
+        return mSensorType;
+    }
 }
diff --git a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
index 34cbcb4..50ea60a2 100644
--- a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
+++ b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
@@ -16,16 +16,24 @@
 
 package android.hardware.face;
 
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.biometrics.SensorPropertiesInternal;
 import android.os.Parcel;
 
+import java.util.List;
+
 /**
  * Container for face sensor properties.
  * @hide
  */
 public class FaceSensorPropertiesInternal extends SensorPropertiesInternal {
     /**
+     * See {@link FaceSensorProperties.SensorType}.
+     */
+    public final @FaceSensorProperties.SensorType int sensorType;
+
+    /**
      * True if the sensor is able to perform generic face detection, without running the
      * matching algorithm, and without affecting the lockout counter.
      */
@@ -40,18 +48,21 @@
      * Initializes SensorProperties with specified values
      */
     public FaceSensorPropertiesInternal(int sensorId, @SensorProperties.Strength int strength,
-            int maxEnrollmentsPerUser, boolean supportsFaceDetection,
+            int maxEnrollmentsPerUser, List<ComponentInfoInternal> componentInfo,
+            @FaceSensorProperties.SensorType int sensorType, boolean supportsFaceDetection,
             boolean supportsSelfIllumination, boolean resetLockoutRequiresChallenge) {
         // resetLockout is managed by the HAL and requires a HardwareAuthToken for all face
         // HAL interfaces (IBiometricsFace@1.0 HIDL and IFace@1.0 AIDL).
-        super(sensorId, strength, maxEnrollmentsPerUser,
-                true /* resetLockoutRequiresHardwareAuthToken */, resetLockoutRequiresChallenge);
+        super(sensorId, strength, maxEnrollmentsPerUser, componentInfo,
+            true /* resetLockoutRequiresHardwareAuthToken */, resetLockoutRequiresChallenge);
+        this.sensorType = sensorType;
         this.supportsFaceDetection = supportsFaceDetection;
         this.supportsSelfIllumination = supportsSelfIllumination;
     }
 
     protected FaceSensorPropertiesInternal(Parcel in) {
         super(in);
+        sensorType = in.readInt();
         supportsFaceDetection = in.readBoolean();
         supportsSelfIllumination = in.readBoolean();
     }
@@ -77,12 +88,13 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         super.writeToParcel(dest, flags);
+        dest.writeInt(sensorType);
         dest.writeBoolean(supportsFaceDetection);
         dest.writeBoolean(supportsSelfIllumination);
     }
 
     @Override
     public String toString() {
-        return "ID: " + sensorId + ", Strength: " + sensorStrength;
+        return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
     }
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java
index 684d7d9..a338575 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorProperties.java
@@ -17,10 +17,13 @@
 package android.hardware.fingerprint;
 
 import android.annotation.IntDef;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.SensorProperties;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Container for fingerprint sensor properties.
@@ -77,8 +80,13 @@
      */
     public static FingerprintSensorProperties from(
             FingerprintSensorPropertiesInternal internalProp) {
+        final List<ComponentInfo> componentInfo = new ArrayList<>();
+        for (ComponentInfoInternal internalComp : internalProp.componentInfo) {
+            componentInfo.add(ComponentInfo.from(internalComp));
+        }
         return new FingerprintSensorProperties(internalProp.sensorId,
                 internalProp.sensorStrength,
+                componentInfo,
                 internalProp.sensorType);
     }
 
@@ -86,8 +94,8 @@
      * @hide
      */
     public FingerprintSensorProperties(int sensorId, int sensorStrength,
-            @SensorType int sensorType) {
-        super(sensorId, sensorStrength);
+            List<ComponentInfo> componentInfo, @SensorType int sensorType) {
+        super(sensorId, sensorStrength, componentInfo);
         mSensorType = sensorType;
     }
 
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
index adc61a7..1b13370 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
@@ -21,10 +21,13 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.biometrics.SensorPropertiesInternal;
 import android.os.Parcel;
 
+import java.util.List;
+
 /**
  * Container for fingerprint sensor properties.
  * @hide
@@ -59,6 +62,7 @@
 
     public FingerprintSensorPropertiesInternal(int sensorId,
             @SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
+            List<ComponentInfoInternal> componentInfo,
             @FingerprintSensorProperties.SensorType int sensorType,
             boolean resetLockoutRequiresHardwareAuthToken, int sensorLocationX, int sensorLocationY,
             int sensorRadius) {
@@ -66,8 +70,8 @@
         // required as it can only be generated/attested/verified by TEE components.
         // IFingerprint@1.0 handles lockout below the HAL, but does not require a challenge. See
         // the HAL interface for more details.
-        super(sensorId, strength, maxEnrollmentsPerUser, resetLockoutRequiresHardwareAuthToken,
-                false /* resetLockoutRequiresChallenge */);
+        super(sensorId, strength, maxEnrollmentsPerUser, componentInfo,
+            resetLockoutRequiresHardwareAuthToken, false /* resetLockoutRequiresChallenge */);
         this.sensorType = sensorType;
         this.sensorLocationX = sensorLocationX;
         this.sensorLocationY = sensorLocationY;
@@ -79,10 +83,11 @@
      */
     public FingerprintSensorPropertiesInternal(int sensorId,
             @SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
+            List<ComponentInfoInternal> componentInfo,
             @FingerprintSensorProperties.SensorType int sensorType,
             boolean resetLockoutRequiresHardwareAuthToken) {
         // TODO(b/179175438): Value should be provided from the HAL
-        this(sensorId, strength, maxEnrollmentsPerUser, sensorType,
+        this(sensorId, strength, maxEnrollmentsPerUser, componentInfo, sensorType,
                 resetLockoutRequiresHardwareAuthToken, 540 /* sensorLocationX */,
                 1636 /* sensorLocationY */, 130 /* sensorRadius */);
     }
@@ -94,10 +99,11 @@
     // TODO(b/179175438): Remove this constructor once all HALs move to AIDL.
     public FingerprintSensorPropertiesInternal(@NonNull Context context, int sensorId,
             @SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
+            List<ComponentInfoInternal> componentInfo,
             @FingerprintSensorProperties.SensorType int sensorType,
             boolean resetLockoutRequiresHardwareAuthToken) {
-        super(sensorId, strength, maxEnrollmentsPerUser, resetLockoutRequiresHardwareAuthToken,
-                false /* resetLockoutRequiresChallenge */);
+        super(sensorId, strength, maxEnrollmentsPerUser, componentInfo,
+            resetLockoutRequiresHardwareAuthToken, false /* resetLockoutRequiresChallenge */);
         this.sensorType = sensorType;
 
         int[] props = context.getResources().getIntArray(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index e35e987..52e2016 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -50,6 +50,7 @@
 import android.content.pm.ServiceInfo;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.face.FaceManager;
 import android.hardware.face.FaceSensorProperties;
@@ -192,9 +193,19 @@
 
         // IBiometricsFace@1.0 does not support detection, only authentication.
         when(mFaceSensorProperties.isEmpty()).thenReturn(false);
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         when(mFaceSensorProperties.get(anyInt())).thenReturn(new FaceSensorPropertiesInternal(
                 0 /* id */,
                 FaceSensorProperties.STRENGTH_STRONG, 1 /* maxTemplatesAllowed */,
+                componentInfo, FaceSensorProperties.TYPE_UNKNOWN,
                 false /* supportsFaceDetection */, true /* supportsSelfIllumination */,
                 false /* resetLockoutRequiresChallenge */));
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index 7f8be91..1565dee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.fingerprint.FingerprintSensorProperties;
@@ -49,6 +50,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
@@ -341,8 +345,18 @@
         final int sensorLocationX = 540;
         final int sensorLocationY = 1600;
         final int sensorRadius = 100;
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal(
                 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
                 sensorRadius);
@@ -379,8 +393,18 @@
         final int sensorLocationX = 540;
         final int sensorLocationY = 1600;
         final int sensorRadius = 100;
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal(
                 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
                 sensorRadius);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index 5088a53..f41c100 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -34,8 +34,8 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.face.FaceSensorPropertiesInternal;
@@ -248,9 +248,19 @@
         config.mPromptInfo = promptInfo;
 
         final List<FingerprintSensorPropertiesInternal> fpProps = new ArrayList<>();
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         fpProps.add(new FingerprintSensorPropertiesInternal(0,
                 SensorProperties.STRENGTH_STRONG,
                 5 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 FingerprintSensorProperties.TYPE_REAR,
                 false /* resetLockoutRequiresHardwareAuthToken */));
         mAuthContainer = new TestableAuthContainer(config, fpProps, null /* faceProps */);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 30c4cf6..fa190a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -34,7 +34,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -43,6 +42,7 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.biometrics.SensorProperties;
@@ -123,10 +123,20 @@
         when(mDialog2.isAllowDeviceCredentials()).thenReturn(false);
 
         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
                 1 /* sensorId */,
                 SensorProperties.STRENGTH_STRONG,
                 1 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 true /* resetLockoutRequireHardwareAuthToken */);
         List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index be110fc..3f1a927 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -26,6 +26,7 @@
 
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorProperties;
@@ -120,9 +121,19 @@
         setUpResources();
         when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)).thenReturn(mUdfpsView);
         final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         props.add(new FingerprintSensorPropertiesInternal(TEST_UDFPS_SENSOR_ID,
                 SensorProperties.STRENGTH_STRONG,
                 5 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 true /* resetLockoutRequiresHardwareAuthToken */));
         when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 07a653f..ebf13e0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -23,6 +23,7 @@
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.content.pm.UserInfo;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
@@ -134,10 +135,21 @@
         for (SensorProps prop : props) {
             final int sensorId = prop.commonProps.sensorId;
 
+            final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+            if (prop.commonProps.componentInfo != null) {
+                for (android.hardware.biometrics.common.ComponentInfo info
+                        : prop.commonProps.componentInfo) {
+                    componentInfo.add(new ComponentInfoInternal(info.componentId,
+                            info.hardwareVersion, info.firmwareVersion, info.serialNumber,
+                            info.softwareVersion));
+                }
+            }
+
             final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
                     prop.commonProps.sensorId, prop.commonProps.sensorStrength,
-                    prop.commonProps.maxEnrollmentsPerUser, false /* supportsFaceDetection */,
-                    prop.halControlsPreview, false /* resetLockoutRequiresChallenge */);
+                    prop.commonProps.maxEnrollmentsPerUser, componentInfo, prop.sensorType,
+                    false /* supportsFaceDetection */, prop.halControlsPreview,
+                    false /* resetLockoutRequiresChallenge */);
             final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
                     internalProp);
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 40c050f..55e9a83 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -27,11 +27,13 @@
 import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
 import android.hardware.biometrics.face.V1_0.IBiometricsFace;
 import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
 import android.hardware.face.Face;
+import android.hardware.face.FaceSensorProperties;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.face.IFaceServiceReceiver;
 import android.os.Binder;
@@ -332,8 +334,9 @@
             @NonNull BiometricScheduler scheduler) {
         mSensorProperties = new FaceSensorPropertiesInternal(sensorId,
                 Utils.authenticatorStrengthToPropertyStrength(strength),
-                maxTemplatesAllowed, false /* supportsFaceDetect */, supportsSelfIllumination,
-                true /* resetLockoutRequiresChallenge */);
+                maxTemplatesAllowed, new ArrayList<ComponentInfoInternal>() /* componentInfo */,
+                FaceSensorProperties.TYPE_UNKNOWN, false /* supportsFaceDetect */,
+                supportsSelfIllumination, true /* resetLockoutRequiresChallenge */);
         mContext = context;
         mSensorId = sensorId;
         mScheduler = scheduler;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index d798198..2c85dc9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -25,6 +25,7 @@
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.content.pm.UserInfo;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
@@ -138,10 +139,21 @@
         for (SensorProps prop : props) {
             final int sensorId = prop.commonProps.sensorId;
 
+            final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+            if (prop.commonProps.componentInfo != null) {
+                for (android.hardware.biometrics.common.ComponentInfo info
+                        : prop.commonProps.componentInfo) {
+                    componentInfo.add(new ComponentInfoInternal(info.componentId,
+                            info.hardwareVersion, info.firmwareVersion, info.serialNumber,
+                            info.softwareVersion));
+                }
+            }
+
             final FingerprintSensorPropertiesInternal internalProp =
                     new FingerprintSensorPropertiesInternal(prop.commonProps.sensorId,
                             prop.commonProps.sensorStrength,
                             prop.commonProps.maxEnrollmentsPerUser,
+                            componentInfo,
                             prop.sensorType,
                             true /* resetLockoutRequiresHardwareAuthToken */);
             final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index e737677..f112549 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -28,6 +28,7 @@
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
 import android.hardware.biometrics.ITestSession;
 import android.hardware.biometrics.ITestSessionCallback;
@@ -355,7 +356,8 @@
 
         mSensorProperties = new FingerprintSensorPropertiesInternal(context, sensorId,
                 Utils.authenticatorStrengthToPropertyStrength(strength), maxEnrollmentsPerUser,
-                sensorType, resetLockoutRequiresHardwareAuthToken);
+                new ArrayList<ComponentInfoInternal>() /* componentInfo */, sensorType,
+                resetLockoutRequiresHardwareAuthToken);
     }
 
     public static Fingerprint21 newInstance(@NonNull Context context, int sensorId, int strength,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index 2394a70..90c4b4a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -22,6 +22,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
@@ -421,6 +422,7 @@
                 .getInteger(R.integer.config_fingerprintMaxTemplatesPerUser);
         mSensorProperties = new FingerprintSensorPropertiesInternal(sensorId,
                 Utils.authenticatorStrengthToPropertyStrength(strength), maxTemplatesAllowed,
+                new ArrayList<ComponentInfoInternal>() /* componentInfo */,
                 FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 resetLockoutRequiresHardwareAuthToken);
         mMockHalResultController = controller;
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 7a4b901..a6d146e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -39,6 +39,7 @@
 import android.app.trust.ITrustManager;
 import android.content.Context;
 import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IBiometricSensorReceiver;
 import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -292,9 +293,18 @@
             }
         });
 
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
         mFingerprintSensorProps.add(new FingerprintSensorPropertiesInternal(id,
                 SensorProperties.STRENGTH_STRONG,
                 5 /* maxEnrollmentsPerUser */,
+                componentInfo,
                 type,
                 false /* resetLockoutRequiresHardwareAuthToken */));
     }