Merge "Cancel non interruptable clients when binder dies" into udc-dev am: 919a4ba823

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23357836

Change-Id: I518f5d7fe6f11b51f93c0346f8c0363fd008de21
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Diya Bera
2023-05-22 23:14:57 +00:00
committed by Automerger Merge Worker
5 changed files with 122 additions and 8 deletions

View File

@@ -70,9 +70,11 @@ public class UserAwareBiometricScheduler extends BiometricScheduler {
// Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
// for that the queue will wait indefinitely until the field is cleared.
if (clientMonitor instanceof StopUserClient<?> && !success) {
Slog.w(getTag(),
"StopUserClient failed(), is the HAL stuck? Clearing mStopUserClient");
if (clientMonitor instanceof StopUserClient<?>) {
if (!success) {
Slog.w(getTag(), "StopUserClient failed(), is the HAL stuck? "
+ "Clearing mStopUserClient");
}
mStopUserClient = null;
}
if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {

View File

@@ -89,7 +89,7 @@ public class Sensor {
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
@NonNull private final Supplier<AidlSession> mLazySession;
@Nullable private AidlSession mCurrentSession;
@Nullable AidlSession mCurrentSession;
@VisibleForTesting
public static class HalSessionCallback extends ISessionCallback.Stub {
@@ -486,7 +486,7 @@ public class Sensor {
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull BiometricContext biometricContext) {
@NonNull BiometricContext biometricContext, AidlSession session) {
mTag = tag;
mProvider = provider;
mContext = context;
@@ -549,6 +549,14 @@ public class Sensor {
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
}
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull BiometricContext biometricContext) {
this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
biometricContext, null);
}
@NonNull Supplier<AidlSession> getLazySession() {
return mLazySession;
}
@@ -557,7 +565,7 @@ public class Sensor {
return mSensorProperties;
}
@Nullable AidlSession getSessionForUser(int userId) {
@VisibleForTesting @Nullable AidlSession getSessionForUser(int userId) {
if (mCurrentSession != null && mCurrentSession.getUserId() == userId) {
return mCurrentSession;
} else {
@@ -641,6 +649,8 @@ public class Sensor {
BiometricsProtoEnums.MODALITY_FACE,
BiometricsProtoEnums.ISSUE_HAL_DEATH,
-1 /* sensorId */);
} else if (client != null) {
client.cancel();
}
mScheduler.recordCrashState();

View File

@@ -90,7 +90,7 @@ public class Sensor {
@NonNull private final LockoutCache mLockoutCache;
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
@Nullable private AidlSession mCurrentSession;
@Nullable AidlSession mCurrentSession;
@NonNull private final Supplier<AidlSession> mLazySession;
@VisibleForTesting
@@ -439,7 +439,7 @@ public class Sensor {
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull BiometricContext biometricContext) {
@NonNull BiometricContext biometricContext, AidlSession session) {
mTag = tag;
mProvider = provider;
mContext = context;
@@ -501,6 +501,16 @@ public class Sensor {
});
mAuthenticatorIds = new HashMap<>();
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
mCurrentSession = session;
}
Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context,
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull BiometricContext biometricContext) {
this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
gestureAvailabilityDispatcher, biometricContext, null);
}
@NonNull Supplier<AidlSession> getLazySession() {
@@ -599,6 +609,8 @@ public class Sensor {
BiometricsProtoEnums.MODALITY_FINGERPRINT,
BiometricsProtoEnums.ISSUE_HAL_DEATH,
-1 /* sensorId */);
} else if (client != null) {
client.cancel();
}
mScheduler.recordCrashState();

View File

@@ -17,12 +17,14 @@
package com.android.server.biometrics.sensors.face.aidl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,6 +43,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
@@ -82,6 +85,10 @@ public class SensorTest {
private AuthSessionCoordinator mAuthSessionCoordinator;
@Mock
FaceProvider mFaceProvider;
@Mock
BaseClientMonitor mClientMonitor;
@Mock
AidlSession mCurrentSession;
private final TestLooper mLooper = new TestLooper();
private final LockoutCache mLockoutCache = new LockoutCache();
@@ -161,6 +168,39 @@ public class SensorTest {
assertNull(sensor.getSessionForUser(USER_ID));
}
@Test
public void onBinderDied_cancelNonInterruptableClient() {
mLooper.dispatchAll();
when(mCurrentSession.getUserId()).thenReturn(USER_ID);
when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
when(mClientMonitor.isInterruptable()).thenReturn(false);
final SensorProps sensorProps = new SensorProps();
sensorProps.commonProps = new CommonProps();
sensorProps.commonProps.sensorId = 1;
final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
sensorProps.commonProps.maxEnrollmentsPerUser, null,
sensorProps.sensorType, sensorProps.supportsDetectInteraction,
sensorProps.halControlsPreview, false /* resetLockoutRequiresChallenge */);
final Sensor sensor = new Sensor("SensorTest", mFaceProvider, mContext, null,
internalProp, mLockoutResetDispatcher, mBiometricContext, mCurrentSession);
mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
USER_ID, mHalCallback);
mScheduler.scheduleClientMonitor(mClientMonitor);
assertNotNull(mScheduler.getCurrentClient());
sensor.onBinderDied();
verify(mClientMonitor).cancel();
assertNull(sensor.getSessionForUser(USER_ID));
assertNull(mScheduler.getCurrentClient());
}
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));

View File

@@ -17,17 +17,23 @@
package com.android.server.biometrics.sensors.fingerprint.aidl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Handler;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
@@ -37,11 +43,13 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import org.junit.Before;
import org.junit.Test;
@@ -76,6 +84,14 @@ public class SensorTest {
private BiometricContext mBiometricContext;
@Mock
private AuthSessionCoordinator mAuthSessionCoordinator;
@Mock
FingerprintProvider mFingerprintProvider;
@Mock
GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
@Mock
private AidlSession mCurrentSession;
@Mock
private BaseClientMonitor mClientMonitor;
private final TestLooper mLooper = new TestLooper();
private final LockoutCache mLockoutCache = new LockoutCache();
@@ -130,6 +146,40 @@ public class SensorTest {
verifyNotLocked();
}
@Test
public void onBinderDied_cancelNonInterruptableClient() {
mLooper.dispatchAll();
when(mCurrentSession.getUserId()).thenReturn(USER_ID);
when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
when(mClientMonitor.isInterruptable()).thenReturn(false);
final SensorProps sensorProps = new SensorProps();
sensorProps.commonProps = new CommonProps();
sensorProps.commonProps.sensorId = 1;
final FingerprintSensorPropertiesInternal internalProp = new
FingerprintSensorPropertiesInternal(
sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
sensorProps.commonProps.maxEnrollmentsPerUser, null,
sensorProps.sensorType, false /* resetLockoutRequiresHardwareAuthToken */);
final Sensor sensor = new Sensor("SensorTest", mFingerprintProvider, mContext,
null /* handler */, internalProp, mLockoutResetDispatcher,
mGestureAvailabilityDispatcher, mBiometricContext, mCurrentSession);
mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
USER_ID, mHalCallback);
mScheduler.scheduleClientMonitor(mClientMonitor);
assertNotNull(mScheduler.getCurrentClient());
sensor.onBinderDied();
verify(mClientMonitor).cancel();
assertNull(sensor.getSessionForUser(USER_ID));
assertNull(mScheduler.getCurrentClient());
}
private void verifyNotLocked() {
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));