Merge "Take in a Surface then convert to a NativeHandle"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d90630ad39
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,13 +38,13 @@ 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;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
@@ -251,15 +249,14 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
|
||||
/**
|
||||
* Defaults to {@link FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback,
|
||||
* int[], NativeHandle)} with {@code windowId} set to null.
|
||||
* int[], Surface)} with {@code surface} set to null.
|
||||
*
|
||||
* @see FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback, int[],
|
||||
* NativeHandle)
|
||||
* @see FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback, int[], Surface)
|
||||
*/
|
||||
@RequiresPermission(MANAGE_BIOMETRIC)
|
||||
public void enroll(int userId, byte[] token, CancellationSignal cancel,
|
||||
EnrollmentCallback callback, int[] disabledFeatures) {
|
||||
enroll(userId, token, cancel, callback, disabledFeatures, null /* windowId */);
|
||||
enroll(userId, token, cancel, callback, disabledFeatures, null /* surface */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,13 +274,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.
|
||||
* @param surface optional camera preview surface 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, @Nullable Surface surface) {
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("Must supply an enrollment callback");
|
||||
}
|
||||
@@ -298,12 +295,11 @@ 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);
|
||||
mContext.getOpPackageName(), disabledFeatures, surface);
|
||||
} 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
|
||||
@@ -313,7 +309,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
0 /* vendorCode */));
|
||||
} finally {
|
||||
Trace.endSection();
|
||||
BiometricNativeHandleUtils.close(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package android.hardware.face;
|
||||
|
||||
import android.hardware.biometrics.IBiometricNativeHandle;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.hardware.face.IFaceServiceReceiver;
|
||||
import android.hardware.face.Face;
|
||||
import android.view.Surface;
|
||||
|
||||
/**
|
||||
* Communication channel from client to the face service. These methods are all require the
|
||||
@@ -52,7 +52,7 @@ interface IFaceService {
|
||||
|
||||
// Start face enrollment
|
||||
void enroll(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
|
||||
String opPackageName, in int [] disabledFeatures, in IBiometricNativeHandle windowId);
|
||||
String opPackageName, in int [] disabledFeatures, in Surface surface);
|
||||
|
||||
// Start remote face enrollment
|
||||
void enrollRemotely(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
|
||||
|
||||
@@ -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,12 +41,12 @@ 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;
|
||||
import android.security.identity.IdentityCredential;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.security.Signature;
|
||||
import java.util.List;
|
||||
@@ -419,17 +417,17 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
|
||||
/**
|
||||
* Defaults to {@link FingerprintManager#authenticate(CryptoObject, CancellationSignal, int,
|
||||
* AuthenticationCallback, Handler, int, NativeHandle)} with {@code windowId} set to null.
|
||||
* AuthenticationCallback, Handler, int, Surface)} with {@code surface} set to null.
|
||||
*
|
||||
* @see FingerprintManager#authenticate(CryptoObject, CancellationSignal, int,
|
||||
* AuthenticationCallback, Handler, int, NativeHandle)
|
||||
* AuthenticationCallback, Handler, int, Surface)
|
||||
*
|
||||
* @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 */);
|
||||
authenticate(crypto, cancel, flags, callback, handler, userId, null /* surface */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -437,14 +435,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
* 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
|
||||
* @param surface 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) {
|
||||
@Nullable Surface surface) {
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("Must supply an authentication callback");
|
||||
}
|
||||
@@ -459,14 +457,13 @@ 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);
|
||||
mContext.getOpPackageName(), surface);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception while authenticating: ", e);
|
||||
// Though this may not be a hardware issue, it will cause apps to give up or try
|
||||
@@ -474,25 +471,23 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
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.
|
||||
* EnrollmentCallback, Surface)} with {@code surface} set to null.
|
||||
*
|
||||
* @see FingerprintManager#enroll(byte[], CancellationSignal, int, int, EnrollmentCallback,
|
||||
* NativeHandle)
|
||||
* Surface)
|
||||
*
|
||||
* @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 */);
|
||||
enroll(token, cancel, flags, userId, callback, null /* surface */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,7 +508,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, @Nullable Surface surface) {
|
||||
if (userId == UserHandle.USER_CURRENT) {
|
||||
userId = getCurrentUserId();
|
||||
}
|
||||
@@ -531,11 +526,10 @@ 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);
|
||||
mContext.getOpPackageName(), surface);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception in enroll: ", e);
|
||||
// Though this may not be a hardware issue, it will cause apps to give up or try
|
||||
@@ -543,8 +537,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||
getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */));
|
||||
} finally {
|
||||
BiometricNativeHandleUtils.close(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package android.hardware.fingerprint;
|
||||
|
||||
import android.hardware.biometrics.IBiometricNativeHandle;
|
||||
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
|
||||
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
|
||||
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.view.Surface;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ interface IFingerprintService {
|
||||
// through FingerprintManager now.
|
||||
void authenticate(IBinder token, long sessionId, int userId,
|
||||
IFingerprintServiceReceiver receiver, int flags, String opPackageName,
|
||||
in IBiometricNativeHandle windowId);
|
||||
in Surface surface);
|
||||
|
||||
// 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 +42,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, in Surface surface);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
void startPreparedClient(int cookie);
|
||||
@@ -57,7 +57,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, in Surface surface);
|
||||
|
||||
// Cancel enrollment in progress
|
||||
void cancelEnrollment(IBinder token);
|
||||
|
||||
@@ -20,14 +20,12 @@ 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 android.view.Surface;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
@@ -44,7 +42,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
|
||||
public static final int LOCKOUT_PERMANENT = 2;
|
||||
|
||||
private final boolean mRequireConfirmation;
|
||||
private final NativeHandle mWindowId;
|
||||
private final Surface mSurface;
|
||||
|
||||
// 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
|
||||
@@ -74,24 +72,12 @@ public abstract class AuthenticationClient extends ClientMonitor {
|
||||
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) {
|
||||
Surface surface) {
|
||||
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();
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
protected long getStartTimeMs() {
|
||||
@@ -251,7 +237,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(), mSurface);
|
||||
if (result != 0) {
|
||||
Slog.w(getLogTag(), "startAuthentication failed, result=" + result);
|
||||
mMetricsLogger.histogram(mConstants.tagAuthStartError(), result);
|
||||
|
||||
@@ -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;
|
||||
@@ -53,6 +51,7 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
@@ -224,9 +223,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) {
|
||||
Surface surface) {
|
||||
super(context, getConstants(), daemon, halDeviceId, token, listener, targetUserId,
|
||||
groupId, opId, restricted, owner, cookie, requireConfirmation, windowId);
|
||||
groupId, opId, restricted, owner, cookie, requireConfirmation, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,10 +286,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, Surface surface) {
|
||||
super(context, getConstants(), daemon, halDeviceId, token, listener,
|
||||
userId, groupId, cryptoToken, restricted, owner, getBiometricUtils(),
|
||||
disabledFeatures, timeoutSec, windowId);
|
||||
disabledFeatures, timeoutSec, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -476,13 +475,13 @@ 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)
|
||||
int authenticate(long operationId, int groupId, Surface surface)
|
||||
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, Surface surface) throws RemoteException;
|
||||
void resetLockout(byte[] token) throws RemoteException;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +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.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -38,7 +36,7 @@ public abstract class EnrollClient extends ClientMonitor {
|
||||
private final BiometricUtils mBiometricUtils;
|
||||
private final int[] mDisabledFeatures;
|
||||
private final int mTimeoutSec;
|
||||
private final NativeHandle mWindowId;
|
||||
private final Surface mSurface;
|
||||
|
||||
private long mEnrollmentStartTimeMs;
|
||||
|
||||
@@ -48,26 +46,14 @@ 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, Surface surface) {
|
||||
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();
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,7 +105,7 @@ public abstract class EnrollClient extends ClientMonitor {
|
||||
}
|
||||
|
||||
final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), mTimeoutSec,
|
||||
disabledFeatures, mWindowId);
|
||||
disabledFeatures, mSurface);
|
||||
if (result != 0) {
|
||||
Slog.w(getLogTag(), "startEnroll failed, result=" + result);
|
||||
mMetricsLogger.histogram(mConstants.tagEnrollStartError(), result);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -57,6 +56,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -216,9 +216,9 @@ public class FaceService 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) {
|
||||
Surface surface) {
|
||||
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
|
||||
restricted, owner, cookie, requireConfirmation, windowId);
|
||||
restricted, owner, cookie, requireConfirmation, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -375,7 +375,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, Surface surface) {
|
||||
checkPermission(MANAGE_BIOMETRIC);
|
||||
updateActiveGroup(userId, opPackageName);
|
||||
|
||||
@@ -386,7 +386,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, surface) {
|
||||
|
||||
@Override
|
||||
public int[] getAcquireIgnorelist() {
|
||||
@@ -436,7 +436,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 */, null /* surface */);
|
||||
authenticateInternal(client, opId, opPackageName);
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ public class FaceService extends BiometricServiceBase {
|
||||
mDaemonWrapper, mHalDeviceId, token,
|
||||
new BiometricPromptServiceListenerImpl(wrapperReceiver),
|
||||
mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName, cookie,
|
||||
requireConfirmation, null /* windowId */);
|
||||
requireConfirmation, null /* surface */);
|
||||
authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
|
||||
callingUserId);
|
||||
}
|
||||
@@ -986,7 +986,7 @@ public class FaceService extends BiometricServiceBase {
|
||||
*/
|
||||
private final DaemonWrapper mDaemonWrapper = new DaemonWrapper() {
|
||||
@Override
|
||||
public int authenticate(long operationId, int groupId, NativeHandle windowId)
|
||||
public int authenticate(long operationId, int groupId, Surface surface)
|
||||
throws RemoteException {
|
||||
IBiometricsFace daemon = getFaceDaemon();
|
||||
if (daemon == null) {
|
||||
@@ -1028,7 +1028,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, Surface surface) throws RemoteException {
|
||||
IBiometricsFace daemon = getFaceDaemon();
|
||||
if (daemon == null) {
|
||||
Slog.w(TAG, "enroll(): no face HAL!");
|
||||
@@ -1042,11 +1042,12 @@ public class FaceService extends BiometricServiceBase {
|
||||
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 daemon11.enroll_1_1(token, timeout, disabledFeatures,
|
||||
convertSurfaceToNativeHandle(surface));
|
||||
} else if (surface == null) {
|
||||
return daemon.enroll(token, timeout, disabledFeatures);
|
||||
} else {
|
||||
Slog.e(TAG, "enroll(): windowId is only supported in @1.1 HAL");
|
||||
Slog.e(TAG, "enroll(): surface is only supported in @1.1 HAL");
|
||||
return ERROR_ESRCH;
|
||||
}
|
||||
}
|
||||
@@ -1323,6 +1324,8 @@ public class FaceService extends BiometricServiceBase {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private native NativeHandle convertSurfaceToNativeHandle(Surface surface);
|
||||
|
||||
private void dumpInternal(PrintWriter pw) {
|
||||
JSONObject dump = new JSONObject();
|
||||
try {
|
||||
|
||||
@@ -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, null /* surface */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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;
|
||||
@@ -62,6 +61,7 @@ import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -135,9 +135,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, Surface surface) {
|
||||
super(context, daemon, halDeviceId, token, listener, targetUserId, groupId, opId,
|
||||
restricted, owner, cookie, requireConfirmation, windowId);
|
||||
restricted, owner, cookie, requireConfirmation, surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,7 +201,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, Surface surface) {
|
||||
checkPermission(MANAGE_FINGERPRINT);
|
||||
|
||||
final boolean restricted = isRestricted();
|
||||
@@ -209,7 +209,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, surface) {
|
||||
@Override
|
||||
public boolean shouldVibrate() {
|
||||
return true;
|
||||
@@ -233,14 +233,14 @@ 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, Surface surface) {
|
||||
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);
|
||||
surface);
|
||||
authenticateInternal(client, opId, opPackageName);
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
public void prepareForAuthentication(IBinder token, long opId, int groupId,
|
||||
IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName,
|
||||
int cookie, int callingUid, int callingPid, int callingUserId,
|
||||
IBiometricNativeHandle windowId) {
|
||||
Surface surface) {
|
||||
checkPermission(MANAGE_BIOMETRIC);
|
||||
updateActiveGroup(groupId, opPackageName);
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
@@ -257,7 +257,7 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
new BiometricPromptServiceListenerImpl(wrapperReceiver),
|
||||
mCurrentUserId, groupId, opId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */,
|
||||
windowId);
|
||||
surface);
|
||||
authenticateInternal(client, opId, opPackageName, callingUid, callingPid,
|
||||
callingUserId);
|
||||
}
|
||||
@@ -656,7 +656,7 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
*/
|
||||
private final DaemonWrapper mDaemonWrapper = new DaemonWrapper() {
|
||||
@Override
|
||||
public int authenticate(long operationId, int groupId, NativeHandle windowId)
|
||||
public int authenticate(long operationId, int groupId, Surface surface)
|
||||
throws RemoteException {
|
||||
IBiometricsFingerprint daemon = getFingerprintDaemon();
|
||||
if (daemon == null) {
|
||||
@@ -667,11 +667,12 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
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 daemon22.authenticate_2_2(operationId, groupId,
|
||||
convertSurfaceToNativeHandle(surface));
|
||||
} else if (surface == null) {
|
||||
return daemon.authenticate(operationId, groupId);
|
||||
} else {
|
||||
Slog.e(TAG, "authenticate(): windowId is only supported in @2.2 HAL");
|
||||
Slog.e(TAG, "authenticate(): surface is only supported in @2.2 HAL");
|
||||
return ERROR_ESRCH;
|
||||
}
|
||||
}
|
||||
@@ -708,7 +709,7 @@ 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, Surface surface) throws RemoteException {
|
||||
IBiometricsFingerprint daemon = getFingerprintDaemon();
|
||||
if (daemon == null) {
|
||||
Slog.w(TAG, "enroll(): no fingerprint HAL!");
|
||||
@@ -722,11 +723,12 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
for (byte b : cryptoToken) {
|
||||
cryptoTokenAsList.add(b);
|
||||
}
|
||||
return daemon22.enroll_2_2(cryptoTokenAsList, groupId, timeout, windowId);
|
||||
} else if (windowId == null) {
|
||||
return daemon22.enroll_2_2(cryptoTokenAsList, groupId, timeout,
|
||||
convertSurfaceToNativeHandle(surface));
|
||||
} else if (surface == null) {
|
||||
return daemon.enroll(cryptoToken, groupId, timeout);
|
||||
} else {
|
||||
Slog.e(TAG, "enroll(): windowId is only supported in @2.2 HAL");
|
||||
Slog.e(TAG, "enroll(): surface is only supported in @2.2 HAL");
|
||||
return ERROR_ESRCH;
|
||||
}
|
||||
}
|
||||
@@ -1029,6 +1031,8 @@ public class FingerprintService extends BiometricServiceBase {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
private native NativeHandle convertSurfaceToNativeHandle(Surface surface);
|
||||
|
||||
private void dumpInternal(PrintWriter pw) {
|
||||
JSONObject dump = new JSONObject();
|
||||
try {
|
||||
|
||||
@@ -26,6 +26,7 @@ cc_library_static {
|
||||
"stats/SubsystemSleepStatePuller.cpp",
|
||||
"com_android_server_adb_AdbDebuggingManager.cpp",
|
||||
"com_android_server_am_BatteryStatsService.cpp",
|
||||
"com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp",
|
||||
"com_android_server_connectivity_Vpn.cpp",
|
||||
"com_android_server_ConsumerIrService.cpp",
|
||||
"com_android_server_devicepolicy_CryptoTestHelper.cpp",
|
||||
@@ -88,6 +89,7 @@ cc_defaults {
|
||||
shared_libs: [
|
||||
"libadb_pairing_server",
|
||||
"libadb_pairing_connection",
|
||||
"libandroid",
|
||||
"libandroid_runtime",
|
||||
"libandroidfw",
|
||||
"libaudioclient",
|
||||
@@ -103,6 +105,7 @@ cc_defaults {
|
||||
"libkeystore_binder",
|
||||
"libmtp",
|
||||
"libnativehelper",
|
||||
"libnativewindow",
|
||||
"libutils",
|
||||
"libui",
|
||||
"libinput",
|
||||
@@ -141,6 +144,7 @@ cc_defaults {
|
||||
"android.hardware.gnss@2.1",
|
||||
"android.hardware.gnss.measurement_corrections@1.0",
|
||||
"android.hardware.gnss.visibility_control@1.0",
|
||||
"android.hardware.graphics.bufferqueue@1.0",
|
||||
"android.hardware.input.classifier@1.0",
|
||||
"android.hardware.ir@1.0",
|
||||
"android.hardware.light@2.0",
|
||||
@@ -156,6 +160,7 @@ cc_defaults {
|
||||
"android.hardware.vibrator@1.2",
|
||||
"android.hardware.vibrator@1.3",
|
||||
"android.hardware.vr@1.0",
|
||||
"android.hidl.token@1.0-utils",
|
||||
"android.frameworks.schedulerservice@1.0",
|
||||
"android.frameworks.sensorservice@1.0",
|
||||
"android.frameworks.stats@1.0",
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "SurfaceToNativeHandleConverter"
|
||||
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include "jni.h"
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android_os_NativeHandle.h>
|
||||
#include <gui/IGraphicBufferProducer.h>
|
||||
#include <gui/Surface.h>
|
||||
#include <gui/bufferqueue/1.0/WGraphicBufferProducer.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
namespace {
|
||||
constexpr int WINDOW_HAL_TOKEN_SIZE_MAX = 256;
|
||||
|
||||
native_handle_t* convertHalTokenToNativeHandle(const HalToken& halToken) {
|
||||
// We attempt to store halToken in the ints of the native_handle_t after its
|
||||
// size. The first int stores the size of the token. We store this in an int
|
||||
// to avoid alignment issues where size_t and int do not have the same
|
||||
// alignment.
|
||||
size_t nhDataByteSize = halToken.size();
|
||||
if (nhDataByteSize > WINDOW_HAL_TOKEN_SIZE_MAX) {
|
||||
// The size of the token isn't reasonable..
|
||||
return nullptr;
|
||||
}
|
||||
size_t numInts = ceil(nhDataByteSize / sizeof(int)) + 1;
|
||||
|
||||
// We don't check for overflow, whether numInts can fit in an int, since we
|
||||
// expect WINDOW_HAL_TOKEN_SIZE_MAX to be a reasonable limit.
|
||||
// create a native_handle_t with 0 numFds and numInts number of ints.
|
||||
native_handle_t* nh = native_handle_create(0, numInts);
|
||||
if (!nh) {
|
||||
return nullptr;
|
||||
}
|
||||
// Store the size of the token in the first int.
|
||||
nh->data[0] = nhDataByteSize;
|
||||
memcpy(&(nh->data[1]), halToken.data(), nhDataByteSize);
|
||||
return nh;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
using ::android::sp;
|
||||
|
||||
static jobject convertSurfaceToNativeHandle(JNIEnv* env, jobject /* clazz */,
|
||||
jobject previewSurface) {
|
||||
ANativeWindow* previewAnw = ANativeWindow_fromSurface(env, previewSurface);
|
||||
sp<Surface> surface = static_cast<Surface*>(previewAnw);
|
||||
sp<IGraphicBufferProducer> igbp = surface->getIGraphicBufferProducer();
|
||||
sp<HGraphicBufferProducer> hgbp = new TWGraphicBufferProducer<HGraphicBufferProducer>(igbp);
|
||||
HalToken halToken;
|
||||
createHalToken(hgbp, &halToken);
|
||||
native_handle_t* native_handle = convertHalTokenToNativeHandle(halToken);
|
||||
return JNativeHandle::MakeJavaNativeHandleObj(env, native_handle);
|
||||
}
|
||||
|
||||
static const JNINativeMethod method_table[] = {
|
||||
{"convertSurfaceToNativeHandle", "(Landroid/view/Surface;)Landroid/os/NativeHandle;",
|
||||
reinterpret_cast<void*>(convertSurfaceToNativeHandle)},
|
||||
};
|
||||
|
||||
int register_android_server_FingerprintService(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env,
|
||||
"com/android/server/biometrics/fingerprint/FingerprintService",
|
||||
method_table, NELEM(method_table));
|
||||
}
|
||||
|
||||
int register_android_server_FaceService(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env, "com/android/server/biometrics/face/FaceService",
|
||||
method_table, NELEM(method_table));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
@@ -61,6 +61,8 @@ int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl
|
||||
int register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(JNIEnv* env);
|
||||
int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
|
||||
int register_android_server_AdbDebuggingManager(JNIEnv* env);
|
||||
int register_android_server_FingerprintService(JNIEnv* env);
|
||||
int register_android_server_FaceService(JNIEnv* env);
|
||||
};
|
||||
|
||||
using namespace android;
|
||||
@@ -115,5 +117,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
|
||||
register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(env);
|
||||
register_android_server_stats_pull_StatsPullAtomService(env);
|
||||
register_android_server_AdbDebuggingManager(env);
|
||||
register_android_server_FingerprintService(env);
|
||||
register_android_server_FaceService(env);
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user