1 /* 2 * Copyright (C) 2024 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 android.os.PersistableBundle; 20 21 /** 22 * Captures the positions and lengths of sections of the stats array, such as time-in-state, 23 * power usage estimates etc. 24 */ 25 public class CpuPowerStatsLayout extends PowerStatsLayout { 26 private static final String EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION = "dt"; 27 private static final String EXTRA_DEVICE_TIME_BY_SCALING_STEP_COUNT = "dtc"; 28 private static final String EXTRA_DEVICE_TIME_BY_CLUSTER_POSITION = "dc"; 29 private static final String EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT = "dcc"; 30 private static final String EXTRA_UID_BRACKETS_POSITION = "ub"; 31 private static final String EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET = "us"; 32 33 private int mDeviceCpuTimeByScalingStepPosition; 34 private int mDeviceCpuTimeByScalingStepCount; 35 private int mDeviceCpuTimeByClusterPosition; 36 private int mDeviceCpuTimeByClusterCount; 37 38 private int mUidPowerBracketsPosition; 39 private int mUidPowerBracketCount; 40 41 private int[] mScalingStepToPowerBracketMap; 42 43 /** 44 * Declare that the stats array has a section capturing CPU time per scaling step 45 */ addDeviceSectionCpuTimeByScalingStep(int scalingStepCount)46 public void addDeviceSectionCpuTimeByScalingStep(int scalingStepCount) { 47 mDeviceCpuTimeByScalingStepPosition = addDeviceSection(scalingStepCount, "steps"); 48 mDeviceCpuTimeByScalingStepCount = scalingStepCount; 49 } 50 getCpuScalingStepCount()51 public int getCpuScalingStepCount() { 52 return mDeviceCpuTimeByScalingStepCount; 53 } 54 55 /** 56 * Saves the time duration in the <code>stats</code> element 57 * corresponding to the CPU scaling <code>state</code>. 58 */ setTimeByScalingStep(long[] stats, int step, long value)59 public void setTimeByScalingStep(long[] stats, int step, long value) { 60 stats[mDeviceCpuTimeByScalingStepPosition + step] = value; 61 } 62 63 /** 64 * Extracts the time duration from the <code>stats</code> element 65 * corresponding to the CPU scaling <code>step</code>. 66 */ getTimeByScalingStep(long[] stats, int step)67 public long getTimeByScalingStep(long[] stats, int step) { 68 return stats[mDeviceCpuTimeByScalingStepPosition + step]; 69 } 70 71 /** 72 * Declare that the stats array has a section capturing CPU time in each cluster 73 */ addDeviceSectionCpuTimeByCluster(int clusterCount)74 public void addDeviceSectionCpuTimeByCluster(int clusterCount) { 75 mDeviceCpuTimeByClusterPosition = addDeviceSection(clusterCount, "clusters"); 76 mDeviceCpuTimeByClusterCount = clusterCount; 77 } 78 getCpuClusterCount()79 public int getCpuClusterCount() { 80 return mDeviceCpuTimeByClusterCount; 81 } 82 83 /** 84 * Saves the time duration in the <code>stats</code> element 85 * corresponding to the CPU <code>cluster</code>. 86 */ setTimeByCluster(long[] stats, int cluster, long value)87 public void setTimeByCluster(long[] stats, int cluster, long value) { 88 stats[mDeviceCpuTimeByClusterPosition + cluster] = value; 89 } 90 91 /** 92 * Extracts the time duration from the <code>stats</code> element 93 * corresponding to the CPU <code>cluster</code>. 94 */ getTimeByCluster(long[] stats, int cluster)95 public long getTimeByCluster(long[] stats, int cluster) { 96 return stats[mDeviceCpuTimeByClusterPosition + cluster]; 97 } 98 99 /** 100 * Declare that the UID stats array has a section capturing CPU time per power bracket. 101 */ addUidSectionCpuTimeByPowerBracket(int[] scalingStepToPowerBracketMap)102 public void addUidSectionCpuTimeByPowerBracket(int[] scalingStepToPowerBracketMap) { 103 mScalingStepToPowerBracketMap = scalingStepToPowerBracketMap; 104 updatePowerBracketCount(); 105 mUidPowerBracketsPosition = addUidSection(mUidPowerBracketCount, "time"); 106 } 107 updatePowerBracketCount()108 private void updatePowerBracketCount() { 109 mUidPowerBracketCount = 1; 110 for (int bracket : mScalingStepToPowerBracketMap) { 111 if (bracket >= mUidPowerBracketCount) { 112 mUidPowerBracketCount = bracket + 1; 113 } 114 } 115 } 116 getScalingStepToPowerBracketMap()117 public int[] getScalingStepToPowerBracketMap() { 118 return mScalingStepToPowerBracketMap; 119 } 120 getCpuPowerBracketCount()121 public int getCpuPowerBracketCount() { 122 return mUidPowerBracketCount; 123 } 124 125 /** 126 * Saves time in <code>bracket</code> in the corresponding section of <code>stats</code>. 127 */ setUidTimeByPowerBracket(long[] stats, int bracket, long value)128 public void setUidTimeByPowerBracket(long[] stats, int bracket, long value) { 129 stats[mUidPowerBracketsPosition + bracket] = value; 130 } 131 132 /** 133 * Extracts the time in <code>bracket</code> from a UID stats array. 134 */ getUidTimeByPowerBracket(long[] stats, int bracket)135 public long getUidTimeByPowerBracket(long[] stats, int bracket) { 136 return stats[mUidPowerBracketsPosition + bracket]; 137 } 138 139 /** 140 * Copies the elements of the stats array layout into <code>extras</code> 141 */ toExtras(PersistableBundle extras)142 public void toExtras(PersistableBundle extras) { 143 super.toExtras(extras); 144 extras.putInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION, 145 mDeviceCpuTimeByScalingStepPosition); 146 extras.putInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_COUNT, 147 mDeviceCpuTimeByScalingStepCount); 148 extras.putInt(EXTRA_DEVICE_TIME_BY_CLUSTER_POSITION, 149 mDeviceCpuTimeByClusterPosition); 150 extras.putInt(EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT, 151 mDeviceCpuTimeByClusterCount); 152 extras.putInt(EXTRA_UID_BRACKETS_POSITION, mUidPowerBracketsPosition); 153 putIntArray(extras, EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET, 154 mScalingStepToPowerBracketMap); 155 } 156 157 /** 158 * Retrieves elements of the stats array layout from <code>extras</code> 159 */ fromExtras(PersistableBundle extras)160 public void fromExtras(PersistableBundle extras) { 161 super.fromExtras(extras); 162 mDeviceCpuTimeByScalingStepPosition = 163 extras.getInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_POSITION); 164 mDeviceCpuTimeByScalingStepCount = 165 extras.getInt(EXTRA_DEVICE_TIME_BY_SCALING_STEP_COUNT); 166 mDeviceCpuTimeByClusterPosition = 167 extras.getInt(EXTRA_DEVICE_TIME_BY_CLUSTER_POSITION); 168 mDeviceCpuTimeByClusterCount = 169 extras.getInt(EXTRA_DEVICE_TIME_BY_CLUSTER_COUNT); 170 mUidPowerBracketsPosition = extras.getInt(EXTRA_UID_BRACKETS_POSITION); 171 mScalingStepToPowerBracketMap = 172 getIntArray(extras, EXTRA_UID_STATS_SCALING_STEP_TO_POWER_BRACKET); 173 if (mScalingStepToPowerBracketMap == null) { 174 mScalingStepToPowerBracketMap = new int[mDeviceCpuTimeByScalingStepCount]; 175 } 176 updatePowerBracketCount(); 177 } 178 } 179