Merge "1/n: Start implementation of IFingerprint aidl"

This commit is contained in:
Kevin Chyn
2020-10-09 02:44:25 +00:00
committed by Android (Google) Code Review
20 changed files with 769 additions and 38 deletions

View File

@@ -761,14 +761,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void onFingerDown(int sensorId, int x, int y, float minor, float major) {
public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
if (mService == null) {
Slog.w(TAG, "onFingerDown: no fingerprint service");
return;
}
try {
mService.onFingerDown(sensorId, x, y, minor, major);
mService.onPointerDown(sensorId, x, y, minor, major);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -778,14 +778,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void onFingerUp(int sensorId) {
public void onPointerUp(int sensorId) {
if (mService == null) {
Slog.w(TAG, "onFingerDown: no fingerprint service");
return;
}
try {
mService.onFingerUp(sensorId);
mService.onPointerUp(sensorId);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}

View File

@@ -85,4 +85,9 @@ public class FingerprintSensorPropertiesInternal extends SensorPropertiesInterna
return false;
}
}
@Override
public String toString() {
return "ID: " + sensorId + ", Strength: " + sensorStrength + ", Type: " + sensorType;
}
}

View File

@@ -121,10 +121,10 @@ interface IFingerprintService {
void initializeConfiguration(int sensorId, int strength);
// Notifies about a finger touching the sensor area.
void onFingerDown(int sensorId, int x, int y, float minor, float major);
void onPointerDown(int sensorId, int x, int y, float minor, float major);
// Notifies about a finger leaving the sensor area.
void onFingerUp(int sensorId);
void onPointerUp(int sensorId);
// Sets the controller for managing the UDFPS overlay.
void setUdfpsOverlayController(in IUdfpsOverlayController controller);

View File

@@ -63,7 +63,7 @@ import javax.inject.Inject;
* Note that the current architecture is designed so that a single {@link UdfpsController}
* controls/manages all UDFPS sensors. In other words, a single controller is registered with
* {@link com.android.server.biometrics.sensors.fingerprint.FingerprintService}, and interfaces such
* as {@link FingerprintManager#onFingerDown(int, int, int, float, float)} or
* as {@link FingerprintManager#onPointerDown(int, int, int, float, float)} or
* {@link IUdfpsOverlayController#showUdfpsOverlay(int)}should all have
* {@code sensorId} parameters.
*/
@@ -374,7 +374,7 @@ class UdfpsController implements DozeReceiver {
fw.write(mHbmEnableCommand);
fw.close();
}
mFingerprintManager.onFingerDown(mUdfpsSensorId, x, y, minor, major);
mFingerprintManager.onPointerDown(mUdfpsSensorId, x, y, minor, major);
} catch (IOException e) {
mView.hideScrimAndDot();
Log.e(TAG, "onFingerDown | failed to enable HBM: " + e.getMessage());
@@ -382,7 +382,7 @@ class UdfpsController implements DozeReceiver {
}
private void onFingerUp() {
mFingerprintManager.onFingerUp(mUdfpsSensorId);
mFingerprintManager.onPointerUp(mUdfpsSensorId);
// Hiding the scrim before disabling HBM results in less noticeable flicker.
mView.hideScrimAndDot();
if (mHbmSupported) {

View File

@@ -222,7 +222,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
event.recycle();
// THEN the event is passed to the FingerprintManager
verify(mFingerprintManager).onFingerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0),
verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0),
eq(0f), eq(0f));
// AND the scrim and dot is shown
verify(mUdfpsView).showScrimAndDot();
@@ -236,7 +236,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
// WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0);
// THEN the event is passed to the FingerprintManager
verify(mFingerprintManager).onFingerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0),
verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mUdfpsSensorId), eq(0), eq(0),
anyFloat(), anyFloat());
// AND the scrim and dot is shown
verify(mUdfpsView).showScrimAndDot();

View File

@@ -109,6 +109,7 @@ java_library_static {
"android.hardware.weaver-V1.0-java",
"android.hardware.biometrics.face-V1.1-java",
"android.hardware.biometrics.fingerprint-V2.3-java",
"android.hardware.biometrics.fingerprint-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",

View File

@@ -73,7 +73,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
T getDaemon();
}
private final int mSequentialId;
protected final int mSequentialId;
@NonNull private final Context mContext;
@NonNull protected final LazyDaemon<T> mLazyDaemon;
private final int mTargetUserId;

View File

@@ -32,6 +32,8 @@ import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
@@ -40,9 +42,12 @@ import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.NativeHandle;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.EventLog;
@@ -53,11 +58,13 @@ import android.view.Surface;
import com.android.internal.R;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
@@ -506,7 +513,7 @@ public class FingerprintService extends SystemService {
}
@Override
public void onFingerDown(int sensorId, int x, int y, float minor, float major) {
public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -514,11 +521,11 @@ public class FingerprintService extends SystemService {
Slog.w(TAG, "No matching provider for onFingerDown, sensorId: " + sensorId);
return;
}
provider.onFingerDown(sensorId, x, y, minor, major);
provider.onPointerDown(sensorId, x, y, minor, major);
}
@Override
public void onFingerUp(int sensorId) {
public void onPointerUp(int sensorId) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -526,7 +533,7 @@ public class FingerprintService extends SystemService {
Slog.w(TAG, "No matching provider for onFingerUp, sensorId: " + sensorId);
return;
}
provider.onFingerUp(sensorId);
provider.onPointerUp(sensorId);
}
@Override
@@ -546,6 +553,39 @@ public class FingerprintService extends SystemService {
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mServiceProviders = new ArrayList<>();
initializeAidlHals();
}
private void initializeAidlHals() {
final String[] instances = ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
if (instances == null || instances.length == 0) {
return;
}
// If for some reason the HAL is not started before the system service, do not block
// the rest of system server. Put this on a background thread.
final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
true /* allowIo */);
thread.start();
final Handler handler = new Handler(thread.getLooper());
handler.post(() -> {
for (String instance : instances) {
final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
final IFingerprint fp = IFingerprint.Stub.asInterface(
ServiceManager.waitForDeclaredService(fqName));
try {
final SensorProps[] props = fp.getSensorProps();
final FingerprintProvider provider =
new FingerprintProvider(getContext(), props, fqName,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
mServiceProviders.add(provider);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when initializing instance: " + fqName);
}
}
});
}
@Override
@@ -571,6 +611,7 @@ public class FingerprintService extends SystemService {
private Pair<Integer, ServiceProvider> getSingleProvider() {
final List<FingerprintSensorPropertiesInternal> properties = getSensorProperties();
if (properties.size() != 1) {
Slog.e(TAG, "Multiple sensors found: " + properties.size());
return null;
}

View File

@@ -92,6 +92,8 @@ public interface ServiceProvider {
@NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
@NonNull String opPackageName);
void scheduleInternalCleanup(int sensorId, int userId);
boolean isHardwareDetected(int sensorId);
void rename(int sensorId, int fingerId, int userId, @NonNull String name);
@@ -102,9 +104,9 @@ public interface ServiceProvider {
long getAuthenticatorId(int sensorId, int userId);
void onFingerDown(int sensorId, int x, int y, float minor, float major);
void onPointerDown(int sensorId, int x, int y, float minor, float major);
void onFingerUp(int sensorId);
void onPointerUp(int sensorId);
void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.server.biometrics.sensors.fingerprint.hidl;
package com.android.server.biometrics.sensors.fingerprint;
/**
* Interface for under-display fingerprint sensors.
@@ -22,6 +22,6 @@ package com.android.server.biometrics.sensors.fingerprint.hidl;
* finger position (e.g. enroll, authenticate) should implement this.
*/
public interface Udfps {
void onFingerDown(int x, int y, float minor, float major);
void onFingerUp();
void onPointerDown(int x, int y, float minor, float major);
void onPointerUp();
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.server.biometrics.sensors.fingerprint.hidl;
package com.android.server.biometrics.sensors.fingerprint;
import android.annotation.Nullable;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
@@ -29,7 +29,7 @@ public class UdfpsHelper {
private static final String TAG = "UdfpsHelper";
static void onFingerDown(IBiometricsFingerprint daemon, int x, int y, float minor,
public static void onFingerDown(IBiometricsFingerprint daemon, int x, int y, float minor,
float major) {
android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
@@ -46,7 +46,7 @@ public class UdfpsHelper {
}
}
static void onFingerUp(IBiometricsFingerprint daemon) {
public static void onFingerUp(IBiometricsFingerprint daemon) {
android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
daemon);
@@ -62,7 +62,7 @@ public class UdfpsHelper {
}
}
static void showUdfpsOverlay(int sensorId,
public static void showUdfpsOverlay(int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;
@@ -74,7 +74,7 @@ public class UdfpsHelper {
}
}
static void hideUdfpsOverlay(int sensorId,
public static void hideUdfpsOverlay(int sensorId,
@Nullable IUdfpsOverlayController udfpsOverlayController) {
if (udfpsOverlayController == null) {
return;

View File

@@ -0,0 +1,111 @@
/*
* 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 com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
public class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
private static final String TAG = "FingerprintEnrollClient";
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@Nullable private ICancellationSignal mCancellationSignal;
private final int mMaxTemplatesPerUser;
public FingerprintEnrollClient(@NonNull Context context,
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils,
int statsModality, int sensorId,
@Nullable IUdfpsOverlayController udfpsOvelayController, int maxTemplatesPerUser) {
super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
0 /* timeoutSec */, statsModality, sensorId, true /* shouldVibrate */);
mUdfpsOverlayController = udfpsOvelayController;
mMaxTemplatesPerUser = maxTemplatesPerUser;
}
@Override
protected boolean hasReachedEnrollmentLimit() {
return FingerprintUtils.getInstance()
.getBiometricsForUser(getContext(), getTargetUserId()).size()
>= mMaxTemplatesPerUser;
}
@Override
protected void stopHalOperation() {
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
if (mCancellationSignal != null) {
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
}
}
}
@Override
protected void startHalOperation() {
UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
try {
// TODO(b/170163175): Need a way to convert byte arrays to HardwareAuthToken
getFreshDaemon().enroll(mSequentialId, null /* hat */);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enroll", e);
onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
}
}
@Override
public void onPointerDown(int x, int y, float minor, float major) {
try {
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to send pointer down", e);
}
}
@Override
public void onPointerUp() {
try {
getFreshDaemon().onPointerUp(0 /* pointerId */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to send pointer up", e);
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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 com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.GenerateChallengeClient;
/**
* Fingerprint-specific generateChallenge client for the {@link IFingerprint} AIDL HAL interface.
*/
public class FingerprintGenerateChallengeClient extends GenerateChallengeClient<IFingerprint> {
private static final String TAG = "FingerprintGenerateChallengeClient";
private static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
private IGenerateChallengeCallback mGenerateChallengeCallback =
new IGenerateChallengeCallback.Stub() {
@Override
public void onChallengeGenerated(int sensorId, int userId, long challenge) {
try {
getListener().onChallengeGenerated(sensorId, challenge);
mCallback.onClientFinished(FingerprintGenerateChallengeClient.this,
true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to send challenge", e);
mCallback.onClientFinished(FingerprintGenerateChallengeClient.this,
false /* success */);
}
}
};
public FingerprintGenerateChallengeClient(@NonNull Context context,
@NonNull LazyDaemon<IFingerprint> lazyDaemon,
@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull String owner, int sensorId) {
super(context, lazyDaemon, token, listener, owner, sensorId);
}
@Override
protected void startHalOperation() {
try {
getFreshDaemon().generateChallenge(getSensorId(), getTargetUserId(),
CHALLENGE_TIMEOUT_SEC,
mGenerateChallengeCallback);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to generateChallenge", e);
}
}
}

View File

@@ -0,0 +1,325 @@
/*
* 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 com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Surface;
import com.android.server.biometrics.sensors.ClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
/**
* Provider for a single instance of the {@link IFingerprint} HAL.
*/
public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvider {
@NonNull private final Context mContext;
@NonNull private final String mHalInstanceName;
@NonNull private final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
@NonNull private final ClientMonitor.LazyDaemon<IFingerprint> mLazyDaemon;
@NonNull private final Handler mHandler;
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
public FingerprintProvider(@NonNull Context context, @NonNull SensorProps[] props,
@NonNull String halInstanceName, @NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
mContext = context;
mHalInstanceName = halInstanceName;
mSensors = new SparseArray<>();
mLazyDaemon = this::getHalInstance;
mHandler = new Handler(Looper.getMainLooper());
for (SensorProps prop : props) {
final int sensorId = prop.commonProps.sensorId;
final FingerprintSensorPropertiesInternal internalProp =
new FingerprintSensorPropertiesInternal(prop.commonProps.sensorId,
prop.commonProps.sensorStrength,
prop.commonProps.maxEnrollmentsPerUser,
prop.sensorType,
true /* resetLockoutRequiresHardwareAuthToken */);
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, internalProp,
gestureAvailabilityDispatcher);
mSensors.put(sensorId, sensor);
Slog.d(getTag(), "Added: " + internalProp);
}
}
private String getTag() {
return "FingerprintProvider/" + mHalInstanceName;
}
@Nullable
private synchronized IFingerprint getHalInstance() {
final IFingerprint daemon = IFingerprint.Stub.asInterface(
ServiceManager.waitForDeclaredService(mHalInstanceName));
if (daemon == null) {
Slog.e(getTag(), "Unable to get daemon");
return null;
}
try {
daemon.asBinder().linkToDeath(this, 0 /* flags */);
} catch (RemoteException e) {
Slog.e(getTag(), "Unable to linkToDeath", e);
}
for (int i = 0; i < mSensors.size(); i++) {
final int sensorId = mSensors.keyAt(i);
scheduleLoadAuthenticatorIds(sensorId);
scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser());
}
return daemon;
}
private void scheduleForSensor(int sensorId, @NonNull ClientMonitor<?> client) {
if (!mSensors.contains(sensorId)) {
throw new IllegalStateException("Unable to schedule client: " + client
+ " for sensor: " + sensorId);
}
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
}
private void scheduleForSensor(int sensorId, @NonNull ClientMonitor<?> client,
ClientMonitor.Callback callback) {
if (!mSensors.contains(sensorId)) {
throw new IllegalStateException("Unable to schedule client: " + client
+ " for sensor: " + sensorId);
}
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback);
}
private void scheduleCreateSessionWithoutHandler(@NonNull IFingerprint daemon, int sensorId,
int userId) throws RemoteException {
// Note that per IFingerprint createSession contract, this method will block until all
// existing operations are canceled/finished. However, also note that this is fine, since
// this method "withoutHandler" means it should only ever be invoked from the worker thread,
// so callers will never be blocked.
mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);
}
private void scheduleLoadAuthenticatorIdsWithoutHandler(int sensorId) {
}
private void scheduleLoadAuthenticatorIds(int sensorId) {
}
@Override
public boolean containsSensor(int sensorId) {
return mSensors.contains(sensorId);
}
@NonNull
@Override
public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
for (int i = 0; i < mSensors.size(); i++) {
props.add(mSensors.valueAt(i).getSensorProperties());
}
return props;
}
@Override
public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) {
}
@Override
public void scheduleGenerateChallenge(int sensorId, @NonNull IBinder token,
@NonNull IFingerprintServiceReceiver receiver, String opPackageName) {
mHandler.post(() -> {
final FingerprintGenerateChallengeClient client =
new FingerprintGenerateChallengeClient(mContext, mLazyDaemon, token,
new ClientMonitorCallbackConverter(receiver), opPackageName, sensorId);
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
});
}
@Override
public void scheduleRevokeChallenge(int sensorId, @NonNull IBinder token,
@NonNull String opPackageName) {
}
@Override
public void scheduleEnroll(int sensorId, @NonNull IBinder token, byte[] hardwareAuthToken,
int userId, @NonNull IFingerprintServiceReceiver receiver,
@NonNull String opPackageName, @Nullable Surface surface) {
mHandler.post(() -> {
final IFingerprint daemon = getHalInstance();
if (daemon == null) {
Slog.e(getTag(), "Null daemon during enroll, sensorId: " + sensorId);
return;
}
try {
if (!mSensors.get(sensorId).hasSessionForUser(userId)) {
scheduleCreateSessionWithoutHandler(daemon, sensorId, userId);
}
final int maxTemplatesPerUser = mSensors.get(sensorId).getSensorProperties()
.maxEnrollmentsPerUser;
final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
mSensors.get(sensorId).getLazySession(), token,
new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
opPackageName, FingerprintUtils.getInstance(),
BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
mUdfpsOverlayController, maxTemplatesPerUser);
scheduleForSensor(sensorId, client, new ClientMonitor.Callback() {
@Override
public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor,
boolean success) {
if (success) {
scheduleLoadAuthenticatorIdsWithoutHandler(sensorId);
}
}
});
} catch (RemoteException e) {
Slog.e(getTag(), "Remote exception when scheduling enroll", e);
}
});
}
@Override
public void cancelEnrollment(int sensorId, @NonNull IBinder token) {
}
@Override
public void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
@Nullable Surface surface, int statsClient) {
}
@Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean isKeyguard) {
}
@Override
public void startPreparedClient(int sensorId, int cookie) {
}
@Override
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
}
@Override
public void scheduleRemove(int sensorId, @NonNull IBinder token,
@NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
@NonNull String opPackageName) {
}
@Override
public void scheduleInternalCleanup(int userId, int sensorId) {
}
@Override
public boolean isHardwareDetected(int sensorId) {
return false;
}
@Override
public void rename(int sensorId, int fingerId, int userId, @NonNull String name) {
}
@NonNull
@Override
public List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId) {
return new ArrayList<>();
}
@Override
public int getLockoutModeForUser(int sensorId, int userId) {
return 0;
}
@Override
public long getAuthenticatorId(int sensorId, int userId) {
return 0;
}
@Override
public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
}
@Override
public void onPointerUp(int sensorId) {
}
@Override
public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
mUdfpsOverlayController = controller;
}
@Override
public void dumpProto(int sensorId, @NonNull FileDescriptor fd) {
}
@Override
public void dumpInternal(int sensorId, @NonNull PrintWriter pw) {
}
@Override
public void binderDied() {
}
}

View File

@@ -0,0 +1,163 @@
/*
* 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 com.android.server.biometrics.sensors.fingerprint.aidl;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.ClientMonitor;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
/**
* Maintains the state of a single sensor within an instance of the
* {@link android.hardware.biometrics.fingerprint.IFingerprint} HAL.
*/
class Sensor {
@NonNull private final String mTag;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
@NonNull private final BiometricScheduler mScheduler;
@Nullable private Session mCurrentSession; // TODO: Death recipient
@NonNull private final ClientMonitor.LazyDaemon<ISession> mLazySession;
private static class Session {
@NonNull private final String mTag;
@NonNull private final ISession mSession;
private final int mUserId;
private final ISessionCallback mSessionCallback;
Session(@NonNull String tag, @NonNull ISession session, int userId,
@NonNull ISessionCallback sessionCallback) {
mTag = tag;
mSession = session;
mUserId = userId;
mSessionCallback = sessionCallback;
Slog.d(mTag, "New session created for user: " + userId);
}
}
Sensor(@NonNull String tag,
@NonNull FingerprintSensorPropertiesInternal sensorProperties,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
mTag = tag;
mSensorProperties = sensorProperties;
mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher);
mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
}
@NonNull ClientMonitor.LazyDaemon<ISession> getLazySession() {
return mLazySession;
}
@NonNull FingerprintSensorPropertiesInternal getSensorProperties() {
return mSensorProperties;
}
boolean hasSessionForUser(int userId) {
return mCurrentSession != null && mCurrentSession.mUserId == userId;
}
void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId)
throws RemoteException {
final ISessionCallback callback = new ISessionCallback.Stub() {
@Override
public void onStateChanged(int cookie, byte state) {
}
@Override
public void onAcquired(byte info, int vendorCode) {
}
@Override
public void onError(byte error, int vendorCode) {
}
@Override
public void onEnrollmentProgress(int enrollmentId, int remaining) {
}
@Override
public void onAuthenticationSucceeded(int enrollmentId, HardwareAuthToken hat) {
}
@Override
public void onAuthenticationFailed() {
}
@Override
public void onLockoutTimed(long durationMillis) {
}
@Override
public void onLockoutPermanent() {
}
@Override
public void onLockoutCleared() {
}
@Override
public void onInteractionDetected() {
}
@Override
public void onEnrollmentsEnumerated(int[] enrollmentIds) {
}
@Override
public void onEnrollmentsRemoved(int[] enrollmentIds) {
}
@Override
public void onAuthenticatorIdRetrieved(long authenticatorId) {
}
@Override
public void onAuthenticatorIdInvalidated() {
}
};
final ISession newSession = daemon.createSession(sensorId, userId, callback);
mCurrentSession = new Session(mTag, newSession, userId, callback);
}
@NonNull BiometricScheduler getScheduler() {
return mScheduler;
}
}

View File

@@ -68,6 +68,7 @@ import com.android.server.biometrics.sensors.RemovalConsumer;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import org.json.JSONArray;
import org.json.JSONException;
@@ -634,6 +635,11 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
});
}
@Override
public void scheduleInternalCleanup(int userId, int sensorId) {
scheduleInternalCleanup(userId);
}
@Override
public boolean isHardwareDetected(int sensorId) {
final IBiometricsFingerprint daemon = getDaemon();
@@ -664,25 +670,25 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
}
@Override
public void onFingerDown(int sensorId, int x, int y, float minor, float major) {
public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
final ClientMonitor<?> client = mScheduler.getCurrentClient();
if (!(client instanceof Udfps)) {
Slog.w(TAG, "onFingerDown received during client: " + client);
return;
}
final Udfps udfps = (Udfps) client;
udfps.onFingerDown(x, y, minor, major);
udfps.onPointerDown(x, y, minor, major);
}
@Override
public void onFingerUp(int sensorId) {
public void onPointerUp(int sensorId) {
final ClientMonitor<?> client = mScheduler.getCurrentClient();
if (!(client instanceof Udfps)) {
Slog.w(TAG, "onFingerDown received during client: " + client);
return;
}
final Udfps udfps = (Udfps) client;
udfps.onFingerUp();
udfps.onPointerUp();
}
@Override

View File

@@ -461,7 +461,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
}
@Override
public void onFingerDown(int sensorId, int x, int y, float minor, float major) {
public void onPointerDown(int sensorId, int x, int y, float minor, float major) {
mHandler.post(() -> {
Slog.d(TAG, "onFingerDown");
final AuthenticationConsumer lastAuthenticatedConsumer =
@@ -508,7 +508,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
}
@Override
public void onFingerUp(int sensorId) {
public void onPointerUp(int sensorId) {
mHandler.post(() -> {
Slog.d(TAG, "onFingerUp");

View File

@@ -33,6 +33,8 @@ import android.util.Slog;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
import java.util.ArrayList;
@@ -138,12 +140,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
}
@Override
public void onFingerDown(int x, int y, float minor, float major) {
public void onPointerDown(int x, int y, float minor, float major) {
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
}
@Override
public void onFingerUp() {
public void onPointerUp() {
UdfpsHelper.onFingerUp(getFreshDaemon());
}

View File

@@ -32,6 +32,8 @@ import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
import java.util.ArrayList;
@@ -93,12 +95,12 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
}
@Override
public void onFingerDown(int x, int y, float minor, float major) {
public void onPointerDown(int x, int y, float minor, float major) {
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
}
@Override
public void onFingerUp() {
public void onPointerUp() {
UdfpsHelper.onFingerUp(getFreshDaemon());
}

View File

@@ -30,6 +30,8 @@ import android.util.Slog;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
/**
* Fingerprint-specific enroll client supporting the
@@ -97,12 +99,12 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
}
@Override
public void onFingerDown(int x, int y, float minor, float major) {
public void onPointerDown(int x, int y, float minor, float major) {
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
}
@Override
public void onFingerUp() {
public void onPointerUp() {
UdfpsHelper.onFingerUp(getFreshDaemon());
}
}