Add options to face and fingerprint manager internal APIs.
These options will include additional context from callers, like keyguard, that will be propogated to the HAL in follow-up changes. Move the new Face & Fingerprint manager tests from services to core (their home project). Fix: 246363169 Bug: 268295421 Test: atest FaceManagerTest FingerprintManagerTest Change-Id: I5327efab56107c9aab72ca8d1e527c4330020942
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Common authentication options that are exposed across all modalities.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public interface AuthenticateOptions {
|
||||
|
||||
/** The user id for this operation. */
|
||||
int getUserId();
|
||||
|
||||
/** The sensor id for this operation. */
|
||||
int getSensorId();
|
||||
|
||||
/** The state is unknown. */
|
||||
int DISPLAY_STATE_UNKNOWN = 0;
|
||||
|
||||
/** The display is on and showing the lockscreen (or an occluding app). */
|
||||
int DISPLAY_STATE_LOCKSCREEN = 1;
|
||||
|
||||
/** The display is off or dozing. */
|
||||
int DISPLAY_STATE_NO_UI = 2;
|
||||
|
||||
/** The display is showing a screensaver (dreaming). */
|
||||
int DISPLAY_STATE_SCREENSAVER = 3;
|
||||
|
||||
/** The display is dreaming with always on display. */
|
||||
int DISPLAY_STATE_AOD = 4;
|
||||
|
||||
/** The doze state of the device. */
|
||||
@IntDef(prefix = "DISPLAY_STATE_", value = {
|
||||
DISPLAY_STATE_UNKNOWN,
|
||||
DISPLAY_STATE_LOCKSCREEN,
|
||||
DISPLAY_STATE_NO_UI,
|
||||
DISPLAY_STATE_SCREENSAVER,
|
||||
DISPLAY_STATE_AOD
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface DisplayState {}
|
||||
|
||||
/** The current doze state of the device. */
|
||||
@DisplayState
|
||||
int getDisplayState();
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*/
|
||||
@NonNull String getOpPackageName();
|
||||
|
||||
/** The attribution tag, if any. */
|
||||
@Nullable String getAttributionTag();
|
||||
}
|
||||
19
core/java/android/hardware/face/FaceAuthenticateOptions.aidl
Normal file
19
core/java/android/hardware/face/FaceAuthenticateOptions.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.face;
|
||||
|
||||
parcelable FaceAuthenticateOptions;
|
||||
624
core/java/android/hardware/face/FaceAuthenticateOptions.java
Normal file
624
core/java/android/hardware/face/FaceAuthenticateOptions.java
Normal file
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.face;
|
||||
|
||||
|
||||
import static android.os.PowerManager.WAKE_REASON_UNKNOWN;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.biometrics.AuthenticateOptions;
|
||||
import android.os.Parcelable;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import com.android.internal.util.DataClass;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Additional options when requesting Face authentication or detection.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass(
|
||||
genParcelable = true,
|
||||
genAidl = true,
|
||||
genBuilder = true,
|
||||
genSetters = true,
|
||||
genEqualsHashCode = true
|
||||
)
|
||||
public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable {
|
||||
|
||||
/** The user id for this operation. */
|
||||
private final int mUserId;
|
||||
private static int defaultUserId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** The sensor id for this operation. */
|
||||
private final int mSensorId;
|
||||
private static int defaultSensorId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** The current doze state of the device. */
|
||||
@AuthenticateOptions.DisplayState
|
||||
private final int mDisplayState;
|
||||
private static int defaultDisplayState() {
|
||||
return DISPLAY_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
public static final int AUTHENTICATE_REASON_UNKNOWN = 0;
|
||||
public static final int AUTHENTICATE_REASON_STARTED_WAKING_UP = 1;
|
||||
public static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN = 2;
|
||||
public static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE = 3;
|
||||
public static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN = 4;
|
||||
public static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED = 5;
|
||||
public static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED = 6;
|
||||
public static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED = 7;
|
||||
public static final int AUTHENTICATE_REASON_QS_EXPANDED = 8;
|
||||
public static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER = 9;
|
||||
public static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN = 10;
|
||||
|
||||
/**
|
||||
* The reason for this operation when requested by the system (sysui),
|
||||
* otherwise AUTHENTICATE_REASON_UNKNOWN.
|
||||
*
|
||||
* See frameworks/base/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
|
||||
* for more details about each reason.
|
||||
*/
|
||||
@AuthenticateReason
|
||||
private final int mAuthenticateReason;
|
||||
private static int defaultAuthenticateReason() {
|
||||
return AUTHENTICATE_REASON_UNKNOWN;
|
||||
}
|
||||
|
||||
/** A reason if this request was triggered due to a power event or WAKE_REASON_UNKNOWN. */
|
||||
@PowerManager.WakeReason
|
||||
private final int mWakeReason;
|
||||
private static int defaultWakeReason() {
|
||||
return WAKE_REASON_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@NonNull
|
||||
private String mOpPackageName;
|
||||
private static String defaultOpPackageName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@Nullable
|
||||
private String mAttributionTag;
|
||||
private static String defaultAttributionTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.23.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/face/FaceAuthenticateOptions.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
//@formatter:off
|
||||
|
||||
|
||||
@IntDef(prefix = "AUTHENTICATE_REASON_", value = {
|
||||
AUTHENTICATE_REASON_UNKNOWN,
|
||||
AUTHENTICATE_REASON_STARTED_WAKING_UP,
|
||||
AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN,
|
||||
AUTHENTICATE_REASON_ASSISTANT_VISIBLE,
|
||||
AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
|
||||
AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED,
|
||||
AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED,
|
||||
AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED,
|
||||
AUTHENTICATE_REASON_QS_EXPANDED,
|
||||
AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER,
|
||||
AUTHENTICATE_REASON_UDFPS_POINTER_DOWN
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@DataClass.Generated.Member
|
||||
public @interface AuthenticateReason {}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static String authenticateReasonToString(@AuthenticateReason int value) {
|
||||
switch (value) {
|
||||
case AUTHENTICATE_REASON_UNKNOWN:
|
||||
return "AUTHENTICATE_REASON_UNKNOWN";
|
||||
case AUTHENTICATE_REASON_STARTED_WAKING_UP:
|
||||
return "AUTHENTICATE_REASON_STARTED_WAKING_UP";
|
||||
case AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN:
|
||||
return "AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN";
|
||||
case AUTHENTICATE_REASON_ASSISTANT_VISIBLE:
|
||||
return "AUTHENTICATE_REASON_ASSISTANT_VISIBLE";
|
||||
case AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN:
|
||||
return "AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN";
|
||||
case AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED:
|
||||
return "AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED";
|
||||
case AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED:
|
||||
return "AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED";
|
||||
case AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED:
|
||||
return "AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED";
|
||||
case AUTHENTICATE_REASON_QS_EXPANDED:
|
||||
return "AUTHENTICATE_REASON_QS_EXPANDED";
|
||||
case AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER:
|
||||
return "AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER";
|
||||
case AUTHENTICATE_REASON_UDFPS_POINTER_DOWN:
|
||||
return "AUTHENTICATE_REASON_UDFPS_POINTER_DOWN";
|
||||
default: return Integer.toHexString(value);
|
||||
}
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ FaceAuthenticateOptions(
|
||||
int userId,
|
||||
int sensorId,
|
||||
@AuthenticateOptions.DisplayState int displayState,
|
||||
@AuthenticateReason int authenticateReason,
|
||||
@PowerManager.WakeReason int wakeReason,
|
||||
@NonNull String opPackageName,
|
||||
@Nullable String attributionTag) {
|
||||
this.mUserId = userId;
|
||||
this.mSensorId = sensorId;
|
||||
this.mDisplayState = displayState;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
AuthenticateOptions.DisplayState.class, null, mDisplayState);
|
||||
this.mAuthenticateReason = authenticateReason;
|
||||
|
||||
if (!(mAuthenticateReason == AUTHENTICATE_REASON_UNKNOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_STARTED_WAKING_UP)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_ASSISTANT_VISIBLE)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_QS_EXPANDED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_UDFPS_POINTER_DOWN)) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"authenticateReason was " + mAuthenticateReason + " but must be one of: "
|
||||
+ "AUTHENTICATE_REASON_UNKNOWN(" + AUTHENTICATE_REASON_UNKNOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_STARTED_WAKING_UP(" + AUTHENTICATE_REASON_STARTED_WAKING_UP + "), "
|
||||
+ "AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN(" + AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_ASSISTANT_VISIBLE(" + AUTHENTICATE_REASON_ASSISTANT_VISIBLE + "), "
|
||||
+ "AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(" + AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED(" + AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED + "), "
|
||||
+ "AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED(" + AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED + "), "
|
||||
+ "AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED(" + AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED + "), "
|
||||
+ "AUTHENTICATE_REASON_QS_EXPANDED(" + AUTHENTICATE_REASON_QS_EXPANDED + "), "
|
||||
+ "AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER(" + AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER + "), "
|
||||
+ "AUTHENTICATE_REASON_UDFPS_POINTER_DOWN(" + AUTHENTICATE_REASON_UDFPS_POINTER_DOWN + ")");
|
||||
}
|
||||
|
||||
this.mWakeReason = wakeReason;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
PowerManager.WakeReason.class, null, mWakeReason);
|
||||
this.mOpPackageName = opPackageName;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
this.mAttributionTag = attributionTag;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/**
|
||||
* The user id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getUserId() {
|
||||
return mUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getSensorId() {
|
||||
return mSensorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current doze state of the device.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @AuthenticateOptions.DisplayState int getDisplayState() {
|
||||
return mDisplayState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reason for this operation when requested by the system (sysui),
|
||||
* otherwise AUTHENTICATE_REASON_UNKNOWN.
|
||||
*
|
||||
* See frameworks/base/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
|
||||
* for more details about each reason.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @AuthenticateReason int getAuthenticateReason() {
|
||||
return mAuthenticateReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* A reason if this request was triggered due to a power event or WAKE_REASON_UNKNOWN.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @PowerManager.WakeReason int getWakeReason() {
|
||||
return mWakeReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull String getOpPackageName() {
|
||||
return mOpPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable String getAttributionTag() {
|
||||
return mAttributionTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FaceAuthenticateOptions setOpPackageName(@NonNull String value) {
|
||||
mOpPackageName = value;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FaceAuthenticateOptions setAttributionTag(@NonNull String value) {
|
||||
mAttributionTag = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public boolean equals(@Nullable Object o) {
|
||||
// You can override field equality logic by defining either of the methods like:
|
||||
// boolean fieldNameEquals(FaceAuthenticateOptions other) { ... }
|
||||
// boolean fieldNameEquals(FieldType otherValue) { ... }
|
||||
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
FaceAuthenticateOptions that = (FaceAuthenticateOptions) o;
|
||||
//noinspection PointlessBooleanExpression
|
||||
return true
|
||||
&& mUserId == that.mUserId
|
||||
&& mSensorId == that.mSensorId
|
||||
&& mDisplayState == that.mDisplayState
|
||||
&& mAuthenticateReason == that.mAuthenticateReason
|
||||
&& mWakeReason == that.mWakeReason
|
||||
&& java.util.Objects.equals(mOpPackageName, that.mOpPackageName)
|
||||
&& java.util.Objects.equals(mAttributionTag, that.mAttributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int hashCode() {
|
||||
// You can override field hashCode logic by defining methods like:
|
||||
// int fieldNameHashCode() { ... }
|
||||
|
||||
int _hash = 1;
|
||||
_hash = 31 * _hash + mUserId;
|
||||
_hash = 31 * _hash + mSensorId;
|
||||
_hash = 31 * _hash + mDisplayState;
|
||||
_hash = 31 * _hash + mAuthenticateReason;
|
||||
_hash = 31 * _hash + mWakeReason;
|
||||
_hash = 31 * _hash + java.util.Objects.hashCode(mOpPackageName);
|
||||
_hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
|
||||
return _hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (mAttributionTag != null) flg |= 0x40;
|
||||
dest.writeByte(flg);
|
||||
dest.writeInt(mUserId);
|
||||
dest.writeInt(mSensorId);
|
||||
dest.writeInt(mDisplayState);
|
||||
dest.writeInt(mAuthenticateReason);
|
||||
dest.writeInt(mWakeReason);
|
||||
dest.writeString(mOpPackageName);
|
||||
if (mAttributionTag != null) dest.writeString(mAttributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
protected FaceAuthenticateOptions(@NonNull android.os.Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
byte flg = in.readByte();
|
||||
int userId = in.readInt();
|
||||
int sensorId = in.readInt();
|
||||
int displayState = in.readInt();
|
||||
int authenticateReason = in.readInt();
|
||||
int wakeReason = in.readInt();
|
||||
String opPackageName = in.readString();
|
||||
String attributionTag = (flg & 0x40) == 0 ? null : in.readString();
|
||||
|
||||
this.mUserId = userId;
|
||||
this.mSensorId = sensorId;
|
||||
this.mDisplayState = displayState;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
AuthenticateOptions.DisplayState.class, null, mDisplayState);
|
||||
this.mAuthenticateReason = authenticateReason;
|
||||
|
||||
if (!(mAuthenticateReason == AUTHENTICATE_REASON_UNKNOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_STARTED_WAKING_UP)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_ASSISTANT_VISIBLE)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_QS_EXPANDED)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER)
|
||||
&& !(mAuthenticateReason == AUTHENTICATE_REASON_UDFPS_POINTER_DOWN)) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"authenticateReason was " + mAuthenticateReason + " but must be one of: "
|
||||
+ "AUTHENTICATE_REASON_UNKNOWN(" + AUTHENTICATE_REASON_UNKNOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_STARTED_WAKING_UP(" + AUTHENTICATE_REASON_STARTED_WAKING_UP + "), "
|
||||
+ "AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN(" + AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_ASSISTANT_VISIBLE(" + AUTHENTICATE_REASON_ASSISTANT_VISIBLE + "), "
|
||||
+ "AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(" + AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN + "), "
|
||||
+ "AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED(" + AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED + "), "
|
||||
+ "AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED(" + AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED + "), "
|
||||
+ "AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED(" + AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED + "), "
|
||||
+ "AUTHENTICATE_REASON_QS_EXPANDED(" + AUTHENTICATE_REASON_QS_EXPANDED + "), "
|
||||
+ "AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER(" + AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER + "), "
|
||||
+ "AUTHENTICATE_REASON_UDFPS_POINTER_DOWN(" + AUTHENTICATE_REASON_UDFPS_POINTER_DOWN + ")");
|
||||
}
|
||||
|
||||
this.mWakeReason = wakeReason;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
PowerManager.WakeReason.class, null, mWakeReason);
|
||||
this.mOpPackageName = opPackageName;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
this.mAttributionTag = attributionTag;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static final @NonNull Parcelable.Creator<FaceAuthenticateOptions> CREATOR
|
||||
= new Parcelable.Creator<FaceAuthenticateOptions>() {
|
||||
@Override
|
||||
public FaceAuthenticateOptions[] newArray(int size) {
|
||||
return new FaceAuthenticateOptions[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaceAuthenticateOptions createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new FaceAuthenticateOptions(in);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A builder for {@link FaceAuthenticateOptions}
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@DataClass.Generated.Member
|
||||
public static class Builder {
|
||||
|
||||
private int mUserId;
|
||||
private int mSensorId;
|
||||
private @AuthenticateOptions.DisplayState int mDisplayState;
|
||||
private @AuthenticateReason int mAuthenticateReason;
|
||||
private @PowerManager.WakeReason int mWakeReason;
|
||||
private @NonNull String mOpPackageName;
|
||||
private @Nullable String mAttributionTag;
|
||||
|
||||
private long mBuilderFieldsSet = 0L;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The user id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setUserId(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x1;
|
||||
mUserId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setSensorId(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x2;
|
||||
mSensorId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current doze state of the device.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setDisplayState(@AuthenticateOptions.DisplayState int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x4;
|
||||
mDisplayState = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reason for this operation when requested by the system (sysui),
|
||||
* otherwise AUTHENTICATE_REASON_UNKNOWN.
|
||||
*
|
||||
* See frameworks/base/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
|
||||
* for more details about each reason.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setAuthenticateReason(@AuthenticateReason int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x8;
|
||||
mAuthenticateReason = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A reason if this request was triggered due to a power event or WAKE_REASON_UNKNOWN.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setWakeReason(@PowerManager.WakeReason int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x10;
|
||||
mWakeReason = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setOpPackageName(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x20;
|
||||
mOpPackageName = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setAttributionTag(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x40;
|
||||
mAttributionTag = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the instance. This builder should not be touched after calling this! */
|
||||
public @NonNull FaceAuthenticateOptions build() {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x80; // Mark builder used
|
||||
|
||||
if ((mBuilderFieldsSet & 0x1) == 0) {
|
||||
mUserId = defaultUserId();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x2) == 0) {
|
||||
mSensorId = defaultSensorId();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x4) == 0) {
|
||||
mDisplayState = defaultDisplayState();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x8) == 0) {
|
||||
mAuthenticateReason = defaultAuthenticateReason();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x10) == 0) {
|
||||
mWakeReason = defaultWakeReason();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x20) == 0) {
|
||||
mOpPackageName = defaultOpPackageName();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x40) == 0) {
|
||||
mAttributionTag = defaultAttributionTag();
|
||||
}
|
||||
FaceAuthenticateOptions o = new FaceAuthenticateOptions(
|
||||
mUserId,
|
||||
mSensorId,
|
||||
mDisplayState,
|
||||
mAuthenticateReason,
|
||||
mWakeReason,
|
||||
mOpPackageName,
|
||||
mAttributionTag);
|
||||
return o;
|
||||
}
|
||||
|
||||
private void checkNotUsed() {
|
||||
if ((mBuilderFieldsSet & 0x80) != 0) {
|
||||
throw new IllegalStateException(
|
||||
"This Builder should not be reused. Use a new Builder instance instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1676508211385L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/hardware/face/FaceAuthenticateOptions.java",
|
||||
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\npublic static final int AUTHENTICATE_REASON_UNKNOWN\npublic static final int AUTHENTICATE_REASON_STARTED_WAKING_UP\npublic static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE\npublic static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED\npublic static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED\npublic static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED\npublic static final int AUTHENTICATE_REASON_QS_EXPANDED\npublic static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER\npublic static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN\nprivate final @android.hardware.face.FaceAuthenticateOptions.AuthenticateReason int mAuthenticateReason\nprivate final @android.os.PowerManager.WakeReason int mWakeReason\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static int defaultDisplayState()\nprivate static int defaultAuthenticateReason()\nprivate static int defaultWakeReason()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FaceAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
|
||||
}
|
||||
@@ -194,18 +194,30 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
}
|
||||
|
||||
/**
|
||||
* Request authentication of a crypto object. This call operates the face recognition hardware
|
||||
* and starts capturing images. It terminates when
|
||||
* @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FaceAuthenticateOptions)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||
@NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId) {
|
||||
authenticate(crypto, cancel, callback, handler, new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(userId)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Request authentication. This call operates the face recognition hardware and starts capturing images.
|
||||
* It terminates when
|
||||
* {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
|
||||
* {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
|
||||
* which point the object is no longer valid. The operation can be canceled by using the
|
||||
* provided cancel object.
|
||||
*
|
||||
* @param crypto object associated with the call or null if none required.
|
||||
* @param crypto object associated with the call or null if none required
|
||||
* @param cancel an object that can be used to cancel authentication
|
||||
* @param callback an object to receive authentication events
|
||||
* @param handler an optional handler to handle callback events
|
||||
* @param userId userId to authenticate for
|
||||
* @param options additional options to customize this request
|
||||
* @throws IllegalArgumentException if the crypto operation is not supported or is not backed
|
||||
* by
|
||||
* <a href="{@docRoot}training/articles/keystore.html">Android
|
||||
@@ -215,8 +227,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||
@NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId,
|
||||
boolean isKeyguardBypassEnabled) {
|
||||
@NonNull AuthenticationCallback callback, @Nullable Handler handler,
|
||||
@NonNull FaceAuthenticateOptions options) {
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("Must supply an authentication callback");
|
||||
}
|
||||
@@ -226,6 +238,9 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
return;
|
||||
}
|
||||
|
||||
options.setOpPackageName(mContext.getOpPackageName());
|
||||
options.setAttributionTag(mContext.getAttributionTag());
|
||||
|
||||
if (mService != null) {
|
||||
try {
|
||||
useHandler(handler);
|
||||
@@ -233,8 +248,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
mCryptoObject = crypto;
|
||||
final long operationId = crypto != null ? crypto.getOpId() : 0;
|
||||
Trace.beginSection("FaceManager#authenticate");
|
||||
final long authId = mService.authenticate(mToken, operationId, userId,
|
||||
mServiceReceiver, mContext.getOpPackageName(), isKeyguardBypassEnabled);
|
||||
final long authId = mService.authenticate(
|
||||
mToken, operationId, mServiceReceiver, options);
|
||||
if (cancel != null) {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
|
||||
}
|
||||
@@ -258,7 +273,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void detectFace(@NonNull CancellationSignal cancel,
|
||||
@NonNull FaceDetectionCallback callback, int userId) {
|
||||
@NonNull FaceDetectionCallback callback, @NonNull FaceAuthenticateOptions options) {
|
||||
if (mService == null) {
|
||||
return;
|
||||
}
|
||||
@@ -268,11 +283,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
return;
|
||||
}
|
||||
|
||||
options.setOpPackageName(mContext.getOpPackageName());
|
||||
options.setAttributionTag(mContext.getAttributionTag());
|
||||
|
||||
mFaceDetectionCallback = callback;
|
||||
|
||||
try {
|
||||
final long authId = mService.detectFace(
|
||||
mToken, userId, mServiceReceiver, mContext.getOpPackageName());
|
||||
final long authId = mService.detectFace(mToken, mServiceReceiver, options);
|
||||
cancel.setOnCancelListener(new OnFaceDetectionCancelListener(authId));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception when requesting finger detect", e);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.view.Surface;
|
||||
|
||||
@@ -52,14 +53,14 @@ interface IFaceService {
|
||||
|
||||
// Authenticate with a face. A requestId is returned that can be used to cancel this operation.
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
long authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
|
||||
String opPackageName, boolean isKeyguardBypassEnabled);
|
||||
long authenticate(IBinder token, long operationId, IFaceServiceReceiver receiver,
|
||||
in FaceAuthenticateOptions options);
|
||||
|
||||
// Uses the face hardware to detect for the presence of a face, without giving details
|
||||
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
|
||||
// operation.
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
long detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
|
||||
long detectFace(IBinder token, IFaceServiceReceiver receiver, in FaceAuthenticateOptions options);
|
||||
|
||||
// This method prepares the service to start authenticating, but doesn't start authentication.
|
||||
// This is protected by the MANAGE_BIOMETRIC signatuer permission. This method should only be
|
||||
@@ -68,8 +69,8 @@ interface IFaceService {
|
||||
// startPreparedClient().
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, long requestId, int cookie,
|
||||
long operationId, IBiometricSensorReceiver sensorReceiver,
|
||||
in FaceAuthenticateOptions options, long requestId, int cookie,
|
||||
boolean allowBackgroundAuthentication);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fingerprint;
|
||||
|
||||
parcelable FingerprintAuthenticateOptions;
|
||||
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fingerprint;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintManager.SENSOR_ID_ANY;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.biometrics.AuthenticateOptions;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.DataClass;
|
||||
|
||||
/**
|
||||
* Additional options when requesting Fingerprint authentication or detection.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass(
|
||||
genParcelable = true,
|
||||
genAidl = true,
|
||||
genBuilder = true,
|
||||
genSetters = true,
|
||||
genEqualsHashCode = true
|
||||
)
|
||||
public final class FingerprintAuthenticateOptions implements AuthenticateOptions, Parcelable {
|
||||
|
||||
/** The user id for this operation. */
|
||||
private final int mUserId;
|
||||
private static int defaultUserId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** The sensor id for this operation. */
|
||||
private final int mSensorId;
|
||||
private static int defaultSensorId() {
|
||||
return SENSOR_ID_ANY;
|
||||
}
|
||||
|
||||
/** If enrollment state should be ignored. */
|
||||
private final boolean mIgnoreEnrollmentState;
|
||||
private static boolean defaultIgnoreEnrollmentState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** The current doze state of the device. */
|
||||
@AuthenticateOptions.DisplayState
|
||||
private final int mDisplayState;
|
||||
private static int defaultDisplayState() {
|
||||
return DISPLAY_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@NonNull private String mOpPackageName;
|
||||
private static String defaultOpPackageName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@Nullable private String mAttributionTag;
|
||||
private static String defaultAttributionTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.23.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
//@formatter:off
|
||||
|
||||
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ FingerprintAuthenticateOptions(
|
||||
int userId,
|
||||
int sensorId,
|
||||
boolean ignoreEnrollmentState,
|
||||
@AuthenticateOptions.DisplayState int displayState,
|
||||
@NonNull String opPackageName,
|
||||
@Nullable String attributionTag) {
|
||||
this.mUserId = userId;
|
||||
this.mSensorId = sensorId;
|
||||
this.mIgnoreEnrollmentState = ignoreEnrollmentState;
|
||||
this.mDisplayState = displayState;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
AuthenticateOptions.DisplayState.class, null, mDisplayState);
|
||||
this.mOpPackageName = opPackageName;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
this.mAttributionTag = attributionTag;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/**
|
||||
* The user id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getUserId() {
|
||||
return mUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public int getSensorId() {
|
||||
return mSensorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enrollment state should be ignored.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public boolean isIgnoreEnrollmentState() {
|
||||
return mIgnoreEnrollmentState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current doze state of the device.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @AuthenticateOptions.DisplayState int getDisplayState() {
|
||||
return mDisplayState;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull String getOpPackageName() {
|
||||
return mOpPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable String getAttributionTag() {
|
||||
return mAttributionTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FingerprintAuthenticateOptions setOpPackageName(@NonNull String value) {
|
||||
mOpPackageName = value;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FingerprintAuthenticateOptions setAttributionTag(@NonNull String value) {
|
||||
mAttributionTag = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public boolean equals(@Nullable Object o) {
|
||||
// You can override field equality logic by defining either of the methods like:
|
||||
// boolean fieldNameEquals(FingerprintAuthenticateOptions other) { ... }
|
||||
// boolean fieldNameEquals(FieldType otherValue) { ... }
|
||||
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
FingerprintAuthenticateOptions that = (FingerprintAuthenticateOptions) o;
|
||||
//noinspection PointlessBooleanExpression
|
||||
return true
|
||||
&& mUserId == that.mUserId
|
||||
&& mSensorId == that.mSensorId
|
||||
&& mIgnoreEnrollmentState == that.mIgnoreEnrollmentState
|
||||
&& mDisplayState == that.mDisplayState
|
||||
&& java.util.Objects.equals(mOpPackageName, that.mOpPackageName)
|
||||
&& java.util.Objects.equals(mAttributionTag, that.mAttributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int hashCode() {
|
||||
// You can override field hashCode logic by defining methods like:
|
||||
// int fieldNameHashCode() { ... }
|
||||
|
||||
int _hash = 1;
|
||||
_hash = 31 * _hash + mUserId;
|
||||
_hash = 31 * _hash + mSensorId;
|
||||
_hash = 31 * _hash + Boolean.hashCode(mIgnoreEnrollmentState);
|
||||
_hash = 31 * _hash + mDisplayState;
|
||||
_hash = 31 * _hash + java.util.Objects.hashCode(mOpPackageName);
|
||||
_hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
|
||||
return _hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (mIgnoreEnrollmentState) flg |= 0x4;
|
||||
if (mAttributionTag != null) flg |= 0x20;
|
||||
dest.writeByte(flg);
|
||||
dest.writeInt(mUserId);
|
||||
dest.writeInt(mSensorId);
|
||||
dest.writeInt(mDisplayState);
|
||||
dest.writeString(mOpPackageName);
|
||||
if (mAttributionTag != null) dest.writeString(mAttributionTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
/* package-private */ FingerprintAuthenticateOptions(@NonNull android.os.Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
byte flg = in.readByte();
|
||||
boolean ignoreEnrollmentState = (flg & 0x4) != 0;
|
||||
int userId = in.readInt();
|
||||
int sensorId = in.readInt();
|
||||
int displayState = in.readInt();
|
||||
String opPackageName = in.readString();
|
||||
String attributionTag = (flg & 0x20) == 0 ? null : in.readString();
|
||||
|
||||
this.mUserId = userId;
|
||||
this.mSensorId = sensorId;
|
||||
this.mIgnoreEnrollmentState = ignoreEnrollmentState;
|
||||
this.mDisplayState = displayState;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
AuthenticateOptions.DisplayState.class, null, mDisplayState);
|
||||
this.mOpPackageName = opPackageName;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mOpPackageName);
|
||||
this.mAttributionTag = attributionTag;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static final @NonNull Parcelable.Creator<FingerprintAuthenticateOptions> CREATOR
|
||||
= new Parcelable.Creator<FingerprintAuthenticateOptions>() {
|
||||
@Override
|
||||
public FingerprintAuthenticateOptions[] newArray(int size) {
|
||||
return new FingerprintAuthenticateOptions[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public FingerprintAuthenticateOptions createFromParcel(@NonNull android.os.Parcel in) {
|
||||
return new FingerprintAuthenticateOptions(in);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A builder for {@link FingerprintAuthenticateOptions}
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@DataClass.Generated.Member
|
||||
public static final class Builder {
|
||||
|
||||
private int mUserId;
|
||||
private int mSensorId;
|
||||
private boolean mIgnoreEnrollmentState;
|
||||
private @AuthenticateOptions.DisplayState int mDisplayState;
|
||||
private @NonNull String mOpPackageName;
|
||||
private @Nullable String mAttributionTag;
|
||||
|
||||
private long mBuilderFieldsSet = 0L;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The user id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setUserId(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x1;
|
||||
mUserId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setSensorId(int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x2;
|
||||
mSensorId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enrollment state should be ignored.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setIgnoreEnrollmentState(boolean value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x4;
|
||||
mIgnoreEnrollmentState = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current doze state of the device.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setDisplayState(@AuthenticateOptions.DisplayState int value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x8;
|
||||
mDisplayState = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setOpPackageName(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x10;
|
||||
mOpPackageName = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribution tag, if any.
|
||||
*
|
||||
* This option may be overridden by the FingerprintManager using the caller's context.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Builder setAttributionTag(@NonNull String value) {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x20;
|
||||
mAttributionTag = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the instance. This builder should not be touched after calling this! */
|
||||
public @NonNull FingerprintAuthenticateOptions build() {
|
||||
checkNotUsed();
|
||||
mBuilderFieldsSet |= 0x40; // Mark builder used
|
||||
|
||||
if ((mBuilderFieldsSet & 0x1) == 0) {
|
||||
mUserId = defaultUserId();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x2) == 0) {
|
||||
mSensorId = defaultSensorId();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x4) == 0) {
|
||||
mIgnoreEnrollmentState = defaultIgnoreEnrollmentState();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x8) == 0) {
|
||||
mDisplayState = defaultDisplayState();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x10) == 0) {
|
||||
mOpPackageName = defaultOpPackageName();
|
||||
}
|
||||
if ((mBuilderFieldsSet & 0x20) == 0) {
|
||||
mAttributionTag = defaultAttributionTag();
|
||||
}
|
||||
FingerprintAuthenticateOptions o = new FingerprintAuthenticateOptions(
|
||||
mUserId,
|
||||
mSensorId,
|
||||
mIgnoreEnrollmentState,
|
||||
mDisplayState,
|
||||
mOpPackageName,
|
||||
mAttributionTag);
|
||||
return o;
|
||||
}
|
||||
|
||||
private void checkNotUsed() {
|
||||
if ((mBuilderFieldsSet & 0x40) != 0) {
|
||||
throw new IllegalStateException(
|
||||
"This Builder should not be reused. Use a new Builder instance instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1676508212083L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java",
|
||||
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static boolean defaultIgnoreEnrollmentState()\nprivate static int defaultDisplayState()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
|
||||
}
|
||||
@@ -577,8 +577,10 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
|
||||
/**
|
||||
* Per-user version of authenticate.
|
||||
* @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FingerprintAuthenticateOptions)}.
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
|
||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||
@NonNull AuthenticationCallback callback, Handler handler, int userId) {
|
||||
@@ -587,13 +589,29 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
|
||||
/**
|
||||
* Per-user and per-sensor version of authenticate.
|
||||
* @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FingerprintAuthenticateOptions)}.
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
|
||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||
@NonNull AuthenticationCallback callback, Handler handler, int sensorId, int userId,
|
||||
int flags) {
|
||||
authenticate(crypto, cancel, callback, handler, new FingerprintAuthenticateOptions.Builder()
|
||||
.setSensorId(sensorId)
|
||||
.setUserId(userId)
|
||||
.setIgnoreEnrollmentState(flags != 0)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of authenticate with additional options.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
|
||||
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
|
||||
@NonNull AuthenticationCallback callback, @NonNull Handler handler,
|
||||
@NonNull FingerprintAuthenticateOptions options) {
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED,
|
||||
AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE,
|
||||
mContext.getApplicationInfo().uid,
|
||||
@@ -608,7 +626,8 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean ignoreEnrollmentState = flags == 0 ? false : true;
|
||||
options.setOpPackageName(mContext.getOpPackageName());
|
||||
options.setAttributionTag(mContext.getAttributionTag());
|
||||
|
||||
if (mService != null) {
|
||||
try {
|
||||
@@ -616,16 +635,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
mAuthenticationCallback = callback;
|
||||
mCryptoObject = crypto;
|
||||
final long operationId = crypto != null ? crypto.getOpId() : 0;
|
||||
final long authId =
|
||||
mService.authenticate(
|
||||
mToken,
|
||||
operationId,
|
||||
sensorId,
|
||||
userId,
|
||||
mServiceReceiver,
|
||||
mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(),
|
||||
ignoreEnrollmentState);
|
||||
final long authId = mService.authenticate(mToken, operationId, mServiceReceiver, options);
|
||||
if (cancel != null) {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
|
||||
}
|
||||
@@ -647,7 +657,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void detectFingerprint(@NonNull CancellationSignal cancel,
|
||||
@NonNull FingerprintDetectionCallback callback, int userId) {
|
||||
@NonNull FingerprintDetectionCallback callback, @NonNull FingerprintAuthenticateOptions options) {
|
||||
if (mService == null) {
|
||||
return;
|
||||
}
|
||||
@@ -657,11 +667,13 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
return;
|
||||
}
|
||||
|
||||
options.setOpPackageName(mContext.getOpPackageName());
|
||||
options.setAttributionTag(mContext.getAttributionTag());
|
||||
|
||||
mFingerprintDetectionCallback = callback;
|
||||
|
||||
try {
|
||||
final long authId = mService.detectFingerprint(mToken, userId, mServiceReceiver,
|
||||
mContext.getOpPackageName());
|
||||
final long authId = mService.detectFingerprint(mToken, mServiceReceiver, options);
|
||||
cancel.setOnCancelListener(new OnFingerprintDetectionCancelListener(authId));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception when requesting finger detect", e);
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlay;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import java.util.List;
|
||||
|
||||
@@ -56,16 +57,15 @@ interface IFingerprintService {
|
||||
// Authenticate with a fingerprint. This is protected by USE_FINGERPRINT/USE_BIOMETRIC
|
||||
// permission. This is effectively deprecated, since it only comes through FingerprintManager
|
||||
// now. A requestId is returned that can be used to cancel this operation.
|
||||
long authenticate(IBinder token, long operationId, int sensorId, int userId,
|
||||
IFingerprintServiceReceiver receiver, String opPackageName, String attributionTag,
|
||||
boolean shouldIgnoreEnrollmentState);
|
||||
long authenticate(IBinder token, long operationId, IFingerprintServiceReceiver receiver,
|
||||
in FingerprintAuthenticateOptions options);
|
||||
|
||||
// Uses the fingerprint hardware to detect for the presence of a finger, without giving details
|
||||
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
|
||||
// operation.
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
long detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver,
|
||||
String opPackageName);
|
||||
long detectFingerprint(IBinder token, IFingerprintServiceReceiver receiver,
|
||||
in FingerprintAuthenticateOptions options);
|
||||
|
||||
// This method prepares the service to start authenticating, but doesn't start authentication.
|
||||
// This is protected by the MANAGE_BIOMETRIC signatuer permission. This method should only be
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.face;
|
||||
|
||||
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FaceManagerTest {
|
||||
private static final int USER_ID = 4;
|
||||
private static final String PACKAGE_NAME = "f.m.test";
|
||||
private static final String ATTRIBUTION_TAG = "blue";
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private IFaceService mService;
|
||||
@Mock
|
||||
private FaceManager.AuthenticationCallback mAuthCallback;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<FaceAuthenticateOptions> mOptionsCaptor;
|
||||
|
||||
private List<FaceSensorPropertiesInternal> mProps;
|
||||
private TestLooper mLooper;
|
||||
private Handler mHandler;
|
||||
private FaceManager mFaceManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mLooper = new TestLooper();
|
||||
mHandler = new Handler(mLooper.getLooper());
|
||||
|
||||
when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
|
||||
when(mContext.getOpPackageName()).thenReturn(PACKAGE_NAME);
|
||||
when(mContext.getAttributionTag()).thenReturn(ATTRIBUTION_TAG);
|
||||
when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getString(anyInt())).thenReturn("string");
|
||||
|
||||
mFaceManager = new FaceManager(mContext, mService);
|
||||
mProps = List.of(new FaceSensorPropertiesInternal(
|
||||
0 /* id */,
|
||||
FaceSensorProperties.STRENGTH_STRONG,
|
||||
1 /* maxTemplatesAllowed */,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
FaceSensorProperties.TYPE_UNKNOWN,
|
||||
true /* supportsFaceDetection */,
|
||||
true /* supportsSelfIllumination */,
|
||||
false /* resetLockoutRequiresChallenge */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
|
||||
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
|
||||
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
|
||||
List<FaceSensorPropertiesInternal> actual = mFaceManager.getSensorPropertiesInternal();
|
||||
|
||||
assertThat(actual).isEqualTo(mProps);
|
||||
verify(mService, never()).getSensorPropertiesInternal(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticate_withOptions() throws Exception {
|
||||
mFaceManager.authenticate(null, new CancellationSignal(), mAuthCallback, mHandler,
|
||||
new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(USER_ID)
|
||||
.setOpPackageName("some.thing")
|
||||
.setAttributionTag(null)
|
||||
.build());
|
||||
|
||||
verify(mService).authenticate(any(IBinder.class), eq(0L),
|
||||
any(IFaceServiceReceiver.class), mOptionsCaptor.capture());
|
||||
|
||||
assertThat(mOptionsCaptor.getValue()).isEqualTo(
|
||||
new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(USER_ID)
|
||||
.setOpPackageName(PACKAGE_NAME)
|
||||
.setAttributionTag(ATTRIBUTION_TAG)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticate_errorWhenUnavailable() throws Exception {
|
||||
when(mService.authenticate(any(), anyLong(), any(), any()))
|
||||
.thenThrow(new RemoteException());
|
||||
|
||||
mFaceManager.authenticate(null, new CancellationSignal(),
|
||||
mAuthCallback, mHandler,
|
||||
new FaceAuthenticateOptions.Builder().build());
|
||||
|
||||
verify(mAuthCallback).onAuthenticationError(eq(FACE_ERROR_HW_UNAVAILABLE), any());
|
||||
}
|
||||
}
|
||||
1
core/tests/coretests/src/android/hardware/face/OWNERS
Normal file
1
core/tests/coretests/src/android/hardware/face/OWNERS
Normal file
@@ -0,0 +1 @@
|
||||
include /services/core/java/com/android/server/biometrics/OWNERS
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fingerprint;
|
||||
|
||||
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FingerprintManagerTest {
|
||||
private static final int USER_ID = 9;
|
||||
private static final String PACKAGE_NAME = "finger.food.test";
|
||||
private static final String ATTRIBUTION_TAG = "taz";
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private IFingerprintService mService;
|
||||
@Mock
|
||||
private FingerprintManager.AuthenticationCallback mAuthCallback;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<FingerprintAuthenticateOptions> mOptionsCaptor;
|
||||
|
||||
private List<FingerprintSensorPropertiesInternal> mProps;
|
||||
private TestLooper mLooper;
|
||||
private Handler mHandler;
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mLooper = new TestLooper();
|
||||
mHandler = new Handler(mLooper.getLooper());
|
||||
|
||||
when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
|
||||
when(mContext.getOpPackageName()).thenReturn(PACKAGE_NAME);
|
||||
when(mContext.getAttributionTag()).thenReturn(ATTRIBUTION_TAG);
|
||||
when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getString(anyInt())).thenReturn("string");
|
||||
|
||||
mFingerprintManager = new FingerprintManager(mContext, mService);
|
||||
mProps = List.of(new FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
FingerprintSensorProperties.STRENGTH_STRONG,
|
||||
1 /* maxEnrollmentsPerUser */,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
FingerprintSensorProperties.TYPE_UNKNOWN,
|
||||
true /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
new ArrayList<>() /* sensorLocations */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
|
||||
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
|
||||
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
|
||||
List<FingerprintSensorPropertiesInternal> actual =
|
||||
mFingerprintManager.getSensorPropertiesInternal();
|
||||
|
||||
assertThat(actual).isEqualTo(mProps);
|
||||
verify(mService, never()).getSensorPropertiesInternal(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticate_withOptions() throws Exception {
|
||||
mFingerprintManager.authenticate(null, new CancellationSignal(), mAuthCallback, mHandler,
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setUserId(USER_ID)
|
||||
.setOpPackageName("some.thing")
|
||||
.setAttributionTag(null)
|
||||
.build());
|
||||
|
||||
verify(mService).authenticate(any(IBinder.class), eq(0L),
|
||||
any(IFingerprintServiceReceiver.class), mOptionsCaptor.capture());
|
||||
|
||||
assertThat(mOptionsCaptor.getValue()).isEqualTo(
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setUserId(USER_ID)
|
||||
.setOpPackageName(PACKAGE_NAME)
|
||||
.setAttributionTag(ATTRIBUTION_TAG)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticate_errorWhenUnavailable() throws Exception {
|
||||
when(mService.authenticate(any(), anyLong(), any(), any()))
|
||||
.thenThrow(new RemoteException());
|
||||
|
||||
mFingerprintManager.authenticate(null, new CancellationSignal(),
|
||||
mAuthCallback, mHandler,
|
||||
new FingerprintAuthenticateOptions.Builder().build());
|
||||
|
||||
verify(mAuthCallback).onAuthenticationError(eq(FINGERPRINT_ERROR_HW_UNAVAILABLE), any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
include /services/core/java/com/android/server/biometrics/OWNERS
|
||||
@@ -96,8 +96,10 @@ import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||
import android.hardware.biometrics.SensorProperties;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
||||
@@ -2942,7 +2944,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
// Trigger the fingerprint success path so the bouncer can be shown
|
||||
handleFingerprintAuthenticated(user, isStrongBiometric);
|
||||
},
|
||||
userId);
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setUserId(userId)
|
||||
.build());
|
||||
} else {
|
||||
mLogger.v("startListeningForFingerprint - authenticate");
|
||||
mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,
|
||||
@@ -2988,7 +2992,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
if (supportsFaceDetection && !udfpsFingerprintAuthRunning) {
|
||||
// Run face detection. (If a face is detected, show the bouncer.)
|
||||
mLogger.v("startListeningForFace - detect");
|
||||
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
|
||||
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback,
|
||||
new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(userId)
|
||||
.build());
|
||||
} else {
|
||||
// Don't run face detection. Instead, inform the user
|
||||
// face auth is unavailable and how to proceed.
|
||||
@@ -3007,7 +3014,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
final boolean isBypassEnabled = mKeyguardBypassController != null
|
||||
&& mKeyguardBypassController.isBypassEnabled();
|
||||
mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
|
||||
mFaceAuthenticationCallback, null /* handler */, userId, isBypassEnabled);
|
||||
mFaceAuthenticationCallback, null /* handler */, userId);
|
||||
}
|
||||
setFaceRunningState(BIOMETRIC_STATE_RUNNING);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.content.Context
|
||||
import android.hardware.face.FaceAuthenticateOptions
|
||||
import android.hardware.face.FaceManager
|
||||
import android.os.CancellationSignal
|
||||
import com.android.internal.logging.InstanceId
|
||||
@@ -235,8 +236,7 @@ constructor(
|
||||
cancellationSignal,
|
||||
faceAuthCallback,
|
||||
null,
|
||||
currentUserId,
|
||||
lockscreenBypassEnabled
|
||||
FaceAuthenticateOptions.Builder().setUserId(currentUserId).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -255,7 +255,11 @@ constructor(
|
||||
withContext(mainDispatcher) {
|
||||
// We always want to invoke face detect in the main thread.
|
||||
faceAuthLogger.faceDetectionStarted()
|
||||
faceManager?.detectFace(cancellationSignal, detectionCallback, currentUserId)
|
||||
faceManager?.detectFace(
|
||||
cancellationSignal,
|
||||
detectionCallback,
|
||||
FaceAuthenticateOptions.Builder().setUserId(currentUserId).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -617,7 +617,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
|
||||
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||
anyInt());
|
||||
verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
|
||||
verify(mFingerprintManager, never()).detectFingerprint(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -629,7 +629,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
|
||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyInt(), anyInt());
|
||||
verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
|
||||
verify(mFingerprintManager, never()).detectFingerprint(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -644,7 +644,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFingerprintManager).detectFingerprint(any(), any(), anyInt());
|
||||
verify(mFingerprintManager).detectFingerprint(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -733,7 +733,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
public void testTriesToAuthenticate_whenBouncer() {
|
||||
setKeyguardBouncerVisibility(true);
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).hasEnrolledTemplates(anyInt());
|
||||
}
|
||||
|
||||
@@ -742,8 +742,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
|
||||
/* bouncerIsOrWillBeShowing */ true, /* bouncerFullyShown */ false);
|
||||
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -751,7 +750,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
keyguardIsVisible();
|
||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mUiEventLogger).logWithInstanceIdAndPosition(
|
||||
eq(FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP),
|
||||
eq(0),
|
||||
@@ -767,8 +766,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
keyguardIsVisible();
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -779,8 +777,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||
mTestableLooper.processAllMessages();
|
||||
keyguardIsVisible();
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -804,9 +801,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
// THEN face detect and authenticate are NOT triggered
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), any());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
|
||||
// THEN biometric help message sent to callback
|
||||
verify(keyguardUpdateMonitorCallback).onBiometricHelp(
|
||||
@@ -827,9 +823,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
// FACE detect is triggered, not authenticate
|
||||
verify(mFaceManager).detectFace(any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager).detectFace(any(), any(), any());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
|
||||
// WHEN bouncer becomes visible
|
||||
setKeyguardBouncerVisibility(true);
|
||||
@@ -837,9 +832,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
|
||||
// THEN face scanning is not run
|
||||
mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -854,9 +848,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
// FACE detect and authenticate are NOT triggered
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), any());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -894,7 +887,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
|
||||
mKeyguardUpdateMonitor.setAssistantVisible(true);
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -906,8 +899,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
anyInt(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -938,7 +930,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
|
||||
new ArrayList<>());
|
||||
keyguardIsVisible();
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -946,7 +938,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
|
||||
mKeyguardUpdateMonitor.setAssistantVisible(true);
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
mTestableLooper.processAllMessages();
|
||||
clearInvocations(mFaceManager);
|
||||
|
||||
@@ -963,8 +955,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
anyInt(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -974,8 +965,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
|
||||
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */, new ArrayList<>());
|
||||
keyguardIsVisible();
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -987,9 +977,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
keyguardIsVisible();
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFaceManager, never()).detectFace(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1019,8 +1008,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
setKeyguardBouncerVisibility(true);
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1147,7 +1135,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
keyguardIsVisible();
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||
anyInt());
|
||||
|
||||
@@ -1599,8 +1587,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mKeyguardUpdateMonitor.setCredentialAttempted();
|
||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(),
|
||||
any(), anyInt());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1975,7 +1962,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
keyguardIsVisible();
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||
anyInt());
|
||||
|
||||
@@ -2004,7 +1991,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
verify(mFaceManager, never()).authenticate(
|
||||
any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2018,14 +2005,14 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
|
||||
// THEN face auth isn't triggered
|
||||
verify(mFaceManager, never()).authenticate(
|
||||
any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
any(), any(), any(), any(), anyInt());
|
||||
|
||||
// WHEN device wakes up from the power button
|
||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||
mTestableLooper.processAllMessages();
|
||||
|
||||
// THEN face auth is triggered
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2195,7 +2182,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
keyguardIsVisible();
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||
anyInt());
|
||||
|
||||
@@ -2228,7 +2215,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mTestableLooper.processAllMessages();
|
||||
keyguardIsVisible();
|
||||
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
|
||||
|
||||
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
|
||||
mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
|
||||
@@ -2596,8 +2583,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
any(),
|
||||
mAuthenticationCallbackCaptor.capture(),
|
||||
any(),
|
||||
anyInt(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
mAuthenticationCallbackCaptor.getValue()
|
||||
.onAuthenticationSucceeded(
|
||||
new FaceManager.AuthenticationResult(null, null, mCurrentUserId, false));
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.pm.UserInfo
|
||||
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
|
||||
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.face.FaceAuthenticateOptions
|
||||
import android.hardware.face.FaceManager
|
||||
import android.hardware.face.FaceSensorProperties
|
||||
import android.hardware.face.FaceSensorPropertiesInternal
|
||||
@@ -62,7 +63,6 @@ import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
@@ -276,7 +276,7 @@ class KeyguardFaceAuthManagerTest : SysuiTestCase() {
|
||||
|
||||
underTest.detect()
|
||||
|
||||
verify(faceManager, never()).detectFace(any(), any(), anyInt())
|
||||
verify(faceManager, never()).detectFace(any(), any(), any())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -379,7 +379,7 @@ class KeyguardFaceAuthManagerTest : SysuiTestCase() {
|
||||
.detectFace(
|
||||
cancellationSignal.capture(),
|
||||
detectionCallback.capture(),
|
||||
eq(currentUserId)
|
||||
eq(FaceAuthenticateOptions.Builder().setUserId(currentUserId).build())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -390,8 +390,7 @@ class KeyguardFaceAuthManagerTest : SysuiTestCase() {
|
||||
cancellationSignal.capture(),
|
||||
authenticationCallback.capture(),
|
||||
isNull(),
|
||||
eq(currentUserId),
|
||||
eq(true)
|
||||
eq(FaceAuthenticateOptions.Builder().setUserId(currentUserId).build())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
private final LockoutTracker mLockoutTracker;
|
||||
private final boolean mIsRestricted;
|
||||
private final boolean mAllowBackgroundAuthentication;
|
||||
private final boolean mIsKeyguardBypassEnabled;
|
||||
// TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
|
||||
// the state. We should think of a way to improve this in the future.
|
||||
@State
|
||||
@@ -95,7 +94,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @Nullable TaskStackListener taskStackListener,
|
||||
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication,
|
||||
boolean shouldVibrate, boolean isKeyguardBypassEnabled, int sensorStrength) {
|
||||
boolean shouldVibrate, int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
|
||||
shouldVibrate, biometricLogger, biometricContext);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
@@ -107,7 +106,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
mLockoutTracker = lockoutTracker;
|
||||
mIsRestricted = restricted;
|
||||
mAllowBackgroundAuthentication = allowBackgroundAuthentication;
|
||||
mIsKeyguardBypassEnabled = isKeyguardBypassEnabled;
|
||||
mShouldUseLockoutTracker = lockoutTracker != null;
|
||||
mSensorStrength = sensorStrength;
|
||||
}
|
||||
@@ -374,14 +372,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
return mState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the client supports bypass (e.g. passive auth such as face), and if it's
|
||||
* enabled by the user.
|
||||
*/
|
||||
public boolean isKeyguardBypassEnabled() {
|
||||
return mIsKeyguardBypassEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_AUTHENTICATE;
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.IInvalidationCallback;
|
||||
import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.biometrics.SensorPropertiesInternal;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.IFaceService;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -64,8 +65,11 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
|
||||
userId, sensorReceiver, opPackageName, requestId, cookie,
|
||||
allowBackgroundAuthentication);
|
||||
sensorReceiver, new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(userId)
|
||||
.setOpPackageName(opPackageName)
|
||||
.build(),
|
||||
requestId, cookie, allowBackgroundAuthentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.biometrics.face.SensorProps;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.face.FaceServiceReceiver;
|
||||
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
|
||||
@@ -238,14 +239,15 @@ public class FaceService extends SystemService {
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public long authenticate(final IBinder token, final long operationId, int userId,
|
||||
final IFaceServiceReceiver receiver, final String opPackageName,
|
||||
boolean isKeyguardBypassEnabled) {
|
||||
public long authenticate(final IBinder token, final long operationId,
|
||||
final IFaceServiceReceiver receiver, final FaceAuthenticateOptions options) {
|
||||
// TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
|
||||
// lockdown, something wrong happened. See similar path in FingerprintService.
|
||||
|
||||
super.authenticate_enforcePermission();
|
||||
|
||||
final int userId = options.getUserId();
|
||||
final String opPackageName = options.getOpPackageName();
|
||||
final boolean restricted = false; // Face APIs are private
|
||||
final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
|
||||
? BiometricsProtoEnums.CLIENT_KEYGUARD
|
||||
@@ -261,18 +263,18 @@ public class FaceService extends SystemService {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
0 /* cookie */,
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
|
||||
statsClient, isKeyguard, isKeyguardBypassEnabled);
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
|
||||
restricted, statsClient, isKeyguard);
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public long detectFace(final IBinder token, final int userId,
|
||||
final IFaceServiceReceiver receiver, final String opPackageName) {
|
||||
public long detectFace(final IBinder token,
|
||||
final IFaceServiceReceiver receiver, final FaceAuthenticateOptions options) {
|
||||
super.detectFace_enforcePermission();
|
||||
|
||||
final String opPackageName = options.getOpPackageName();
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "detectFace called from non-sysui package: " + opPackageName);
|
||||
return -1;
|
||||
@@ -284,7 +286,7 @@ public class FaceService extends SystemService {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return provider.second.scheduleFaceDetect(provider.first, token, userId,
|
||||
return provider.second.scheduleFaceDetect(provider.first, token, options.getUserId(),
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD);
|
||||
}
|
||||
@@ -292,9 +294,9 @@ public class FaceService extends SystemService {
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
|
||||
IBinder token, long operationId, int userId,
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
|
||||
int cookie, boolean allowBackgroundAuthentication) {
|
||||
IBinder token, long operationId, IBiometricSensorReceiver sensorReceiver,
|
||||
FaceAuthenticateOptions options, long requestId, int cookie,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
super.prepareForAuthentication_enforcePermission();
|
||||
|
||||
final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
|
||||
@@ -305,10 +307,10 @@ public class FaceService extends SystemService {
|
||||
|
||||
final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
|
||||
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
allowBackgroundAuthentication);
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.hardware.biometrics.IInvalidationCallback;
|
||||
import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
@@ -88,15 +89,15 @@ public interface ServiceProvider extends BiometricServiceProvider<FaceSensorProp
|
||||
|
||||
void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled);
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
|
||||
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled);
|
||||
@NonNull FaceAuthenticateOptions options, long requestId,
|
||||
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
|
||||
|
||||
void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
|
||||
@@ -85,11 +85,11 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull UsageStats usageStats,
|
||||
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
|
||||
boolean isKeyguardBypassEnabled, @Authenticators.Types int sensorStrength) {
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
this(context, lazyDaemon, token, requestId, listener, targetUserId, operationId,
|
||||
restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, usageStats, lockoutCache /* lockoutCache */,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
allowBackgroundAuthentication,
|
||||
context.getSystemService(SensorPrivacyManager.class), sensorStrength);
|
||||
}
|
||||
|
||||
@@ -102,13 +102,13 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull UsageStats usageStats,
|
||||
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
|
||||
boolean isKeyguardBypassEnabled, SensorPrivacyManager sensorPrivacyManager,
|
||||
SensorPrivacyManager sensorPrivacyManager,
|
||||
@Authenticators.Types int biometricStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */, null /* lockoutCache */,
|
||||
allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled, biometricStrength);
|
||||
biometricStrength);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.hardware.biometrics.common.ComponentInfo;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.biometrics.face.SensorProps;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.os.Binder;
|
||||
@@ -435,21 +436,21 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
mHandler.post(() -> {
|
||||
final int userId = options.getUserId();
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
userId, operationId, restricted, options.getOpPackageName(), cookie,
|
||||
false /* requireConfirmation */, sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
Utils.getCurrentStrength(sensorId)
|
||||
);
|
||||
allowBackgroundAuthentication, Utils.getCurrentStrength(sensorId));
|
||||
scheduleForSensor(sensorId, client, new ClientMonitorCallback() {
|
||||
@Override
|
||||
public void onClientStarted(
|
||||
@@ -470,14 +471,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback,
|
||||
opPackageName, id, restricted, statsClient,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
scheduleAuthenticate(sensorId, token, operationId, cookie, callback,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ 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.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.os.Binder;
|
||||
@@ -665,19 +666,20 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
|
||||
int statsClient, boolean allowBackgroundAuthentication) {
|
||||
mHandler.post(() -> {
|
||||
final int userId = options.getUserId();
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
|
||||
mLazyDaemon, token, requestId, receiver, userId, operationId, restricted,
|
||||
opPackageName, cookie, false /* requireConfirmation */, mSensorId,
|
||||
options.getOpPackageName(), cookie, false /* requireConfirmation */, mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric, mLockoutTracker,
|
||||
mUsageStats, allowBackgroundAuthentication, isKeyguardBypassEnabled,
|
||||
mUsageStats, allowBackgroundAuthentication,
|
||||
Utils.getCurrentStrength(mSensorId));
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
@@ -685,14 +687,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, receiver,
|
||||
opPackageName, id, restricted, statsClient,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
scheduleAuthenticate(sensorId, token, operationId, cookie, receiver,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
|
||||
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
|
||||
boolean isKeyguardBypassEnabled, @Authenticators.Types int sensorStrength) {
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */,
|
||||
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled, sensorStrength);
|
||||
sensorStrength);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.biometrics.fingerprint.IFingerprint;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.FingerprintServiceReceiver;
|
||||
@@ -252,15 +253,15 @@ public class FingerprintService extends SystemService {
|
||||
public long authenticate(
|
||||
final IBinder token,
|
||||
final long operationId,
|
||||
final int sensorId,
|
||||
final int userId,
|
||||
final IFingerprintServiceReceiver receiver,
|
||||
final String opPackageName,
|
||||
final String attributionTag,
|
||||
boolean ignoreEnrollmentState) {
|
||||
final FingerprintAuthenticateOptions options) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
final String opPackageName = options.getOpPackageName();
|
||||
final String attributionTag = options.getAttributionTag();
|
||||
final int userId = options.getUserId();
|
||||
final int sensorId = options.getSensorId();
|
||||
|
||||
if (!canUseFingerprint(
|
||||
opPackageName,
|
||||
@@ -314,7 +315,8 @@ public class FingerprintService extends SystemService {
|
||||
&& sensorProps != null && sensorProps.isAnyUdfpsType()) {
|
||||
try {
|
||||
return authenticateWithPrompt(operationId, sensorProps, callingUid,
|
||||
callingUserId, receiver, opPackageName, ignoreEnrollmentState);
|
||||
callingUserId, receiver, opPackageName,
|
||||
options.isIgnoreEnrollmentState());
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Slog.e(TAG, "Invalid package", e);
|
||||
return -1;
|
||||
@@ -412,16 +414,18 @@ public class FingerprintService extends SystemService {
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override
|
||||
public long detectFingerprint(final IBinder token, final int userId,
|
||||
final IFingerprintServiceReceiver receiver, final String opPackageName) {
|
||||
public long detectFingerprint(final IBinder token,
|
||||
final IFingerprintServiceReceiver receiver,
|
||||
final FingerprintAuthenticateOptions options) {
|
||||
super.detectFingerprint_enforcePermission();
|
||||
|
||||
final String opPackageName = options.getOpPackageName();
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
|
||||
if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, options.getUserId())) {
|
||||
// If this happens, something in KeyguardUpdateMonitor is wrong. This should only
|
||||
// ever be invoked when the user is encrypted or lockdown.
|
||||
Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown");
|
||||
@@ -434,7 +438,7 @@ public class FingerprintService extends SystemService {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return provider.second.scheduleFingerDetect(provider.first, token, userId,
|
||||
return provider.second.scheduleFingerDetect(provider.first, token, options.getUserId(),
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
null /* lockoutCache */,
|
||||
allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */,
|
||||
biometricStrength);
|
||||
setRequestId(requestId);
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController,
|
||||
|
||||
@@ -87,8 +87,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */, false /* isKeyguardBypassEnabled */,
|
||||
sensorStrength);
|
||||
false /* shouldVibrate */, sensorStrength);
|
||||
setRequestId(requestId);
|
||||
mLockoutFrameworkImpl = lockoutTracker;
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController,
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.face;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FaceManagerTest {
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
Context mContext;
|
||||
@Mock
|
||||
IFaceService mService;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mCaptor;
|
||||
|
||||
List<FaceSensorPropertiesInternal> mProps;
|
||||
FaceManager mFaceManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
|
||||
mFaceManager = new FaceManager(mContext, mService);
|
||||
mProps = new ArrayList<>();
|
||||
mProps.add(new FaceSensorPropertiesInternal(
|
||||
0 /* id */,
|
||||
FaceSensorProperties.STRENGTH_STRONG,
|
||||
1 /* maxTemplatesAllowed */,
|
||||
new ArrayList<>() /* conponentInfo */,
|
||||
FaceSensorProperties.TYPE_UNKNOWN,
|
||||
true /* supportsFaceDetection */,
|
||||
true /* supportsSelfIllumination */,
|
||||
false /* resetLockoutRequiresChallenge */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
|
||||
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
|
||||
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
|
||||
List<FaceSensorPropertiesInternal> actual = mFaceManager.getSensorPropertiesInternal();
|
||||
|
||||
assertThat(actual).isEqualTo(mProps);
|
||||
verify(mService, never()).getSensorPropertiesInternal(any());
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fingerprint;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FingerprintManagerTest {
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
Context mContext;
|
||||
@Mock
|
||||
IFingerprintService mService;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mCaptor;
|
||||
|
||||
List<FingerprintSensorPropertiesInternal> mProps;
|
||||
FingerprintManager mFingerprintManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
|
||||
mFingerprintManager = new FingerprintManager(mContext, mService);
|
||||
mProps = new ArrayList<>();
|
||||
mProps.add(new FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
FingerprintSensorProperties.STRENGTH_STRONG,
|
||||
1 /* maxEnrollmentsPerUser */,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
FingerprintSensorProperties.TYPE_UNKNOWN,
|
||||
true /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
new ArrayList<>() /* sensorLocations */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
|
||||
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
|
||||
|
||||
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
|
||||
List<FingerprintSensorPropertiesInternal> actual =
|
||||
mFingerprintManager.getSensorPropertiesInternal();
|
||||
|
||||
assertThat(actual).isEqualTo(mProps);
|
||||
verify(mService, never()).getSensorPropertiesInternal(any());
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
include /services/core/java/com/android/server/biometrics/OWNERS
|
||||
include /services/core/java/com/android/server/biometrics/OWNERS
|
||||
|
||||
@@ -705,7 +705,7 @@ public class BiometricSchedulerTest {
|
||||
TEST_SENSOR_ID, mock(BiometricLogger.class), biometricContext,
|
||||
true /* isStrongBiometric */, null /* taskStackListener */,
|
||||
null /* lockoutTracker */, false /* isKeyguard */,
|
||||
true /* shouldVibrate */, false /* isKeyguardBypassEnabled */,
|
||||
true /* shouldVibrate */,
|
||||
0 /* sensorStrength */);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ public class FaceAuthenticationClientTest {
|
||||
false /* requireConfirmation */, 9 /* sensorId */,
|
||||
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
|
||||
mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
|
||||
false /* isKeyguardBypassEnabled */, null /* sensorPrivacyManager */,
|
||||
null /* sensorPrivacyManager */,
|
||||
0 /* biometricStrength */) {
|
||||
@Override
|
||||
protected ActivityTaskManager getActivityTaskManager() {
|
||||
|
||||
Reference in New Issue
Block a user