• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package android.os.cts;
18 
19 import static com.android.compatibility.common.util.TestUtils.waitUntil;
20 
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.os.PowerManager;
26 import android.os.PowerManager.WakeLock;
27 import android.platform.test.annotations.AppModeFull;
28 import android.platform.test.annotations.LargeTest;
29 import android.provider.Settings.Global;
30 import android.test.AndroidTestCase;
31 
32 import com.android.compatibility.common.util.BatteryUtils;
33 import com.android.compatibility.common.util.CallbackAsserter;
34 import com.android.compatibility.common.util.SystemUtil;
35 
36 import org.junit.After;
37 import org.junit.Before;
38 
39 import java.time.Duration;
40 
41 @AppModeFull(reason = "Instant Apps don't have the WRITE_SECURE_SETTINGS permission "
42         + "required in tearDown for Global#putInt")
43 public class PowerManagerTest extends AndroidTestCase {
44     private static final String TAG = "PowerManagerTest";
45     public static final long TIME = 3000;
46     public static final int MORE_TIME = 300;
47     private static final int BROADCAST_TIMEOUT_SECONDS = 70;
48     private static final Duration LONG_DISCHARGE_DURATION = Duration.ofMillis(2000);
49     private static final Duration SHORT_DISCHARGE_DURATION = Duration.ofMillis(1000);
50 
51     private int mInitialPowerSaverMode;
52     private int mInitialDynamicPowerSavingsEnabled;
53     private int mInitialThreshold;
54 
55     /**
56      * test points:
57      * 1 Get a wake lock at the level of the flags parameter
58      * 2 Force the device to go to sleep
59      * 3 User activity happened
60      */
testPowerManager()61     public void testPowerManager() throws InterruptedException {
62         PowerManager pm = (PowerManager)getContext().getSystemService(Context.POWER_SERVICE);
63 
64         WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG);
65         wl.acquire(TIME);
66         assertTrue(wl.isHeld());
67         Thread.sleep(TIME + MORE_TIME);
68         assertFalse(wl.isHeld());
69 
70         try {
71             pm.reboot("Testing");
72             fail("reboot should throw SecurityException");
73         } catch (SecurityException e) {
74             // expected
75         }
76     }
77 
78     @Before
setUp()79     public void setUp() {
80         // store the current value so we can restore it
81         ContentResolver resolver = getContext().getContentResolver();
82         mInitialPowerSaverMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 0);
83         mInitialDynamicPowerSavingsEnabled =
84                 Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
85         mInitialThreshold =
86                 Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 0);
87 
88     }
89 
90     @After
tearDown()91     public void tearDown() {
92         SystemUtil.runWithShellPermissionIdentity(() -> {
93             ContentResolver resolver = getContext().getContentResolver();
94 
95             // Verify we can change it to dynamic.
96             Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, mInitialPowerSaverMode);
97             Global.putInt(resolver,
98                     Global.DYNAMIC_POWER_SAVINGS_ENABLED, mInitialDynamicPowerSavingsEnabled);
99             Global.putInt(resolver,
100                     Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, mInitialThreshold);
101         });
102     }
103 
testPowerManager_getPowerSaveMode()104     public void testPowerManager_getPowerSaveMode() {
105         SystemUtil.runWithShellPermissionIdentity(() -> {
106             PowerManager manager = BatteryUtils.getPowerManager();
107             ContentResolver resolver = getContext().getContentResolver();
108 
109             // Verify we can change it to percentage.
110             Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 0);
111             assertEquals(
112                     PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE,
113                     manager.getPowerSaveModeTrigger());
114 
115             // Verify we can change it to dynamic.
116             Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, 1);
117             assertEquals(
118                     PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC,
119                     manager.getPowerSaveModeTrigger());
120         });
121     }
122 
testPowerManager_setDynamicPowerSavings()123     public void testPowerManager_setDynamicPowerSavings() {
124         SystemUtil.runWithShellPermissionIdentity(() -> {
125             PowerManager manager = BatteryUtils.getPowerManager();
126             ContentResolver resolver = getContext().getContentResolver();
127 
128             // Verify settings are actually updated.
129             manager.setDynamicPowerSaveHint(true, 80);
130             assertEquals(1, Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0));
131             assertEquals(80, Global.getInt(resolver,
132                     Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 0));
133 
134             manager.setDynamicPowerSaveHint(false, 20);
135             assertEquals(0, Global.getInt(resolver, Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1));
136             assertEquals(20, Global.getInt(resolver,
137                     Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 0));
138         });
139     }
140 
141     @LargeTest
testPowerManager_batteryDischargePrediction()142     public void testPowerManager_batteryDischargePrediction() throws Exception {
143         final PowerManager manager = BatteryUtils.getPowerManager();
144 
145         if (!BatteryUtils.hasBattery()) {
146             assertNull(manager.getBatteryDischargePrediction());
147             return;
148         }
149 
150         // Unplug to ensure the plugged in broadcast is sent.
151         BatteryUtils.runDumpsysBatteryUnplug();
152 
153         // Plugged in. No prediction should be given.
154         final CallbackAsserter pluggedBroadcastAsserter = CallbackAsserter.forBroadcast(
155                 new IntentFilter(Intent.ACTION_POWER_CONNECTED));
156         BatteryUtils.runDumpsysBatterySetPluggedIn(true);
157         pluggedBroadcastAsserter.assertCalled("Didn't get power connected broadcast",
158                 BROADCAST_TIMEOUT_SECONDS);
159         // PowerManagerService may get the BATTERY_CHANGED broadcast after we get our broadcast,
160         // so we have to have a little wait.
161         waitUntil("PowerManager doesn't think the device has connected power",
162                 () -> manager.getBatteryDischargePrediction() == null);
163 
164         // Not plugged in. At the very least, the basic discharge estimation should be returned.
165         final CallbackAsserter unpluggedBroadcastAsserter = CallbackAsserter.forBroadcast(
166                 new IntentFilter(Intent.ACTION_POWER_DISCONNECTED));
167         BatteryUtils.runDumpsysBatteryUnplug();
168         unpluggedBroadcastAsserter.assertCalled("Didn't get power disconnected broadcast",
169                 BROADCAST_TIMEOUT_SECONDS);
170         // PowerManagerService may get the BATTERY_CHANGED broadcast after we get our broadcast,
171         // so we have to have a little wait.
172         waitUntil("PowerManager still thinks the device has connected power",
173                 () -> manager.getBatteryDischargePrediction() != null);
174 
175         CallbackAsserter predictionChangedBroadcastAsserter = CallbackAsserter.forBroadcast(
176                 new IntentFilter(PowerManager.ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED));
177         setDischargePrediction(LONG_DISCHARGE_DURATION, true);
178         assertDischargePrediction(LONG_DISCHARGE_DURATION, true);
179         predictionChangedBroadcastAsserter.assertCalled("Prediction changed broadcast not received",
180                 BROADCAST_TIMEOUT_SECONDS);
181 
182 
183         predictionChangedBroadcastAsserter = CallbackAsserter.forBroadcast(
184                 new IntentFilter(PowerManager.ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED));
185         setDischargePrediction(SHORT_DISCHARGE_DURATION, false);
186         assertDischargePrediction(SHORT_DISCHARGE_DURATION, false);
187         predictionChangedBroadcastAsserter.assertCalled("Prediction changed broadcast not received",
188                 BROADCAST_TIMEOUT_SECONDS);
189     }
190 
setDischargePrediction(Duration d, boolean isPersonalized)191     private void setDischargePrediction(Duration d, boolean isPersonalized) {
192         final PowerManager manager = BatteryUtils.getPowerManager();
193         SystemUtil.runWithShellPermissionIdentity(
194                 () -> manager.setBatteryDischargePrediction(d, isPersonalized),
195                 android.Manifest.permission.BATTERY_PREDICTION);
196     }
197 
assertDischargePrediction(Duration d, boolean isPersonalized)198     private void assertDischargePrediction(Duration d, boolean isPersonalized) {
199         final PowerManager manager = BatteryUtils.getPowerManager();
200         // We can't pause time so must use >= because the time remaining should decrease as
201         // time goes on.
202         Duration prediction = manager.getBatteryDischargePrediction();
203         assertTrue("Prediction is greater than " + d.toMillis() + "ms: "
204                 + prediction, d.toMillis() >= prediction.toMillis());
205         assertEquals(isPersonalized, manager.isBatteryDischargePredictionPersonalized());
206     }
207 }
208