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:
@@ -70,9 +70,11 @@ public class UserAwareBiometricScheduler extends BiometricScheduler {
|
|||||||
|
|
||||||
// Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
|
// Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
|
||||||
// for that the queue will wait indefinitely until the field is cleared.
|
// for that the queue will wait indefinitely until the field is cleared.
|
||||||
if (clientMonitor instanceof StopUserClient<?> && !success) {
|
if (clientMonitor instanceof StopUserClient<?>) {
|
||||||
Slog.w(getTag(),
|
if (!success) {
|
||||||
"StopUserClient failed(), is the HAL stuck? Clearing mStopUserClient");
|
Slog.w(getTag(), "StopUserClient failed(), is the HAL stuck? "
|
||||||
|
+ "Clearing mStopUserClient");
|
||||||
|
}
|
||||||
mStopUserClient = null;
|
mStopUserClient = null;
|
||||||
}
|
}
|
||||||
if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
|
if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class Sensor {
|
|||||||
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
||||||
|
|
||||||
@NonNull private final Supplier<AidlSession> mLazySession;
|
@NonNull private final Supplier<AidlSession> mLazySession;
|
||||||
@Nullable private AidlSession mCurrentSession;
|
@Nullable AidlSession mCurrentSession;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static class HalSessionCallback extends ISessionCallback.Stub {
|
public static class HalSessionCallback extends ISessionCallback.Stub {
|
||||||
@@ -486,7 +486,7 @@ public class Sensor {
|
|||||||
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
|
Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
|
||||||
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
|
@NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
|
||||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||||
@NonNull BiometricContext biometricContext) {
|
@NonNull BiometricContext biometricContext, AidlSession session) {
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
mProvider = provider;
|
mProvider = provider;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -549,6 +549,14 @@ public class Sensor {
|
|||||||
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
|
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() {
|
@NonNull Supplier<AidlSession> getLazySession() {
|
||||||
return mLazySession;
|
return mLazySession;
|
||||||
}
|
}
|
||||||
@@ -557,7 +565,7 @@ public class Sensor {
|
|||||||
return mSensorProperties;
|
return mSensorProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable AidlSession getSessionForUser(int userId) {
|
@VisibleForTesting @Nullable AidlSession getSessionForUser(int userId) {
|
||||||
if (mCurrentSession != null && mCurrentSession.getUserId() == userId) {
|
if (mCurrentSession != null && mCurrentSession.getUserId() == userId) {
|
||||||
return mCurrentSession;
|
return mCurrentSession;
|
||||||
} else {
|
} else {
|
||||||
@@ -641,6 +649,8 @@ public class Sensor {
|
|||||||
BiometricsProtoEnums.MODALITY_FACE,
|
BiometricsProtoEnums.MODALITY_FACE,
|
||||||
BiometricsProtoEnums.ISSUE_HAL_DEATH,
|
BiometricsProtoEnums.ISSUE_HAL_DEATH,
|
||||||
-1 /* sensorId */);
|
-1 /* sensorId */);
|
||||||
|
} else if (client != null) {
|
||||||
|
client.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
mScheduler.recordCrashState();
|
mScheduler.recordCrashState();
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class Sensor {
|
|||||||
@NonNull private final LockoutCache mLockoutCache;
|
@NonNull private final LockoutCache mLockoutCache;
|
||||||
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
||||||
|
|
||||||
@Nullable private AidlSession mCurrentSession;
|
@Nullable AidlSession mCurrentSession;
|
||||||
@NonNull private final Supplier<AidlSession> mLazySession;
|
@NonNull private final Supplier<AidlSession> mLazySession;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -439,7 +439,7 @@ public class Sensor {
|
|||||||
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
|
@NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
|
||||||
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
|
||||||
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
|
||||||
@NonNull BiometricContext biometricContext) {
|
@NonNull BiometricContext biometricContext, AidlSession session) {
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
mProvider = provider;
|
mProvider = provider;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -501,6 +501,16 @@ public class Sensor {
|
|||||||
});
|
});
|
||||||
mAuthenticatorIds = new HashMap<>();
|
mAuthenticatorIds = new HashMap<>();
|
||||||
mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
|
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() {
|
@NonNull Supplier<AidlSession> getLazySession() {
|
||||||
@@ -599,6 +609,8 @@ public class Sensor {
|
|||||||
BiometricsProtoEnums.MODALITY_FINGERPRINT,
|
BiometricsProtoEnums.MODALITY_FINGERPRINT,
|
||||||
BiometricsProtoEnums.ISSUE_HAL_DEATH,
|
BiometricsProtoEnums.ISSUE_HAL_DEATH,
|
||||||
-1 /* sensorId */);
|
-1 /* sensorId */);
|
||||||
|
} else if (client != null) {
|
||||||
|
client.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
mScheduler.recordCrashState();
|
mScheduler.recordCrashState();
|
||||||
|
|||||||
@@ -17,12 +17,14 @@
|
|||||||
package com.android.server.biometrics.sensors.face.aidl;
|
package com.android.server.biometrics.sensors.face.aidl;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
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.BiometricContext;
|
||||||
import com.android.server.biometrics.log.BiometricLogger;
|
import com.android.server.biometrics.log.BiometricLogger;
|
||||||
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
|
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.BiometricScheduler;
|
||||||
import com.android.server.biometrics.sensors.LockoutCache;
|
import com.android.server.biometrics.sensors.LockoutCache;
|
||||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||||
@@ -82,6 +85,10 @@ public class SensorTest {
|
|||||||
private AuthSessionCoordinator mAuthSessionCoordinator;
|
private AuthSessionCoordinator mAuthSessionCoordinator;
|
||||||
@Mock
|
@Mock
|
||||||
FaceProvider mFaceProvider;
|
FaceProvider mFaceProvider;
|
||||||
|
@Mock
|
||||||
|
BaseClientMonitor mClientMonitor;
|
||||||
|
@Mock
|
||||||
|
AidlSession mCurrentSession;
|
||||||
|
|
||||||
private final TestLooper mLooper = new TestLooper();
|
private final TestLooper mLooper = new TestLooper();
|
||||||
private final LockoutCache mLockoutCache = new LockoutCache();
|
private final LockoutCache mLockoutCache = new LockoutCache();
|
||||||
@@ -161,6 +168,39 @@ public class SensorTest {
|
|||||||
assertNull(sensor.getSessionForUser(USER_ID));
|
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() {
|
private void verifyNotLocked() {
|
||||||
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
|
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
|
||||||
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
|
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
|
||||||
|
|||||||
@@ -17,17 +17,23 @@
|
|||||||
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
package com.android.server.biometrics.sensors.fingerprint.aidl;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
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.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.biometrics.IBiometricService;
|
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.biometrics.fingerprint.ISession;
|
||||||
|
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
import android.platform.test.annotations.Presubmit;
|
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.BiometricContext;
|
||||||
import com.android.server.biometrics.log.BiometricLogger;
|
import com.android.server.biometrics.log.BiometricLogger;
|
||||||
import com.android.server.biometrics.sensors.AuthSessionCoordinator;
|
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.BiometricScheduler;
|
||||||
import com.android.server.biometrics.sensors.LockoutCache;
|
import com.android.server.biometrics.sensors.LockoutCache;
|
||||||
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
|
||||||
import com.android.server.biometrics.sensors.LockoutTracker;
|
import com.android.server.biometrics.sensors.LockoutTracker;
|
||||||
import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
|
import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
|
||||||
|
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -76,6 +84,14 @@ public class SensorTest {
|
|||||||
private BiometricContext mBiometricContext;
|
private BiometricContext mBiometricContext;
|
||||||
@Mock
|
@Mock
|
||||||
private AuthSessionCoordinator mAuthSessionCoordinator;
|
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 TestLooper mLooper = new TestLooper();
|
||||||
private final LockoutCache mLockoutCache = new LockoutCache();
|
private final LockoutCache mLockoutCache = new LockoutCache();
|
||||||
@@ -130,6 +146,40 @@ public class SensorTest {
|
|||||||
verifyNotLocked();
|
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() {
|
private void verifyNotLocked() {
|
||||||
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
|
assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
|
||||||
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
|
verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
|
||||||
|
|||||||
Reference in New Issue
Block a user