Clean up biometric AIDL binderDied handling

1) We should only register one death recipient - in the top-level
   provider class. The provider can notify all sensors to clean up
   when the HAL dies
2) Always set mCurrentSession to null. Otherwise, if current client
   is null, or non-interruptable, subsequent attempts to access the
   HAL will result in a DeadObjectException

Fixes: 179097844
Test: atest com.android.server.biometrics
Change-Id: I8604dc1988b8b7f3572596b1431da4d6e5c393c2
This commit is contained in:
Kevin Chyn
2021-02-08 12:42:37 -08:00
parent 98ed521f0a
commit 77df3dffa5
4 changed files with 32 additions and 44 deletions

View File

@@ -643,8 +643,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
final Sensor sensor = mSensors.valueAt(i);
final int sensorId = mSensors.keyAt(i);
PerformanceTracker.getInstanceForSensorId(sensorId).incrementHALDeathCount();
sensor.getScheduler().recordCrashState();
sensor.getScheduler().reset();
sensor.onBinderDied();
}
});
}

View File

@@ -33,7 +33,6 @@ import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Slog;
@@ -63,7 +62,7 @@ import java.util.Map;
/**
* Maintains the state of a single sensor within an instance of the {@link IFace} HAL.
*/
public class Sensor implements IBinder.DeathRecipient {
public class Sensor {
private boolean mTestHalEnabled;
@@ -481,7 +480,6 @@ public class Sensor implements IBinder.DeathRecipient {
mTag, mScheduler, sensorId, userId, callback);
final ISession newSession = daemon.createSession(sensorId, userId, resultController);
newSession.asBinder().linkToDeath(this, 0 /* flags */);
mCurrentSession = new Session(mTag, newSession, userId, resultController);
}
@@ -523,24 +521,21 @@ public class Sensor implements IBinder.DeathRecipient {
proto.end(sensorToken);
}
@Override
public void binderDied() {
Slog.e(mTag, "Binder died");
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
public void onBinderDied() {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mScheduler.recordCrashState();
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
BiometricsProtoEnums.MODALITY_FACE,
BiometricsProtoEnums.ISSUE_HAL_DEATH);
}
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
BiometricsProtoEnums.MODALITY_FACE,
BiometricsProtoEnums.ISSUE_HAL_DEATH);
mCurrentSession = null;
}
});
mScheduler.recordCrashState();
mScheduler.reset();
mCurrentSession = null;
}
}

View File

@@ -697,8 +697,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
final Sensor sensor = mSensors.valueAt(i);
final int sensorId = mSensors.keyAt(i);
PerformanceTracker.getInstanceForSensorId(sensorId).incrementHALDeathCount();
sensor.getScheduler().recordCrashState();
sensor.getScheduler().reset();
sensor.onBinderDied();
}
});
}

View File

@@ -31,7 +31,6 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Slog;
@@ -65,7 +64,7 @@ import java.util.Map;
* {@link android.hardware.biometrics.fingerprint.IFingerprint} HAL.
*/
@SuppressWarnings("deprecation")
class Sensor implements IBinder.DeathRecipient {
class Sensor {
private boolean mTestHalEnabled;
@@ -461,7 +460,6 @@ class Sensor implements IBinder.DeathRecipient {
mTag, mScheduler, sensorId, userId, callback);
final ISession newSession = daemon.createSession(sensorId, userId, resultController);
newSession.asBinder().linkToDeath(this, 0 /* flags */);
mCurrentSession = new Session(mTag, newSession, userId, resultController);
}
@@ -503,24 +501,21 @@ class Sensor implements IBinder.DeathRecipient {
proto.end(sensorToken);
}
@Override
public void binderDied() {
Slog.e(mTag, "Binder died");
mHandler.post(() -> {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
public void onBinderDied() {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mScheduler.recordCrashState();
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
BiometricsProtoEnums.MODALITY_FINGERPRINT,
BiometricsProtoEnums.ISSUE_HAL_DEATH);
}
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
BiometricsProtoEnums.MODALITY_FINGERPRINT,
BiometricsProtoEnums.ISSUE_HAL_DEATH);
mCurrentSession = null;
}
});
mScheduler.recordCrashState();
mScheduler.reset();
mCurrentSession = null;
}
}