1 /*
2  * Copyright (C) 2018 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.fuelgauge;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.spy;
22 
23 import android.content.Context;
24 import android.text.format.DateUtils;
25 import android.util.SparseLongArray;
26 
27 import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
28 import com.android.settings.fuelgauge.batterytip.AppInfo;
29 import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
30 import com.android.settings.testutils.DatabaseTestUtils;
31 
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.MockitoAnnotations;
37 import org.robolectric.RobolectricTestRunner;
38 import org.robolectric.RuntimeEnvironment;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 @RunWith(RobolectricTestRunner.class)
44 public class BatteryDatabaseManagerTest {
45     private static String PACKAGE_NAME_NEW = "com.android.app1";
46     private static int UID_NEW = 345;
47     private static int TYPE_NEW = 1;
48     private static String PACKAGE_NAME_OLD = "com.android.app2";
49     private static int UID_OLD = 543;
50     private static int TYPE_OLD = 2;
51     private static long NOW = System.currentTimeMillis();
52     private static long ONE_DAY_BEFORE = NOW - DateUtils.DAY_IN_MILLIS;
53     private static long TWO_DAYS_BEFORE = NOW - 2 * DateUtils.DAY_IN_MILLIS;
54 
55     private Context mContext;
56     private BatteryDatabaseManager mBatteryDatabaseManager;
57     private AppInfo mNewAppInfo;
58     private AppInfo mOldAppInfo;
59     private AppInfo mCombinedAppInfo;
60 
61     @Before
setUp()62     public void setUp() {
63         MockitoAnnotations.initMocks(this);
64 
65         mContext = RuntimeEnvironment.application;
66         mBatteryDatabaseManager = spy(BatteryDatabaseManager.getInstance(mContext));
67 
68         mNewAppInfo = new AppInfo.Builder()
69                 .setUid(UID_NEW)
70                 .setPackageName(PACKAGE_NAME_NEW)
71                 .addAnomalyType(TYPE_NEW)
72                 .build();
73         mOldAppInfo = new AppInfo.Builder()
74                 .setUid(UID_OLD)
75                 .setPackageName(PACKAGE_NAME_OLD)
76                 .addAnomalyType(TYPE_OLD)
77                 .build();
78         mCombinedAppInfo = new AppInfo.Builder()
79                 .setUid(UID_NEW)
80                 .setPackageName(PACKAGE_NAME_NEW)
81                 .addAnomalyType(TYPE_NEW)
82                 .addAnomalyType(TYPE_OLD)
83                 .build();
84     }
85 
86     @After
cleanUp()87     public void cleanUp() {
88         DatabaseTestUtils.clearDb(mContext);
89     }
90 
91     @Test
allAnomalyFunctions()92     public void allAnomalyFunctions() {
93         mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
94                 AnomalyDatabaseHelper.State.NEW, NOW);
95         mBatteryDatabaseManager.insertAnomaly(UID_OLD, PACKAGE_NAME_OLD, TYPE_OLD,
96                 AnomalyDatabaseHelper.State.NEW, TWO_DAYS_BEFORE);
97 
98         // In database, it contains two record
99         List<AppInfo> totalAppInfos = mBatteryDatabaseManager.queryAllAnomalies(0 /* timeMsAfter */,
100                 AnomalyDatabaseHelper.State.NEW);
101         assertThat(totalAppInfos).containsExactly(mNewAppInfo, mOldAppInfo);
102 
103         // Only one record shows up if we query by timestamp
104         List<AppInfo> appInfos = mBatteryDatabaseManager.queryAllAnomalies(ONE_DAY_BEFORE,
105                 AnomalyDatabaseHelper.State.NEW);
106         assertThat(appInfos).containsExactly(mNewAppInfo);
107 
108         mBatteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp(ONE_DAY_BEFORE);
109 
110         // The obsolete record is removed from database
111         List<AppInfo> appInfos1 = mBatteryDatabaseManager.queryAllAnomalies(0 /* timeMsAfter */,
112                 AnomalyDatabaseHelper.State.NEW);
113         assertThat(appInfos1).containsExactly(mNewAppInfo);
114     }
115 
116     @Test
updateAnomalies_updateSuccessfully()117     public void updateAnomalies_updateSuccessfully() {
118         mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
119                 AnomalyDatabaseHelper.State.NEW, NOW);
120         mBatteryDatabaseManager.insertAnomaly(UID_OLD, PACKAGE_NAME_OLD, TYPE_OLD,
121                 AnomalyDatabaseHelper.State.NEW, NOW);
122         final AppInfo appInfo = new AppInfo.Builder().setPackageName(PACKAGE_NAME_OLD).build();
123         final List<AppInfo> updateAppInfos = new ArrayList<>();
124         updateAppInfos.add(appInfo);
125 
126         // Change state of PACKAGE_NAME_OLD to handled
127         mBatteryDatabaseManager.updateAnomalies(updateAppInfos,
128                 AnomalyDatabaseHelper.State.HANDLED);
129 
130         // The state of PACKAGE_NAME_NEW is still new
131         List<AppInfo> newAppInfos = mBatteryDatabaseManager.queryAllAnomalies(ONE_DAY_BEFORE,
132                 AnomalyDatabaseHelper.State.NEW);
133         assertThat(newAppInfos).containsExactly(mNewAppInfo);
134 
135         // The state of PACKAGE_NAME_OLD is changed to handled
136         List<AppInfo> handledAppInfos = mBatteryDatabaseManager.queryAllAnomalies(ONE_DAY_BEFORE,
137                 AnomalyDatabaseHelper.State.HANDLED);
138         assertThat(handledAppInfos).containsExactly(mOldAppInfo);
139     }
140 
141     @Test
queryAnomalies_removeDuplicateByUid()142     public void queryAnomalies_removeDuplicateByUid() {
143         mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_NEW,
144                 AnomalyDatabaseHelper.State.NEW, NOW);
145         mBatteryDatabaseManager.insertAnomaly(UID_NEW, PACKAGE_NAME_NEW, TYPE_OLD,
146                 AnomalyDatabaseHelper.State.NEW, NOW);
147 
148         // Only contain one AppInfo with multiple types
149         List<AppInfo> newAppInfos = mBatteryDatabaseManager.queryAllAnomalies(ONE_DAY_BEFORE,
150                 AnomalyDatabaseHelper.State.NEW);
151         assertThat(newAppInfos).containsExactly(mCombinedAppInfo);
152     }
153 
154     @Test
allActionFunctions()155     public void allActionFunctions() {
156         final long timestamp = System.currentTimeMillis();
157         mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_OLD,
158                 PACKAGE_NAME_OLD, 0);
159         mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_OLD,
160                 PACKAGE_NAME_OLD, 1);
161         mBatteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_NEW,
162                 PACKAGE_NAME_NEW, timestamp);
163 
164         final SparseLongArray timeArray = mBatteryDatabaseManager.queryActionTime(
165                 AnomalyDatabaseHelper.ActionType.RESTRICTION);
166         assertThat(timeArray.size()).isEqualTo(2);
167         assertThat(timeArray.get(UID_OLD)).isEqualTo(1);
168         assertThat(timeArray.get(UID_NEW)).isEqualTo(timestamp);
169 
170         mBatteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION, UID_NEW,
171                 PACKAGE_NAME_NEW);
172         final SparseLongArray recentTimeArray = mBatteryDatabaseManager.queryActionTime(
173                 AnomalyDatabaseHelper.ActionType.RESTRICTION);
174         assertThat(recentTimeArray.size()).isEqualTo(1);
175         assertThat(timeArray.get(UID_OLD)).isEqualTo(1);
176     }
177 }
178