1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.power.batterysaver;
17 
18 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyBoolean;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.Mockito.doAnswer;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.app.NotificationManager;
34 import android.content.ContentResolver;
35 import android.content.Context;
36 import android.content.res.Resources;
37 import android.os.PowerManager;
38 import android.provider.Settings.Global;
39 
40 import androidx.test.filters.SmallTest;
41 import androidx.test.runner.AndroidJUnit4;
42 
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.mockito.InOrder;
47 
48 import java.util.HashMap;
49 import java.util.Objects;
50 
51 /**
52  * atest com.android.server.power.batterysaver.BatterySaverStateMachineTest
53  */
54 @SmallTest
55 @RunWith(AndroidJUnit4.class)
56 public class BatterySaverStateMachineTest {
57 
58     private Context mMockContext;
59     private ContentResolver mMockContextResolver;
60     private BatterySaverController mMockBatterySaverController;
61     private NotificationManager mMockNotificationManager;
62     private Device mDevice;
63     private TestableBatterySaverStateMachine mTarget;
64     private Resources mMockResources;
65 
66     private DevicePersistedState mPersistedState;
67 
68     private class DevicePersistedState {
69         // Current battery level.
70         public int batteryLevel = 100;
71 
72         // Whether battery level is currently low or not.
73         public boolean batteryLow = false;
74 
75         // Whether the device is plugged in or not.
76         public boolean powered = false;
77 
78         // Global settings.
79         public final HashMap<String, Integer> global = new HashMap<>();
80     }
81 
82     /**
83      * This class simulates a device's volatile status that will be reset by {@link #initDevice()}.
84      */
85     private class Device {
86         public boolean batterySaverEnabled = false;
87 
getLowPowerModeTriggerLevel()88         public int getLowPowerModeTriggerLevel() {
89             return mPersistedState.global.getOrDefault(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
90         }
91 
setBatteryLevel(int level)92         public void setBatteryLevel(int level) {
93             mPersistedState.batteryLevel = level;
94             if (mPersistedState.batteryLevel <= Math.max(15, getLowPowerModeTriggerLevel())) {
95                 mPersistedState.batteryLow = true;
96             } else if (mPersistedState.batteryLow
97                     && (mPersistedState.batteryLevel >= (getLowPowerModeTriggerLevel() + 5))) {
98                 mPersistedState.batteryLow = false;
99             }
100             pushBatteryStatus();
101         }
102 
setPowered(boolean newPowered)103         public void setPowered(boolean newPowered) {
104             mPersistedState.powered = newPowered;
105             pushBatteryStatus();
106         }
107 
pushBatteryStatus()108         public void pushBatteryStatus() {
109             mTarget.setBatteryStatus(mPersistedState.powered, mPersistedState.batteryLevel,
110                     mPersistedState.batteryLow);
111         }
112 
pushGlobalSettings()113         public void pushGlobalSettings() {
114             mTarget.setSettingsLocked(
115                     mPersistedState.global.getOrDefault(Global.LOW_POWER_MODE, 0) != 0,
116                     mPersistedState.global.getOrDefault(Global.LOW_POWER_MODE_STICKY, 0) != 0,
117                     mDevice.getLowPowerModeTriggerLevel(),
118                     mPersistedState.global.getOrDefault(
119                             Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0) != 0,
120                     mPersistedState.global.getOrDefault(
121                             Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90),
122                     mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVE_MODE, 0),
123                     mPersistedState.global.getOrDefault(
124                             Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0,
125                     mPersistedState.global.getOrDefault(
126                             Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 100));
127         }
128 
putGlobalSetting(String key, int value)129         public void putGlobalSetting(String key, int value) {
130             mPersistedState.global.put(key, value);
131             pushGlobalSettings();
132         }
133 
getGlobalSetting(String key, int defValue)134         public int getGlobalSetting(String key, int defValue) {
135             return mPersistedState.global.getOrDefault(key, defValue);
136         }
137     }
138 
139     /**
140      * Test target class.
141      */
142     private class TestableBatterySaverStateMachine extends BatterySaverStateMachine {
TestableBatterySaverStateMachine()143         TestableBatterySaverStateMachine() {
144             super(new Object(), mMockContext, mMockBatterySaverController);
145         }
146 
147         @Override
putGlobalSetting(String key, int value)148         protected void putGlobalSetting(String key, int value) {
149             if (Objects.equals(mPersistedState.global.get(key), value)) {
150                 return;
151             }
152             mDevice.putGlobalSetting(key, value);
153         }
154 
155         @Override
getGlobalSetting(String key, int defValue)156         protected int getGlobalSetting(String key, int defValue) {
157             return mDevice.getGlobalSetting(key, defValue);
158         }
159 
160         @Override
runOnBgThread(Runnable r)161         void runOnBgThread(Runnable r) {
162             r.run();
163         }
164 
165         @Override
runOnBgThreadLazy(Runnable r, int delayMillis)166         void runOnBgThreadLazy(Runnable r, int delayMillis) {
167             r.run();
168         }
169 
170         @Override
triggerDynamicModeNotification()171         void triggerDynamicModeNotification() {
172             // Do nothing
173         }
174     }
175 
176     @Before
setUp()177     public void setUp() {
178         mMockContext = mock(Context.class);
179         mMockContextResolver = mock(ContentResolver.class);
180         mMockBatterySaverController = mock(BatterySaverController.class);
181         mMockNotificationManager = mock(NotificationManager.class);
182         mMockResources = mock(Resources.class);
183 
184         doReturn(mMockContextResolver).when(mMockContext).getContentResolver();
185         doReturn(mMockResources).when(mMockContext).getResources();
186         doReturn(mMockNotificationManager).when(mMockContext)
187                 .getSystemService(NotificationManager.class);
188         doAnswer((inv) -> mDevice.batterySaverEnabled = inv.getArgument(0))
189                 .when(mMockBatterySaverController).enableBatterySaver(anyBoolean(), anyInt());
190         doReturn(true).when(mMockBatterySaverController)
191                 .setAdaptivePolicyLocked(any(BatterySaverPolicy.Policy.class), anyInt());
192         when(mMockBatterySaverController.isEnabled())
193                 .thenAnswer((inv) -> mDevice.batterySaverEnabled);
194         when(mMockBatterySaverController.isFullEnabled())
195                 .thenAnswer((inv) -> mDevice.batterySaverEnabled);
196         when(mMockResources.getBoolean(
197                 com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled))
198                 .thenReturn(false);
199         when(mMockResources.getInteger(
200                 com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold))
201                 .thenReturn(80);
202 
203         mPersistedState = new DevicePersistedState();
204         initDevice();
205     }
206 
initDevice()207     private void initDevice() {
208         mDevice = new Device();
209 
210         mTarget = new TestableBatterySaverStateMachine();
211         spyOn(mTarget);
212         doNothing().when(mTarget).triggerStickyDisabledNotification();
213 
214         mDevice.pushBatteryStatus();
215         mTarget.onBootCompleted();
216     }
217 
218     @Test
testNoAutoBatterySaver()219     public void testNoAutoBatterySaver() {
220         assertEquals(0, mDevice.getLowPowerModeTriggerLevel());
221 
222         assertEquals(false, mDevice.batterySaverEnabled);
223         assertEquals(100, mPersistedState.batteryLevel);
224         assertEquals(false, mPersistedState.batteryLow);
225 
226         mDevice.setBatteryLevel(90);
227 
228         assertEquals(false, mDevice.batterySaverEnabled);
229         assertEquals(90, mPersistedState.batteryLevel);
230         assertEquals(false, mPersistedState.batteryLow);
231 
232         mDevice.setBatteryLevel(50);
233 
234         assertEquals(false, mDevice.batterySaverEnabled);
235         assertEquals(50, mPersistedState.batteryLevel);
236         assertEquals(false, mPersistedState.batteryLow);
237 
238         mDevice.setBatteryLevel(16);
239 
240         assertEquals(false, mDevice.batterySaverEnabled);
241         assertEquals(16, mPersistedState.batteryLevel);
242         assertEquals(false, mPersistedState.batteryLow);
243 
244         // When LOW_POWER_MODE_TRIGGER_LEVEL is 0, 15% will still trigger low-battery, but
245         // BS wont be enabled.
246         mDevice.setBatteryLevel(15);
247 
248         assertEquals(false, mDevice.batterySaverEnabled);
249         assertEquals(15, mPersistedState.batteryLevel);
250         assertEquals(true, mPersistedState.batteryLow);
251 
252         mDevice.setBatteryLevel(10);
253 
254         assertEquals(false, mDevice.batterySaverEnabled);
255         assertEquals(10, mPersistedState.batteryLevel);
256         assertEquals(true, mPersistedState.batteryLow);
257 
258         // Manually enable BS.
259         mTarget.setBatterySaverEnabledManually(true);
260 
261         assertEquals(true, mDevice.batterySaverEnabled);
262         assertEquals(10, mPersistedState.batteryLevel);
263         assertEquals(true, mPersistedState.batteryLow);
264 
265         mDevice.setBatteryLevel(50);
266 
267         assertEquals(true, mDevice.batterySaverEnabled);
268         assertEquals(50, mPersistedState.batteryLevel);
269         assertEquals(false, mPersistedState.batteryLow);
270 
271         // Start charging. It'll disable BS.
272         mDevice.setPowered(true);
273 
274         assertEquals(false, mDevice.batterySaverEnabled);
275         assertEquals(50, mPersistedState.batteryLevel);
276         assertEquals(false, mPersistedState.batteryLow);
277 
278         mDevice.setBatteryLevel(60);
279 
280         assertEquals(false, mDevice.batterySaverEnabled);
281         assertEquals(60, mPersistedState.batteryLevel);
282         assertEquals(false, mPersistedState.batteryLow);
283 
284         // Unplug.
285         mDevice.setPowered(false);
286 
287         assertEquals(true, mDevice.batterySaverEnabled);
288         assertEquals(60, mPersistedState.batteryLevel);
289         assertEquals(false, mPersistedState.batteryLow);
290 
291         mDevice.setBatteryLevel(10);
292 
293         assertEquals(true, mDevice.batterySaverEnabled);
294         assertEquals(10, mPersistedState.batteryLevel);
295         assertEquals(true, mPersistedState.batteryLow);
296 
297         mDevice.setBatteryLevel(80);
298 
299         assertEquals(true, mDevice.batterySaverEnabled);
300         assertEquals(80, mPersistedState.batteryLevel);
301         assertEquals(false, mPersistedState.batteryLow);
302 
303         // Reboot the device.
304         initDevice();
305 
306         assertEquals(true, mDevice.batterySaverEnabled); // Sticky.
307         assertEquals(80, mPersistedState.batteryLevel);
308         assertEquals(false, mPersistedState.batteryLow);
309 
310         mDevice.setBatteryLevel(30);
311         initDevice();
312 
313         assertEquals(true, mDevice.batterySaverEnabled); // Still sticky.
314         assertEquals(30, mPersistedState.batteryLevel);
315         assertEquals(false, mPersistedState.batteryLow);
316 
317         mTarget.setBatterySaverEnabledManually(false);
318 
319         assertEquals(false, mDevice.batterySaverEnabled);
320         assertEquals(30, mPersistedState.batteryLevel);
321         assertEquals(false, mPersistedState.batteryLow);
322 
323         initDevice(); // reboot.
324 
325         assertEquals(false, mDevice.batterySaverEnabled);
326         assertEquals(30, mPersistedState.batteryLevel);
327         assertEquals(false, mPersistedState.batteryLow);
328     }
329 
330     @Test
testAutoBatterySaver()331     public void testAutoBatterySaver() {
332         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
333         mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
334 
335         assertEquals(false, mDevice.batterySaverEnabled);
336         assertEquals(100, mPersistedState.batteryLevel);
337         assertEquals(false, mPersistedState.batteryLow);
338 
339         mDevice.setBatteryLevel(90);
340 
341         assertEquals(false, mDevice.batterySaverEnabled);
342         assertEquals(90, mPersistedState.batteryLevel);
343         assertEquals(false, mPersistedState.batteryLow);
344 
345         mDevice.setBatteryLevel(51);
346 
347         assertEquals(false, mDevice.batterySaverEnabled);
348         assertEquals(51, mPersistedState.batteryLevel);
349         assertEquals(false, mPersistedState.batteryLow);
350 
351         // Hit the threshold. BS should be enabled.
352         mDevice.setBatteryLevel(50);
353 
354         assertEquals(true, mDevice.batterySaverEnabled);
355         assertEquals(50, mPersistedState.batteryLevel);
356         assertEquals(true, mPersistedState.batteryLow);
357 
358         // Battery goes up, but until it hits 55%, we still keep BS on.
359         mDevice.setBatteryLevel(54);
360 
361         assertEquals(true, mDevice.batterySaverEnabled);
362         assertEquals(54, mPersistedState.batteryLevel);
363         assertEquals(true, mPersistedState.batteryLow);
364 
365         // 50% + 5%, now BS will be off.
366         mDevice.setBatteryLevel(55);
367 
368         assertEquals(false, mDevice.batterySaverEnabled);
369         assertEquals(55, mPersistedState.batteryLevel);
370         assertEquals(false, mPersistedState.batteryLow);
371 
372         mDevice.setBatteryLevel(40);
373 
374         assertEquals(true, mDevice.batterySaverEnabled);
375         assertEquals(40, mPersistedState.batteryLevel);
376         assertEquals(true, mPersistedState.batteryLow);
377 
378         mDevice.setPowered(true);
379 
380         assertEquals(false, mDevice.batterySaverEnabled);
381         assertEquals(40, mPersistedState.batteryLevel);
382         assertEquals(true, mPersistedState.batteryLow);
383 
384         mDevice.setPowered(false);
385 
386         assertEquals(true, mDevice.batterySaverEnabled);
387         assertEquals(40, mPersistedState.batteryLevel);
388         assertEquals(true, mPersistedState.batteryLow);
389 
390         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
391 
392         assertEquals(false, mDevice.batterySaverEnabled);
393         assertEquals(40, mPersistedState.batteryLevel);
394         assertEquals(true, mPersistedState.batteryLow);
395 
396         mDevice.setBatteryLevel(30);
397 
398         assertEquals(false, mDevice.batterySaverEnabled);
399         assertEquals(30, mPersistedState.batteryLevel);
400         assertEquals(true, mPersistedState.batteryLow);
401 
402         // Plug in and out, snooze will reset.
403         mDevice.setPowered(true);
404         mDevice.setPowered(false);
405 
406         assertEquals(true, mDevice.batterySaverEnabled);
407         assertEquals(30, mPersistedState.batteryLevel);
408         assertEquals(true, mPersistedState.batteryLow);
409 
410         mDevice.setPowered(true);
411         mDevice.setBatteryLevel(60);
412 
413         assertEquals(false, mDevice.batterySaverEnabled);
414         assertEquals(60, mPersistedState.batteryLevel);
415         assertEquals(false, mPersistedState.batteryLow);
416 
417         mDevice.setPowered(false);
418 
419         assertEquals(false, mDevice.batterySaverEnabled);
420         assertEquals(60, mPersistedState.batteryLevel);
421         assertEquals(false, mPersistedState.batteryLow);
422 
423         mDevice.setBatteryLevel(50);
424 
425         assertEquals(true, mDevice.batterySaverEnabled);
426         assertEquals(50, mPersistedState.batteryLevel);
427         assertEquals(true, mPersistedState.batteryLow);
428 
429         mDevice.setBatteryLevel(70);
430 
431         assertEquals(false, mDevice.batterySaverEnabled);
432         assertEquals(70, mPersistedState.batteryLevel);
433         assertEquals(false, mPersistedState.batteryLow);
434 
435         // Bump up the threshold.
436         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 70);
437         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
438 
439         assertEquals(true, mDevice.batterySaverEnabled);
440         assertEquals(70, mPersistedState.batteryLevel);
441         assertEquals(true, mPersistedState.batteryLow);
442 
443         // Then down.
444         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 60);
445         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
446 
447         assertEquals(false, mDevice.batterySaverEnabled);
448         assertEquals(70, mPersistedState.batteryLevel);
449         assertEquals(false, mPersistedState.batteryLow);
450 
451         // Reboot in low state -> automatically enable BS.
452         mDevice.setPowered(false);
453         mDevice.setBatteryLevel(30);
454         mTarget.setBatterySaverEnabledManually(false);
455 
456         assertEquals(false, mDevice.batterySaverEnabled);
457         assertEquals(30, mPersistedState.batteryLevel);
458         assertEquals(true, mPersistedState.batteryLow);
459 
460         initDevice();
461 
462         assertEquals(true, mDevice.batterySaverEnabled);
463         assertEquals(30, mPersistedState.batteryLevel);
464         assertEquals(true, mPersistedState.batteryLow);
465 
466         // Disable auto battery saver.
467         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
468         mDevice.setBatteryLevel(25);
469 
470         assertEquals(false, mDevice.batterySaverEnabled);
471         assertEquals(25, mPersistedState.batteryLevel);
472         assertEquals(false, mPersistedState.batteryLow);
473 
474         // PowerManager sets batteryLow to true at 15% if battery saver trigger level is lower.
475         mDevice.setBatteryLevel(15);
476 
477         assertEquals(false, mDevice.batterySaverEnabled);
478         assertEquals(15, mPersistedState.batteryLevel);
479         assertEquals(true, mPersistedState.batteryLow);
480     }
481 
482     @Test
testAutoBatterySaver_withSticky_withAutoOffDisabled()483     public void testAutoBatterySaver_withSticky_withAutoOffDisabled() {
484         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
485         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0);
486 
487         mTarget.setBatterySaverEnabledManually(true);
488 
489         assertEquals(true, mDevice.batterySaverEnabled);
490         assertEquals(100, mPersistedState.batteryLevel);
491         assertEquals(false, mPersistedState.batteryLow);
492 
493         mDevice.setBatteryLevel(30);
494 
495         assertEquals(true, mDevice.batterySaverEnabled);
496         assertEquals(30, mPersistedState.batteryLevel);
497         assertEquals(true, mPersistedState.batteryLow);
498 
499         mDevice.setBatteryLevel(80);
500 
501         assertEquals(true, mDevice.batterySaverEnabled); // Still enabled.
502         assertEquals(80, mPersistedState.batteryLevel);
503         assertEquals(false, mPersistedState.batteryLow);
504 
505         mDevice.setPowered(true);
506 
507         assertEquals(false, mDevice.batterySaverEnabled);
508         assertEquals(80, mPersistedState.batteryLevel);
509         assertEquals(false, mPersistedState.batteryLow);
510 
511         mDevice.setBatteryLevel(30);
512 
513         assertEquals(false, mDevice.batterySaverEnabled);
514         assertEquals(30, mPersistedState.batteryLevel);
515         assertEquals(true, mPersistedState.batteryLow);
516 
517         mDevice.setPowered(false);
518 
519         assertEquals(true, mDevice.batterySaverEnabled); // Restores BS.
520         assertEquals(30, mPersistedState.batteryLevel);
521         assertEquals(true, mPersistedState.batteryLow);
522 
523         mDevice.setPowered(true);
524         mDevice.setBatteryLevel(90);
525 
526         assertEquals(false, mDevice.batterySaverEnabled);
527         assertEquals(90, mPersistedState.batteryLevel);
528         assertEquals(false, mPersistedState.batteryLow);
529 
530         initDevice();
531 
532         assertEquals(false, mDevice.batterySaverEnabled);
533         assertEquals(90, mPersistedState.batteryLevel);
534         assertEquals(false, mPersistedState.batteryLow);
535 
536         mDevice.setPowered(false);
537 
538         assertEquals(true, mDevice.batterySaverEnabled);
539         assertEquals(90, mPersistedState.batteryLevel);
540         assertEquals(false, mPersistedState.batteryLow);
541 
542         mTarget.setBatterySaverEnabledManually(false);
543 
544         assertEquals(false, mDevice.batterySaverEnabled);
545         assertEquals(90, mPersistedState.batteryLevel);
546         assertEquals(false, mPersistedState.batteryLow);
547 
548         initDevice();
549 
550         assertEquals(false, mDevice.batterySaverEnabled);
551         assertEquals(90, mPersistedState.batteryLevel);
552         assertEquals(false, mPersistedState.batteryLow);
553     }
554 
555     @Test
testAutoBatterySaver_withSticky_withAutoOffEnabled()556     public void testAutoBatterySaver_withSticky_withAutoOffEnabled() {
557         InOrder inOrder = inOrder(mTarget);
558 
559         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
560         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
561         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90);
562 
563         // Scenario 1: User turns BS on manually above the threshold, it shouldn't turn off even
564         // with battery level change above threshold.
565         mDevice.setBatteryLevel(100);
566         mTarget.setBatterySaverEnabledManually(true);
567 
568         assertEquals(true, mDevice.batterySaverEnabled);
569         assertEquals(100, mPersistedState.batteryLevel);
570         assertEquals(false, mPersistedState.batteryLow);
571 
572         mDevice.setBatteryLevel(97);
573 
574         assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
575         assertEquals(97, mPersistedState.batteryLevel);
576         assertEquals(false, mPersistedState.batteryLow);
577 
578         mDevice.setBatteryLevel(95);
579 
580         assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
581         assertEquals(95, mPersistedState.batteryLevel);
582         assertEquals(false, mPersistedState.batteryLow);
583         inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
584 
585         // Scenario 2: User turns BS on manually above the threshold then charges device. BS
586         // shouldn't turn back on.
587         mDevice.setPowered(true);
588 
589         assertEquals(false, mDevice.batterySaverEnabled);
590         assertEquals(95, mPersistedState.batteryLevel);
591         assertEquals(false, mPersistedState.batteryLow);
592 
593         mDevice.setBatteryLevel(97);
594         mDevice.setPowered(false);
595 
596         assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
597         assertEquals(97, mPersistedState.batteryLevel);
598         assertEquals(false, mPersistedState.batteryLow);
599         inOrder.verify(mTarget).triggerStickyDisabledNotification();
600 
601         // Scenario 3: User turns BS on manually above the threshold. Device drains below
602         // threshold and then charged to below threshold. Sticky BS should activate.
603         mTarget.setBatterySaverEnabledManually(true);
604         mDevice.setBatteryLevel(30);
605 
606         assertEquals(true, mDevice.batterySaverEnabled);
607         assertEquals(30, mPersistedState.batteryLevel);
608         assertEquals(true, mPersistedState.batteryLow);
609 
610         mDevice.setPowered(true);
611         mDevice.setBatteryLevel(80);
612 
613         assertEquals(false, mDevice.batterySaverEnabled);
614         assertEquals(80, mPersistedState.batteryLevel);
615         assertEquals(false, mPersistedState.batteryLow);
616 
617         mDevice.setPowered(false);
618 
619         assertEquals(true, mDevice.batterySaverEnabled); // Still enabled.
620         assertEquals(80, mPersistedState.batteryLevel);
621         assertEquals(false, mPersistedState.batteryLow);
622 
623         mDevice.setBatteryLevel(30);
624 
625         assertEquals(true, mDevice.batterySaverEnabled);
626         assertEquals(30, mPersistedState.batteryLevel);
627         assertEquals(true, mPersistedState.batteryLow);
628         inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
629 
630         // Scenario 4: User turns BS on manually above the threshold. Device drains below
631         // threshold and is eventually charged to above threshold. Sticky BS should turn off.
632         mDevice.setPowered(true);
633         mDevice.setBatteryLevel(90);
634 
635         assertEquals(false, mDevice.batterySaverEnabled);
636         assertEquals(90, mPersistedState.batteryLevel);
637         assertEquals(false, mPersistedState.batteryLow);
638 
639         mDevice.setPowered(false);
640 
641         assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
642         assertEquals(90, mPersistedState.batteryLevel);
643         assertEquals(false, mPersistedState.batteryLow);
644         inOrder.verify(mTarget).triggerStickyDisabledNotification();
645 
646         // Scenario 5: User turns BS on manually below threshold and charges to below threshold.
647         // Sticky BS should activate.
648         mDevice.setBatteryLevel(70);
649 
650         assertEquals(false, mDevice.batterySaverEnabled);
651         assertEquals(70, mPersistedState.batteryLevel);
652         assertEquals(false, mPersistedState.batteryLow);
653 
654         mTarget.setBatterySaverEnabledManually(true);
655 
656         assertEquals(true, mDevice.batterySaverEnabled);
657         assertEquals(70, mPersistedState.batteryLevel);
658         assertEquals(false, mPersistedState.batteryLow);
659 
660         mDevice.setPowered(true);
661         mDevice.setBatteryLevel(80);
662 
663         assertEquals(false, mDevice.batterySaverEnabled);
664         assertEquals(80, mPersistedState.batteryLevel);
665         assertEquals(false, mPersistedState.batteryLow);
666 
667         mDevice.setPowered(false);
668 
669         assertEquals(true, mDevice.batterySaverEnabled); // Sticky BS still on.
670         assertEquals(80, mPersistedState.batteryLevel);
671         assertEquals(false, mPersistedState.batteryLow);
672         inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
673 
674         // Scenario 6: User turns BS on manually below threshold and eventually charges to above
675         // threshold. Sticky BS should turn off.
676 
677         mDevice.setPowered(true);
678         mDevice.setBatteryLevel(95);
679         mDevice.setPowered(false);
680 
681         assertEquals(false, mDevice.batterySaverEnabled);
682         assertEquals(95, mPersistedState.batteryLevel);
683         assertEquals(false, mPersistedState.batteryLow);
684         inOrder.verify(mTarget).triggerStickyDisabledNotification();
685 
686         // Scenario 7: User turns BS on above threshold and then reboots device. Sticky BS
687         // shouldn't activate.
688         mTarget.setBatterySaverEnabledManually(true);
689         mPersistedState.batteryLevel = 93;
690 
691         initDevice();
692 
693         assertEquals(false, mDevice.batterySaverEnabled);
694         assertEquals(93, mPersistedState.batteryLevel);
695         assertEquals(false, mPersistedState.batteryLow);
696         // initDevice() changes the mTarget reference, so inOrder is invalid here.
697         verify(mTarget).triggerStickyDisabledNotification();
698 
699         // Scenario 8: User turns BS on below threshold and then reboots device without charging.
700         // Sticky BS should activate.
701         mDevice.setBatteryLevel(75);
702         mTarget.setBatterySaverEnabledManually(true);
703         assertEquals(true, mDevice.batterySaverEnabled);
704         assertEquals(75, mPersistedState.batteryLevel);
705         assertEquals(false, mPersistedState.batteryLow);
706 
707         initDevice();
708 
709         assertEquals(true, mDevice.batterySaverEnabled);
710         assertEquals(75, mPersistedState.batteryLevel);
711         assertEquals(false, mPersistedState.batteryLow);
712         // initDevice() changes the mTarget reference, so inOrder is invalid here.
713         verify(mTarget, never()).triggerStickyDisabledNotification();
714 
715         // Scenario 9: User turns BS on below threshold and then reboots device after charging
716         // above threshold. Sticky BS shouldn't activate.
717         mDevice.setBatteryLevel(80);
718         mTarget.setBatterySaverEnabledManually(true);
719         mPersistedState.batteryLevel = 100;
720 
721         initDevice();
722 
723         assertEquals(false, mDevice.batterySaverEnabled);
724         assertEquals(100, mPersistedState.batteryLevel);
725         assertEquals(false, mPersistedState.batteryLow);
726         // initDevice() changes the mTarget reference, so inOrder is invalid here.
727         verify(mTarget).triggerStickyDisabledNotification();
728 
729         // Scenario 10: Somehow autoDisableLevel is set to a value below lowPowerModeTriggerLevel
730         // and then user enables manually above both thresholds, discharges below
731         // autoDisableLevel and then charges up to between autoDisableLevel and
732         // lowPowerModeTriggerLevel. Sticky BS shouldn't activate, but BS should still be on
733         // because the level is below lowPowerModeTriggerLevel.
734         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 75);
735         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
736         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 60);
737         initDevice();
738 
739         mDevice.setBatteryLevel(90);
740         mTarget.setBatterySaverEnabledManually(true);
741 
742         assertEquals(true, mDevice.batterySaverEnabled);
743         assertEquals(90, mPersistedState.batteryLevel);
744         assertEquals(false, mPersistedState.batteryLow);
745 
746         mDevice.setBatteryLevel(50);
747 
748         assertEquals(true, mDevice.batterySaverEnabled);
749         assertEquals(50, mPersistedState.batteryLevel);
750         assertEquals(true, mPersistedState.batteryLow);
751 
752         mDevice.setPowered(true);
753         mDevice.setBatteryLevel(65);
754 
755         assertEquals(false, mDevice.batterySaverEnabled);
756         assertEquals(65, mPersistedState.batteryLevel);
757         assertEquals(true, mPersistedState.batteryLow);
758 
759         mDevice.setPowered(false);
760 
761         assertEquals(true, mDevice.batterySaverEnabled);
762         assertEquals(65, mPersistedState.batteryLevel);
763         assertEquals(true, mPersistedState.batteryLow);
764         // initDevice() changes the mTarget reference, so inOrder is invalid here.
765         verify(mTarget, never()).triggerStickyDisabledNotification();
766     }
767 
768     @Test
testAutoBatterySaver_withSticky_withAutoOffToggled()769     public void testAutoBatterySaver_withSticky_withAutoOffToggled() {
770         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
771         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
772         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90);
773 
774         // Scenario 1: User turns BS on manually above the threshold, it shouldn't turn off even
775         // with battery level change above threshold.
776         mDevice.setBatteryLevel(100);
777         mTarget.setBatterySaverEnabledManually(true);
778 
779         assertEquals(true, mDevice.batterySaverEnabled);
780         assertEquals(100, mPersistedState.batteryLevel);
781         assertEquals(false, mPersistedState.batteryLow);
782 
783         mDevice.setBatteryLevel(95);
784 
785         assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
786         assertEquals(95, mPersistedState.batteryLevel);
787         assertEquals(false, mPersistedState.batteryLow);
788 
789         // Disable auto disable while in the pending sticky state. BS should reactivate after
790         // unplug.
791         mDevice.setPowered(true);
792         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0);
793         mDevice.setPowered(false);
794 
795         assertEquals(true, mDevice.batterySaverEnabled); // Sticky BS should activate.
796         assertEquals(95, mPersistedState.batteryLevel);
797         assertEquals(false, mPersistedState.batteryLow);
798 
799         // Enable auto disable while in the pending sticky state. Sticky should turn off after
800         // unplug.
801         mDevice.setPowered(true);
802         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
803         mDevice.setPowered(false);
804 
805         assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
806         assertEquals(95, mPersistedState.batteryLevel);
807         assertEquals(false, mPersistedState.batteryLow);
808         verify(mTarget).triggerStickyDisabledNotification();
809     }
810 
811     @Test
testAutoBatterySaver_withStickyDisabled()812     public void testAutoBatterySaver_withStickyDisabled() {
813         when(mMockResources.getBoolean(
814                 com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled))
815                 .thenReturn(true);
816         initDevice();
817         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
818         mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
819 
820         mTarget.setBatterySaverEnabledManually(true);
821 
822         assertEquals(true, mDevice.batterySaverEnabled);
823         assertEquals(100, mPersistedState.batteryLevel);
824         assertEquals(false, mPersistedState.batteryLow);
825 
826         mDevice.setBatteryLevel(30);
827 
828         assertEquals(true, mDevice.batterySaverEnabled);
829         assertEquals(30, mPersistedState.batteryLevel);
830         assertEquals(true, mPersistedState.batteryLow);
831 
832         mDevice.setPowered(true);
833         mDevice.setBatteryLevel(80);
834         mDevice.setPowered(false);
835 
836         assertEquals(false, mDevice.batterySaverEnabled); // Not sticky.
837         assertEquals(80, mPersistedState.batteryLevel);
838         assertEquals(false, mPersistedState.batteryLow);
839 
840         mDevice.setPowered(true);
841 
842         assertEquals(false, mDevice.batterySaverEnabled);
843         assertEquals(80, mPersistedState.batteryLevel);
844         assertEquals(false, mPersistedState.batteryLow);
845 
846         mDevice.setBatteryLevel(30);
847 
848         assertEquals(false, mDevice.batterySaverEnabled);
849         assertEquals(30, mPersistedState.batteryLevel);
850         assertEquals(true, mPersistedState.batteryLow);
851 
852         mDevice.setPowered(false);
853 
854         assertEquals(true, mDevice.batterySaverEnabled); // Restores BS.
855         assertEquals(30, mPersistedState.batteryLevel);
856         assertEquals(true, mPersistedState.batteryLow);
857 
858         mDevice.setPowered(true);
859         mDevice.setBatteryLevel(90);
860 
861         assertEquals(false, mDevice.batterySaverEnabled);
862         assertEquals(90, mPersistedState.batteryLevel);
863         assertEquals(false, mPersistedState.batteryLow);
864 
865         initDevice();
866 
867         assertEquals(false, mDevice.batterySaverEnabled);
868         assertEquals(90, mPersistedState.batteryLevel);
869         assertEquals(false, mPersistedState.batteryLow);
870 
871         mDevice.setPowered(false);
872 
873         assertEquals(false, mDevice.batterySaverEnabled);
874         assertEquals(90, mPersistedState.batteryLevel);
875         assertEquals(false, mPersistedState.batteryLow);
876 
877         mTarget.setBatterySaverEnabledManually(false);
878 
879         assertEquals(false, mDevice.batterySaverEnabled);
880         assertEquals(90, mPersistedState.batteryLevel);
881         assertEquals(false, mPersistedState.batteryLow);
882 
883         initDevice();
884 
885         assertEquals(false, mDevice.batterySaverEnabled);
886         assertEquals(90, mPersistedState.batteryLevel);
887         assertEquals(false, mPersistedState.batteryLow);
888     }
889 
890     @Test
testNoAutoBatterySaver_fromAdb()891     public void testNoAutoBatterySaver_fromAdb() {
892         assertEquals(0, mDevice.getLowPowerModeTriggerLevel());
893 
894         assertEquals(false, mDevice.batterySaverEnabled);
895         assertEquals(100, mPersistedState.batteryLevel);
896         assertEquals(false, mPersistedState.batteryLow);
897 
898         mDevice.setBatteryLevel(90);
899 
900         assertEquals(false, mDevice.batterySaverEnabled);
901         assertEquals(90, mPersistedState.batteryLevel);
902         assertEquals(false, mPersistedState.batteryLow);
903 
904         // Enable
905         mDevice.putGlobalSetting(Global.LOW_POWER_MODE, 1);
906 
907         assertEquals(true, mDevice.batterySaverEnabled);
908         assertEquals(90, mPersistedState.batteryLevel);
909         assertEquals(false, mPersistedState.batteryLow);
910 
911         // Disable
912         mDevice.putGlobalSetting(Global.LOW_POWER_MODE, 0);
913 
914         assertEquals(false, mDevice.batterySaverEnabled);
915         assertEquals(90, mPersistedState.batteryLevel);
916         assertEquals(false, mPersistedState.batteryLow);
917 
918         // Enable again
919         mDevice.putGlobalSetting(Global.LOW_POWER_MODE, 1);
920 
921         assertEquals(true, mDevice.batterySaverEnabled);
922         assertEquals(90, mPersistedState.batteryLevel);
923         assertEquals(false, mPersistedState.batteryLow);
924 
925         // Reboot -- LOW_POWER_MODE shouldn't be persisted.
926         initDevice();
927         assertEquals(false, mDevice.batterySaverEnabled);
928         assertEquals(90, mPersistedState.batteryLevel);
929         assertEquals(false, mPersistedState.batteryLow);
930     }
931 
932     @Test
testAutoBatterySaver_smartBatterySaverEnabled()933     public void testAutoBatterySaver_smartBatterySaverEnabled() {
934         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
935         mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
936                 PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
937         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
938 
939         assertEquals(false, mDevice.batterySaverEnabled);
940         assertEquals(100, mPersistedState.batteryLevel);
941 
942         mDevice.setBatteryLevel(90);
943 
944         assertEquals(false, mDevice.batterySaverEnabled);
945         assertEquals(90, mPersistedState.batteryLevel);
946 
947         mDevice.setBatteryLevel(51);
948 
949         assertEquals(false, mDevice.batterySaverEnabled);
950         assertEquals(51, mPersistedState.batteryLevel);
951 
952         // Hit the threshold. BS should be disabled since dynamic power savings still off
953         mDevice.setBatteryLevel(50);
954 
955         assertEquals(false, mDevice.batterySaverEnabled);
956         assertEquals(50, mPersistedState.batteryLevel);
957 
958         // dynamic power savings comes on, battery saver should turn on
959         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
960         mDevice.setBatteryLevel(40);
961 
962         assertEquals(true, mDevice.batterySaverEnabled);
963         assertEquals(40, mPersistedState.batteryLevel);
964 
965         mDevice.setPowered(true);
966 
967         assertEquals(false, mDevice.batterySaverEnabled);
968         assertEquals(40, mPersistedState.batteryLevel);
969 
970         mDevice.setPowered(false);
971 
972         assertEquals(true, mDevice.batterySaverEnabled);
973         assertEquals(40, mPersistedState.batteryLevel);
974 
975         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
976 
977         assertEquals(false, mDevice.batterySaverEnabled);
978         assertEquals(40, mPersistedState.batteryLevel);
979 
980         mDevice.setBatteryLevel(30);
981 
982         assertEquals(false, mDevice.batterySaverEnabled);
983         assertEquals(30, mPersistedState.batteryLevel);
984 
985         // Plug in and out, snooze will reset.
986         mDevice.setPowered(true);
987         mDevice.setPowered(false);
988 
989         assertEquals(true, mDevice.batterySaverEnabled);
990         assertEquals(30, mPersistedState.batteryLevel);
991 
992         mDevice.setPowered(true);
993         mDevice.setBatteryLevel(60);
994 
995         assertEquals(false, mDevice.batterySaverEnabled);
996         assertEquals(60, mPersistedState.batteryLevel);
997 
998         mDevice.setPowered(false);
999 
1000         assertEquals(false, mDevice.batterySaverEnabled);
1001         assertEquals(60, mPersistedState.batteryLevel);
1002 
1003         mDevice.setBatteryLevel(40);
1004 
1005         assertEquals(true, mDevice.batterySaverEnabled);
1006         assertEquals(40, mPersistedState.batteryLevel);
1007 
1008         mDevice.setBatteryLevel(70);
1009 
1010         assertEquals(false, mDevice.batterySaverEnabled);
1011         assertEquals(70, mPersistedState.batteryLevel);
1012 
1013         // Bump up the threshold.
1014         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 71);
1015         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
1016 
1017         // Changes should register immediately.
1018         assertEquals(true, mDevice.batterySaverEnabled);
1019         assertEquals(70, mPersistedState.batteryLevel);
1020 
1021         mDevice.setBatteryLevel(69);
1022 
1023         assertEquals(true, mDevice.batterySaverEnabled);
1024         assertEquals(69, mPersistedState.batteryLevel);
1025 
1026         // Then down.
1027         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 60);
1028         mDevice.setBatteryLevel(mPersistedState.batteryLevel);
1029 
1030         // Changes should register immediately.
1031         assertEquals(false, mDevice.batterySaverEnabled);
1032         assertEquals(69, mPersistedState.batteryLevel);
1033 
1034         mDevice.setBatteryLevel(68);
1035         assertEquals(false, mDevice.batterySaverEnabled);
1036         assertEquals(68, mPersistedState.batteryLevel);
1037 
1038         // Reboot in low state -> automatically enable BS.
1039         mDevice.setPowered(false);
1040         mDevice.setBatteryLevel(30);
1041         mTarget.setBatterySaverEnabledManually(false);
1042 
1043         assertEquals(false, mDevice.batterySaverEnabled);
1044         assertEquals(30, mPersistedState.batteryLevel);
1045 
1046         initDevice();
1047 
1048         assertEquals(true, mDevice.batterySaverEnabled);
1049         assertEquals(30, mPersistedState.batteryLevel);
1050     }
1051 
1052     @Test
testAutoBatterySaver_snoozed_autoEnabled()1053     public void testAutoBatterySaver_snoozed_autoEnabled() {
1054         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 30);
1055         // Test dynamic threshold higher than automatic to make sure it doesn't interfere when it's
1056         // not enabled.
1057         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
1058         mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
1059                 PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
1060         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
1061 
1062         assertEquals(false, mDevice.batterySaverEnabled);
1063         assertEquals(100, mPersistedState.batteryLevel);
1064 
1065         mDevice.setBatteryLevel(90);
1066 
1067         assertEquals(false, mDevice.batterySaverEnabled);
1068         assertEquals(90, mPersistedState.batteryLevel);
1069 
1070         mDevice.setBatteryLevel(51);
1071 
1072         assertEquals(false, mDevice.batterySaverEnabled);
1073         assertEquals(51, mPersistedState.batteryLevel);
1074 
1075         // Hit dynamic threshold. BS should be disabled since dynamic is off
1076         mDevice.setBatteryLevel(50);
1077 
1078         assertEquals(false, mDevice.batterySaverEnabled);
1079         assertEquals(50, mPersistedState.batteryLevel);
1080 
1081         mDevice.setBatteryLevel(30);
1082 
1083         assertEquals(true, mDevice.batterySaverEnabled);
1084         assertEquals(30, mPersistedState.batteryLevel);
1085 
1086         mDevice.setPowered(true);
1087 
1088         assertEquals(false, mDevice.batterySaverEnabled);
1089         assertEquals(30, mPersistedState.batteryLevel);
1090 
1091         mDevice.setPowered(false);
1092 
1093         assertEquals(true, mDevice.batterySaverEnabled);
1094         assertEquals(30, mPersistedState.batteryLevel);
1095 
1096         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1097 
1098         assertEquals(false, mDevice.batterySaverEnabled);
1099         assertEquals(30, mPersistedState.batteryLevel);
1100 
1101         mDevice.setBatteryLevel(20);
1102 
1103         assertEquals(false, mDevice.batterySaverEnabled);
1104         assertEquals(20, mPersistedState.batteryLevel);
1105 
1106         // Lower threshold. Level is still below, so should still be snoozed.
1107         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 25);
1108 
1109         assertEquals(false, mDevice.batterySaverEnabled);
1110         assertEquals(20, mPersistedState.batteryLevel);
1111 
1112         // Lower threshold even more. Battery no longer considered "low" so snoozing should be
1113         // disabled.
1114         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 10);
1115         // "batteryLow" is set in setBatteryLevel.
1116         mDevice.setBatteryLevel(19);
1117 
1118         assertEquals(false, mDevice.batterySaverEnabled);
1119         assertEquals(19, mPersistedState.batteryLevel);
1120 
1121         mDevice.setBatteryLevel(10);
1122 
1123         assertEquals(true, mDevice.batterySaverEnabled); // No longer snoozing.
1124         assertEquals(10, mPersistedState.batteryLevel);
1125 
1126         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1127 
1128         // Plug in and out, snooze will reset.
1129         mDevice.setPowered(true);
1130         mDevice.setPowered(false);
1131 
1132         assertEquals(true, mDevice.batterySaverEnabled);
1133         assertEquals(10, mPersistedState.batteryLevel);
1134 
1135         mDevice.setPowered(true);
1136         mDevice.setBatteryLevel(60);
1137 
1138         assertEquals(false, mDevice.batterySaverEnabled);
1139         assertEquals(60, mPersistedState.batteryLevel);
1140 
1141         // Test toggling resets snooze.
1142         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
1143         mDevice.setPowered(false);
1144         mDevice.setBatteryLevel(45);
1145 
1146         assertEquals(true, mDevice.batterySaverEnabled);
1147         assertEquals(45, mPersistedState.batteryLevel);
1148 
1149         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1150         assertEquals(false, mDevice.batterySaverEnabled);
1151         assertEquals(45, mPersistedState.batteryLevel);
1152 
1153         // Disable and re-enable.
1154         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
1155         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
1156 
1157         assertEquals(true, mDevice.batterySaverEnabled); // Snooze reset
1158         assertEquals(45, mPersistedState.batteryLevel);
1159     }
1160 
1161     @Test
testAutoBatterySaver_snoozed_dynamicEnabled()1162     public void testAutoBatterySaver_snoozed_dynamicEnabled() {
1163         // Test auto threshold higher than dynamic to make sure it doesn't interfere when it's
1164         // not enabled.
1165         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
1166         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 30);
1167         mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
1168                 PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
1169         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
1170 
1171         assertEquals(false, mDevice.batterySaverEnabled);
1172         assertEquals(100, mPersistedState.batteryLevel);
1173 
1174         mDevice.setBatteryLevel(90);
1175 
1176         assertEquals(false, mDevice.batterySaverEnabled);
1177         assertEquals(90, mPersistedState.batteryLevel);
1178 
1179         mDevice.setBatteryLevel(51);
1180 
1181         assertEquals(false, mDevice.batterySaverEnabled);
1182         assertEquals(51, mPersistedState.batteryLevel);
1183 
1184         // Hit automatic threshold. BS should be disabled since automatic is off
1185         mDevice.setBatteryLevel(50);
1186 
1187         assertEquals(false, mDevice.batterySaverEnabled);
1188         assertEquals(50, mPersistedState.batteryLevel);
1189 
1190         mDevice.setBatteryLevel(30);
1191 
1192         assertEquals(true, mDevice.batterySaverEnabled);
1193         assertEquals(30, mPersistedState.batteryLevel);
1194 
1195         mDevice.setPowered(true);
1196 
1197         assertEquals(false, mDevice.batterySaverEnabled);
1198         assertEquals(30, mPersistedState.batteryLevel);
1199 
1200         mDevice.setPowered(false);
1201 
1202         assertEquals(true, mDevice.batterySaverEnabled);
1203         assertEquals(30, mPersistedState.batteryLevel);
1204 
1205         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1206 
1207         assertEquals(false, mDevice.batterySaverEnabled);
1208         assertEquals(30, mPersistedState.batteryLevel);
1209 
1210         mDevice.setBatteryLevel(20);
1211 
1212         assertEquals(false, mDevice.batterySaverEnabled);
1213         assertEquals(20, mPersistedState.batteryLevel);
1214 
1215         // Lower threshold. Level is still below, so should still be snoozed.
1216         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 25);
1217 
1218         assertEquals(false, mDevice.batterySaverEnabled);
1219         assertEquals(20, mPersistedState.batteryLevel);
1220 
1221         // Lower threshold even more. Battery no longer considered "low" so snoozing should be
1222         // disabled.
1223         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 10);
1224 
1225         assertEquals(false, mDevice.batterySaverEnabled);
1226         assertEquals(20, mPersistedState.batteryLevel);
1227 
1228         mDevice.setBatteryLevel(10);
1229 
1230         assertEquals(true, mDevice.batterySaverEnabled); // No longer snoozing.
1231         assertEquals(10, mPersistedState.batteryLevel);
1232 
1233         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1234 
1235         // Plug in and out, snooze will reset.
1236         mDevice.setPowered(true);
1237         mDevice.setPowered(false);
1238 
1239         assertEquals(true, mDevice.batterySaverEnabled);
1240         assertEquals(10, mPersistedState.batteryLevel);
1241 
1242         mDevice.setPowered(true);
1243         mDevice.setBatteryLevel(60);
1244 
1245         assertEquals(false, mDevice.batterySaverEnabled);
1246         assertEquals(60, mPersistedState.batteryLevel);
1247 
1248         // Test toggling resets snooze.
1249         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
1250         mDevice.setPowered(false);
1251         mDevice.setBatteryLevel(45);
1252 
1253         assertEquals(true, mDevice.batterySaverEnabled);
1254         assertEquals(45, mPersistedState.batteryLevel);
1255 
1256         mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze.
1257         assertEquals(false, mDevice.batterySaverEnabled);
1258         assertEquals(45, mPersistedState.batteryLevel);
1259 
1260         // Disable and re-enable.
1261         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
1262         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
1263 
1264         assertEquals(true, mDevice.batterySaverEnabled); // Snooze reset
1265         assertEquals(45, mPersistedState.batteryLevel);
1266     }
1267 }
1268