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