OSDN Git Service

Merge "NullPointerException when running monkey test in IccLockSettings" am: 2c8d826b...
[android-x86/packages-apps-Settings.git] / tests / robotests / src / com / android / settings / fuelgauge / BatteryUtilsTest.java
1 /*
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 package com.android.settings.fuelgauge;
17
18 import android.content.Context;
19 import android.os.BatteryStats;
20 import android.os.Process;
21 import android.text.format.DateUtils;
22
23 import com.android.internal.os.BatterySipper;
24 import com.android.internal.os.BatteryStatsHelper;
25 import com.android.settings.SettingsRobolectricTestRunner;
26 import com.android.settings.TestConfig;
27 import com.android.settings.testutils.FakeFeatureFactory;
28
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.Answers;
33 import org.mockito.Mock;
34 import org.mockito.MockitoAnnotations;
35 import org.robolectric.RuntimeEnvironment;
36 import org.robolectric.annotation.Config;
37
38 import java.util.ArrayList;
39 import java.util.List;
40
41 import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
42 import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND;
43 import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE;
44 import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
45 import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING;
46
47 import static com.google.common.truth.Truth.assertThat;
48
49 import static org.mockito.Matchers.any;
50 import static org.mockito.Matchers.anyInt;
51 import static org.mockito.Matchers.anyLong;
52 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
53 import static org.mockito.Mockito.doNothing;
54 import static org.mockito.Mockito.doReturn;
55 import static org.mockito.Matchers.eq;
56 import static org.mockito.Mockito.mock;
57 import static org.mockito.Mockito.when;
58 import static org.mockito.Mockito.spy;
59
60 @RunWith(SettingsRobolectricTestRunner.class)
61 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
62 public class BatteryUtilsTest {
63     // unit that used to converted ms to us
64     private static final long UNIT = 1000;
65     private static final long TIME_STATE_TOP = 1500 * UNIT;
66     private static final long TIME_STATE_FOREGROUND_SERVICE = 2000 * UNIT;
67     private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT;
68     private static final long TIME_STATE_FOREGROUND = 3000 * UNIT;
69     private static final long TIME_STATE_BACKGROUND = 6000 * UNIT;
70     private static final long TIME_FOREGROUND_ACTIVITY_ZERO = 0;
71     private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS;
72     private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000;
73     private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
74             TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;
75
76     private static final int UID = 123;
77     private static final long TIME_EXPECTED_FOREGROUND = 1500;
78     private static final long TIME_EXPECTED_BACKGROUND = 6000;
79     private static final long TIME_EXPECTED_ALL = 7500;
80     private static final double BATTERY_SCREEN_USAGE = 300;
81     private static final double BATTERY_SYSTEM_USAGE = 600;
82     private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
83     private static final double BATTERY_UNACCOUNTED_USAGE = 700;
84     private static final double BATTERY_APP_USAGE = 100;
85     private static final double TOTAL_BATTERY_USAGE = 1000;
86     private static final double HIDDEN_USAGE = 200;
87     private static final int DISCHARGE_AMOUNT = 80;
88     private static final double PERCENT_SYSTEM_USAGE = 60;
89     private static final double PRECISION = 0.001;
90
91     @Mock
92     private BatteryStats.Uid mUid;
93     @Mock
94     private BatterySipper mNormalBatterySipper;
95     @Mock
96     private BatterySipper mScreenBatterySipper;
97     @Mock
98     private BatterySipper mOvercountedBatterySipper;
99     @Mock
100     private BatterySipper mUnaccountedBatterySipper;
101     @Mock
102     private BatterySipper mSystemBatterySipper;
103     @Mock
104     private BatterySipper mCellBatterySipper;
105     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
106     private Context mContext;
107     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
108     private BatteryStatsHelper mBatteryStatsHelper;
109     private BatteryUtils mBatteryUtils;
110     private FakeFeatureFactory mFeatureFactory;
111     private PowerUsageFeatureProvider mProvider;
112
113     @Before
114     public void setUp() {
115         MockitoAnnotations.initMocks(this);
116
117         FakeFeatureFactory.setupForTest(mContext);
118         mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
119         mProvider = mFeatureFactory.powerUsageFeatureProvider;
120
121         doReturn(TIME_STATE_TOP).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP), anyLong(),
122                 anyInt());
123         doReturn(TIME_STATE_FOREGROUND_SERVICE).when(mUid).getProcessStateTime(
124                 eq(PROCESS_STATE_FOREGROUND_SERVICE), anyLong(), anyInt());
125         doReturn(TIME_STATE_TOP_SLEEPING).when(mUid).getProcessStateTime(
126                 eq(PROCESS_STATE_TOP_SLEEPING), anyLong(), anyInt());
127         doReturn(TIME_STATE_FOREGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_FOREGROUND),
128                 anyLong(), anyInt());
129         doReturn(TIME_STATE_BACKGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_BACKGROUND),
130                 anyLong(), anyInt());
131         when(mBatteryStatsHelper.getStats().computeBatteryRealtime(anyLong(), anyInt())).thenReturn(
132                 TIME_SINCE_LAST_FULL_CHARGE_US);
133
134         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
135         mNormalBatterySipper.totalPowerMah = TOTAL_BATTERY_USAGE;
136
137         mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
138         mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE;
139
140         mSystemBatterySipper.drainType = BatterySipper.DrainType.APP;
141         mSystemBatterySipper.totalPowerMah = BATTERY_SYSTEM_USAGE;
142         when(mSystemBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID);
143
144         mOvercountedBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
145         mOvercountedBatterySipper.totalPowerMah = BATTERY_OVERACCOUNTED_USAGE;
146
147         mUnaccountedBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
148         mUnaccountedBatterySipper.totalPowerMah = BATTERY_UNACCOUNTED_USAGE;
149
150         mBatteryUtils = BatteryUtils.getInstance(RuntimeEnvironment.application);
151         mBatteryUtils.mPowerUsageFeatureProvider = mProvider;
152
153         mBatteryUtils = spy(new BatteryUtils(RuntimeEnvironment.application));
154     }
155
156     @Test
157     public void testGetProcessTimeMs_typeForeground_timeCorrect() {
158         final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid,
159                 BatteryStats.STATS_SINCE_CHARGED);
160
161         assertThat(time).isEqualTo(TIME_EXPECTED_FOREGROUND);
162     }
163
164     @Test
165     public void testGetProcessTimeMs_typeBackground_timeCorrect() {
166         final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid,
167                 BatteryStats.STATS_SINCE_CHARGED);
168
169         assertThat(time).isEqualTo(TIME_EXPECTED_BACKGROUND);
170     }
171
172     @Test
173     public void testGetProcessTimeMs_typeAll_timeCorrect() {
174         final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid,
175                 BatteryStats.STATS_SINCE_CHARGED);
176
177         assertThat(time).isEqualTo(TIME_EXPECTED_ALL);
178     }
179
180     @Test
181     public void testGetProcessTimeMs_uidNull_returnZero() {
182         final long time = mBatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null,
183                 BatteryStats.STATS_SINCE_CHARGED);
184
185         assertThat(time).isEqualTo(0);
186     }
187
188     @Test
189     public void testRemoveHiddenBatterySippers_ContainsHiddenSippers_RemoveAndReturnValue() {
190         final List<BatterySipper> sippers = new ArrayList<>();
191         sippers.add(mNormalBatterySipper);
192         sippers.add(mScreenBatterySipper);
193         sippers.add(mSystemBatterySipper);
194         sippers.add(mOvercountedBatterySipper);
195         sippers.add(mUnaccountedBatterySipper);
196         when(mProvider.isTypeSystem(mSystemBatterySipper))
197                 .thenReturn(true);
198         doNothing().when(mBatteryUtils).smearScreenBatterySipper(any(), any());
199
200         final double totalUsage = mBatteryUtils.removeHiddenBatterySippers(sippers);
201
202         assertThat(sippers).containsExactly(mNormalBatterySipper);
203         assertThat(totalUsage).isWithin(PRECISION).of(BATTERY_SYSTEM_USAGE);
204     }
205
206     @Test
207     public void testShouldHideSipper_TypeUnAccounted_ReturnTrue() {
208         mNormalBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
209         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
210     }
211
212     @Test
213     public void testShouldHideSipper_TypeOverAccounted_ReturnTrue() {
214         mNormalBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED;
215         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
216     }
217
218     @Test
219     public void testShouldHideSipper_TypeIdle_ReturnTrue() {
220         mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
221         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
222     }
223
224     @Test
225     public void testShouldHideSipper_TypeCell_ReturnTrue() {
226         mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
227         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
228     }
229
230     @Test
231     public void testShouldHideSipper_TypeScreen_ReturnTrue() {
232         mNormalBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
233         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
234     }
235
236     @Test
237     public void testShouldHideSipper_TypeSystem_ReturnTrue() {
238         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
239         when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
240         when(mProvider.isTypeSystem(any())).thenReturn(true);
241         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
242     }
243
244     @Test
245     public void testShouldHideSipper_UidNormal_ReturnFalse() {
246         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
247         when(mNormalBatterySipper.getUid()).thenReturn(UID);
248         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isFalse();
249     }
250
251     @Test
252     public void testShouldHideSipper_TypeService_ReturnTrue() {
253         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
254         when(mNormalBatterySipper.getUid()).thenReturn(UID);
255         when(mProvider.isTypeService(any())).thenReturn(true);
256
257         assertThat(mBatteryUtils.shouldHideSipper(mNormalBatterySipper)).isTrue();
258     }
259
260     @Test
261     public void testCalculateBatteryPercent() {
262         assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE,
263                 HIDDEN_USAGE, DISCHARGE_AMOUNT))
264                 .isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE);
265     }
266
267     @Test
268     public void testSmearScreenBatterySipper() {
269         final BatterySipper sipperNull = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
270                 BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */);
271         final BatterySipper sipperBg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
272                 BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */);
273         final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY,
274                 BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);
275
276         final List<BatterySipper> sippers = new ArrayList<>();
277         sippers.add(sipperNull);
278         sippers.add(sipperBg);
279         sippers.add(sipperFg);
280
281         mBatteryUtils.smearScreenBatterySipper(sippers, mScreenBatterySipper);
282
283         assertThat(sipperNull.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
284         assertThat(sipperBg.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
285         assertThat(sipperFg.totalPowerMah).isWithin(PRECISION).of(
286                 BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE);
287     }
288
289     @Test
290     public void testCalculateRunningTimeBasedOnStatsType() {
291         assertThat(mBatteryUtils.calculateRunningTimeBasedOnStatsType(mBatteryStatsHelper,
292                 BatteryStats.STATS_SINCE_CHARGED)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
293     }
294
295     @Test
296     public void testSortUsageList() {
297         final List<BatterySipper> sippers = new ArrayList<>();
298         sippers.add(mNormalBatterySipper);
299         sippers.add(mScreenBatterySipper);
300         sippers.add(mSystemBatterySipper);
301
302         mBatteryUtils.sortUsageList(sippers);
303
304         assertThat(sippers).containsExactly(mNormalBatterySipper, mSystemBatterySipper,
305                 mScreenBatterySipper);
306     }
307
308     @Test
309     public void testCalculateLastFullChargeTime() {
310         final long currentTimeMs = System.currentTimeMillis();
311         when(mBatteryStatsHelper.getStats().getStartClockTime()).thenReturn(
312                 currentTimeMs - TIME_SINCE_LAST_FULL_CHARGE_MS);
313
314         assertThat(mBatteryUtils.calculateLastFullChargeTime(
315                 mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS);
316     }
317
318     private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
319             int uidCode, boolean isUidNull) {
320         final BatterySipper sipper = mock(BatterySipper.class);
321         sipper.drainType = BatterySipper.DrainType.APP;
322         sipper.totalPowerMah = totalPowerMah;
323         doReturn(uidCode).when(sipper).getUid();
324         if (!isUidNull) {
325             final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
326             doReturn(activityTime).when(mBatteryUtils).getForegroundActivityTotalTimeMs(eq(uid),
327                     anyLong());
328             doReturn(uidCode).when(uid).getUid();
329             sipper.uidObj = uid;
330         }
331
332         return sipper;
333     }
334 }