From 6e5eb1dfa6b73e0f6f4dc98baf88a9826e2f1d25 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Fri, 30 Mar 2018 16:15:35 -0700 Subject: [PATCH] Fix dead lock between AM and BatterySaverStateMachine Change-Id: If641ad1a0961376de65fdb9d557e7e2e601af389 Fixes: 77308319 Test: Boot, toggle battery saver Test: atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java --- .../batterysaver/BatterySaverStateMachine.java | 39 +++++++++++++--------- .../batterysaver/BatterySaverStateMachineTest.java | 5 +++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java index 5b3182ebd699..28605215e19d 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -26,6 +26,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; import com.android.server.power.BatterySaverPolicy; import com.android.server.power.BatterySaverStateMachineProto; @@ -124,25 +125,33 @@ public class BatterySaverStateMachine { if (DEBUG) { Slog.d(TAG, "onBootCompleted"); } - synchronized (mLock) { + // This is called with the power manager lock held. Don't do any + runOnBgThread(() -> { + synchronized (mLock) { - final ContentResolver cr = mContext.getContentResolver(); - cr.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.LOW_POWER_MODE), - false, mSettingsObserver, UserHandle.USER_SYSTEM); - cr.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.LOW_POWER_MODE_STICKY), - false, mSettingsObserver, UserHandle.USER_SYSTEM); - cr.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), - false, mSettingsObserver, UserHandle.USER_SYSTEM); + final ContentResolver cr = mContext.getContentResolver(); + cr.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.LOW_POWER_MODE), + false, mSettingsObserver, UserHandle.USER_SYSTEM); + cr.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.LOW_POWER_MODE_STICKY), + false, mSettingsObserver, UserHandle.USER_SYSTEM); + cr.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), + false, mSettingsObserver, UserHandle.USER_SYSTEM); - mBootCompleted = true; + mBootCompleted = true; - refreshSettingsLocked(); + refreshSettingsLocked(); - doAutoBatterySaverLocked(); - } + doAutoBatterySaverLocked(); + } + }); + } + + @VisibleForTesting + void runOnBgThread(Runnable r) { + BackgroundThread.getHandler().post(r); } void refreshSettingsLocked() { diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java index ab640d66b222..1367f583ba38 100644 --- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java +++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java @@ -139,6 +139,11 @@ public class BatterySaverStateMachineTest { protected int getGlobalSetting(String key, int defValue) { return mDevice.getGlobalSetting(key, defValue); } + + @Override + void runOnBgThread(Runnable r) { + r.run(); + } } @Before -- 2.11.0