From 7ceb724d0f792897e66fca8566fcabca969c5b57 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 16 Aug 2019 13:20:57 -0700 Subject: [PATCH] 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 --- .../java/com/android/server/BatteryService.java | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 3b78fdafbd94..946561788d80 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -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; -- 2.11.0