• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.settings.testutils;
18 
19 import static org.mockito.Mockito.when;
20 
21 import android.app.settings.SettingsEnums;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.hardware.usb.UsbManager;
25 import android.hardware.usb.UsbPort;
26 import android.hardware.usb.UsbPortStatus;
27 import android.os.BatteryManager;
28 import android.os.UserManager;
29 
30 import androidx.room.Room;
31 
32 import com.android.settings.DisplaySettings;
33 import com.android.settings.display.ScreenTimeoutSettings;
34 import com.android.settings.fuelgauge.batteryusage.BatteryInformation;
35 import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
36 import com.android.settings.fuelgauge.batteryusage.DeviceBatteryState;
37 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEvent;
38 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
39 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyKey;
40 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyType;
41 import com.android.settings.fuelgauge.batteryusage.WarningBannerInfo;
42 import com.android.settings.fuelgauge.batteryusage.WarningItemInfo;
43 import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao;
44 import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity;
45 import com.android.settings.fuelgauge.batteryusage.db.BatteryState;
46 import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao;
47 import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
48 
49 import com.google.common.collect.ImmutableList;
50 
51 import org.robolectric.Shadows;
52 
53 import java.util.ArrayList;
54 import java.util.List;
55 
56 public class BatteryTestUtils {
57 
getChargingIntent()58     public static Intent getChargingIntent() {
59         return getCustomBatteryIntent(
60                 BatteryManager.BATTERY_PLUGGED_AC,
61                 50 /* level */,
62                 100 /* scale */,
63                 BatteryManager.BATTERY_STATUS_CHARGING);
64     }
65 
getDischargingIntent()66     public static Intent getDischargingIntent() {
67         return getCustomBatteryIntent(
68                 0 /* plugged */,
69                 10 /* level */,
70                 100 /* scale */,
71                 BatteryManager.BATTERY_STATUS_DISCHARGING);
72     }
73 
74     /**
75      * Sets the work profile mode.
76      */
setWorkProfile(Context context)77     public static void setWorkProfile(Context context) {
78         final UserManager userManager = context.getSystemService(UserManager.class);
79         Shadows.shadowOf(userManager).setManagedProfile(true);
80         Shadows.shadowOf(userManager).setIsSystemUser(false);
81     }
82 
83     /**
84      * Creates and sets up the in-memory {@link BatteryStateDatabase}.
85      */
setUpBatteryStateDatabase(Context context)86     public static BatteryStateDatabase setUpBatteryStateDatabase(Context context) {
87         final BatteryStateDatabase inMemoryDatabase =
88                 Room.inMemoryDatabaseBuilder(context, BatteryStateDatabase.class)
89                         .allowMainThreadQueries()
90                         .build();
91         BatteryStateDatabase.setBatteryStateDatabase(inMemoryDatabase);
92         return inMemoryDatabase;
93     }
94 
95     /**
96      * Inserts a fake data into the database for testing.
97      */
insertDataToBatteryStateTable( Context context, long timestamp, String packageName)98     public static void insertDataToBatteryStateTable(
99             Context context, long timestamp, String packageName) {
100         insertDataToBatteryStateTable(
101                 context, timestamp, packageName, /*multiple=*/ false, /*isFullChargeStart=*/ false);
102     }
103 
104     /**
105      * Inserts a fake data into the database for testing.
106      */
insertDataToBatteryStateTable( Context context, long timestamp, String packageName, boolean isFullChargeStart)107     public static void insertDataToBatteryStateTable(
108             Context context, long timestamp, String packageName, boolean isFullChargeStart) {
109         insertDataToBatteryStateTable(
110                 context, timestamp, packageName, /*multiple=*/ false, isFullChargeStart);
111     }
112 
113     /**
114      * Inserts a fake data into the database for testing.
115      */
insertDataToBatteryStateTable( Context context, long timestamp, String packageName, boolean multiple, boolean isFullChargeStart)116     public static void insertDataToBatteryStateTable(
117             Context context, long timestamp, String packageName, boolean multiple,
118             boolean isFullChargeStart) {
119         DeviceBatteryState deviceBatteryState =
120                 DeviceBatteryState
121                         .newBuilder()
122                         .setBatteryLevel(31)
123                         .setBatteryStatus(0)
124                         .setBatteryHealth(0)
125                         .build();
126         BatteryInformation batteryInformation =
127                 BatteryInformation
128                         .newBuilder()
129                         .setDeviceBatteryState(deviceBatteryState)
130                         .setIsHidden(true)
131                         .setBootTimestamp(timestamp - 1)
132                         .setZoneId("Europe/Paris")
133                         .setAppLabel("Settings")
134                         .setTotalPower(100f)
135                         .setConsumePower(0.3f)
136                         .setPercentOfTotal(10f)
137                         .setDrainType(1)
138                         .setForegroundUsageTimeInMs(60000)
139                         .setBackgroundUsageTimeInMs(10000)
140                         .setForegroundUsageConsumePower(0.1f)
141                         .setForegroundServiceUsageConsumePower(0.05f)
142                         .setBackgroundUsageConsumePower(0.1f)
143                         .setCachedUsageConsumePower(0.05f)
144                         .build();
145 
146         final BatteryState state =
147                 new BatteryState(
148                         /*uid=*/ 1001L,
149                         /*userId=*/ 100L,
150                         packageName,
151                         timestamp,
152                         /*consumerType=*/ 2,
153                         isFullChargeStart,
154                         ConvertUtils.convertBatteryInformationToString(batteryInformation),
155                         "");
156         BatteryStateDao dao =
157                 BatteryStateDatabase.getInstance(context).batteryStateDao();
158         if (multiple) {
159             dao.insertAll(ImmutableList.of(state));
160         } else {
161             dao.insert(state);
162         }
163     }
164 
165     /**
166      * Inserts a fake data into the database for testing.
167      */
insertDataToAppUsageEventTable( Context context, long userId, long timestamp, String packageName)168     public static void insertDataToAppUsageEventTable(
169             Context context, long userId, long timestamp, String packageName) {
170         insertDataToAppUsageEventTable(
171                 context, userId, timestamp, packageName, /*multiple=*/ false);
172     }
173 
174     /**
175      * Inserts a fake data into the database for testing.
176      */
insertDataToAppUsageEventTable( Context context, long userId, long timestamp, String packageName, boolean multiple)177     public static void insertDataToAppUsageEventTable(
178             Context context, long userId, long timestamp, String packageName, boolean multiple) {
179         final AppUsageEventEntity entity =
180                 new AppUsageEventEntity(
181                         /*uid=*/ 101L,
182                         userId,
183                         timestamp,
184                         /*appUsageEventType=*/ 2,
185                         packageName,
186                         /*instanceId=*/ 10001,
187                         /*taskRootPackageName=*/ "com.android.settings");
188         AppUsageEventDao dao =
189                 BatteryStateDatabase.getInstance(context).appUsageEventDao();
190         if (multiple) {
191             dao.insertAll(ImmutableList.of(entity));
192         } else {
193             dao.insert(entity);
194         }
195     }
196 
197     /**
198      * Gets customized battery changed intent.
199      */
getCustomBatteryIntent(int plugged, int level, int scale, int status)200     public static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) {
201         Intent intent = new Intent();
202         intent.putExtra(BatteryManager.EXTRA_PLUGGED, plugged);
203         intent.putExtra(BatteryManager.EXTRA_LEVEL, level);
204         intent.putExtra(BatteryManager.EXTRA_SCALE, scale);
205         intent.putExtra(BatteryManager.EXTRA_STATUS, status);
206 
207         return intent;
208     }
209 
210     /**
211      * Configures the incompatible charger environment.
212      */
setupIncompatibleEvent( UsbPort mockUsbPort, UsbManager mockUsbManager, UsbPortStatus mockUsbPortStatus)213     public static void setupIncompatibleEvent(
214             UsbPort mockUsbPort, UsbManager mockUsbManager, UsbPortStatus mockUsbPortStatus) {
215         final List<UsbPort> usbPorts = new ArrayList<>();
216         usbPorts.add(mockUsbPort);
217         when(mockUsbManager.getPorts()).thenReturn(usbPorts);
218         when(mockUsbPort.getStatus()).thenReturn(mockUsbPortStatus);
219         when(mockUsbPort.supportsComplianceWarnings()).thenReturn(true);
220         when(mockUsbPortStatus.isConnected()).thenReturn(true);
221         when(mockUsbPortStatus.getComplianceWarnings())
222                 .thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_OTHER});
223     }
224 
225     /**
226      * Create an empty power anomaly event list proto.
227      */
createEmptyPowerAnomalyEventList()228     public static PowerAnomalyEventList createEmptyPowerAnomalyEventList() {
229         return PowerAnomalyEventList.getDefaultInstance();
230     }
231 
232     /**
233      * Create an non-empty power anomaly event list proto.
234      */
createNonEmptyPowerAnomalyEventList()235     public static PowerAnomalyEventList createNonEmptyPowerAnomalyEventList() {
236         return PowerAnomalyEventList.newBuilder()
237                 .addPowerAnomalyEvents(0, createAdaptiveBrightnessAnomalyEvent())
238                 .addPowerAnomalyEvents(1, createScreenTimeoutAnomalyEvent())
239                 .build();
240     }
241 
242     /**
243      * Create a power anomaly event proto of adaptive brightness.
244      */
createAdaptiveBrightnessAnomalyEvent()245     public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() {
246         return PowerAnomalyEvent.newBuilder()
247                 .setEventId("BrightnessAnomaly")
248                 .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
249                 .setKey(PowerAnomalyKey.KEY_BRIGHTNESS)
250                 .setDismissRecordKey(PowerAnomalyKey.KEY_BRIGHTNESS.name())
251                 .setScore(1.2f)
252                 .setWarningBannerInfo(WarningBannerInfo.newBuilder()
253                         .setMainButtonDestination(DisplaySettings.class.getName())
254                         .setMainButtonSourceMetricsCategory(SettingsEnums.DISPLAY)
255                         .setMainButtonSourceHighlightKey("auto_brightness_entry")
256                         .build())
257                 .build();
258     }
259 
260     /**
261      * Create a power anomaly event proto of screen timeout.
262      */
createScreenTimeoutAnomalyEvent()263     public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() {
264         return PowerAnomalyEvent.newBuilder()
265                 .setEventId("ScreenTimeoutAnomaly")
266                 .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
267                 .setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT)
268                 .setDismissRecordKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT.name())
269                 .setScore(1.1f)
270                 .setWarningBannerInfo(WarningBannerInfo.newBuilder()
271                         .setMainButtonDestination(ScreenTimeoutSettings.class.getName())
272                         .setMainButtonSourceMetricsCategory(SettingsEnums.SCREEN_TIMEOUT)
273                         .setMainButtonSourceHighlightKey("60000")
274                         .build())
275                 .build();
276     }
277 
278     /**
279      * Create a power anomaly event proto of app anomaly.
280      */
createAppAnomalyEvent()281     public static PowerAnomalyEvent createAppAnomalyEvent() {
282         return PowerAnomalyEvent.newBuilder()
283                 .setEventId("AppAnomaly")
284                 .setType(PowerAnomalyType.TYPE_APPS_ITEM)
285                 .setKey(PowerAnomalyKey.KEY_APP_TOTAL_HIGHER_THAN_USUAL)
286                 .setDismissRecordKey("KEY_APP_1")
287                 .setScore(2.0f)
288                 .setWarningItemInfo(WarningItemInfo.newBuilder()
289                         .setStartTimestamp(1694361600000L)  // 2023-09-11 00:00:00
290                         .setEndTimestamp(1694368800000L)    // 2023-09-11 02:00:00
291                         .build())
292                 .build();
293     }
294 }
295