Loading core/java/android/hardware/biometrics/BiometricNativeHandleUtils.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * 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. } } } } } } core/java/android/hardware/biometrics/IBiometricNativeHandle.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * 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; } core/java/android/hardware/face/FaceManager.java +78 −8 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ 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; Loading @@ -38,6 +40,7 @@ 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; Loading Loading @@ -244,6 +247,19 @@ 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 Loading @@ -259,11 +275,13 @@ 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) { EnrollmentCallback callback, int[] disabledFeatures, @Nullable NativeHandle windowId) { if (callback == null) { throw new IllegalArgumentException("Must supply an enrollment callback"); } Loading @@ -278,20 +296,72 @@ 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); mContext.getOpPackageName(), disabledFeatures, handle); } catch (RemoteException e) { 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(); 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, 0 /* vendorCode */)); } finally { Trace.endSection(); } Loading core/java/android/hardware/face/IFaceService.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.hardware.face; import android.hardware.biometrics.IBiometricNativeHandle; import android.hardware.biometrics.IBiometricServiceReceiverInternal; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.face.IFaceServiceReceiver; Loading Loading @@ -51,6 +52,10 @@ 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 Loading core/java/android/hardware/fingerprint/FingerprintManager.java +63 −21 Original line number Diff line number Diff line Loading @@ -32,7 +32,9 @@ 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; Loading @@ -41,6 +43,7 @@ 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; Loading Loading @@ -402,16 +405,34 @@ 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) * * @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) { int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId, @Nullable NativeHandle windowId) { if (callback == null) { throw new IllegalArgumentException("Must supply an authentication callback"); } Loading @@ -425,25 +446,43 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } if (mService != null) try { 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()); mContext.getOpPackageName(), handle); } 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); } } } /** * 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 Loading @@ -462,7 +501,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing */ @RequiresPermission(MANAGE_FINGERPRINT) public void enroll(byte [] token, CancellationSignal cancel, int flags, int userId, EnrollmentCallback callback) { int userId, EnrollmentCallback callback, @Nullable NativeHandle windowId) { if (userId == UserHandle.USER_CURRENT) { userId = getCurrentUserId(); } Loading @@ -479,18 +518,21 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } if (mService != null) try { if (mService != null) { IBiometricNativeHandle handle = BiometricNativeHandleUtils.dup(windowId); try { mEnrollmentCallback = callback; mService.enroll(mToken, token, userId, mServiceReceiver, flags, mContext.getOpPackageName()); mContext.getOpPackageName(), handle); } 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); } } } Loading Loading
core/java/android/hardware/biometrics/BiometricNativeHandleUtils.java 0 → 100644 +79 −0 Original line number Diff line number Diff line /* * 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. } } } } } }
core/java/android/hardware/biometrics/IBiometricNativeHandle.aidl 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * 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; }
core/java/android/hardware/face/FaceManager.java +78 −8 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ 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; Loading @@ -38,6 +40,7 @@ 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; Loading Loading @@ -244,6 +247,19 @@ 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 Loading @@ -259,11 +275,13 @@ 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) { EnrollmentCallback callback, int[] disabledFeatures, @Nullable NativeHandle windowId) { if (callback == null) { throw new IllegalArgumentException("Must supply an enrollment callback"); } Loading @@ -278,20 +296,72 @@ 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); mContext.getOpPackageName(), disabledFeatures, handle); } catch (RemoteException e) { 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(); 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, 0 /* vendorCode */)); } finally { Trace.endSection(); } Loading
core/java/android/hardware/face/IFaceService.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.hardware.face; import android.hardware.biometrics.IBiometricNativeHandle; import android.hardware.biometrics.IBiometricServiceReceiverInternal; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.face.IFaceServiceReceiver; Loading Loading @@ -51,6 +52,10 @@ 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 Loading
core/java/android/hardware/fingerprint/FingerprintManager.java +63 −21 Original line number Diff line number Diff line Loading @@ -32,7 +32,9 @@ 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; Loading @@ -41,6 +43,7 @@ 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; Loading Loading @@ -402,16 +405,34 @@ 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) * * @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) { int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId, @Nullable NativeHandle windowId) { if (callback == null) { throw new IllegalArgumentException("Must supply an authentication callback"); } Loading @@ -425,25 +446,43 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } if (mService != null) try { 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()); mContext.getOpPackageName(), handle); } 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); } } } /** * 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 Loading @@ -462,7 +501,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing */ @RequiresPermission(MANAGE_FINGERPRINT) public void enroll(byte [] token, CancellationSignal cancel, int flags, int userId, EnrollmentCallback callback) { int userId, EnrollmentCallback callback, @Nullable NativeHandle windowId) { if (userId == UserHandle.USER_CURRENT) { userId = getCurrentUserId(); } Loading @@ -479,18 +518,21 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } } if (mService != null) try { if (mService != null) { IBiometricNativeHandle handle = BiometricNativeHandleUtils.dup(windowId); try { mEnrollmentCallback = callback; mService.enroll(mToken, token, userId, mServiceReceiver, flags, mContext.getOpPackageName()); mContext.getOpPackageName(), handle); } 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); } } } Loading