• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.stats.processor;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.annotation.SuppressLint;
22 import android.os.BatteryConsumer;
23 import android.os.PersistableBundle;
24 import android.util.SparseArray;
25 import android.util.Xml;
26 
27 import androidx.test.filters.SmallTest;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import com.android.internal.os.PowerStats;
31 import com.android.modules.utils.TypedXmlPullParser;
32 import com.android.modules.utils.TypedXmlSerializer;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 import java.io.ByteArrayInputStream;
39 import java.io.ByteArrayOutputStream;
40 import java.text.ParseException;
41 
42 @RunWith(AndroidJUnit4.class)
43 @SmallTest
44 public class AggregatedPowerStatsTest {
45     private static final int TEST_POWER_COMPONENT = 1077;
46     private static final int CUSTOM_POWER_COMPONENT = 1042;
47     private static final int APP_1 = 27;
48     private static final int APP_2 = 42;
49     private static final int COMPONENT_STATE_0 = 0;
50     private static final int COMPONENT_STATE_1 = 1;
51     private static final int COMPONENT_STATE_2 = 2;
52 
53     private AggregatedPowerStatsConfig
54             mAggregatedPowerStatsConfig;
55     private PowerStats.Descriptor mPowerComponentDescriptor;
56 
57     @Before
setup()58     public void setup() throws ParseException {
59         mAggregatedPowerStatsConfig = new AggregatedPowerStatsConfig();
60         mAggregatedPowerStatsConfig.trackPowerComponent(TEST_POWER_COMPONENT)
61                 .trackDeviceStates(
62                         AggregatedPowerStatsConfig.STATE_POWER,
63                         AggregatedPowerStatsConfig.STATE_SCREEN)
64                 .trackUidStates(
65                         AggregatedPowerStatsConfig.STATE_POWER,
66                         AggregatedPowerStatsConfig.STATE_SCREEN,
67                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
68 
69         mAggregatedPowerStatsConfig.trackCustomPowerComponents(
70                         () -> new PowerStatsProcessor() {
71                             @Override
72                             void finish(
73                                     PowerComponentAggregatedPowerStats stats,
74                                     long timestampMs) {
75                             }
76                         })
77                 .trackDeviceStates(
78                         AggregatedPowerStatsConfig.STATE_POWER,
79                         AggregatedPowerStatsConfig.STATE_SCREEN)
80                 .trackUidStates(
81                         AggregatedPowerStatsConfig.STATE_POWER,
82                         AggregatedPowerStatsConfig.STATE_SCREEN,
83                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
84         SparseArray<String> stateLabels = new SparseArray<>();
85         stateLabels.put(COMPONENT_STATE_1, "one");
86         mPowerComponentDescriptor = new PowerStats.Descriptor(TEST_POWER_COMPONENT, "fan", 2,
87                 stateLabels, 1, 3, PersistableBundle.forPair("speed", "fast"));
88     }
89 
90     @Test
aggregation()91     public void aggregation() {
92         AggregatedPowerStats stats = prepareAggregatePowerStats();
93 
94         verifyAggregatedPowerStats(stats);
95     }
96 
97     @Test
xmlPersistence()98     public void xmlPersistence() throws Exception {
99         AggregatedPowerStats stats = prepareAggregatePowerStats();
100 
101         ByteArrayOutputStream baos = new ByteArrayOutputStream();
102         TypedXmlSerializer serializer = Xml.newFastSerializer();
103         serializer.setOutput(baos, "UTF-8");
104         stats.writeXml(serializer);
105         serializer.flush();
106 
107         TypedXmlPullParser parser = Xml.newFastPullParser();
108         parser.setInput(new ByteArrayInputStream(baos.toByteArray()), "UTF-8");
109         AggregatedPowerStats actualStats =
110                 AggregatedPowerStats.createFromXml(parser, mAggregatedPowerStatsConfig);
111 
112         verifyAggregatedPowerStats(actualStats);
113     }
114 
prepareAggregatePowerStats()115     private AggregatedPowerStats prepareAggregatePowerStats() {
116         AggregatedPowerStats stats = new AggregatedPowerStats(mAggregatedPowerStatsConfig);
117         stats.start(0);
118 
119         PowerStats ps = new PowerStats(mPowerComponentDescriptor);
120         stats.addPowerStats(ps, 0);
121 
122         stats.addClockUpdate(1000, 456);
123         stats.setDuration(789);
124 
125         stats.setDeviceState(AggregatedPowerStatsConfig.STATE_SCREEN,
126                 AggregatedPowerStatsConfig.SCREEN_STATE_ON, 2000);
127         stats.setUidState(APP_1, AggregatedPowerStatsConfig.STATE_PROCESS_STATE,
128                 BatteryConsumer.PROCESS_STATE_CACHED, 2000);
129         stats.setUidState(APP_2, AggregatedPowerStatsConfig.STATE_PROCESS_STATE,
130                 BatteryConsumer.PROCESS_STATE_FOREGROUND, 2000);
131 
132         ps.stats[0] = 100;
133         ps.stats[1] = 987;
134 
135         ps.stateStats.put(COMPONENT_STATE_0, new long[]{1111});
136         ps.stateStats.put(COMPONENT_STATE_1, new long[]{5000});
137 
138         ps.uidStats.put(APP_1, new long[]{389, 0, 739});
139         ps.uidStats.put(APP_2, new long[]{278, 314, 628});
140 
141         stats.addPowerStats(ps, 3000);
142 
143         stats.setDeviceState(AggregatedPowerStatsConfig.STATE_SCREEN,
144                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER, 4000);
145         stats.setUidState(APP_2, AggregatedPowerStatsConfig.STATE_PROCESS_STATE,
146                 BatteryConsumer.PROCESS_STATE_BACKGROUND, 4000);
147 
148         ps.stats[0] = 444;
149         ps.stats[1] = 0;
150 
151         ps.stateStats.clear();
152         ps.stateStats.put(COMPONENT_STATE_1, new long[]{1000});
153         ps.stateStats.put(COMPONENT_STATE_2, new long[]{9000});
154 
155         ps.uidStats.put(APP_1, new long[]{0, 0, 400});
156         ps.uidStats.put(APP_2, new long[]{100, 200, 300});
157 
158         stats.addPowerStats(ps, 5000);
159 
160         PowerStats custom = new PowerStats(
161                 new PowerStats.Descriptor(CUSTOM_POWER_COMPONENT, "cu570m", 1, null, 0, 2,
162                         new PersistableBundle()));
163         custom.stats = new long[]{123};
164         custom.uidStats.put(APP_1, new long[]{500, 600});
165         stats.addPowerStats(custom, 6000);
166         return stats;
167     }
168 
verifyAggregatedPowerStats( AggregatedPowerStats stats)169     private void verifyAggregatedPowerStats(
170             AggregatedPowerStats stats) {
171         PowerStats.Descriptor descriptor = stats.getPowerComponentStats(TEST_POWER_COMPONENT)
172                 .getPowerStatsDescriptor();
173         assertThat(descriptor.powerComponentId).isEqualTo(TEST_POWER_COMPONENT);
174         assertThat(descriptor.name).isEqualTo("fan");
175         assertThat(descriptor.statsArrayLength).isEqualTo(2);
176         assertThat(descriptor.uidStatsArrayLength).isEqualTo(3);
177         assertThat(descriptor.extras.getString("speed")).isEqualTo("fast");
178 
179         assertThat(getDeviceStats(stats, TEST_POWER_COMPONENT,
180                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
181                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
182                 .isEqualTo(new long[]{322, 987});
183 
184         assertThat(getDeviceStats(stats, TEST_POWER_COMPONENT,
185                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
186                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
187                 .isEqualTo(new long[]{222, 0});
188 
189         assertThat(getStateStats(stats, COMPONENT_STATE_0,
190                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
191                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
192                 .isEqualTo(new long[]{1111});
193 
194         assertThat(getStateStats(stats, COMPONENT_STATE_1,
195                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
196                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
197                 .isEqualTo(new long[]{5500});
198 
199         assertThat(getStateStats(stats, COMPONENT_STATE_1,
200                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
201                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
202                 .isEqualTo(new long[]{500});
203 
204         assertThat(getStateStats(stats, COMPONENT_STATE_2,
205                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
206                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
207                 .isEqualTo(new long[]{4500});
208 
209         assertThat(getStateStats(stats, COMPONENT_STATE_2,
210                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
211                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
212                 .isEqualTo(new long[]{4500});
213 
214         assertThat(getUidDeviceStats(stats,
215                 TEST_POWER_COMPONENT, APP_1,
216                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
217                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
218                 BatteryConsumer.PROCESS_STATE_UNSPECIFIED))
219                 .isEqualTo(new long[]{259, 0, 492});
220 
221         assertThat(getUidDeviceStats(stats,
222                 TEST_POWER_COMPONENT, APP_1,
223                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
224                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
225                 BatteryConsumer.PROCESS_STATE_CACHED))
226                 .isEqualTo(new long[]{129, 0, 446});
227 
228         assertThat(getUidDeviceStats(stats,
229                 TEST_POWER_COMPONENT, APP_1,
230                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
231                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
232                 BatteryConsumer.PROCESS_STATE_CACHED))
233                 .isEqualTo(new long[]{0, 0, 200});
234 
235         assertThat(getUidDeviceStats(stats,
236                 TEST_POWER_COMPONENT, APP_2,
237                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
238                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
239                 BatteryConsumer.PROCESS_STATE_UNSPECIFIED))
240                 .isEqualTo(new long[]{185, 209, 418});
241 
242         assertThat(getUidDeviceStats(stats,
243                 TEST_POWER_COMPONENT, APP_2,
244                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
245                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
246                 BatteryConsumer.PROCESS_STATE_FOREGROUND))
247                 .isEqualTo(new long[]{142, 204, 359});
248 
249         assertThat(getUidDeviceStats(stats,
250                 TEST_POWER_COMPONENT, APP_2,
251                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
252                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
253                 BatteryConsumer.PROCESS_STATE_BACKGROUND))
254                 .isEqualTo(new long[]{50, 100, 150});
255 
256         descriptor = stats.getPowerComponentStats(CUSTOM_POWER_COMPONENT)
257                 .getPowerStatsDescriptor();
258         assertThat(descriptor.powerComponentId).isEqualTo(CUSTOM_POWER_COMPONENT);
259         assertThat(descriptor.statsArrayLength).isEqualTo(1);
260         assertThat(descriptor.uidStatsArrayLength).isEqualTo(2);
261 
262         assertThat(getDeviceStats(stats, CUSTOM_POWER_COMPONENT,
263                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
264                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
265                 .isEqualTo(new long[]{61});
266         assertThat(getDeviceStats(stats, CUSTOM_POWER_COMPONENT,
267                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
268                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
269                 .isEqualTo(new long[]{61});
270         assertThat(getUidDeviceStats(stats,
271                 CUSTOM_POWER_COMPONENT, APP_1,
272                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
273                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
274                 BatteryConsumer.PROCESS_STATE_CACHED))
275                 .isEqualTo(new long[]{250, 300});
276         assertThat(getUidDeviceStats(stats,
277                 CUSTOM_POWER_COMPONENT, APP_1,
278                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
279                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
280                 BatteryConsumer.PROCESS_STATE_CACHED))
281                 .isEqualTo(new long[]{250, 300});
282     }
283 
284     @SuppressLint("CheckResult")
getDeviceStats( AggregatedPowerStats stats, int powerComponentId, int... states)285     private static long[] getDeviceStats(
286             AggregatedPowerStats stats, int powerComponentId,
287             int... states) {
288         PowerComponentAggregatedPowerStats powerComponentStats =
289                 stats.getPowerComponentStats(powerComponentId);
290         long[] out = new long[powerComponentStats.getPowerStatsDescriptor().statsArrayLength];
291         powerComponentStats.getDeviceStats(out, states);
292         return out;
293     }
294 
295     @SuppressLint("CheckResult")
getStateStats( AggregatedPowerStats stats, int key, int... states)296     private static long[] getStateStats(
297             AggregatedPowerStats stats, int key, int... states) {
298         PowerComponentAggregatedPowerStats powerComponentStats =
299                 stats.getPowerComponentStats(TEST_POWER_COMPONENT);
300         long[] out = new long[powerComponentStats.getPowerStatsDescriptor().stateStatsArrayLength];
301         powerComponentStats.getStateStats(out, key, states);
302         return out;
303     }
304 
305     @SuppressLint("CheckResult")
getUidDeviceStats( AggregatedPowerStats stats, int powerComponentId, int uid, int... states)306     private static long[] getUidDeviceStats(
307             AggregatedPowerStats stats, int powerComponentId,
308             int uid, int... states) {
309         PowerComponentAggregatedPowerStats powerComponentStats =
310                 stats.getPowerComponentStats(powerComponentId);
311         long[] out = new long[powerComponentStats.getPowerStatsDescriptor().uidStatsArrayLength];
312         powerComponentStats.getUidStats(out, uid, states);
313         return out;
314     }
315 }
316