Cache PowerManager binder calls

Use PropertyInvalidatedCache to save on redundant
binder calls for isPowerSaveMode and isInteractive.

Bug: 140788621
Test: atest BatterySaverTest
Test: atest PowerManagerTest
Change-Id: I849a48eb7c901d3178097d33dce01630dbb78267
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 267613f..a8fa6db 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -26,6 +26,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.app.PropertyInvalidatedCache;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.service.dreams.Sandman;
@@ -877,6 +878,39 @@
         }
     }
 
+    private static final String CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY =
+            "cache_key.is_power_save_mode";
+
+    private static final String CACHE_KEY_IS_INTERACTIVE_PROPERTY = "cache_key.is_interactive";
+
+    private static final int MAX_CACHE_ENTRIES = 1;
+
+    private PropertyInvalidatedCache<Void, Boolean> mPowerSaveModeCache =
+            new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES,
+                CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY) {
+                @Override
+                protected Boolean recompute(Void query) {
+                    try {
+                        return mService.isPowerSaveMode();
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            };
+
+    private PropertyInvalidatedCache<Void, Boolean> mInteractiveCache =
+            new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES,
+                CACHE_KEY_IS_INTERACTIVE_PROPERTY) {
+                @Override
+                protected Boolean recompute(Void query) {
+                    try {
+                        return mService.isInteractive();
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            };
+
     final Context mContext;
     @UnsupportedAppUsage
     final IPowerManager mService;
@@ -1440,11 +1474,7 @@
      * @see android.content.Intent#ACTION_SCREEN_OFF
      */
     public boolean isInteractive() {
-        try {
-            return mService.isInteractive();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return mInteractiveCache.query(null);
     }
 
     /**
@@ -1504,11 +1534,7 @@
      * @return Returns true if currently in low power mode, else false.
      */
     public boolean isPowerSaveMode() {
-        try {
-            return mService.isPowerSaveMode();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return mPowerSaveModeCache.query(null);
     }
 
     /**
@@ -2508,4 +2534,18 @@
             };
         }
     }
+
+    /**
+     * @hide
+     */
+    public static void invalidatePowerSaveModeCaches() {
+        PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY);
+    }
+
+    /**
+     * @hide
+     */
+    public static void invalidateIsInteractiveCaches() {
+        PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_INTERACTIVE_PROPERTY);
+    }
 }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a7b0d84..8483c77 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -242,8 +242,8 @@
     private final ServiceThread mHandlerThread;
     private final PowerManagerHandler mHandler;
     private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
-    private final BatterySaverPolicy mBatterySaverPolicy;
     private final BatterySaverController mBatterySaverController;
+    private final BatterySaverPolicy mBatterySaverPolicy;
     private final BatterySaverStateMachine mBatterySaverStateMachine;
     private final BatterySavingStats mBatterySavingStats;
     private final AttentionDetector mAttentionDetector;
@@ -275,7 +275,8 @@
 
     // Indicates whether the device is awake or asleep or somewhere in between.
     // This is distinct from the screen power state, which is managed separately.
-    private int mWakefulness;
+    // Do not access directly; always use {@link #setWakefulness} and {@link getWakefulness}.
+    private int mWakefulnessRaw;
     private boolean mWakefulnessChanging;
 
     // True if the sandman has just been summoned for the first time since entering the
@@ -764,6 +765,13 @@
             return new BatterySaverPolicy(lock, context, batterySavingStats);
         }
 
+        BatterySaverController createBatterySaverController(
+                Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+                BatterySavingStats batterySavingStats) {
+            return new BatterySaverController(lock, context, BackgroundThread.get().getLooper(),
+                    batterySaverPolicy, batterySavingStats);
+        }
+
         NativeWrapper createNativeWrapper() {
             return new NativeWrapper();
         }
@@ -794,6 +802,10 @@
                 }
             };
         }
+
+        void invalidateIsInteractiveCaches() {
+            PowerManager.invalidateIsInteractiveCaches();
+        }
     }
 
     final Constants mConstants;
@@ -833,9 +845,8 @@
         mBatterySavingStats = new BatterySavingStats(mLock);
         mBatterySaverPolicy =
                 mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats);
-        mBatterySaverController = new BatterySaverController(mLock, mContext,
-                BackgroundThread.get().getLooper(), mBatterySaverPolicy,
-                mBatterySavingStats);
+        mBatterySaverController = mInjector.createBatterySaverController(mLock, mContext,
+                mBatterySaverPolicy, mBatterySavingStats);
         mBatterySaverStateMachine = new BatterySaverStateMachine(
                 mLock, mContext, mBatterySaverController);
 
@@ -939,13 +950,14 @@
             mHalAutoSuspendModeEnabled = false;
             mHalInteractiveModeEnabled = true;
 
-            mWakefulness = WAKEFULNESS_AWAKE;
+            mWakefulnessRaw = WAKEFULNESS_AWAKE;
             sQuiescent = mSystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
 
             mNativeWrapper.nativeInit(this);
             mNativeWrapper.nativeSetAutoSuspend(false);
             mNativeWrapper.nativeSetInteractive(true);
             mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
+            mInjector.invalidateIsInteractiveCaches();
         }
     }
 
@@ -1567,8 +1579,8 @@
                 mOverriddenTimeout = -1;
             }
 
-            if (mWakefulness == WAKEFULNESS_ASLEEP
-                    || mWakefulness == WAKEFULNESS_DOZING
+            if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+                    || getWakefulnessLocked() == WAKEFULNESS_DOZING
                     || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
                 return false;
             }
@@ -1624,7 +1636,7 @@
             Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
         }
 
-        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
+        if (eventTime < mLastSleepTime || getWakefulnessLocked() == WAKEFULNESS_AWAKE
                 || mForceSuspendActive || !mSystemReady) {
             return false;
         }
@@ -1634,7 +1646,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
         try {
             Slog.i(TAG, "Waking up from "
-                    + PowerManagerInternal.wakefulnessToString(mWakefulness)
+                    + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                     + " (uid=" + reasonUid
                     + ", reason=" + PowerManager.wakeReasonToString(reason)
                     + ", details=" + details
@@ -1680,8 +1692,8 @@
         }
 
         if (eventTime < mLastWakeTime
-                || mWakefulness == WAKEFULNESS_ASLEEP
-                || mWakefulness == WAKEFULNESS_DOZING
+                || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+                || getWakefulnessLocked() == WAKEFULNESS_DOZING
                 || !mSystemReady
                 || !mBootCompleted) {
             return false;
@@ -1738,7 +1750,7 @@
             Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid);
         }
 
-        if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
+        if (eventTime < mLastWakeTime || getWakefulnessLocked() != WAKEFULNESS_AWAKE
                 || !mBootCompleted || !mSystemReady) {
             return false;
         }
@@ -1762,7 +1774,7 @@
                     + ", uid=" + uid);
         }
 
-        if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
+        if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
                 || !mBootCompleted || !mSystemReady) {
             return false;
         }
@@ -1781,13 +1793,15 @@
 
     @VisibleForTesting
     void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
-        if (mWakefulness != wakefulness) {
-            mWakefulness = wakefulness;
+        if (getWakefulnessLocked() != wakefulness) {
+            // Under lock, invalidate before set ensures caches won't return stale values.
+            mInjector.invalidateIsInteractiveCaches();
+            mWakefulnessRaw = wakefulness;
             mWakefulnessChanging = true;
             mDirty |= DIRTY_WAKEFULNESS;
 
             // This is only valid while we are in wakefulness dozing. Set to false otherwise.
-            mDozeStartInProgress &= (mWakefulness == WAKEFULNESS_DOZING);
+            mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING);
 
             if (mNotifier != null) {
                 mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
@@ -1797,8 +1811,8 @@
     }
 
     @VisibleForTesting
-    int getWakefulness() {
-        return mWakefulness;
+    int getWakefulnessLocked() {
+        return mWakefulnessRaw;
     }
 
     /**
@@ -1816,17 +1830,18 @@
 
     private void finishWakefulnessChangeIfNeededLocked() {
         if (mWakefulnessChanging && mDisplayReady) {
-            if (mWakefulness == WAKEFULNESS_DOZING
+            if (getWakefulnessLocked() == WAKEFULNESS_DOZING
                     && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                 return; // wait until dream has enabled dozing
             } else {
                 // Doze wakelock acquired (doze started) or device is no longer dozing.
                 mDozeStartInProgress = false;
             }
-            if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) {
+            if (getWakefulnessLocked() == WAKEFULNESS_DOZING
+                    || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
                 logSleepTimeoutRecapturedLocked();
             }
-            if (mWakefulness == WAKEFULNESS_AWAKE) {
+            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
                 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
                 final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
                 if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
@@ -2006,7 +2021,7 @@
         }
 
         // If already dreaming and becoming powered, then don't wake.
-        if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
+        if (mIsPowered && getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
             return false;
         }
 
@@ -2016,7 +2031,7 @@
         }
 
         // On Always On Display, SystemUI shows the charging indicator
-        if (mAlwaysOnEnabled && mWakefulness == WAKEFULNESS_DOZING) {
+        if (mAlwaysOnEnabled && getWakefulnessLocked() == WAKEFULNESS_DOZING) {
             return false;
         }
 
@@ -2081,7 +2096,7 @@
 
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
-                        + PowerManagerInternal.wakefulnessToString(mWakefulness)
+                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                         + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
             }
         }
@@ -2089,23 +2104,23 @@
 
     private int adjustWakeLockSummaryLocked(int wakeLockSummary) {
         // Cancel wake locks that make no sense based on the current state.
-        if (mWakefulness != WAKEFULNESS_DOZING) {
+        if (getWakefulnessLocked() != WAKEFULNESS_DOZING) {
             wakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
         }
-        if (mWakefulness == WAKEFULNESS_ASLEEP
+        if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
                 || (wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
             wakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
                     | WAKE_LOCK_BUTTON_BRIGHT);
-            if (mWakefulness == WAKEFULNESS_ASLEEP) {
+            if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
                 wakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
             }
         }
 
         // Infer implied wake locks where necessary based on the current state.
         if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
-            if (mWakefulness == WAKEFULNESS_AWAKE) {
+            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
                 wakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
-            } else if (mWakefulness == WAKEFULNESS_DREAMING) {
+            } else if (getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
                 wakeLockSummary |= WAKE_LOCK_CPU;
             }
         }
@@ -2213,9 +2228,9 @@
             mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
 
             long nextTimeout = 0;
-            if (mWakefulness == WAKEFULNESS_AWAKE
-                    || mWakefulness == WAKEFULNESS_DREAMING
-                    || mWakefulness == WAKEFULNESS_DOZING) {
+            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE
+                    || getWakefulnessLocked() == WAKEFULNESS_DREAMING
+                    || getWakefulnessLocked() == WAKEFULNESS_DOZING) {
                 final long attentiveTimeout = getAttentiveTimeoutLocked();
                 final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
                 final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
@@ -2299,7 +2314,7 @@
 
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
-                        + PowerManagerInternal.wakefulnessToString(mWakefulness)
+                        + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
                         + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                         + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
             }
@@ -2368,7 +2383,7 @@
                 mInattentiveSleepWarningOverlayController.show();
                 nextTimeout = goToSleepTime;
             } else {
-                if (DEBUG && mWakefulness != WAKEFULNESS_ASLEEP) {
+                if (DEBUG && getWakefulnessLocked() != WAKEFULNESS_ASLEEP) {
                     Slog.i(TAG, "Going to sleep now due to long user inactivity");
                 }
             }
@@ -2386,7 +2401,7 @@
             return false;
         }
 
-        if (mWakefulness != WAKEFULNESS_AWAKE) {
+        if (getWakefulnessLocked() != WAKEFULNESS_AWAKE) {
             mInattentiveSleepWarningOverlayController.dismiss(false);
             return true;
         } else if (attentiveTimeout < 0 || isBeingKeptFromShowingInattentiveSleepWarningLocked()
@@ -2490,7 +2505,7 @@
                 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
                 | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS
                 | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
-            if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
+            if (getWakefulnessLocked() == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
                 if (DEBUG_SPEW) {
                     Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
                 }
@@ -2613,7 +2628,7 @@
         final int wakefulness;
         synchronized (mLock) {
             mSandmanScheduled = false;
-            wakefulness = mWakefulness;
+            wakefulness = getWakefulnessLocked();
             if (mSandmanSummoned && mDisplayReady) {
                 startDreaming = canDreamLocked() || canDozeLocked();
                 mSandmanSummoned = false;
@@ -2655,7 +2670,7 @@
 
             // If preconditions changed, wait for the next iteration to determine
             // whether the dream should continue (or be restarted).
-            if (mSandmanSummoned || mWakefulness != wakefulness) {
+            if (mSandmanSummoned || getWakefulnessLocked() != wakefulness) {
                 return; // wait for next cycle
             }
 
@@ -2717,7 +2732,7 @@
      * Returns true if the device is allowed to dream in its current state.
      */
     private boolean canDreamLocked() {
-        if (mWakefulness != WAKEFULNESS_DREAMING
+        if (getWakefulnessLocked() != WAKEFULNESS_DREAMING
                 || !mDreamsSupportedConfig
                 || !mDreamsEnabledSetting
                 || !mDisplayPowerRequest.isBrightOrDim()
@@ -2749,7 +2764,7 @@
      * Returns true if the device is allowed to doze in its current state.
      */
     private boolean canDozeLocked() {
-        return mWakefulness == WAKEFULNESS_DOZING;
+        return getWakefulnessLocked() == WAKEFULNESS_DOZING;
     }
 
     /**
@@ -2825,7 +2840,7 @@
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
                         + ", policy=" + mDisplayPowerRequest.policy
-                        + ", mWakefulness=" + mWakefulness
+                        + ", mWakefulness=" + getWakefulnessLocked()
                         + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
                         + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                         + ", mBootCompleted=" + mBootCompleted
@@ -2871,11 +2886,11 @@
 
     @VisibleForTesting
     int getDesiredScreenPolicyLocked() {
-        if (mWakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
+        if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP || sQuiescent) {
             return DisplayPowerRequest.POLICY_OFF;
         }
 
-        if (mWakefulness == WAKEFULNESS_DOZING) {
+        if (getWakefulnessLocked() == WAKEFULNESS_DOZING) {
             if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
                 return DisplayPowerRequest.POLICY_DOZE;
             }
@@ -3079,7 +3094,7 @@
         // Here we wait for mWakefulnessChanging to become false since the wakefulness
         // transition to DOZING isn't considered "changed" until the doze wake lock is
         // acquired.
-        if (mWakefulness == WAKEFULNESS_DOZING && mDozeStartInProgress) {
+        if (getWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) {
             return true;
         }
 
@@ -3119,7 +3134,7 @@
 
     private boolean isInteractiveInternal() {
         synchronized (mLock) {
-            return PowerManagerInternal.isInteractive(mWakefulness);
+            return PowerManagerInternal.isInteractive(getWakefulnessLocked());
         }
     }
 
@@ -3495,7 +3510,7 @@
 
     private void boostScreenBrightnessInternal(long eventTime, int uid) {
         synchronized (mLock) {
-            if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP
+            if (!mSystemReady || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
                     || eventTime < mLastScreenBrightnessBoostTime) {
                 return;
             }
@@ -3725,7 +3740,8 @@
             pw.println("Power Manager State:");
             mConstants.dump(pw);
             pw.println("  mDirty=0x" + Integer.toHexString(mDirty));
-            pw.println("  mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness));
+            pw.println("  mWakefulness="
+                    + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked()));
             pw.println("  mWakefulnessChanging=" + mWakefulnessChanging);
             pw.println("  mIsPowered=" + mIsPowered);
             pw.println("  mPlugType=" + mPlugType);
@@ -3936,7 +3952,7 @@
         synchronized (mLock) {
             mConstants.dumpProto(proto);
             proto.write(PowerManagerServiceDumpProto.DIRTY, mDirty);
-            proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, mWakefulness);
+            proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getWakefulnessLocked());
             proto.write(PowerManagerServiceDumpProto.IS_WAKEFULNESS_CHANGING, mWakefulnessChanging);
             proto.write(PowerManagerServiceDumpProto.IS_POWERED, mIsPowered);
             proto.write(PowerManagerServiceDumpProto.PLUG_TYPE, mPlugType);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 4142e6f..beba106 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -38,7 +38,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.Preconditions;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.power.PowerManagerService;
@@ -76,11 +75,19 @@
     @GuardedBy("mLock")
     private final ArrayList<LowPowerModeListener> mListeners = new ArrayList<>();
 
+    /**
+     * Do not access directly; always use {@link #setFullEnabledLocked}
+     * and {@link #getFullEnabledLocked}
+     */
     @GuardedBy("mLock")
-    private boolean mFullEnabled;
+    private boolean mFullEnabledRaw;
 
+    /**
+     * Do not access directly; always use {@link #setAdaptiveEnabledLocked} and
+     * {@link #getAdaptiveEnabledLocked}.
+     */
     @GuardedBy("mLock")
-    private boolean mAdaptiveEnabled;
+    private boolean mAdaptiveEnabledRaw;
 
     @GuardedBy("mLock")
     private boolean mIsPluggedIn;
@@ -208,6 +215,7 @@
         mPlugins = new Plugin[] {
                 new BatterySaverLocationPlugin(mContext)
         };
+        PowerManager.invalidatePowerSaveModeCaches();
     }
 
     /**
@@ -294,10 +302,10 @@
     @VisibleForTesting
     public void enableBatterySaver(boolean enable, int reason) {
         synchronized (mLock) {
-            if (mFullEnabled == enable) {
+            if (getFullEnabledLocked() == enable) {
                 return;
             }
-            mFullEnabled = enable;
+            setFullEnabledLocked(enable);
 
             if (updatePolicyLevelLocked()) {
                 mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
@@ -306,9 +314,9 @@
     }
 
     private boolean updatePolicyLevelLocked() {
-        if (mFullEnabled) {
+        if (getFullEnabledLocked()) {
             return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_FULL);
-        } else if (mAdaptiveEnabled) {
+        } else if (getAdaptiveEnabledLocked()) {
             return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_ADAPTIVE);
         } else {
             return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_OFF);
@@ -321,8 +329,8 @@
      */
     public boolean isEnabled() {
         synchronized (mLock) {
-            return mFullEnabled
-                    || (mAdaptiveEnabled && mBatterySaverPolicy.shouldAdvertiseIsEnabled());
+            return getFullEnabledLocked() || (getAdaptiveEnabledLocked()
+                    && mBatterySaverPolicy.shouldAdvertiseIsEnabled());
         }
     }
 
@@ -332,19 +340,19 @@
      */
     private boolean isPolicyEnabled() {
         synchronized (mLock) {
-            return mFullEnabled || mAdaptiveEnabled;
+            return getFullEnabledLocked() || getAdaptiveEnabledLocked();
         }
     }
 
     boolean isFullEnabled() {
         synchronized (mLock) {
-            return mFullEnabled;
+            return getFullEnabledLocked();
         }
     }
 
     boolean isAdaptiveEnabled() {
         synchronized (mLock) {
-            return mAdaptiveEnabled;
+            return getAdaptiveEnabledLocked();
         }
     }
 
@@ -375,10 +383,10 @@
     }
 
     boolean setAdaptivePolicyEnabledLocked(boolean enabled, int reason) {
-        if (mAdaptiveEnabled == enabled) {
+        if (getAdaptiveEnabledLocked() == enabled) {
             return false;
         }
-        mAdaptiveEnabled = enabled;
+        setAdaptiveEnabledLocked(enabled);
         if (updatePolicyLevelLocked()) {
             mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
             return true;
@@ -427,19 +435,19 @@
         final ArrayMap<String, String> fileValues;
 
         synchronized (mLock) {
-            enabled = mFullEnabled || mAdaptiveEnabled;
+            enabled = getFullEnabledLocked() || getAdaptiveEnabledLocked();
 
             EventLogTags.writeBatterySaverMode(
                     mFullPreviouslyEnabled ? 1 : 0, // Previously off or on.
                     mAdaptivePreviouslyEnabled ? 1 : 0, // Previously off or on.
-                    mFullEnabled ? 1 : 0, // Now off or on.
-                    mAdaptiveEnabled ? 1 : 0, // Now off or on.
+                    getFullEnabledLocked() ? 1 : 0, // Now off or on.
+                    getAdaptiveEnabledLocked() ? 1 : 0, // Now off or on.
                     isInteractive ?  1 : 0, // Device interactive state.
                     enabled ? mBatterySaverPolicy.toEventLogString() : "",
                     reason);
 
-            mFullPreviouslyEnabled = mFullEnabled;
-            mAdaptivePreviouslyEnabled = mAdaptiveEnabled;
+            mFullPreviouslyEnabled = getFullEnabledLocked();
+            mAdaptivePreviouslyEnabled = getAdaptiveEnabledLocked();
 
             listeners = mListeners.toArray(new LowPowerModeListener[0]);
 
@@ -518,10 +526,40 @@
                 return;
             }
             mBatterySavingStats.transitionState(
-                    mFullEnabled ? BatterySaverState.ON :
-                            (mAdaptiveEnabled ? BatterySaverState.ADAPTIVE : BatterySaverState.OFF),
-                    isInteractive ? InteractiveState.INTERACTIVE : InteractiveState.NON_INTERACTIVE,
-                    dozeMode);
+                    getFullEnabledLocked() ? BatterySaverState.ON :
+                            (getAdaptiveEnabledLocked() ? BatterySaverState.ADAPTIVE :
+                            BatterySaverState.OFF),
+                            isInteractive ? InteractiveState.INTERACTIVE :
+                            InteractiveState.NON_INTERACTIVE,
+                            dozeMode);
         }
     }
+
+    @GuardedBy("mLock")
+    private void setFullEnabledLocked(boolean value) {
+        if (mFullEnabledRaw == value) {
+            return;
+        }
+        PowerManager.invalidatePowerSaveModeCaches();
+        mFullEnabledRaw = value;
+    }
+
+    /** Non-blocking getter exists as a reminder not to directly modify the cached field */
+    private boolean getFullEnabledLocked() {
+        return mFullEnabledRaw;
+    }
+
+    @GuardedBy("mLock")
+    private void setAdaptiveEnabledLocked(boolean value) {
+        if (mAdaptiveEnabledRaw == value) {
+            return;
+        }
+        PowerManager.invalidatePowerSaveModeCaches();
+        mAdaptiveEnabledRaw = value;
+    }
+
+    /** Non-blocking getter exists as a reminder not to directly modify the cached field */
+    private boolean getAdaptiveEnabledLocked() {
+        return mAdaptiveEnabledRaw;
+    }
 }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index 38bdc62..233417d 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -219,8 +219,12 @@
     static final int POLICY_LEVEL_ADAPTIVE = 1;
     static final int POLICY_LEVEL_FULL = 2;
 
+    /**
+     * Do not access directly; always use {@link #setPolicyLevel}
+     * and {@link #getPolicyLevelLocked}
+     */
     @GuardedBy("mLock")
-    private int mPolicyLevel = POLICY_LEVEL_OFF;
+    private int mPolicyLevelRaw = POLICY_LEVEL_OFF;
 
     private final Context mContext;
     private final ContentResolver mContentResolver;
@@ -290,6 +294,11 @@
         return R.string.config_batterySaverDeviceSpecificConfig;
     }
 
+    @VisibleForTesting
+    void invalidatePowerSaveModeCaches() {
+        PowerManager.invalidatePowerSaveModeCaches();
+    }
+
     @Override
     public void onChange(boolean selfChange, Uri uri) {
         refreshSettings();
@@ -373,14 +382,14 @@
         boolean changed = false;
         Policy newFullPolicy = Policy.fromSettings(setting, deviceSpecificSetting,
                 DEFAULT_FULL_POLICY);
-        if (mPolicyLevel == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
+        if (getPolicyLevelLocked() == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
             changed = true;
         }
         mFullPolicy = newFullPolicy;
 
         mDefaultAdaptivePolicy = Policy.fromSettings(adaptiveSetting, adaptiveDeviceSpecificSetting,
                 DEFAULT_ADAPTIVE_POLICY);
-        if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE
+        if (getPolicyLevelLocked() == POLICY_LEVEL_ADAPTIVE
                 && !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) {
             changed = true;
         }
@@ -882,14 +891,14 @@
      */
     boolean setPolicyLevel(@PolicyLevel int level) {
         synchronized (mLock) {
-            if (mPolicyLevel == level) {
+            if (getPolicyLevelLocked() == level) {
                 return false;
             }
             switch (level) {
                 case POLICY_LEVEL_FULL:
                 case POLICY_LEVEL_ADAPTIVE:
                 case POLICY_LEVEL_OFF:
-                    mPolicyLevel = level;
+                    setPolicyLevelLocked(level);
                     break;
                 default:
                     Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level);
@@ -911,7 +920,7 @@
         }
 
         mAdaptivePolicy = p;
-        if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE) {
+        if (getPolicyLevelLocked() == POLICY_LEVEL_ADAPTIVE) {
             updatePolicyDependenciesLocked();
             return true;
         }
@@ -924,7 +933,7 @@
     }
 
     private Policy getCurrentPolicyLocked() {
-        switch (mPolicyLevel) {
+        switch (getPolicyLevelLocked()) {
             case POLICY_LEVEL_FULL:
                 return mFullPolicy;
             case POLICY_LEVEL_ADAPTIVE:
@@ -985,7 +994,7 @@
             pw.println("    value: " + mAdaptiveDeviceSpecificSettings);
 
             pw.println("  mAccessibilityEnabled=" + mAccessibilityEnabled);
-            pw.println("  mPolicyLevel=" + mPolicyLevel);
+            pw.println("  mPolicyLevel=" + getPolicyLevelLocked());
 
             dumpPolicyLocked(pw, "  ", "full", mFullPolicy);
             dumpPolicyLocked(pw, "  ", "default adaptive", mDefaultAdaptivePolicy);
@@ -1067,4 +1076,20 @@
             updatePolicyDependenciesLocked();
         }
     }
+
+    /** Non-blocking getter exists as a reminder not to modify cached fields directly */
+    @GuardedBy("mLock")
+    private int getPolicyLevelLocked() {
+        return mPolicyLevelRaw;
+    }
+
+    @GuardedBy("mLock")
+    private void setPolicyLevelLocked(int level) {
+        if (mPolicyLevelRaw == level) {
+            return;
+        }
+        // Under lock, invalidate before set ensures caches won't return stale values.
+        invalidatePowerSaveModeCaches();
+        mPolicyLevelRaw = level;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
index 7666ab9..1c2d8e8 100644
--- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
@@ -45,6 +45,7 @@
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.server.LocalServices;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.batterysaver.BatterySaverController;
 import com.android.server.power.batterysaver.BatterySaverPolicy;
 import com.android.server.power.batterysaver.BatterySavingStats;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -61,6 +62,7 @@
     private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
     private static final int USER_ID = 0;
 
+    @Mock private BatterySaverController mBatterySaverControllerMock;
     @Mock private BatterySaverPolicy mBatterySaverPolicyMock;
     @Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
     @Mock private Notifier mNotifierMock;
@@ -223,6 +225,13 @@
         }
 
         @Override
+        BatterySaverController createBatterySaverController(
+                Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+                BatterySavingStats batterySavingStats) {
+            return mBatterySaverControllerMock;
+        }
+
+        @Override
         PowerManagerService.NativeWrapper createNativeWrapper() {
             return mNativeWrapperMock;
         }
@@ -247,6 +256,11 @@
         public SystemPropertiesWrapper createSystemPropertiesWrapper() {
             return mSystemPropertiesMock;
         }
+
+        @Override
+        void invalidateIsInteractiveCaches() {
+            // Avoids an SELinux denial.
+        }
     };
 
     private void enableChargingFeedback(boolean chargingFeedbackEnabled, boolean dndOn) {
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 811089a..0ee2f55 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -81,6 +81,7 @@
 import com.android.server.power.PowerManagerService.Injector;
 import com.android.server.power.PowerManagerService.NativeWrapper;
 import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
+import com.android.server.power.batterysaver.BatterySaverController;
 import com.android.server.power.batterysaver.BatterySaverPolicy;
 import com.android.server.power.batterysaver.BatterySavingStats;
 
@@ -106,6 +107,7 @@
     private static final float BRIGHTNESS_FACTOR = 0.7f;
     private static final boolean BATTERY_SAVER_ENABLED = true;
 
+    @Mock private BatterySaverController mBatterySaverControllerMock;
     @Mock private BatterySaverPolicy mBatterySaverPolicyMock;
     @Mock private LightsManager mLightsManagerMock;
     @Mock private DisplayManagerInternal mDisplayManagerInternalMock;
@@ -207,6 +209,13 @@
             }
 
             @Override
+            BatterySaverController createBatterySaverController(
+                    Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+                    BatterySavingStats batterySavingStats) {
+                return mBatterySaverControllerMock;
+            }
+
+            @Override
             NativeWrapper createNativeWrapper() {
                 return mNativeWrapperMock;
             }
@@ -231,6 +240,11 @@
             public SystemPropertiesWrapper createSystemPropertiesWrapper() {
                 return mSystemPropertiesMock;
             }
+
+            @Override
+            void invalidateIsInteractiveCaches() {
+                // Avoids an SELinux failure.
+            }
         });
         return mService;
     }
@@ -369,7 +383,7 @@
     @Test
     public void testWakefulnessAwake_InitialValue() throws Exception {
         createService();
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
     }
 
     @Test
@@ -377,12 +391,12 @@
         createService();
         // Start with AWAKE state
         startSystem();
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
 
         // Take a nap and verify.
         mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
                 PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 
     @Test
@@ -399,21 +413,21 @@
         int flags = PowerManager.FULL_WAKE_LOCK;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
                 null /* workSource */, null /* historyTag */);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
 
         // Ensure that the flag does *NOT* work with a partial wake lock.
         flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
                 null /* workSource */, null /* historyTag */);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
 
         // Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK
         flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
                 null /* workSource */, null /* historyTag */);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
     }
 
@@ -424,7 +438,7 @@
         forceSleep();
         mService.getBinderServiceInstance().wakeUp(SystemClock.uptimeMillis(),
                 PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
     }
 
     /**
@@ -445,7 +459,7 @@
                 .thenReturn(false);
         mService.readConfigurationLocked();
         setPluggedIn(true);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
                 .thenReturn(true);
         mService.readConfigurationLocked();
@@ -460,20 +474,20 @@
         when(mWirelessChargerDetectorMock.update(true /* isPowered */,
                 BatteryManager.BATTERY_PLUGGED_WIRELESS)).thenReturn(false);
         setPluggedIn(true);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
 
         // Test 3:
         // Do not wake up if the phone is being REMOVED from a wireless charger
         when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
         setPluggedIn(false);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
 
         // Test 4:
         // Do not wake if we are dreaming.
         forceAwake();  // Needs to be awake first before it can dream.
         forceDream();
         setPluggedIn(true);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DREAMING);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
         forceSleep();
 
         // Test 5:
@@ -486,7 +500,7 @@
                 com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug))
                 .thenReturn(false);
         setPluggedIn(false);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         Settings.Global.putInt(
                 mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
         mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
@@ -499,14 +513,14 @@
         forceAwake();
         forceDozing();
         setPluggedIn(true);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
 
         // Test 7:
         // Finally, take away all the factors above and ensure the device wakes up!
         forceAwake();
         forceSleep();
         setPluggedIn(false);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
     }
 
     @Test
@@ -514,12 +528,12 @@
         createService();
         // Start with AWAKE state
         startSystem();
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
 
         // Take a nap and verify.
         mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
                 PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
     }
 
     @Test
@@ -546,12 +560,12 @@
         mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
         // Verify that we start awake
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
 
         // Grab the wakefulness value when PowerManager finally calls into the
         // native component to actually perform the suspend.
         when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> {
-            assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+            assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
             return true;
         });
 
@@ -559,7 +573,7 @@
         assertThat(retval).isTrue();
 
         // Still asleep when the function returns.
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 
     @Test
@@ -592,7 +606,7 @@
         mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
         // Verify that we start awake
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
 
         // Create a wakelock
         mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
@@ -647,7 +661,7 @@
 
         // Start with AWAKE state
         startSystem();
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         assertTrue(isAcquired[0]);
 
         // Take a nap and verify we no longer hold the blocker
@@ -657,7 +671,7 @@
         when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
         mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
                 PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
         assertFalse(isAcquired[0]);
 
         // Override the display state by DreamManager and verify is reacquires the blocker.
@@ -737,7 +751,7 @@
         createService();
         startSystem();
         SystemClock.sleep(20);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 
     @FlakyTest
@@ -757,7 +771,7 @@
                 null /* workSource */, null /* historyTag */);
 
         SystemClock.sleep(11);
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
     }
 
     @Test
@@ -765,7 +779,7 @@
         createService();
         startSystem();
 
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
     }
 
@@ -784,7 +798,7 @@
         createService();
         startSystem();
 
-        assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
         verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
                 anyLong());
     }
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
index 98cfc41..30ab9cd 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
@@ -78,6 +78,11 @@
             return mDeviceSpecificConfigResId;
         }
 
+        @Override
+        void invalidatePowerSaveModeCaches() {
+            // Avoids an SELinux denial.
+        }
+
         @VisibleForTesting
         void onChange() {
             onChange(true, null);