1 /*
2  * Copyright (C) 2022 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 com.android.server.power;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.ArgumentMatchers.eq;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.ActivityManagerInternal;
31 import android.attention.AttentionManagerInternal;
32 import android.content.Context;
33 import android.content.ContextWrapper;
34 import android.content.res.Resources;
35 import android.hardware.SensorManager;
36 import android.hardware.devicestate.DeviceStateManager;
37 import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
38 import android.hardware.display.AmbientDisplayConfiguration;
39 import android.hardware.display.DisplayManagerInternal;
40 import android.os.BatteryManagerInternal;
41 import android.os.Handler;
42 import android.os.Looper;
43 import android.os.PowerManager;
44 import android.os.PowerSaveState;
45 import android.os.test.TestLooper;
46 import android.provider.Settings;
47 import android.service.dreams.DreamManagerInternal;
48 import android.test.mock.MockContentResolver;
49 import android.view.Display;
50 import android.view.DisplayInfo;
51 
52 import androidx.test.InstrumentationRegistry;
53 
54 import com.android.internal.app.IBatteryStats;
55 import com.android.internal.util.test.FakeSettingsProvider;
56 import com.android.server.LocalServices;
57 import com.android.server.SystemService;
58 import com.android.server.lights.LightsManager;
59 import com.android.server.policy.WindowManagerPolicy;
60 import com.android.server.power.PowerManagerService.BatteryReceiver;
61 import com.android.server.power.PowerManagerService.Injector;
62 import com.android.server.power.PowerManagerService.NativeWrapper;
63 import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
64 import com.android.server.power.batterysaver.BatterySaverController;
65 import com.android.server.power.batterysaver.BatterySaverPolicy;
66 import com.android.server.power.batterysaver.BatterySaverStateMachine;
67 import com.android.server.power.batterysaver.BatterySavingStats;
68 import com.android.server.testutils.OffsettableClock;
69 
70 import java.util.concurrent.Executor;
71 
72 import org.junit.After;
73 import org.junit.Before;
74 import org.junit.Test;
75 import org.mockito.ArgumentCaptor;
76 import org.mockito.Mock;
77 import org.mockito.MockitoAnnotations;
78 
79 /**
80  * Tests for {@link com.android.server.power.PowerManagerService}.
81  *
82  * Build/Install/Run:
83  *  atest FrameworksServicesTests:PowerManagerServiceMockingTest
84  */
85 public class PowerManagerServiceMockingTest {
86     private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
87     private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason";
88 
89     private static final float BRIGHTNESS_FACTOR = 0.7f;
90     private static final boolean BATTERY_SAVER_ENABLED = true;
91 
92     @Mock private BatterySaverController mBatterySaverControllerMock;
93     @Mock private BatterySaverPolicy mBatterySaverPolicyMock;
94     @Mock private BatterySaverStateMachine mBatterySaverStateMachineMock;
95     @Mock private LightsManager mLightsManagerMock;
96     @Mock private DisplayManagerInternal mDisplayManagerInternalMock;
97     @Mock private BatteryManagerInternal mBatteryManagerInternalMock;
98     @Mock private ActivityManagerInternal mActivityManagerInternalMock;
99     @Mock private AttentionManagerInternal mAttentionManagerInternalMock;
100     @Mock private DreamManagerInternal mDreamManagerInternalMock;
101     @Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
102     @Mock private Notifier mNotifierMock;
103     @Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
104     @Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock;
105     @Mock private SystemPropertiesWrapper mSystemPropertiesMock;
106     @Mock private DeviceStateManager mDeviceStateManagerMock;
107 
108     @Mock
109     private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
110 
111     private PowerManagerService mService;
112     private PowerSaveState mPowerSaveState;
113     private ContextWrapper mContextSpy;
114     private BatteryReceiver mBatteryReceiver;
115     private UserSwitchedReceiver mUserSwitchedReceiver;
116     private Resources mResourcesSpy;
117     private OffsettableClock mClock;
118     private TestLooper mTestLooper;
119 
120     @Before
setUp()121     public void setUp() throws Exception {
122         MockitoAnnotations.initMocks(this);
123         FakeSettingsProvider.clearSettingsProvider();
124 
125         mPowerSaveState = new PowerSaveState.Builder()
126                 .setBatterySaverEnabled(BATTERY_SAVER_ENABLED)
127                 .setBrightnessFactor(BRIGHTNESS_FACTOR)
128                 .build();
129         when(mBatterySaverPolicyMock.getBatterySaverPolicy(
130                 eq(PowerManager.ServiceType.SCREEN_BRIGHTNESS)))
131                 .thenReturn(mPowerSaveState);
132         when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(false);
133         when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(false);
134         when(mDisplayManagerInternalMock.requestPowerState(anyInt(), any(), anyBoolean()))
135                 .thenReturn(true);
136         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
137         when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
138 
139         addLocalServiceMock(LightsManager.class, mLightsManagerMock);
140         addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
141         addLocalServiceMock(BatteryManagerInternal.class, mBatteryManagerInternalMock);
142         addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
143         addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock);
144         addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock);
145 
146         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
147         mResourcesSpy = spy(mContextSpy.getResources());
148         when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
149 
150         MockContentResolver cr = new MockContentResolver(mContextSpy);
151         cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
152         when(mContextSpy.getContentResolver()).thenReturn(cr);
153 
154         when(mContextSpy.getSystemService(DeviceStateManager.class))
155                 .thenReturn(mDeviceStateManagerMock);
156 
157         Settings.Global.putInt(mContextSpy.getContentResolver(),
158                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
159 
160         mClock = new OffsettableClock.Stopped();
161         mTestLooper = new TestLooper(mClock::now);
162     }
163 
createService()164     private PowerManagerService createService() {
165         mService = new PowerManagerService(mContextSpy, new Injector() {
166             @Override
167             Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
168                     SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
169                     FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
170                     Executor executor) {
171                 return mNotifierMock;
172             }
173 
174             @Override
175             SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
176                 return super.createSuspendBlocker(service, name);
177             }
178 
179             @Override
180             BatterySaverPolicy createBatterySaverPolicy(
181                     Object lock, Context context, BatterySavingStats batterySavingStats) {
182                 return mBatterySaverPolicyMock;
183             }
184 
185             @Override
186             BatterySaverController createBatterySaverController(
187                     Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
188                     BatterySavingStats batterySavingStats) {
189                 return mBatterySaverControllerMock;
190             }
191 
192             @Override
193             BatterySaverStateMachine createBatterySaverStateMachine(Object lock, Context context,
194                     BatterySaverController batterySaverController) {
195                 return mBatterySaverStateMachineMock;
196             }
197 
198             @Override
199             NativeWrapper createNativeWrapper() {
200                 return mNativeWrapperMock;
201             }
202 
203             @Override
204             WirelessChargerDetector createWirelessChargerDetector(
205                     SensorManager sensorManager, SuspendBlocker suspendBlocker, Handler handler) {
206                 return mWirelessChargerDetectorMock;
207             }
208 
209             @Override
210             AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) {
211                 return mAmbientDisplayConfigurationMock;
212             }
213 
214             @Override
215             InattentiveSleepWarningController createInattentiveSleepWarningController() {
216                 return mInattentiveSleepWarningControllerMock;
217             }
218 
219             @Override
220             public SystemPropertiesWrapper createSystemPropertiesWrapper() {
221                 return mSystemPropertiesMock;
222             }
223 
224             @Override
225             PowerManagerService.Clock createClock() {
226                 return new PowerManagerService.Clock() {
227                     @Override
228                     public long uptimeMillis() {
229                         return mClock.now();
230                     }
231 
232                     @Override
233                     public long elapsedRealtime() {
234                         return mClock.now();
235                     }
236                 };
237             }
238 
239             @Override
240             Handler createHandler(Looper looper, Handler.Callback callback) {
241                 return new Handler(mTestLooper.getLooper(), callback);
242             }
243 
244             @Override
245             void invalidateIsInteractiveCaches() {
246                 // Avoids an SELinux failure.
247             }
248         });
249         return mService;
250     }
251 
252     @After
tearDown()253     public void tearDown() throws Exception {
254         LocalServices.removeServiceForTest(LightsManager.class);
255         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
256         LocalServices.removeServiceForTest(BatteryManagerInternal.class);
257         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
258         LocalServices.removeServiceForTest(AttentionManagerInternal.class);
259         LocalServices.removeServiceForTest(DreamManagerInternal.class);
260         FakeSettingsProvider.clearSettingsProvider();
261     }
262 
263     /**
264      * Creates a mock and registers it to {@link LocalServices}.
265      */
addLocalServiceMock(Class<T> clazz, T mock)266     private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
267         LocalServices.removeServiceForTest(clazz);
268         LocalServices.addService(clazz, mock);
269     }
270 
advanceTime(long timeMs)271     private void advanceTime(long timeMs) {
272         mClock.fastForward(timeMs);
273         mTestLooper.dispatchAll();
274     }
275 
276     @Test
testUserActivityOnDeviceStateChange()277     public void testUserActivityOnDeviceStateChange() {
278         createService();
279         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
280         mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
281 
282         final DisplayInfo info = new DisplayInfo();
283         info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
284         when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
285 
286         final ArgumentCaptor<DeviceStateCallback> deviceStateCallbackCaptor =
287                 ArgumentCaptor.forClass(DeviceStateCallback.class);
288         verify(mDeviceStateManagerMock).registerCallback(any(),
289                 deviceStateCallbackCaptor.capture());
290 
291         // Advance the time 10001 and verify that the device thinks it has been idle
292         // for just less than that.
293         mService.onUserActivity();
294         advanceTime(10001);
295         assertThat(mService.wasDeviceIdleForInternal(10000)).isTrue();
296 
297         // Send a display state change event and advance the clock 10.
298         final DeviceStateCallback deviceStateCallback = deviceStateCallbackCaptor.getValue();
299         deviceStateCallback.onStateChanged(1);
300         final long timeToAdvance = 10;
301         advanceTime(timeToAdvance);
302 
303         // Ensure that the device has been idle for only 10 (doesn't include the idle time
304         // before the display state event).
305         assertThat(mService.wasDeviceIdleForInternal(timeToAdvance - 1)).isTrue();
306         assertThat(mService.wasDeviceIdleForInternal(timeToAdvance)).isFalse();
307 
308         // Send the same state and ensure that does not trigger an update.
309         deviceStateCallback.onStateChanged(1);
310         advanceTime(timeToAdvance);
311         final long newTime = timeToAdvance * 2;
312 
313         assertThat(mService.wasDeviceIdleForInternal(newTime - 1)).isTrue();
314         assertThat(mService.wasDeviceIdleForInternal(newTime)).isFalse();
315     }
316 }
317