blob: 911c4a2f41221b7554e31452cfe566837fc16530 [file] [log] [blame]
jackqdyulei92681e82017-02-28 11:26:28 -08001/*
2 * Copyright (C) 2017 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
17package com.android.server.power;
18
Makoto Onuki66a78122017-11-14 15:03:21 -080019import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
20import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
21
22import static com.google.common.truth.Truth.assertThat;
23
Santos Cordon12f92eb2019-02-01 21:28:47 +000024import static org.mockito.ArgumentMatchers.any;
25import static org.mockito.ArgumentMatchers.anyInt;
26import static org.mockito.ArgumentMatchers.anyString;
Santos Cordon64a6e612018-08-22 19:27:04 +010027import static org.mockito.ArgumentMatchers.eq;
Santos Cordon12f92eb2019-02-01 21:28:47 +000028import static org.mockito.Mockito.doAnswer;
Santos Cordon64a6e612018-08-22 19:27:04 +010029import static org.mockito.Mockito.mock;
Makoto Onuki66a78122017-11-14 15:03:21 -080030import static org.mockito.Mockito.when;
31
Santos Cordon64a6e612018-08-22 19:27:04 +010032import android.app.ActivityManagerInternal;
Santos Cordon12f92eb2019-02-01 21:28:47 +000033import android.attention.AttentionManagerInternal;
Santos Cordon64a6e612018-08-22 19:27:04 +010034import android.content.Context;
35import android.hardware.display.DisplayManagerInternal;
jackqdyulei92681e82017-02-28 11:26:28 -080036import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
Santos Cordon64a6e612018-08-22 19:27:04 +010037import android.os.BatteryManagerInternal;
Santos Cordon12f92eb2019-02-01 21:28:47 +000038import android.os.Binder;
Santos Cordon64a6e612018-08-22 19:27:04 +010039import android.os.Looper;
Salvador Martineza6f7b252017-04-10 10:46:15 -070040import android.os.PowerManager;
jackqdyulei92681e82017-02-28 11:26:28 -080041import android.os.PowerSaveState;
Santos Cordon64a6e612018-08-22 19:27:04 +010042import android.os.SystemClock;
Mark Salyzyne65c0c62017-08-15 07:53:47 -070043import android.os.SystemProperties;
jackqdyulei92681e82017-02-28 11:26:28 -080044import android.test.AndroidTestCase;
Alex Kershaw2418ea92018-10-19 17:17:49 +010045import android.test.suitebuilder.annotation.MediumTest;
jackqdyulei92681e82017-02-28 11:26:28 -080046import android.test.suitebuilder.annotation.SmallTest;
Makoto Onuki66a78122017-11-14 15:03:21 -080047
Santos Cordon64a6e612018-08-22 19:27:04 +010048import com.android.internal.app.IBatteryStats;
49import com.android.server.LocalServices;
50import com.android.server.SystemService;
51import com.android.server.lights.LightsManager;
52import com.android.server.policy.WindowManagerPolicy;
53import com.android.server.power.PowerManagerService.Injector;
54import com.android.server.power.PowerManagerService.NativeWrapper;
Kweku Adams7fb72a42019-01-08 16:08:49 -080055import com.android.server.power.batterysaver.BatterySaverPolicy;
Santos Cordon64a6e612018-08-22 19:27:04 +010056import com.android.server.power.batterysaver.BatterySavingStats;
Makoto Onuki66a78122017-11-14 15:03:21 -080057
Salvador Martineza6f7b252017-04-10 10:46:15 -070058import org.junit.Rule;
jackqdyulei92681e82017-02-28 11:26:28 -080059import org.mockito.Mock;
60import org.mockito.MockitoAnnotations;
61
Santos Cordon12f92eb2019-02-01 21:28:47 +000062import java.util.HashMap;
63import java.util.Map;
64
jackqdyulei92681e82017-02-28 11:26:28 -080065/**
66 * Tests for {@link com.android.server.power.PowerManagerService}
67 */
68public class PowerManagerServiceTest extends AndroidTestCase {
69 private static final float PRECISION = 0.001f;
70 private static final float BRIGHTNESS_FACTOR = 0.7f;
71 private static final boolean BATTERY_SAVER_ENABLED = true;
Mark Salyzyne65c0c62017-08-15 07:53:47 -070072 private static final String TEST_LAST_REBOOT_PROPERTY = "test.sys.boot.reason";
jackqdyulei92681e82017-02-28 11:26:28 -080073
Santos Cordon64a6e612018-08-22 19:27:04 +010074 private @Mock BatterySaverPolicy mBatterySaverPolicyMock;
75 private @Mock LightsManager mLightsManagerMock;
76 private @Mock DisplayManagerInternal mDisplayManagerInternalMock;
77 private @Mock BatteryManagerInternal mBatteryManagerInternalMock;
78 private @Mock ActivityManagerInternal mActivityManagerInternalMock;
Santos Cordon12f92eb2019-02-01 21:28:47 +000079 private @Mock AttentionManagerInternal mAttentionManagerInternalMock;
Santos Cordon64a6e612018-08-22 19:27:04 +010080 private @Mock PowerManagerService.NativeWrapper mNativeWrapperMock;
81 private @Mock Notifier mNotifierMock;
jackqdyulei92681e82017-02-28 11:26:28 -080082 private PowerManagerService mService;
83 private PowerSaveState mPowerSaveState;
84 private DisplayPowerRequest mDisplayPowerRequest;
Salvador Martineza6f7b252017-04-10 10:46:15 -070085
Santos Cordon64a6e612018-08-22 19:27:04 +010086
87
Salvador Martineza6f7b252017-04-10 10:46:15 -070088 @Rule
jackqdyulei92681e82017-02-28 11:26:28 -080089 public void setUp() throws Exception {
90 super.setUp();
91 MockitoAnnotations.initMocks(this);
92
93 mPowerSaveState = new PowerSaveState.Builder()
94 .setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
95 .setBrightnessFactor(BRIGHTNESS_FACTOR)
96 .build();
Santos Cordon64a6e612018-08-22 19:27:04 +010097 when(mBatterySaverPolicyMock.getBatterySaverPolicy(
Kweku Adams9f488e22019-01-14 16:25:08 -080098 eq(PowerManager.ServiceType.SCREEN_BRIGHTNESS)))
jackqdyulei92681e82017-02-28 11:26:28 -080099 .thenReturn(mPowerSaveState);
Santos Cordon64a6e612018-08-22 19:27:04 +0100100
jackqdyulei92681e82017-02-28 11:26:28 -0800101 mDisplayPowerRequest = new DisplayPowerRequest();
Santos Cordon64a6e612018-08-22 19:27:04 +0100102 addLocalServiceMock(LightsManager.class, mLightsManagerMock);
103 addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
104 addLocalServiceMock(BatteryManagerInternal.class, mBatteryManagerInternalMock);
105 addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
Santos Cordon12f92eb2019-02-01 21:28:47 +0000106 addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock);
Santos Cordon64a6e612018-08-22 19:27:04 +0100107
108 mService = new PowerManagerService(getContext(), new Injector() {
109 Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
110 SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
111 return mNotifierMock;
112 }
113
114 SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
115 return mock(SuspendBlocker.class);
116 }
117
118 BatterySaverPolicy createBatterySaverPolicy(
119 Object lock, Context context, BatterySavingStats batterySavingStats) {
120 return mBatterySaverPolicyMock;
121 }
122
123 NativeWrapper createNativeWrapper() {
124 return mNativeWrapperMock;
125 }
126 });
127 }
128
129 @Override
130 public void tearDown() throws Exception {
131 LocalServices.removeServiceForTest(LightsManager.class);
132 LocalServices.removeServiceForTest(DisplayManagerInternal.class);
133 LocalServices.removeServiceForTest(BatteryManagerInternal.class);
134 LocalServices.removeServiceForTest(ActivityManagerInternal.class);
135 }
136
137 /**
138 * Creates a mock and registers it to {@link LocalServices}.
139 */
140 private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
141 LocalServices.removeServiceForTest(clazz);
142 LocalServices.addService(clazz, mock);
jackqdyulei92681e82017-02-28 11:26:28 -0800143 }
144
145 @SmallTest
146 public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() {
147 mService.updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
148 assertThat(mDisplayPowerRequest.lowPowerMode).isEqualTo(BATTERY_SAVER_ENABLED);
149 assertThat(mDisplayPowerRequest.screenLowPowerBrightnessFactor)
150 .isWithin(PRECISION).of(BRIGHTNESS_FACTOR);
151 }
Salvador Martineza6f7b252017-04-10 10:46:15 -0700152
153 @SmallTest
154 public void testGetLastShutdownReasonInternal() {
Mark Salyzyne65c0c62017-08-15 07:53:47 -0700155 SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "shutdown,thermal");
156 int reason = mService.getLastShutdownReasonInternal(TEST_LAST_REBOOT_PROPERTY);
157 SystemProperties.set(TEST_LAST_REBOOT_PROPERTY, "");
Salvador Martineza6f7b252017-04-10 10:46:15 -0700158 assertThat(reason).isEqualTo(PowerManager.SHUTDOWN_REASON_THERMAL_SHUTDOWN);
159 }
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700160
161 @SmallTest
162 public void testGetDesiredScreenPolicy_WithVR() throws Exception {
163 // Brighten up the screen
Michael Wrighte3001042019-02-05 00:13:14 +0000164 mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700165 assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
166 DisplayPowerRequest.POLICY_BRIGHT);
167
168 // Move to VR
169 mService.setVrModeEnabled(true);
170 assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
171 DisplayPowerRequest.POLICY_VR);
172
173 // Then take a nap
Michael Wrighte3001042019-02-05 00:13:14 +0000174 mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
175 0);
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700176 assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
177 DisplayPowerRequest.POLICY_OFF);
178
179 // Wake up to VR
Michael Wrighte3001042019-02-05 00:13:14 +0000180 mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700181 assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
182 DisplayPowerRequest.POLICY_VR);
183
184 // And back to normal
185 mService.setVrModeEnabled(false);
186 assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
187 DisplayPowerRequest.POLICY_BRIGHT);
Santos Cordon64a6e612018-08-22 19:27:04 +0100188 }
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700189
Santos Cordon64a6e612018-08-22 19:27:04 +0100190 @SmallTest
191 public void testWakefulnessAwake_InitialValue() throws Exception {
192 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
193 }
194
195 @SmallTest
196 public void testWakefulnessSleep_NoDozeSleepFlag() throws Exception {
197 // Start with AWAKE state
198 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
199
200 mService.systemReady(null);
201 mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
202
203 // Take a nap with a flag.
204 mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
205 PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
206
207 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
Santos Cordon21e9f2b2017-09-13 11:59:39 -0700208 }
Alex Kershaw2418ea92018-10-19 17:17:49 +0100209
210 @MediumTest
211 public void testWasDeviceIdleFor_true() {
212 int interval = 1000;
213 mService.onUserActivity();
214 SystemClock.sleep(interval);
215 assertThat(mService.wasDeviceIdleForInternal(interval)).isTrue();
216 }
217
218 @SmallTest
219 public void testWasDeviceIdleFor_false() {
220 int interval = 1000;
221 mService.onUserActivity();
222 assertThat(mService.wasDeviceIdleForInternal(interval)).isFalse();
223 }
Santos Cordon12f92eb2019-02-01 21:28:47 +0000224
225 @SmallTest
226 public void testForceSuspend_putsDeviceToSleep() {
227 mService.systemReady(null);
228 mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
229
230 // Verify that we start awake
231 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
232
233 // Grab the wakefulness value when PowerManager finally calls into the
234 // native component to actually perform the suspend.
235 when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> {
236 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
237 return true;
238 });
239
240 boolean retval = mService.getBinderServiceInstance().forceSuspend();
241 assertThat(retval).isTrue();
242
243 // Still asleep when the function returns.
244 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
245 }
246
247 @SmallTest
248 public void testForceSuspend_pakeLocksDisabled() {
249 final String tag = "TestWakelockTag_098213";
250 final int flags = PowerManager.PARTIAL_WAKE_LOCK;
251 final String pkg = getContext().getOpPackageName();
252
253 // Set up the Notification mock to keep track of the wakelocks that are currently
254 // active or disabled. We'll use this to verify that wakelocks are disabled when
255 // they should be.
256 final Map<String, Integer> wakelockMap = new HashMap<>(1);
257 doAnswer(inv -> {
258 wakelockMap.put((String) inv.getArguments()[1], (int) inv.getArguments()[0]);
259 return null;
260 }).when(mNotifierMock).onWakeLockAcquired(anyInt(), anyString(), anyString(), anyInt(),
261 anyInt(), any(), any());
262 doAnswer(inv -> {
263 wakelockMap.remove((String) inv.getArguments()[1]);
264 return null;
265 }).when(mNotifierMock).onWakeLockReleased(anyInt(), anyString(), anyString(), anyInt(),
266 anyInt(), any(), any());
267
268 //
269 // TEST STARTS HERE
270 //
271 mService.systemReady(null);
272 mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
273
274 // Verify that we start awake
275 assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
276
277 // Create a wakelock
278 mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
279 null /* workSource */, null /* historyTag */);
280 assertThat(wakelockMap.get(tag)).isEqualTo(flags); // Verify wakelock is active.
281
282 // Confirm that the wakelocks have been disabled when the forceSuspend is in flight.
283 when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> {
284 // Verify that the wakelock is disabled by the time we get to the native force
285 // suspend call.
286 assertThat(wakelockMap.containsKey(tag)).isFalse();
287 return true;
288 });
289
290 assertThat(mService.getBinderServiceInstance().forceSuspend()).isTrue();
291 assertThat(wakelockMap.get(tag)).isEqualTo(flags);
292
293 }
294
295 @SmallTest
296 public void testForceSuspend_forceSuspendFailurePropogated() {
297 when(mNativeWrapperMock.nativeForceSuspend()).thenReturn(false);
298 assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();
299 }
jackqdyulei92681e82017-02-28 11:26:28 -0800300}