blob: 0aed63d2511229bf4f0fd5311b181f09f5bf2362 [file] [log] [blame]
Jason Monkd819c312017-08-11 12:53:36 -04001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.power;
16
Jason Monkd819c312017-08-11 12:53:36 -040017import static android.provider.Settings.Global.SHOW_TEMPERATURE_WARNING;
Sherry Huangce02ed32019-01-17 20:37:29 +080018import static android.provider.Settings.Global.SHOW_USB_TEMPERATURE_ALARM;
Jason Monkd819c312017-08-11 12:53:36 -040019
Salvador Martinezf9e47502018-01-04 13:45:48 -080020import static junit.framework.Assert.assertFalse;
21import static junit.framework.Assert.assertTrue;
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040022
Sherry Huangce02ed32019-01-17 20:37:29 +080023import static org.mockito.Matchers.eq;
24import static org.mockito.Mockito.anyObject;
Jason Monkd819c312017-08-11 12:53:36 -040025import static org.mockito.Mockito.mock;
26import static org.mockito.Mockito.never;
Salvador Martinez926f0712018-07-03 18:07:07 -070027import static org.mockito.Mockito.times;
Jason Monkd819c312017-08-11 12:53:36 -040028import static org.mockito.Mockito.verify;
29import static org.mockito.Mockito.when;
30
31import android.content.Context;
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040032import android.content.Intent;
Salvador Martinezf9e47502018-01-04 13:45:48 -080033import android.os.BatteryManager;
Sherry Huangce02ed32019-01-17 20:37:29 +080034import android.os.IThermalEventListener;
Wei Wangbf05e602018-11-21 11:46:48 -080035import android.os.IThermalService;
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040036import android.os.PowerManager;
Sherry Huangce02ed32019-01-17 20:37:29 +080037import android.os.Temperature;
Jason Monkd819c312017-08-11 12:53:36 -040038import android.provider.Settings;
Wei Wangbf05e602018-11-21 11:46:48 -080039import android.test.suitebuilder.annotation.SmallTest;
Jason Monkd819c312017-08-11 12:53:36 -040040import android.testing.AndroidTestingRunner;
Wei Wangfeb9de62018-11-26 14:35:17 -080041import android.testing.TestableLooper;
Jason Monkd819c312017-08-11 12:53:36 -040042import android.testing.TestableLooper.RunWithLooper;
43import android.testing.TestableResources;
Jason Monkd819c312017-08-11 12:53:36 -040044
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040045import com.android.settingslib.utils.ThreadUtils;
Jason Monkd819c312017-08-11 12:53:36 -040046import com.android.systemui.R;
47import com.android.systemui.SysuiTestCase;
48import com.android.systemui.power.PowerUI.WarningsUI;
49import com.android.systemui.statusbar.phone.StatusBar;
50
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040054import org.mockito.Mock;
55import org.mockito.MockitoAnnotations;
Jason Monkd819c312017-08-11 12:53:36 -040056
Wei Wangbf05e602018-11-21 11:46:48 -080057import java.time.Duration;
58import java.util.concurrent.CountDownLatch;
59import java.util.concurrent.TimeUnit;
60
Jason Monkd819c312017-08-11 12:53:36 -040061@RunWith(AndroidTestingRunner.class)
62@RunWithLooper
63@SmallTest
64public class PowerUITest extends SysuiTestCase {
65
Salvador Martinezf9e47502018-01-04 13:45:48 -080066 private static final boolean UNPLUGGED = false;
67 private static final boolean POWER_SAVER_OFF = false;
68 private static final int ABOVE_WARNING_BUCKET = 1;
Salvador Martinezbb902fc2018-01-22 19:46:55 -080069 private static final long ONE_HOUR_MILLIS = Duration.ofHours(1).toMillis();
Salvador Martinezf9e47502018-01-04 13:45:48 -080070 public static final int BELOW_WARNING_BUCKET = -1;
71 public static final long BELOW_HYBRID_THRESHOLD = TimeUnit.HOURS.toMillis(2);
Salvador Martinez88b0d502018-10-01 11:31:43 -070072 public static final long BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(30);
Salvador Martinezf9e47502018-01-04 13:45:48 -080073 public static final long ABOVE_HYBRID_THRESHOLD = TimeUnit.HOURS.toMillis(4);
Salvador Martinezfd38aa52018-03-28 23:56:59 -070074 private static final long ABOVE_CHARGE_CYCLE_THRESHOLD = Duration.ofHours(8).toMillis();
Salvador Martinez926f0712018-07-03 18:07:07 -070075 private static final int OLD_BATTERY_LEVEL_NINE = 9;
76 private static final int OLD_BATTERY_LEVEL_10 = 10;
Salvador Martinez88b0d502018-10-01 11:31:43 -070077 private static final long VERY_BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(15);
Jason Monkd819c312017-08-11 12:53:36 -040078 private WarningsUI mMockWarnings;
79 private PowerUI mPowerUI;
Salvador Martinezbb902fc2018-01-22 19:46:55 -080080 private EnhancedEstimates mEnhancedEstimates;
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040081 @Mock private PowerManager mPowerManager;
Wei Wangbf05e602018-11-21 11:46:48 -080082 @Mock private IThermalService mThermalServiceMock;
Sherry Huangce02ed32019-01-17 20:37:29 +080083 private IThermalEventListener mThermalEventUsbListener;
84 private IThermalEventListener mThermalEventSkinListener;
Jason Monkd819c312017-08-11 12:53:36 -040085
86 @Before
87 public void setup() {
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040088 MockitoAnnotations.initMocks(this);
Jason Monkd819c312017-08-11 12:53:36 -040089 mMockWarnings = mDependency.injectMockDependency(WarningsUI.class);
Salvador Martinezbb902fc2018-01-22 19:46:55 -080090 mEnhancedEstimates = mDependency.injectMockDependency(EnhancedEstimates.class);
Salvador Martinezf9e47502018-01-04 13:45:48 -080091
Jason Monkd819c312017-08-11 12:53:36 -040092 mContext.putComponent(StatusBar.class, mock(StatusBar.class));
Amin Shaikh2f6c45c2018-04-16 14:00:09 -040093 mContext.addMockSystemService(Context.POWER_SERVICE, mPowerManager);
Jason Monkd819c312017-08-11 12:53:36 -040094
95 createPowerUi();
Sherry Huangce02ed32019-01-17 20:37:29 +080096 mThermalEventSkinListener = mPowerUI.new ThermalEventSkinListener();
97 mThermalEventUsbListener = mPowerUI.new ThermalEventUsbListener();
Jason Monkd819c312017-08-11 12:53:36 -040098 }
99
100 @Test
Sherry Huangce02ed32019-01-17 20:37:29 +0800101 public void testSkinWarning_throttlingCritical() throws Exception {
Jason Monkd819c312017-08-11 12:53:36 -0400102 mPowerUI.start();
Jason Monkd819c312017-08-11 12:53:36 -0400103
Sherry Huangce02ed32019-01-17 20:37:29 +0800104 final Temperature temp = getCriticalStatusTemp(Temperature.TYPE_SKIN, "skin1");
105 mThermalEventSkinListener.notifyThrottling(temp);
Jason Monkd819c312017-08-11 12:53:36 -0400106
Sherry Huangce02ed32019-01-17 20:37:29 +0800107 // dismiss skin high temperature warning when throttling status is critical
Wei Wangfeb9de62018-11-26 14:35:17 -0800108 TestableLooper.get(this).processAllMessages();
Sherry Huangce02ed32019-01-17 20:37:29 +0800109 verify(mMockWarnings, never()).showHighTemperatureWarning();
110 verify(mMockWarnings, times(1)).dismissHighTemperatureWarning();
Jason Monkd819c312017-08-11 12:53:36 -0400111 }
112
113 @Test
Sherry Huangce02ed32019-01-17 20:37:29 +0800114 public void testSkinWarning_throttlingEmergency() throws Exception {
115 mPowerUI.start();
116
117 final Temperature temp = getEmergencyStatusTemp(Temperature.TYPE_SKIN, "skin2");
118 mThermalEventSkinListener.notifyThrottling(temp);
119
120 // show skin high temperature warning when throttling status is emergency
121 TestableLooper.get(this).processAllMessages();
122 verify(mMockWarnings, times(1)).showHighTemperatureWarning();
123 verify(mMockWarnings, never()).dismissHighTemperatureWarning();
124 }
125
126 @Test
127 public void testUsbAlarm_throttlingCritical() throws Exception {
128 mPowerUI.start();
129
130 final Temperature temp = getCriticalStatusTemp(Temperature.TYPE_USB_PORT, "usb1");
131 mThermalEventUsbListener.notifyThrottling(temp);
132
133 // not show usb high temperature alarm when throttling status is critical
134 TestableLooper.get(this).processAllMessages();
135 verify(mMockWarnings, never()).showUsbHighTemperatureAlarm();
136 }
137
138 @Test
139 public void testUsbAlarm_throttlingEmergency() throws Exception {
140 mPowerUI.start();
141
142 final Temperature temp = getEmergencyStatusTemp(Temperature.TYPE_USB_PORT, "usb2");
143 mThermalEventUsbListener.notifyThrottling(temp);
144
145 // show usb high temperature alarm when throttling status is emergency
146 TestableLooper.get(this).processAllMessages();
147 verify(mMockWarnings, times(1)).showUsbHighTemperatureAlarm();
148 }
149
150 @Test
151 public void testSettingOverrideConfig_enableSkinTemperatureWarning() throws Exception {
Jason Monkd819c312017-08-11 12:53:36 -0400152 Settings.Global.putInt(mContext.getContentResolver(), SHOW_TEMPERATURE_WARNING, 1);
153 TestableResources resources = mContext.getOrCreateTestableResources();
154 resources.addOverride(R.integer.config_showTemperatureWarning, 0);
Jason Monkd819c312017-08-11 12:53:36 -0400155
156 mPowerUI.start();
Sherry Huangce02ed32019-01-17 20:37:29 +0800157 mPowerUI.registerThermalEventListener();
158
Wei Wangfeb9de62018-11-26 14:35:17 -0800159 TestableLooper.get(this).processAllMessages();
Sherry Huangce02ed32019-01-17 20:37:29 +0800160 verify(mThermalServiceMock, times(1))
161 .registerThermalEventListenerWithType(anyObject(), eq(Temperature.TYPE_SKIN));
Jason Monkd819c312017-08-11 12:53:36 -0400162 }
163
164 @Test
Sherry Huangce02ed32019-01-17 20:37:29 +0800165 public void testSettingOverrideConfig_enableUsbTemperatureAlarm() throws Exception {
166 Settings.Global.putInt(mContext.getContentResolver(), SHOW_USB_TEMPERATURE_ALARM, 1);
Jason Monkd819c312017-08-11 12:53:36 -0400167 TestableResources resources = mContext.getOrCreateTestableResources();
Sherry Huangce02ed32019-01-17 20:37:29 +0800168 resources.addOverride(R.integer.config_showUsbPortAlarm, 0);
Jason Monkd819c312017-08-11 12:53:36 -0400169
Jason Monkd819c312017-08-11 12:53:36 -0400170 mPowerUI.start();
Sherry Huangce02ed32019-01-17 20:37:29 +0800171 mPowerUI.registerThermalEventListener();
Jason Monkd819c312017-08-11 12:53:36 -0400172
Sherry Huangce02ed32019-01-17 20:37:29 +0800173 TestableLooper.get(this).processAllMessages();
174 verify(mThermalServiceMock, times(1))
175 .registerThermalEventListenerWithType(anyObject(), eq(Temperature.TYPE_USB_PORT));
Jason Monkd819c312017-08-11 12:53:36 -0400176 }
177
Salvador Martinezf9e47502018-01-04 13:45:48 -0800178 @Test
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800179 public void testShouldShowLowBatteryWarning_showHybridOnly_overrideThresholdHigh_returnsNoShow() {
180 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
181 when(mEnhancedEstimates.getLowWarningThreshold())
182 .thenReturn(Duration.ofHours(1).toMillis());
183 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
184 mPowerUI.start();
185
186 // unplugged device that would not show the non-hybrid notification but would show the
187 // hybrid but the threshold has been overriden to be too low
188 boolean shouldShow =
189 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800190 ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800191 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
192 assertFalse(shouldShow);
193 }
194
195 @Test
196 public void testShouldShowLowBatteryWarning_showHybridOnly_overrideThresholdHigh_returnsShow() {
197 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
198 when(mEnhancedEstimates.getLowWarningThreshold())
199 .thenReturn(Duration.ofHours(5).toMillis());
200 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
201 mPowerUI.start();
202
203 // unplugged device that would not show the non-hybrid notification but would show the
204 // hybrid since the threshold has been overriden to be much higher
205 boolean shouldShow =
206 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800207 ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800208 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
209 assertTrue(shouldShow);
210 }
211
212 @Test
Salvador Martinezf9e47502018-01-04 13:45:48 -0800213 public void testShouldShowLowBatteryWarning_showHybridOnly_returnsShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800214 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
215 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
216 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800217 mPowerUI.start();
218
219 // unplugged device that would not show the non-hybrid notification but would show the
220 // hybrid
221 boolean shouldShow =
222 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800223 ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800224 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
225 assertTrue(shouldShow);
226 }
227
228 @Test
229 public void testShouldShowLowBatteryWarning_showHybrid_showStandard_returnsShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800230 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
231 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
232 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezfd38aa52018-03-28 23:56:59 -0700233 mPowerUI.mBatteryLevel = 10;
Salvador Martinezf9e47502018-01-04 13:45:48 -0800234 mPowerUI.start();
235
236 // unplugged device that would show the non-hybrid notification and the hybrid
237 boolean shouldShow =
238 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800239 BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800240 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
241 assertTrue(shouldShow);
242 }
243
244 @Test
245 public void testShouldShowLowBatteryWarning_showStandardOnly_returnsShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800246 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
247 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
248 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezfd38aa52018-03-28 23:56:59 -0700249 mPowerUI.mBatteryLevel = 10;
Salvador Martinezf9e47502018-01-04 13:45:48 -0800250 mPowerUI.start();
251
252 // unplugged device that would show the non-hybrid but not the hybrid
253 boolean shouldShow =
254 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800255 BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800256 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
257 assertTrue(shouldShow);
258 }
259
260 @Test
261 public void testShouldShowLowBatteryWarning_deviceHighBattery_returnsNoShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800262 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
263 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
264 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800265 mPowerUI.start();
266
267 // unplugged device that would show the neither due to battery level being good
268 boolean shouldShow =
269 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800270 ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800271 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
272 assertFalse(shouldShow);
273 }
274
275 @Test
276 public void testShouldShowLowBatteryWarning_devicePlugged_returnsNoShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800277 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
278 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
279 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800280 mPowerUI.start();
281
282 // plugged device that would show the neither due to being plugged
283 boolean shouldShow =
284 mPowerUI.shouldShowLowBatteryWarning(!UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800285 BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800286 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
287 assertFalse(shouldShow);
288 }
289
290 @Test
Salvador Martinezfd38aa52018-03-28 23:56:59 -0700291 public void testShouldShowLowBatteryWarning_deviceBatteryStatusUnknown_returnsNoShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800292 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
293 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
294 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800295 mPowerUI.start();
296
Salvador Martinezfd38aa52018-03-28 23:56:59 -0700297 // Unknown battery status device that would show the neither due to the battery status being
298 // unknown
Salvador Martinezf9e47502018-01-04 13:45:48 -0800299 boolean shouldShow =
300 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800301 BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800302 !POWER_SAVER_OFF, BatteryManager.BATTERY_STATUS_UNKNOWN);
303 assertFalse(shouldShow);
304 }
305
306 @Test
307 public void testShouldShowLowBatteryWarning_batterySaverEnabled_returnsNoShow() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800308 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
309 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
310 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800311 mPowerUI.start();
312
313 // BatterySaverEnabled device that would show the neither due to battery saver
314 boolean shouldShow =
315 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
Salvador Martinez36307962018-02-08 14:29:08 -0800316 BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
Salvador Martinezf9e47502018-01-04 13:45:48 -0800317 !POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
318 assertFalse(shouldShow);
319 }
320
321 @Test
Salvador Martinez36307962018-02-08 14:29:08 -0800322 public void testShouldShowLowBatteryWarning_onlyShowsOncePerChargeCycle() {
323 mPowerUI.start();
324 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
325 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
326 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
327 when(mEnhancedEstimates.getEstimate())
328 .thenReturn(new Estimate(BELOW_HYBRID_THRESHOLD, true));
329 mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
330
Salvador Martinez926f0712018-07-03 18:07:07 -0700331 mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
332 ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
Salvador Martinezfd38aa52018-03-28 23:56:59 -0700333
334 // reduce battery level to handle time based trigger -> level trigger interactions
335 mPowerUI.mBatteryLevel = 10;
Salvador Martinez36307962018-02-08 14:29:08 -0800336 boolean shouldShow =
337 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
338 ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
339 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
340 assertFalse(shouldShow);
341 }
342
343 @Test
Salvador Martinezc25604b2018-08-03 14:07:44 -0700344 public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabledLegacy() {
Salvador Martinezf9e47502018-01-04 13:45:48 -0800345 mPowerUI.start();
Salvador Martinezc25604b2018-08-03 14:07:44 -0700346 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false);
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800347 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
348 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
349
Salvador Martinezf9e47502018-01-04 13:45:48 -0800350 // device that gets power saver turned on should dismiss
351 boolean shouldDismiss =
352 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
353 BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF);
354 assertTrue(shouldDismiss);
355 }
356
357 @Test
Salvador Martinezc25604b2018-08-03 14:07:44 -0700358 public void testShouldNotDismissLowBatteryWarning_dismissWhenPowerSaverEnabledHybrid() {
359 mPowerUI.start();
360 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
361 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
362 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
363
364 // device that gets power saver turned on should dismiss
365 boolean shouldDismiss =
366 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
367 BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF);
368 assertFalse(shouldDismiss);
369 }
370
371 @Test
Salvador Martinezf9e47502018-01-04 13:45:48 -0800372 public void testShouldDismissLowBatteryWarning_dismissWhenPlugged() {
373 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800374 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
375 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
376 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800377
378 // device that gets plugged in should dismiss
379 boolean shouldDismiss =
380 mPowerUI.shouldDismissLowBatteryWarning(!UNPLUGGED, BELOW_WARNING_BUCKET,
381 BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
382 assertTrue(shouldDismiss);
383 }
384
385 @Test
386 public void testShouldDismissLowBatteryWarning_dismissHybridSignal_showStandardSignal_shouldShow() {
387 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800388 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
389 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
390 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
391
Salvador Martinezf9e47502018-01-04 13:45:48 -0800392 // would dismiss hybrid but not non-hybrid should not dismiss
393 boolean shouldDismiss =
394 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
395 BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
396 assertFalse(shouldDismiss);
397 }
398
399 @Test
400 public void testShouldDismissLowBatteryWarning_showHybridSignal_dismissStandardSignal_shouldShow() {
401 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800402 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
403 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
404 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800405
406 // would dismiss non-hybrid but not hybrid should not dismiss
407 boolean shouldDismiss =
408 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
409 ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD, POWER_SAVER_OFF);
410 assertFalse(shouldDismiss);
411 }
412
413 @Test
414 public void testShouldDismissLowBatteryWarning_showBothSignal_shouldShow() {
415 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800416 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
417 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
418 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800419
420 // should not dismiss when both would not dismiss
421 boolean shouldDismiss =
422 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
423 BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD, POWER_SAVER_OFF);
424 assertFalse(shouldDismiss);
425 }
426
427 @Test
428 public void testShouldDismissLowBatteryWarning_dismissBothSignal_shouldDismiss() {
429 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800430 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
431 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
432 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800433
434 //should dismiss if both would dismiss
435 boolean shouldDismiss =
436 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
437 ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
438 assertTrue(shouldDismiss);
439 }
440
441 @Test
442 public void testShouldDismissLowBatteryWarning_dismissStandardSignal_hybridDisabled_shouldDismiss() {
443 mPowerUI.start();
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800444 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false);
445 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
446 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800447
448 // would dismiss non-hybrid with hybrid disabled should dismiss
449 boolean shouldDismiss =
450 mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
451 ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
452 assertTrue(shouldDismiss);
453 }
454
Amin Shaikh2f6c45c2018-04-16 14:00:09 -0400455 @Test
456 public void testShouldDismissLowBatteryWarning_powerSaverModeEnabled()
457 throws InterruptedException {
458 when(mPowerManager.isPowerSaveMode()).thenReturn(true);
459
460 mPowerUI.start();
461 mPowerUI.mReceiver.onReceive(mContext,
462 new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
463
464 CountDownLatch latch = new CountDownLatch(1);
465 ThreadUtils.postOnBackgroundThread(() -> latch.countDown());
466 latch.await(5, TimeUnit.SECONDS);
467
468 verify(mMockWarnings).dismissLowBatteryWarning();
469 }
470
471 @Test
472 public void testShouldNotDismissLowBatteryWarning_powerSaverModeDisabled()
473 throws InterruptedException {
474 when(mPowerManager.isPowerSaveMode()).thenReturn(false);
475
476 mPowerUI.start();
477 mPowerUI.mReceiver.onReceive(mContext,
478 new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
479
480 CountDownLatch latch = new CountDownLatch(1);
481 ThreadUtils.postOnBackgroundThread(() -> latch.countDown());
482 latch.await(5, TimeUnit.SECONDS);
483
484 verify(mMockWarnings, never()).dismissLowBatteryWarning();
485 }
486
Salvador Martinez926f0712018-07-03 18:07:07 -0700487 @Test
Salvador Martinez88b0d502018-10-01 11:31:43 -0700488 public void testSevereWarning_countsAsLowAndSevere_WarningOnlyShownOnce() {
489 mPowerUI.start();
490 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
491 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
492 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
493 when(mEnhancedEstimates.getEstimate())
494 .thenReturn(new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true));
495 mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
496
497 // reduce battery level to handle time based trigger -> level trigger interactions
498 mPowerUI.mBatteryLevel = 5;
499 boolean shouldShow =
500 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
501 ABOVE_WARNING_BUCKET, BELOW_SEVERE_HYBRID_THRESHOLD,
502 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
503 assertTrue(shouldShow);
504
505 // actually run the end to end since it handles changing the internal state.
506 mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_10, UNPLUGGED, UNPLUGGED,
507 ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
508
509 shouldShow =
510 mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
511 ABOVE_WARNING_BUCKET, VERY_BELOW_SEVERE_HYBRID_THRESHOLD,
512 POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
513 assertFalse(shouldShow);
514 }
515
516 @Test
Salvador Martinez926f0712018-07-03 18:07:07 -0700517 public void testMaybeShowBatteryWarning_onlyQueriesEstimateOnBatteryLevelChangeOrNull() {
518 mPowerUI.start();
519 Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
520 when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
521 when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
522 when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
523 when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
524 mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
525
526 // we expect that the first time it will query even if the level is the same
527 mPowerUI.mBatteryLevel = 9;
528 mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
529 ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
530 verify(mEnhancedEstimates, times(1)).getEstimate();
531
532 // We should NOT query again if the battery level hasn't changed
533 mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
534 ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
535 verify(mEnhancedEstimates, times(1)).getEstimate();
536
537 // Battery level has changed, so we should query again
538 mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_10, UNPLUGGED, UNPLUGGED,
539 ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
540 verify(mEnhancedEstimates, times(2)).getEstimate();
541 }
542
Sherry Huangce02ed32019-01-17 20:37:29 +0800543 private Temperature getEmergencyStatusTemp(int type, String name) {
544 final float value = 65;
545 return new Temperature(value, type, name, Temperature.THROTTLING_EMERGENCY);
Jason Monkd819c312017-08-11 12:53:36 -0400546 }
547
Sherry Huangce02ed32019-01-17 20:37:29 +0800548 private Temperature getCriticalStatusTemp(int type, String name) {
549 final float value = 60;
550 return new Temperature(value, type, name, Temperature.THROTTLING_CRITICAL);
Jason Monkd819c312017-08-11 12:53:36 -0400551 }
552
553 private void createPowerUi() {
554 mPowerUI = new PowerUI();
555 mPowerUI.mContext = mContext;
556 mPowerUI.mComponents = mContext.getComponents();
Wei Wangbf05e602018-11-21 11:46:48 -0800557 mPowerUI.mThermalService = mThermalServiceMock;
Jason Monkd819c312017-08-11 12:53:36 -0400558 }
559}