BatteryService: scheduleUpdate asynchronously

IBatteryPropertiesRegistrar.scheduleUpdate calls IHealth.update()
asynchronously.

BatteryStatsImpl calls scheduleUpdate while holding a lock, which
may lead to deadlocks if the remote process calls back to the
framework.

Fixes: 139503418
Test: monitor HealthScheduleUpdate trace points
Change-Id: I8168d7c4e4a0b1d31343360d2c7f6d36c7aa692a
This commit is contained in:
Yifan Hong
2019-08-16 13:20:57 -07:00
parent ce98a32755
commit 7ceb724d0f

View File

@@ -1227,14 +1227,21 @@ public final class BatteryService extends SystemService {
}
@Override
public void scheduleUpdate() throws RemoteException {
traceBegin("HealthScheduleUpdate");
try {
IHealth service = mHealthServiceWrapper.getLastService();
if (service == null) throw new RemoteException("no health service");
service.update();
} finally {
traceEnd();
}
mHealthServiceWrapper.getHandlerThread().getThreadHandler().post(() -> {
traceBegin("HealthScheduleUpdate");
try {
IHealth service = mHealthServiceWrapper.getLastService();
if (service == null) {
Slog.e(TAG, "no health service");
return;
}
service.update();
} catch (RemoteException ex) {
Slog.e(TAG, "Cannot call update on health HAL", ex);
} finally {
traceEnd();
}
});
}
}
@@ -1311,7 +1318,7 @@ public final class BatteryService extends SystemService {
Arrays.asList(INSTANCE_VENDOR, INSTANCE_HEALTHD);
private final IServiceNotification mNotification = new Notification();
private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceRefresh");
private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceHwbinder");
// These variables are fixed after init.
private Callback mCallback;
private IHealthSupplier mHealthSupplier;