[DO NOT MERGE] Enable biometrics.fingerprint@2.2 am: 7f91123ea4 am: d1c630d805

Change-Id: Ic42054018bedf1816f78f2059acc3a2667500ae1
This commit is contained in:
Ilya Matyukhin
2020-03-20 18:14:23 +00:00
committed by Automerger Merge Worker
14 changed files with 68 additions and 414 deletions

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.biometrics;
import android.os.NativeHandle;
import android.os.ParcelFileDescriptor;
import java.io.IOException;
/**
* A class that contains utilities for IBiometricNativeHandle.
*
* @hide
*/
public final class BiometricNativeHandleUtils {
private BiometricNativeHandleUtils() {
}
/**
* Converts a {@link NativeHandle} into an {@link IBiometricNativeHandle} by duplicating the
* underlying file descriptors.
*
* Both the original and new handle must be closed after use.
*
* @param h {@link NativeHandle}. Usually used to identify a WindowManager window. Can be null.
* @return A {@link IBiometricNativeHandle} representation of {@code h}. Will be null if
* {@code h} or its raw file descriptors are null.
*/
public static IBiometricNativeHandle dup(NativeHandle h) {
IBiometricNativeHandle handle = null;
if (h != null && h.getFileDescriptors() != null && h.getInts() != null) {
handle = new IBiometricNativeHandle();
handle.ints = h.getInts().clone();
handle.fds = new ParcelFileDescriptor[h.getFileDescriptors().length];
for (int i = 0; i < h.getFileDescriptors().length; ++i) {
try {
handle.fds[i] = ParcelFileDescriptor.dup(h.getFileDescriptors()[i]);
} catch (IOException e) {
return null;
}
}
}
return handle;
}
/**
* Closes the handle's file descriptors.
*
* @param h {@link IBiometricNativeHandle} handle.
*/
public static void close(IBiometricNativeHandle h) {
if (h != null) {
for (ParcelFileDescriptor fd : h.fds) {
if (fd != null) {
try {
fd.close();
} catch (IOException e) {
// do nothing.
}
}
}
}
}
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.biometrics;
/**
* Representation of a native handle.
* Copied from /common/aidl/android/hardware/common/NativeHandle.aidl
* @hide
*/
parcelable IBiometricNativeHandle {
ParcelFileDescriptor[] fds;
int[] ints;
}

View File

@@ -29,9 +29,7 @@ import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricNativeHandleUtils;
import android.hardware.biometrics.CryptoObject;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.os.Binder;
import android.os.CancellationSignal;
@@ -40,7 +38,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.NativeHandle;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.Trace;
@@ -249,19 +246,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
}
/**
* Defaults to {@link FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback,
* int[], NativeHandle)} with {@code windowId} set to null.
*
* @see FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback, int[],
* NativeHandle)
*/
@RequiresPermission(MANAGE_BIOMETRIC)
public void enroll(int userId, byte[] token, CancellationSignal cancel,
EnrollmentCallback callback, int[] disabledFeatures) {
enroll(userId, token, cancel, callback, disabledFeatures, null /* windowId */);
}
/**
* Request face authentication enrollment. This call operates the face authentication hardware
* and starts capturing images. Progress will be indicated by callbacks to the
@@ -277,13 +261,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @param flags optional flags
* @param userId the user to whom this face will belong to
* @param callback an object to receive enrollment events
* @param windowId optional ID of a camera preview window for a single-camera device. Must be
* null if not used.
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
public void enroll(int userId, byte[] token, CancellationSignal cancel,
EnrollmentCallback callback, int[] disabledFeatures, @Nullable NativeHandle windowId) {
EnrollmentCallback callback, int[] disabledFeatures) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an enrollment callback");
}
@@ -298,72 +280,20 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
if (mService != null) {
IBiometricNativeHandle handle = BiometricNativeHandleUtils.dup(windowId);
try {
mEnrollmentCallback = callback;
Trace.beginSection("FaceManager#enroll");
mService.enroll(userId, mToken, token, mServiceReceiver,
mContext.getOpPackageName(), disabledFeatures, handle);
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in enroll: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or
// try again later.
callback.onEnrollmentError(FACE_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */));
} finally {
Trace.endSection();
BiometricNativeHandleUtils.close(handle);
}
}
}
/**
* Request face authentication enrollment for a remote client, for example Android Auto.
* This call operates the face authentication hardware and starts capturing images.
* Progress will be indicated by callbacks to the
* {@link EnrollmentCallback} object. It terminates when
* {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
* {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
* which point the object is no longer valid. The operation can be canceled by using the
* provided cancel object.
*
* @param token a unique token provided by a recent creation or verification of device
* credentials (e.g. pin, pattern or password).
* @param cancel an object that can be used to cancel enrollment
* @param userId the user to whom this face will belong to
* @param callback an object to receive enrollment events
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
public void enrollRemotely(int userId, byte[] token, CancellationSignal cancel,
EnrollmentCallback callback, int[] disabledFeatures) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an enrollment callback");
}
if (cancel != null) {
if (cancel.isCanceled()) {
Log.w(TAG, "enrollRemotely is already canceled.");
return;
} else {
cancel.setOnCancelListener(new OnEnrollCancelListener());
}
}
if (mService != null) {
try {
mEnrollmentCallback = callback;
Trace.beginSection("FaceManager#enrollRemotely");
mService.enrollRemotely(userId, mToken, token, mServiceReceiver,
mContext.getOpPackageName(), disabledFeatures);
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in enrollRemotely: ", e);
// Though this may not be a hardware issue, it will cause apps to give up or
// try again later.
callback.onEnrollmentError(FACE_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
Log.w(TAG, "Remote exception in enroll: ", e);
if (callback != null) {
// Though this may not be a hardware issue, it will cause apps to give up or
// try again later.
callback.onEnrollmentError(FACE_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */));
}
} finally {
Trace.endSection();
}

View File

@@ -15,7 +15,6 @@
*/
package android.hardware.face;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.face.IFaceServiceReceiver;
@@ -52,10 +51,6 @@ interface IFaceService {
// Start face enrollment
void enroll(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures, in IBiometricNativeHandle windowId);
// Start remote face enrollment
void enrollRemotely(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress

View File

@@ -32,9 +32,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricNativeHandleUtils;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.os.Binder;
import android.os.CancellationSignal;
@@ -43,7 +41,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.NativeHandle;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -415,33 +412,15 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
/**
* Defaults to {@link FingerprintManager#authenticate(CryptoObject, CancellationSignal, int,
* AuthenticationCallback, Handler, int, NativeHandle)} with {@code windowId} set to null.
*
* @see FingerprintManager#authenticate(CryptoObject, CancellationSignal, int,
* AuthenticationCallback, Handler, int, NativeHandle)
*
* Per-user version, see {@link FingerprintManager#authenticate(CryptoObject,
* CancellationSignal, int, AuthenticationCallback, Handler)}. This version does not
* display the BiometricPrompt.
* @param userId the user ID that the fingerprint hardware will authenticate for.
* @hide
*/
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId) {
authenticate(crypto, cancel, flags, callback, handler, userId, null /* windowId */);
}
/**
* Per-user version, see {@link FingerprintManager#authenticate(CryptoObject,
* CancellationSignal, int, AuthenticationCallback, Handler)}. This version does not
* display the BiometricPrompt.
* @param userId the user ID that the fingerprint hardware will authenticate for.
* @param windowId for optical fingerprint sensors that require active illumination by the OLED
* display. Should be null for devices that don't require illumination.
* @hide
*/
@RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT})
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId,
@Nullable NativeHandle windowId) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an authentication callback");
}
@@ -455,43 +434,25 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
}
if (mService != null) {
IBiometricNativeHandle handle = BiometricNativeHandleUtils.dup(windowId);
try {
useHandler(handler);
mAuthenticationCallback = callback;
mCryptoObject = crypto;
long sessionId = crypto != null ? crypto.getOpId() : 0;
mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
mContext.getOpPackageName(), handle);
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception while authenticating: ", e);
if (mService != null) try {
useHandler(handler);
mAuthenticationCallback = callback;
mCryptoObject = crypto;
long sessionId = crypto != null ? crypto.getOpId() : 0;
mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
mContext.getOpPackageName());
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception while authenticating: ", e);
if (callback != null) {
// Though this may not be a hardware issue, it will cause apps to give up or try
// again later.
callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */));
} finally {
BiometricNativeHandleUtils.close(handle);
0 /* vendorCode */));
}
}
}
/**
* Defaults to {@link FingerprintManager#enroll(byte[], CancellationSignal, int, int,
* EnrollmentCallback, NativeHandle)} with {@code windowId} set to null.
*
* @see FingerprintManager#enroll(byte[], CancellationSignal, int, int, EnrollmentCallback,
* NativeHandle)
*
* @hide
*/
@RequiresPermission(MANAGE_FINGERPRINT)
public void enroll(byte [] token, CancellationSignal cancel, int flags,
int userId, EnrollmentCallback callback) {
enroll(token, cancel, flags, userId, callback, null /* windowId */);
}
/**
* Request fingerprint enrollment. This call warms up the fingerprint hardware
* and starts scanning for fingerprints. Progress will be indicated by callbacks to the
@@ -510,7 +471,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
*/
@RequiresPermission(MANAGE_FINGERPRINT)
public void enroll(byte [] token, CancellationSignal cancel, int flags,
int userId, EnrollmentCallback callback, @Nullable NativeHandle windowId) {
int userId, EnrollmentCallback callback) {
if (userId == UserHandle.USER_CURRENT) {
userId = getCurrentUserId();
}
@@ -527,21 +488,18 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
}
if (mService != null) {
IBiometricNativeHandle handle = BiometricNativeHandleUtils.dup(windowId);
try {
mEnrollmentCallback = callback;
mService.enroll(mToken, token, userId, mServiceReceiver, flags,
mContext.getOpPackageName(), handle);
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception in enroll: ", e);
if (mService != null) try {
mEnrollmentCallback = callback;
mService.enroll(mToken, token, userId, mServiceReceiver, flags,
mContext.getOpPackageName());
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception in enroll: ", e);
if (callback != null) {
// Though this may not be a hardware issue, it will cause apps to give up or try
// again later.
callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */));
} finally {
BiometricNativeHandleUtils.close(handle);
0 /* vendorCode */));
}
}
}

View File

@@ -15,7 +15,6 @@
*/
package android.hardware.fingerprint;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
@@ -32,8 +31,7 @@ interface IFingerprintService {
// USE_FINGERPRINT/USE_BIOMETRIC permission. This is effectively deprecated, since it only comes
// through FingerprintManager now.
void authenticate(IBinder token, long sessionId, int userId,
IFingerprintServiceReceiver receiver, int flags, String opPackageName,
in IBiometricNativeHandle windowId);
IFingerprintServiceReceiver receiver, int flags, String opPackageName);
// 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
@@ -42,7 +40,7 @@ interface IFingerprintService {
// startPreparedClient().
void prepareForAuthentication(IBinder token, long sessionId, int userId,
IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName, int cookie,
int callingUid, int callingPid, int callingUserId, in IBiometricNativeHandle windowId);
int callingUid, int callingPid, int callingUserId);
// Starts authentication with the previously prepared client.
void startPreparedClient(int cookie);
@@ -57,7 +55,7 @@ interface IFingerprintService {
// Start fingerprint enrollment
void enroll(IBinder token, in byte [] cryptoToken, int groupId, IFingerprintServiceReceiver receiver,
int flags, String opPackageName, in IBiometricNativeHandle windowId);
int flags, String opPackageName);
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);

View File

@@ -118,7 +118,7 @@ java_library_static {
"android.hardware.health-V2.1-java",
"android.hardware.light-java",
"android.hardware.weaver-V1.0-java",
"android.hardware.biometrics.face-V1.1-java",
"android.hardware.biometrics.face-V1.0-java",
"android.hardware.biometrics.fingerprint-V2.2-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.configstore-V1.0-java",

View File

@@ -20,14 +20,11 @@ import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.os.IBinder;
import android.os.NativeHandle;
import android.os.RemoteException;
import android.security.KeyStore;
import android.util.Slog;
import java.io.IOException;
import java.util.ArrayList;
/**
@@ -44,7 +41,6 @@ public abstract class AuthenticationClient extends ClientMonitor {
public static final int LOCKOUT_PERMANENT = 2;
private final boolean mRequireConfirmation;
private final NativeHandle mWindowId;
// We need to track this state since it's possible for applications to request for
// authentication while the device is already locked out. In that case, the client is created
@@ -73,25 +69,11 @@ public abstract class AuthenticationClient extends ClientMonitor {
public AuthenticationClient(Context context, Constants constants,
BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
BiometricServiceBase.ServiceListener listener, int targetUserId, int groupId, long opId,
boolean restricted, String owner, int cookie, boolean requireConfirmation,
IBiometricNativeHandle windowId) {
boolean restricted, String owner, int cookie, boolean requireConfirmation) {
super(context, constants, daemon, halDeviceId, token, listener, targetUserId, groupId,
restricted, owner, cookie);
mOpId = opId;
mRequireConfirmation = requireConfirmation;
mWindowId = Utils.dupNativeHandle(windowId);
}
@Override
public void destroy() {
if (mWindowId != null && mWindowId.getFileDescriptors() != null) {
try {
mWindowId.close();
} catch (IOException e) {
Slog.e(getLogTag(), "Failed to close windowId NativeHandle: ", e);
}
}
super.destroy();
}
protected long getStartTimeMs() {
@@ -251,7 +233,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
onStart();
try {
mStartTimeMs = System.currentTimeMillis();
final int result = getDaemonWrapper().authenticate(mOpId, getGroupId(), mWindowId);
final int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
if (result != 0) {
Slog.w(getLogTag(), "startAuthentication failed, result=" + result);
mMetricsLogger.histogram(mConstants.tagAuthStartError(), result);

View File

@@ -32,7 +32,6 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
@@ -44,7 +43,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IHwBinder;
import android.os.IRemoteCallback;
import android.os.NativeHandle;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -223,10 +221,9 @@ public abstract class BiometricServiceBase extends SystemService
public AuthenticationClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
IBinder token, ServiceListener listener, int targetUserId, int groupId, long opId,
boolean restricted, String owner, int cookie, boolean requireConfirmation,
IBiometricNativeHandle windowId) {
boolean restricted, String owner, int cookie, boolean requireConfirmation) {
super(context, getConstants(), daemon, halDeviceId, token, listener, targetUserId,
groupId, opId, restricted, owner, cookie, requireConfirmation, windowId);
groupId, opId, restricted, owner, cookie, requireConfirmation);
}
@Override
@@ -287,10 +284,10 @@ public abstract class BiometricServiceBase extends SystemService
public EnrollClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
IBinder token, ServiceListener listener, int userId, int groupId,
byte[] cryptoToken, boolean restricted, String owner,
final int[] disabledFeatures, int timeoutSec, IBiometricNativeHandle windowId) {
final int[] disabledFeatures, int timeoutSec) {
super(context, getConstants(), daemon, halDeviceId, token, listener,
userId, groupId, cryptoToken, restricted, owner, getBiometricUtils(),
disabledFeatures, timeoutSec, windowId);
disabledFeatures, timeoutSec);
}
@Override
@@ -476,13 +473,12 @@ public abstract class BiometricServiceBase extends SystemService
*/
protected interface DaemonWrapper {
int ERROR_ESRCH = 3; // Likely HAL is dead. see errno.h.
int authenticate(long operationId, int groupId, NativeHandle windowId)
throws RemoteException;
int authenticate(long operationId, int groupId) throws RemoteException;
int cancel() throws RemoteException;
int remove(int groupId, int biometricId) throws RemoteException;
int enumerate() throws RemoteException;
int enroll(byte[] token, int groupId, int timeout,
ArrayList<Integer> disabledFeatures, NativeHandle windowId) throws RemoteException;
ArrayList<Integer> disabledFeatures) throws RemoteException;
void resetLockout(byte[] token) throws RemoteException;
}

View File

@@ -20,13 +20,10 @@ import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.os.IBinder;
import android.os.NativeHandle;
import android.os.RemoteException;
import android.util.Slog;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,7 +35,6 @@ public abstract class EnrollClient extends ClientMonitor {
private final BiometricUtils mBiometricUtils;
private final int[] mDisabledFeatures;
private final int mTimeoutSec;
private final NativeHandle mWindowId;
private long mEnrollmentStartTimeMs;
@@ -48,26 +44,13 @@ public abstract class EnrollClient extends ClientMonitor {
BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
BiometricServiceBase.ServiceListener listener, int userId, int groupId,
byte[] cryptoToken, boolean restricted, String owner, BiometricUtils utils,
final int[] disabledFeatures, int timeoutSec, IBiometricNativeHandle windowId) {
final int[] disabledFeatures, int timeoutSec) {
super(context, constants, daemon, halDeviceId, token, listener, userId, groupId, restricted,
owner, 0 /* cookie */);
mBiometricUtils = utils;
mCryptoToken = Arrays.copyOf(cryptoToken, cryptoToken.length);
mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length);
mTimeoutSec = timeoutSec;
mWindowId = Utils.dupNativeHandle(windowId);
}
@Override
public void destroy() {
if (mWindowId != null && mWindowId.getFileDescriptors() != null) {
try {
mWindowId.close();
} catch (IOException e) {
Slog.e(getLogTag(), "Failed to close windowId NativeHandle: ", e);
}
}
super.destroy();
}
@Override
@@ -119,7 +102,7 @@ public abstract class EnrollClient extends ClientMonitor {
}
final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), mTimeoutSec,
disabledFeatures, mWindowId);
disabledFeatures);
if (result != 0) {
Slog.w(getLogTag(), "startEnroll failed, result=" + result);
mMetricsLogger.histogram(mConstants.tagEnrollStartError(), result);

View File

@@ -23,17 +23,12 @@ import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.os.Build;
import android.os.Bundle;
import android.os.NativeHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import java.io.FileDescriptor;
import java.io.IOException;
public class Utils {
public static boolean isDebugEnabled(Context context, int targetUserId) {
if (targetUserId == UserHandle.USER_NULL) {
@@ -261,31 +256,4 @@ public class Utils {
throw new IllegalArgumentException("Unsupported dismissal reason: " + reason);
}
}
/**
* Converts an {@link IBiometricNativeHandle} to a {@link NativeHandle} by duplicating the
* the underlying file descriptors.
*
* Both the original and new handle must be closed after use.
*
* @param h {@link IBiometricNativeHandle} received as a binder call argument. Usually used to
* identify a WindowManager window. Can be null.
* @return A {@link NativeHandle} representation of {@code h}. Will be null if either {@code h}
* or its contents are null.
*/
public static NativeHandle dupNativeHandle(IBiometricNativeHandle h) {
NativeHandle handle = null;
if (h != null && h.fds != null && h.ints != null) {
FileDescriptor[] fds = new FileDescriptor[h.fds.length];
for (int i = 0; i < h.fds.length; ++i) {
try {
fds[i] = h.fds[i].dup().getFileDescriptor();
} catch (IOException e) {
return null;
}
}
handle = new NativeHandle(fds, h.ints, true /* own */);
}
return handle;
}
}

View File

@@ -34,7 +34,6 @@ import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
@@ -215,10 +214,9 @@ public class FaceService extends BiometricServiceBase {
public FaceAuthClient(Context context,
DaemonWrapper daemon, long halDeviceId, IBinder token,
ServiceListener listener, int targetUserId, int groupId, long opId,
boolean restricted, String owner, int cookie, boolean requireConfirmation,
IBiometricNativeHandle windowId) {
boolean restricted, String owner, int cookie, boolean requireConfirmation) {
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
restricted, owner, cookie, requireConfirmation, windowId);
restricted, owner, cookie, requireConfirmation);
}
@Override
@@ -375,7 +373,7 @@ public class FaceService extends BiometricServiceBase {
@Override // Binder call
public void enroll(int userId, final IBinder token, final byte[] cryptoToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures, IBiometricNativeHandle windowId) {
final int[] disabledFeatures) {
checkPermission(MANAGE_BIOMETRIC);
updateActiveGroup(userId, opPackageName);
@@ -386,7 +384,7 @@ public class FaceService extends BiometricServiceBase {
final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId,
0 /* groupId */, cryptoToken, restricted, opPackageName, disabledFeatures,
ENROLL_TIMEOUT_SEC, windowId) {
ENROLL_TIMEOUT_SEC) {
@Override
public int[] getAcquireIgnorelist() {
@@ -412,14 +410,6 @@ public class FaceService extends BiometricServiceBase {
enrollInternal(client, mCurrentUserId);
}
@Override // Binder call
public void enrollRemotely(int userId, final IBinder token, final byte[] cryptoToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures) {
checkPermission(MANAGE_BIOMETRIC);
// TODO(b/145027036): Implement this.
}
@Override // Binder call
public void cancelEnrollment(final IBinder token) {
checkPermission(MANAGE_BIOMETRIC);
@@ -436,7 +426,7 @@ public class FaceService extends BiometricServiceBase {
final AuthenticationClientImpl client = new FaceAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver),
mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName,
0 /* cookie */, false /* requireConfirmation */, null /* windowId */);
0 /* cookie */, false /* requireConfirmation */);
authenticateInternal(client, opId, opPackageName);
}
@@ -452,7 +442,7 @@ public class FaceService extends BiometricServiceBase {
mDaemonWrapper, mHalDeviceId, token,
new BiometricPromptServiceListenerImpl(wrapperReceiver),
mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName, cookie,
requireConfirmation, null /* windowId */);
requireConfirmation);
authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
callingUserId);
}
@@ -986,8 +976,7 @@ public class FaceService extends BiometricServiceBase {
*/
private final DaemonWrapper mDaemonWrapper = new DaemonWrapper() {
@Override
public int authenticate(long operationId, int groupId, NativeHandle windowId)
throws RemoteException {
public int authenticate(long operationId, int groupId) throws RemoteException {
IBiometricsFace daemon = getFaceDaemon();
if (daemon == null) {
Slog.w(TAG, "authenticate(): no face HAL!");
@@ -1028,7 +1017,7 @@ public class FaceService extends BiometricServiceBase {
@Override
public int enroll(byte[] cryptoToken, int groupId, int timeout,
ArrayList<Integer> disabledFeatures, NativeHandle windowId) throws RemoteException {
ArrayList<Integer> disabledFeatures) throws RemoteException {
IBiometricsFace daemon = getFaceDaemon();
if (daemon == null) {
Slog.w(TAG, "enroll(): no face HAL!");
@@ -1038,17 +1027,7 @@ public class FaceService extends BiometricServiceBase {
for (int i = 0; i < cryptoToken.length; i++) {
token.add(cryptoToken[i]);
}
android.hardware.biometrics.face.V1_1.IBiometricsFace daemon11 =
android.hardware.biometrics.face.V1_1.IBiometricsFace.castFrom(
daemon);
if (daemon11 != null) {
return daemon11.enroll_1_1(token, timeout, disabledFeatures, windowId);
} else if (windowId == null) {
return daemon.enroll(token, timeout, disabledFeatures);
} else {
Slog.e(TAG, "enroll(): windowId is only supported in @1.1 HAL");
return ERROR_ESRCH;
}
return daemon.enroll(token, timeout, disabledFeatures);
}
@Override

View File

@@ -38,7 +38,7 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
String opPackageName, int cookie, int callingUid, int callingPid, int callingUserId)
throws RemoteException {
mFingerprintService.prepareForAuthentication(token, sessionId, userId, wrapperReceiver,
opPackageName, cookie, callingUid, callingPid, callingUserId, null /* windowId */);
opPackageName, cookie, callingUid, callingPid, callingUserId);
}
@Override

View File

@@ -38,7 +38,6 @@ import android.content.pm.UserInfo;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricNativeHandle;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
@@ -52,7 +51,6 @@ import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.NativeHandle;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SystemClock;
@@ -135,9 +133,9 @@ public class FingerprintService extends BiometricServiceBase {
DaemonWrapper daemon, long halDeviceId, IBinder token,
ServiceListener listener, int targetUserId, int groupId, long opId,
boolean restricted, String owner, int cookie,
boolean requireConfirmation, IBiometricNativeHandle windowId) {
boolean requireConfirmation) {
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
restricted, owner, cookie, requireConfirmation, windowId);
restricted, owner, cookie, requireConfirmation);
}
@Override
@@ -201,7 +199,7 @@ public class FingerprintService extends BiometricServiceBase {
@Override // Binder call
public void enroll(final IBinder token, final byte[] cryptoToken, final int userId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName, IBiometricNativeHandle windowId) {
final String opPackageName) {
checkPermission(MANAGE_FINGERPRINT);
final boolean restricted = isRestricted();
@@ -209,7 +207,7 @@ public class FingerprintService extends BiometricServiceBase {
final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId, groupId,
cryptoToken, restricted, opPackageName, new int[0] /* disabledFeatures */,
ENROLL_TIMEOUT_SEC, windowId) {
ENROLL_TIMEOUT_SEC) {
@Override
public boolean shouldVibrate() {
return true;
@@ -233,22 +231,20 @@ public class FingerprintService extends BiometricServiceBase {
@Override // Binder call
public void authenticate(final IBinder token, final long opId, final int groupId,
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName, IBiometricNativeHandle windowId) {
final String opPackageName) {
updateActiveGroup(groupId, opPackageName);
final boolean restricted = isRestricted();
final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token, new ServiceListenerImpl(receiver),
mCurrentUserId, groupId, opId, restricted, opPackageName,
0 /* cookie */, false /* requireConfirmation */,
windowId);
0 /* cookie */, false /* requireConfirmation */);
authenticateInternal(client, opId, opPackageName);
}
@Override // Binder call
public void prepareForAuthentication(IBinder token, long opId, int groupId,
IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName,
int cookie, int callingUid, int callingPid, int callingUserId,
IBiometricNativeHandle windowId) {
int cookie, int callingUid, int callingPid, int callingUserId) {
checkPermission(MANAGE_BIOMETRIC);
updateActiveGroup(groupId, opPackageName);
final boolean restricted = true; // BiometricPrompt is always restricted
@@ -256,8 +252,7 @@ public class FingerprintService extends BiometricServiceBase {
mDaemonWrapper, mHalDeviceId, token,
new BiometricPromptServiceListenerImpl(wrapperReceiver),
mCurrentUserId, groupId, opId, restricted, opPackageName, cookie,
false /* requireConfirmation */,
windowId);
false /* requireConfirmation */);
authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
callingUserId);
}
@@ -656,24 +651,13 @@ public class FingerprintService extends BiometricServiceBase {
*/
private final DaemonWrapper mDaemonWrapper = new DaemonWrapper() {
@Override
public int authenticate(long operationId, int groupId, NativeHandle windowId)
throws RemoteException {
public int authenticate(long operationId, int groupId) throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "authenticate(): no fingerprint HAL!");
return ERROR_ESRCH;
}
android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprint daemon22 =
android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprint.castFrom(
daemon);
if (daemon22 != null) {
return daemon22.authenticate_2_2(operationId, groupId, windowId);
} else if (windowId == null) {
return daemon.authenticate(operationId, groupId);
} else {
Slog.e(TAG, "authenticate(): windowId is only supported in @2.2 HAL");
return ERROR_ESRCH;
}
return daemon.authenticate(operationId, groupId);
}
@Override
@@ -708,27 +692,13 @@ public class FingerprintService extends BiometricServiceBase {
@Override
public int enroll(byte[] cryptoToken, int groupId, int timeout,
ArrayList<Integer> disabledFeatures, NativeHandle windowId) throws RemoteException {
ArrayList<Integer> disabledFeatures) throws RemoteException {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
Slog.w(TAG, "enroll(): no fingerprint HAL!");
return ERROR_ESRCH;
}
android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprint daemon22 =
android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprint.castFrom(
daemon);
if (daemon22 != null) {
ArrayList<Byte> cryptoTokenAsList = new ArrayList<>(cryptoToken.length);
for (byte b : cryptoToken) {
cryptoTokenAsList.add(b);
}
return daemon22.enroll_2_2(cryptoTokenAsList, groupId, timeout, windowId);
} else if (windowId == null) {
return daemon.enroll(cryptoToken, groupId, timeout);
} else {
Slog.e(TAG, "enroll(): windowId is only supported in @2.2 HAL");
return ERROR_ESRCH;
}
return daemon.enroll(cryptoToken, groupId, timeout);
}
@Override