Loading core/java/com/android/internal/os/PowerProfile.java +5 −6 Original line number Diff line number Diff line Loading @@ -274,16 +274,15 @@ public class PowerProfile { * [31:0] - per Subsystem fields, see {@link ModemPowerProfile}. * */ private static final int SUBSYSTEM_SHIFT = 32; private static final long SUBSYSTEM_MASK = 0xF << SUBSYSTEM_SHIFT; private static final long SUBSYSTEM_MASK = 0xF_0000_0000L; /** * Power constant not associated with a subsystem. */ public static final long SUBSYSTEM_NONE = 0 << SUBSYSTEM_SHIFT; public static final long SUBSYSTEM_NONE = 0x0_0000_0000L; /** * Modem power constant. */ public static final long SUBSYSTEM_MODEM = 1 << SUBSYSTEM_SHIFT; public static final long SUBSYSTEM_MODEM = 0x1_0000_0000L; @LongDef(prefix = { "SUBSYSTEM_" }, value = { SUBSYSTEM_NONE, Loading @@ -292,7 +291,7 @@ public class PowerProfile { @Retention(RetentionPolicy.SOURCE) public @interface Subsystem {} private static final long SUBSYSTEM_FIELDS_MASK = 0xFFFFFFFF; private static final long SUBSYSTEM_FIELDS_MASK = 0xFFFF_FFFF; /** * A map from Power Use Item to its power consumption. Loading Loading @@ -582,7 +581,7 @@ public class PowerProfile { handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_SLEEP, POWER_MODEM_CONTROLLER_SLEEP, 0); handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_IDLE, POWER_MODEM_CONTROLLER_SLEEP, 0); POWER_MODEM_CONTROLLER_IDLE, 0); handleDeprecatedModemConstant( ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_RX, POWER_MODEM_CONTROLLER_RX, 0); Loading core/java/com/android/internal/power/ModemPowerProfile.java +96 −63 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ import android.telephony.ModemActivityInfo; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Slog; import android.util.SparseArray; import android.util.SparseDoubleArray; import com.android.internal.telephony.util.ArrayUtils; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -64,34 +64,27 @@ public class ModemPowerProfile { */ private final SparseDoubleArray mPowerConstants = new SparseDoubleArray(); private static final int MODEM_DRAIN_TYPE_SHIFT = 28; private static final int MODEM_DRAIN_TYPE_MASK = 0xF << MODEM_DRAIN_TYPE_SHIFT; private static final int MODEM_TX_LEVEL_SHIFT = 24; private static final int MODEM_TX_LEVEL_MASK = 0xF << MODEM_TX_LEVEL_SHIFT; private static final int MODEM_RAT_TYPE_SHIFT = 20; private static final int MODEM_RAT_TYPE_MASK = 0xF << MODEM_RAT_TYPE_SHIFT; private static final int MODEM_NR_FREQUENCY_RANGE_SHIFT = 16; private static final int MODEM_NR_FREQUENCY_RANGE_MASK = 0xF << MODEM_NR_FREQUENCY_RANGE_SHIFT; private static final int MODEM_DRAIN_TYPE_MASK = 0xF000_0000; private static final int MODEM_TX_LEVEL_MASK = 0x0F00_0000; private static final int MODEM_RAT_TYPE_MASK = 0x00F0_0000; private static final int MODEM_NR_FREQUENCY_RANGE_MASK = 0x000F_0000; /** * Corresponds to the overall modem battery drain while asleep. */ public static final int MODEM_DRAIN_TYPE_SLEEP = 0 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_SLEEP = 0x0000_0000; /** * Corresponds to the overall modem battery drain while idle. */ public static final int MODEM_DRAIN_TYPE_IDLE = 1 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_IDLE = 0x1000_0000; /** * Corresponds to the modem battery drain while receiving data. A specific Rx battery drain * power constant can be selected using a bitwise OR (|) with {@link ModemRatType} and * {@link ModemNrFrequencyRange} (when applicable). */ public static final int MODEM_DRAIN_TYPE_RX = 2 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_RX = 0x2000_0000; /** * Corresponds to the modem battery drain while receiving data. Loading @@ -99,7 +92,7 @@ public class ModemPowerProfile { * Specific Tx battery drain power constanta can be selected using a bitwise OR (|) with * {@link ModemRatType} and {@link ModemNrFrequencyRange} (when applicable). */ public static final int MODEM_DRAIN_TYPE_TX = 3 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_TX = 0x3000_0000; @IntDef(prefix = {"MODEM_DRAIN_TYPE_"}, value = { MODEM_DRAIN_TYPE_SLEEP, Loading @@ -111,33 +104,44 @@ public class ModemPowerProfile { public @interface ModemDrainType { } private static final String[] MODEM_DRAIN_TYPE_NAMES = new String[]{"SLEEP", "IDLE", "RX", "TX"}; private static final SparseArray<String> MODEM_DRAIN_TYPE_NAMES = new SparseArray<>(4); static { MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_SLEEP, "SLEEP"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_IDLE, "IDLE"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_RX, "RX"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_TX, "TX"); } /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_0}. */ public static final int MODEM_TX_LEVEL_0 = 0 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_0 = 0x0000_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_1}. */ public static final int MODEM_TX_LEVEL_1 = 1 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_1 = 0x0100_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_2}. */ public static final int MODEM_TX_LEVEL_2 = 2 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_2 = 0x0200_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_3}. */ public static final int MODEM_TX_LEVEL_3 = 3 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_3 = 0x0300_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_4}. */ public static final int MODEM_TX_LEVEL_4 = 4 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_4 = 0x0400_0000; private static final int MODEM_TX_LEVEL_COUNT = 5; Loading @@ -152,21 +156,37 @@ public class ModemPowerProfile { public @interface ModemTxLevel { } private static final SparseArray<String> MODEM_TX_LEVEL_NAMES = new SparseArray<>(5); static { MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_0, "0"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_1, "1"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_2, "2"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_3, "3"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_4, "4"); } private static final int[] MODEM_TX_LEVEL_MAP = new int[]{ MODEM_TX_LEVEL_0, MODEM_TX_LEVEL_1, MODEM_TX_LEVEL_2, MODEM_TX_LEVEL_3, MODEM_TX_LEVEL_4}; /** * Fallback for any active modem usage that does not match specified Radio Access Technology * (RAT) power constants. */ public static final int MODEM_RAT_TYPE_DEFAULT = 0 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_DEFAULT = 0x0000_0000; /** * Corresponds to active modem usage on 4G {@link TelephonyManager#NETWORK_TYPE_LTE} RAT. */ public static final int MODEM_RAT_TYPE_LTE = 1 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_LTE = 0x0010_0000; /** * Corresponds to active modem usage on 5G {@link TelephonyManager#NETWORK_TYPE_NR} RAT. */ public static final int MODEM_RAT_TYPE_NR = 2 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_NR = 0x0020_0000; @IntDef(prefix = {"MODEM_RAT_TYPE_"}, value = { MODEM_RAT_TYPE_DEFAULT, Loading @@ -177,33 +197,38 @@ public class ModemPowerProfile { public @interface ModemRatType { } private static final String[] MODEM_RAT_TYPE_NAMES = new String[]{"DEFAULT", "LTE", "NR"}; private static final SparseArray<String> MODEM_RAT_TYPE_NAMES = new SparseArray<>(3); static { MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_DEFAULT, "DEFAULT"); MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_LTE, "LTE"); MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_NR, "NR"); } /** * Fallback for any active 5G modem usage that does not match specified NR frequency power * constants. */ public static final int MODEM_NR_FREQUENCY_RANGE_DEFAULT = 0 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_DEFAULT = 0x0000_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_LOW}. */ public static final int MODEM_NR_FREQUENCY_RANGE_LOW = 1 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_LOW = 0x0001_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_MID}. */ public static final int MODEM_NR_FREQUENCY_RANGE_MID = 2 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_MID = 0x0002_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_HIGH}. */ public static final int MODEM_NR_FREQUENCY_RANGE_HIGH = 3 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_HIGH = 0x0003_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_MMWAVE}. */ public static final int MODEM_NR_FREQUENCY_RANGE_MMWAVE = 4 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_MMWAVE = 0x0004_0000; @IntDef(prefix = {"MODEM_NR_FREQUENCY_RANGE_"}, value = { MODEM_RAT_TYPE_DEFAULT, Loading @@ -215,9 +240,14 @@ public class ModemPowerProfile { @Retention(RetentionPolicy.SOURCE) public @interface ModemNrFrequencyRange { } private static final String[] MODEM_NR_FREQUENCY_RANGE_NAMES = new String[]{"DEFAULT", "LOW", "MID", "HIGH", "MMWAVE"}; private static final SparseArray<String> MODEM_NR_FREQUENCY_RANGE_NAMES = new SparseArray<>(5); static { MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_DEFAULT, "DEFAULT"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_LOW, "LOW"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_MID, "MID"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_HIGH, "HIGH"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_MMWAVE, "MMWAVE"); } public ModemPowerProfile() { } Loading Loading @@ -261,11 +291,10 @@ public class ModemPowerProfile { final int ratType; final int nrfType; try { ratType = getTypeFromAttribute(parser, ATTR_RAT, MODEM_RAT_TYPE_SHIFT, MODEM_RAT_TYPE_NAMES); ratType = getTypeFromAttribute(parser, ATTR_RAT, MODEM_RAT_TYPE_NAMES); if (ratType == MODEM_RAT_TYPE_NR) { nrfType = getTypeFromAttribute(parser, ATTR_NR_FREQUENCY, MODEM_NR_FREQUENCY_RANGE_SHIFT, MODEM_NR_FREQUENCY_RANGE_NAMES); MODEM_NR_FREQUENCY_RANGE_NAMES); } else { nrfType = 0; } Loading Loading @@ -299,10 +328,7 @@ public class ModemPowerProfile { MODEM_TX_LEVEL_COUNT - 1)); continue; } final int modemTxLevel = level << MODEM_TX_LEVEL_SHIFT; Slog.d("MWACHENS", "parsing tx at level:" + level + ", aka 0x" + Integer.toHexString( modemTxLevel)); final int modemTxLevel = MODEM_TX_LEVEL_MAP[level]; final int txKey = MODEM_DRAIN_TYPE_TX | modemTxLevel | ratType | nrfType; setPowerConstant(txKey, txDrain); break; Loading @@ -312,20 +338,31 @@ public class ModemPowerProfile { } } private static int getTypeFromAttribute(XmlResourceParser parser, String attr, int shift, String[] names) { private static int getTypeFromAttribute(XmlResourceParser parser, String attr, SparseArray<String> names) { final String value = XmlUtils.readStringAttribute(parser, attr); final int index = ArrayUtils.indexOf(names, value); if (value == null) { // Attribute was not specified, just use the default. return 0; } int index = -1; final int size = names.size(); // Manual linear search for string. (SparseArray uses == not equals.) for (int i = 0; i < size; i++) { if (value.equals(names.valueAt(i))) { index = i; } } if (index < 0) { final String[] stringNames = new String[size]; for (int i = 0; i < size; i++) { stringNames[i] = names.valueAt(i); } throw new IllegalArgumentException( "Unexpected " + attr + " value : " + value + ". Acceptable values are " + Arrays.toString(names)); + Arrays.toString(stringNames)); } return index << shift; return names.keyAt(index); } /** Loading Loading @@ -384,39 +421,35 @@ public class ModemPowerProfile { private static String keyToString(int key) { StringBuilder sb = new StringBuilder(); final int drainType = key & MODEM_DRAIN_TYPE_MASK; appendFieldToString(sb, "drain", MODEM_DRAIN_TYPE_NAMES, drainType >> MODEM_DRAIN_TYPE_SHIFT); appendFieldToString(sb, "drain", MODEM_DRAIN_TYPE_NAMES, drainType); sb.append(","); if (drainType == MODEM_DRAIN_TYPE_TX) { final int txLevel = (key & MODEM_TX_LEVEL_MASK) >> MODEM_TX_LEVEL_SHIFT; sb.append("level:"); sb.append(txLevel); sb.append(","); final int txLevel = key & MODEM_TX_LEVEL_MASK; appendFieldToString(sb, "level", MODEM_TX_LEVEL_NAMES, txLevel); } final int ratType = key & MODEM_RAT_TYPE_MASK; appendFieldToString(sb, "RAT", MODEM_RAT_TYPE_NAMES, ratType >> MODEM_RAT_TYPE_SHIFT); appendFieldToString(sb, "RAT", MODEM_RAT_TYPE_NAMES, ratType); if (ratType == MODEM_RAT_TYPE_NR) { sb.append(","); final int nrFreq = key & MODEM_NR_FREQUENCY_RANGE_MASK; appendFieldToString(sb, "nrFreq", MODEM_NR_FREQUENCY_RANGE_NAMES, nrFreq >> MODEM_NR_FREQUENCY_RANGE_SHIFT); appendFieldToString(sb, "nrFreq", MODEM_NR_FREQUENCY_RANGE_NAMES, nrFreq); } return sb.toString(); } private static void appendFieldToString(StringBuilder sb, String fieldName, String[] names, int index) { private static void appendFieldToString(StringBuilder sb, String fieldName, SparseArray<String> names, int key) { sb.append(fieldName); sb.append(":"); if (index < 0 || index >= names.length) { sb.append("UNKNOWN("); sb.append(index); final String name = names.get(key, null); if (name == null) { sb.append("UNKNOWN(0x"); sb.append(Integer.toHexString(key)); sb.append(")"); } else { sb.append(names[index]); sb.append(name); } } Loading core/tests/coretests/res/xml/power_profile_test.xml 0 → 100644 +123 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2022 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <device name="Android"> <!-- This is the battery capacity in mAh --> <item name="battery.capacity">3000</item> <!-- Number of cores each CPU cluster contains --> <array name="cpu.clusters.cores"> <value>4</value> <!-- Cluster 0 has 4 cores (cpu0, cpu1, cpu2, cpu3) --> <value>4</value> <!-- Cluster 1 has 4 cores (cpu4, cpu5, cpu5, cpu7) --> </array> <!-- Power consumption when CPU is suspended --> <item name="cpu.suspend">5</item> <!-- Additional power consumption when CPU is in a kernel idle loop --> <item name="cpu.idle">1.11</item> <!-- Additional power consumption by CPU excluding cluster and core when running --> <item name="cpu.active">2.55</item> <!-- Additional power consumption by CPU cluster0 itself when running excluding cores in it --> <item name="cpu.cluster_power.cluster0">2.11</item> <!-- Additional power consumption by CPU cluster1 itself when running excluding cores in it --> <item name="cpu.cluster_power.cluster1">2.22</item> <!-- Different CPU speeds as reported in /sys/devices/system/cpu/cpu0/cpufreq/stats/scaling_available_frequencies --> <array name="cpu.core_speeds.cluster0"> <value>300000</value> <!-- 300 MHz CPU speed --> <value>1000000</value> <!-- 1000 MHz CPU speed --> <value>2000000</value> <!-- 2000 MHz CPU speed --> </array> <!-- Different CPU speeds as reported in /sys/devices/system/cpu/cpu4/cpufreq/stats/scaling_available_frequencies --> <array name="cpu.core_speeds.cluster1"> <value>300000</value> <!-- 300 MHz CPU speed --> <value>1000000</value> <!-- 1000 MHz CPU speed --> <value>2500000</value> <!-- 2500 MHz CPU speed --> <value>3000000</value> <!-- 3000 MHz CPU speed --> </array> <!-- Additional power used by a CPU from cluster 0 when running at different speeds. Currently this measurement also includes cluster cost. --> <array name="cpu.core_power.cluster0"> <value>10</value> <!-- 300 MHz CPU speed --> <value>20</value> <!-- 1000 MHz CPU speed --> <value>30</value> <!-- 1900 MHz CPU speed --> </array> <!-- Additional power used by a CPU from cluster 1 when running at different speeds. Currently this measurement also includes cluster cost. --> <array name="cpu.core_power.cluster1"> <value>25</value> <!-- 300 MHz CPU speed --> <value>35</value> <!-- 1000 MHz CPU speed --> <value>50</value> <!-- 2500 MHz CPU speed --> <value>60</value> <!-- 3000 MHz CPU speed --> </array> <!-- Power used by display unit in ambient display mode, including back lighting--> <item name="ambient.on">0.5</item> <!-- Additional power used when screen is turned on at minimum brightness --> <item name="screen.on">100</item> <!-- Additional power used when screen is at maximum brightness, compared to screen at minimum brightness --> <item name="screen.full">800</item> <!-- Average power used by the camera flash module when on --> <item name="camera.flashlight">500</item> <!-- Average power use by the camera subsystem for a typical camera application. Intended as a rough estimate for an application running a preview and capturing approximately 10 full-resolution pictures per minute. --> <item name="camera.avg">600</item> <!-- Additional power used by the audio hardware, probably due to DSP --> <item name="audio">100.0</item> <!-- Additional power used by the video hardware, probably due to DSP --> <item name="video">150.0</item> <!-- ~50mA --> <!-- Additional power used when GPS is acquiring a signal --> <item name="gps.on">10</item> <!-- Additional power used when cellular radio is transmitting/receiving --> <item name="radio.active">60</item> <!-- Additional power used when cellular radio is paging the tower --> <item name="radio.scanning">3</item> <!-- Additional power used when the cellular radio is on. Multi-value entry, one per signal strength (no signal, weak, moderate, strong) --> <array name="radio.on"> <!-- Strength 0 to BINS-1 --> <value>6</value> <!-- none --> <value>5</value> <!-- poor --> <value>4</value> <!-- moderate --> <value>3</value> <!-- good --> <value>3</value> <!-- great --> </array> <!-- Cellular modem related values. These constants are deprecated, but still supported and need to be tested --> <item name="modem.controller.sleep">123</item> <item name="modem.controller.idle">456</item> <item name="modem.controller.rx">789</item> <array name="modem.controller.tx"> <!-- Strength 0 to 4 --> <value>10</value> <value>20</value> <value>30</value> <value>40</value> <value>50</value> </array> </device> No newline at end of file core/tests/coretests/src/com/android/internal/os/PowerProfileTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -57,11 +57,13 @@ public class PowerProfileTest extends TestCase { @Before public void setUp() { mContext = InstrumentationRegistry.getContext(); mProfile = new PowerProfile(mContext, true); mProfile = new PowerProfile(mContext); } @Test public void testPowerProfile() { mProfile.forceInitForTesting(mContext, R.xml.power_profile_test); assertEquals(2, mProfile.getNumCpuClusters()); assertEquals(4, mProfile.getNumCoresInCpuCluster(0)); assertEquals(4, mProfile.getNumCoresInCpuCluster(1)); Loading @@ -83,6 +85,43 @@ public class PowerProfileTest extends TestCase { mProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0)); assertEquals(100.0, mProfile.getAveragePower(PowerProfile.POWER_AUDIO)); assertEquals(150.0, mProfile.getAveragePower(PowerProfile.POWER_VIDEO)); assertEquals(123.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP)); assertEquals(456.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE)); assertEquals(789.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX)); assertEquals(10.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 0)); assertEquals(20.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 1)); assertEquals(30.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 2)); assertEquals(40.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 3)); assertEquals(50.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 4)); // Deprecated Modem constants should work with current format. assertEquals(123.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_SLEEP)); assertEquals(456.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_IDLE)); assertEquals(789.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_RX)); assertEquals(10.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_0)); assertEquals(20.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_1)); assertEquals(30.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_2)); assertEquals(40.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_3)); assertEquals(50.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_4)); } @Test Loading Loading
core/java/com/android/internal/os/PowerProfile.java +5 −6 Original line number Diff line number Diff line Loading @@ -274,16 +274,15 @@ public class PowerProfile { * [31:0] - per Subsystem fields, see {@link ModemPowerProfile}. * */ private static final int SUBSYSTEM_SHIFT = 32; private static final long SUBSYSTEM_MASK = 0xF << SUBSYSTEM_SHIFT; private static final long SUBSYSTEM_MASK = 0xF_0000_0000L; /** * Power constant not associated with a subsystem. */ public static final long SUBSYSTEM_NONE = 0 << SUBSYSTEM_SHIFT; public static final long SUBSYSTEM_NONE = 0x0_0000_0000L; /** * Modem power constant. */ public static final long SUBSYSTEM_MODEM = 1 << SUBSYSTEM_SHIFT; public static final long SUBSYSTEM_MODEM = 0x1_0000_0000L; @LongDef(prefix = { "SUBSYSTEM_" }, value = { SUBSYSTEM_NONE, Loading @@ -292,7 +291,7 @@ public class PowerProfile { @Retention(RetentionPolicy.SOURCE) public @interface Subsystem {} private static final long SUBSYSTEM_FIELDS_MASK = 0xFFFFFFFF; private static final long SUBSYSTEM_FIELDS_MASK = 0xFFFF_FFFF; /** * A map from Power Use Item to its power consumption. Loading Loading @@ -582,7 +581,7 @@ public class PowerProfile { handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_SLEEP, POWER_MODEM_CONTROLLER_SLEEP, 0); handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_IDLE, POWER_MODEM_CONTROLLER_SLEEP, 0); POWER_MODEM_CONTROLLER_IDLE, 0); handleDeprecatedModemConstant( ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_RX, POWER_MODEM_CONTROLLER_RX, 0); Loading
core/java/com/android/internal/power/ModemPowerProfile.java +96 −63 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ import android.telephony.ModemActivityInfo; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Slog; import android.util.SparseArray; import android.util.SparseDoubleArray; import com.android.internal.telephony.util.ArrayUtils; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -64,34 +64,27 @@ public class ModemPowerProfile { */ private final SparseDoubleArray mPowerConstants = new SparseDoubleArray(); private static final int MODEM_DRAIN_TYPE_SHIFT = 28; private static final int MODEM_DRAIN_TYPE_MASK = 0xF << MODEM_DRAIN_TYPE_SHIFT; private static final int MODEM_TX_LEVEL_SHIFT = 24; private static final int MODEM_TX_LEVEL_MASK = 0xF << MODEM_TX_LEVEL_SHIFT; private static final int MODEM_RAT_TYPE_SHIFT = 20; private static final int MODEM_RAT_TYPE_MASK = 0xF << MODEM_RAT_TYPE_SHIFT; private static final int MODEM_NR_FREQUENCY_RANGE_SHIFT = 16; private static final int MODEM_NR_FREQUENCY_RANGE_MASK = 0xF << MODEM_NR_FREQUENCY_RANGE_SHIFT; private static final int MODEM_DRAIN_TYPE_MASK = 0xF000_0000; private static final int MODEM_TX_LEVEL_MASK = 0x0F00_0000; private static final int MODEM_RAT_TYPE_MASK = 0x00F0_0000; private static final int MODEM_NR_FREQUENCY_RANGE_MASK = 0x000F_0000; /** * Corresponds to the overall modem battery drain while asleep. */ public static final int MODEM_DRAIN_TYPE_SLEEP = 0 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_SLEEP = 0x0000_0000; /** * Corresponds to the overall modem battery drain while idle. */ public static final int MODEM_DRAIN_TYPE_IDLE = 1 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_IDLE = 0x1000_0000; /** * Corresponds to the modem battery drain while receiving data. A specific Rx battery drain * power constant can be selected using a bitwise OR (|) with {@link ModemRatType} and * {@link ModemNrFrequencyRange} (when applicable). */ public static final int MODEM_DRAIN_TYPE_RX = 2 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_RX = 0x2000_0000; /** * Corresponds to the modem battery drain while receiving data. Loading @@ -99,7 +92,7 @@ public class ModemPowerProfile { * Specific Tx battery drain power constanta can be selected using a bitwise OR (|) with * {@link ModemRatType} and {@link ModemNrFrequencyRange} (when applicable). */ public static final int MODEM_DRAIN_TYPE_TX = 3 << MODEM_DRAIN_TYPE_SHIFT; public static final int MODEM_DRAIN_TYPE_TX = 0x3000_0000; @IntDef(prefix = {"MODEM_DRAIN_TYPE_"}, value = { MODEM_DRAIN_TYPE_SLEEP, Loading @@ -111,33 +104,44 @@ public class ModemPowerProfile { public @interface ModemDrainType { } private static final String[] MODEM_DRAIN_TYPE_NAMES = new String[]{"SLEEP", "IDLE", "RX", "TX"}; private static final SparseArray<String> MODEM_DRAIN_TYPE_NAMES = new SparseArray<>(4); static { MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_SLEEP, "SLEEP"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_IDLE, "IDLE"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_RX, "RX"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_DRAIN_TYPE_TX, "TX"); } /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_0}. */ public static final int MODEM_TX_LEVEL_0 = 0 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_0 = 0x0000_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_1}. */ public static final int MODEM_TX_LEVEL_1 = 1 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_1 = 0x0100_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_2}. */ public static final int MODEM_TX_LEVEL_2 = 2 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_2 = 0x0200_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_3}. */ public static final int MODEM_TX_LEVEL_3 = 3 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_3 = 0x0300_0000; /** * Corresponds to {@link ModemActivityInfo#TX_POWER_LEVEL_4}. */ public static final int MODEM_TX_LEVEL_4 = 4 << MODEM_TX_LEVEL_SHIFT; public static final int MODEM_TX_LEVEL_4 = 0x0400_0000; private static final int MODEM_TX_LEVEL_COUNT = 5; Loading @@ -152,21 +156,37 @@ public class ModemPowerProfile { public @interface ModemTxLevel { } private static final SparseArray<String> MODEM_TX_LEVEL_NAMES = new SparseArray<>(5); static { MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_0, "0"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_1, "1"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_2, "2"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_3, "3"); MODEM_DRAIN_TYPE_NAMES.put(MODEM_TX_LEVEL_4, "4"); } private static final int[] MODEM_TX_LEVEL_MAP = new int[]{ MODEM_TX_LEVEL_0, MODEM_TX_LEVEL_1, MODEM_TX_LEVEL_2, MODEM_TX_LEVEL_3, MODEM_TX_LEVEL_4}; /** * Fallback for any active modem usage that does not match specified Radio Access Technology * (RAT) power constants. */ public static final int MODEM_RAT_TYPE_DEFAULT = 0 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_DEFAULT = 0x0000_0000; /** * Corresponds to active modem usage on 4G {@link TelephonyManager#NETWORK_TYPE_LTE} RAT. */ public static final int MODEM_RAT_TYPE_LTE = 1 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_LTE = 0x0010_0000; /** * Corresponds to active modem usage on 5G {@link TelephonyManager#NETWORK_TYPE_NR} RAT. */ public static final int MODEM_RAT_TYPE_NR = 2 << MODEM_RAT_TYPE_SHIFT; public static final int MODEM_RAT_TYPE_NR = 0x0020_0000; @IntDef(prefix = {"MODEM_RAT_TYPE_"}, value = { MODEM_RAT_TYPE_DEFAULT, Loading @@ -177,33 +197,38 @@ public class ModemPowerProfile { public @interface ModemRatType { } private static final String[] MODEM_RAT_TYPE_NAMES = new String[]{"DEFAULT", "LTE", "NR"}; private static final SparseArray<String> MODEM_RAT_TYPE_NAMES = new SparseArray<>(3); static { MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_DEFAULT, "DEFAULT"); MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_LTE, "LTE"); MODEM_RAT_TYPE_NAMES.put(MODEM_RAT_TYPE_NR, "NR"); } /** * Fallback for any active 5G modem usage that does not match specified NR frequency power * constants. */ public static final int MODEM_NR_FREQUENCY_RANGE_DEFAULT = 0 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_DEFAULT = 0x0000_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_LOW}. */ public static final int MODEM_NR_FREQUENCY_RANGE_LOW = 1 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_LOW = 0x0001_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_MID}. */ public static final int MODEM_NR_FREQUENCY_RANGE_MID = 2 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_MID = 0x0002_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_HIGH}. */ public static final int MODEM_NR_FREQUENCY_RANGE_HIGH = 3 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_HIGH = 0x0003_0000; /** * Corresponds to active NR modem usage on {@link ServiceState#FREQUENCY_RANGE_MMWAVE}. */ public static final int MODEM_NR_FREQUENCY_RANGE_MMWAVE = 4 << MODEM_NR_FREQUENCY_RANGE_SHIFT; public static final int MODEM_NR_FREQUENCY_RANGE_MMWAVE = 0x0004_0000; @IntDef(prefix = {"MODEM_NR_FREQUENCY_RANGE_"}, value = { MODEM_RAT_TYPE_DEFAULT, Loading @@ -215,9 +240,14 @@ public class ModemPowerProfile { @Retention(RetentionPolicy.SOURCE) public @interface ModemNrFrequencyRange { } private static final String[] MODEM_NR_FREQUENCY_RANGE_NAMES = new String[]{"DEFAULT", "LOW", "MID", "HIGH", "MMWAVE"}; private static final SparseArray<String> MODEM_NR_FREQUENCY_RANGE_NAMES = new SparseArray<>(5); static { MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_DEFAULT, "DEFAULT"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_LOW, "LOW"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_MID, "MID"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_HIGH, "HIGH"); MODEM_NR_FREQUENCY_RANGE_NAMES.put(MODEM_NR_FREQUENCY_RANGE_MMWAVE, "MMWAVE"); } public ModemPowerProfile() { } Loading Loading @@ -261,11 +291,10 @@ public class ModemPowerProfile { final int ratType; final int nrfType; try { ratType = getTypeFromAttribute(parser, ATTR_RAT, MODEM_RAT_TYPE_SHIFT, MODEM_RAT_TYPE_NAMES); ratType = getTypeFromAttribute(parser, ATTR_RAT, MODEM_RAT_TYPE_NAMES); if (ratType == MODEM_RAT_TYPE_NR) { nrfType = getTypeFromAttribute(parser, ATTR_NR_FREQUENCY, MODEM_NR_FREQUENCY_RANGE_SHIFT, MODEM_NR_FREQUENCY_RANGE_NAMES); MODEM_NR_FREQUENCY_RANGE_NAMES); } else { nrfType = 0; } Loading Loading @@ -299,10 +328,7 @@ public class ModemPowerProfile { MODEM_TX_LEVEL_COUNT - 1)); continue; } final int modemTxLevel = level << MODEM_TX_LEVEL_SHIFT; Slog.d("MWACHENS", "parsing tx at level:" + level + ", aka 0x" + Integer.toHexString( modemTxLevel)); final int modemTxLevel = MODEM_TX_LEVEL_MAP[level]; final int txKey = MODEM_DRAIN_TYPE_TX | modemTxLevel | ratType | nrfType; setPowerConstant(txKey, txDrain); break; Loading @@ -312,20 +338,31 @@ public class ModemPowerProfile { } } private static int getTypeFromAttribute(XmlResourceParser parser, String attr, int shift, String[] names) { private static int getTypeFromAttribute(XmlResourceParser parser, String attr, SparseArray<String> names) { final String value = XmlUtils.readStringAttribute(parser, attr); final int index = ArrayUtils.indexOf(names, value); if (value == null) { // Attribute was not specified, just use the default. return 0; } int index = -1; final int size = names.size(); // Manual linear search for string. (SparseArray uses == not equals.) for (int i = 0; i < size; i++) { if (value.equals(names.valueAt(i))) { index = i; } } if (index < 0) { final String[] stringNames = new String[size]; for (int i = 0; i < size; i++) { stringNames[i] = names.valueAt(i); } throw new IllegalArgumentException( "Unexpected " + attr + " value : " + value + ". Acceptable values are " + Arrays.toString(names)); + Arrays.toString(stringNames)); } return index << shift; return names.keyAt(index); } /** Loading Loading @@ -384,39 +421,35 @@ public class ModemPowerProfile { private static String keyToString(int key) { StringBuilder sb = new StringBuilder(); final int drainType = key & MODEM_DRAIN_TYPE_MASK; appendFieldToString(sb, "drain", MODEM_DRAIN_TYPE_NAMES, drainType >> MODEM_DRAIN_TYPE_SHIFT); appendFieldToString(sb, "drain", MODEM_DRAIN_TYPE_NAMES, drainType); sb.append(","); if (drainType == MODEM_DRAIN_TYPE_TX) { final int txLevel = (key & MODEM_TX_LEVEL_MASK) >> MODEM_TX_LEVEL_SHIFT; sb.append("level:"); sb.append(txLevel); sb.append(","); final int txLevel = key & MODEM_TX_LEVEL_MASK; appendFieldToString(sb, "level", MODEM_TX_LEVEL_NAMES, txLevel); } final int ratType = key & MODEM_RAT_TYPE_MASK; appendFieldToString(sb, "RAT", MODEM_RAT_TYPE_NAMES, ratType >> MODEM_RAT_TYPE_SHIFT); appendFieldToString(sb, "RAT", MODEM_RAT_TYPE_NAMES, ratType); if (ratType == MODEM_RAT_TYPE_NR) { sb.append(","); final int nrFreq = key & MODEM_NR_FREQUENCY_RANGE_MASK; appendFieldToString(sb, "nrFreq", MODEM_NR_FREQUENCY_RANGE_NAMES, nrFreq >> MODEM_NR_FREQUENCY_RANGE_SHIFT); appendFieldToString(sb, "nrFreq", MODEM_NR_FREQUENCY_RANGE_NAMES, nrFreq); } return sb.toString(); } private static void appendFieldToString(StringBuilder sb, String fieldName, String[] names, int index) { private static void appendFieldToString(StringBuilder sb, String fieldName, SparseArray<String> names, int key) { sb.append(fieldName); sb.append(":"); if (index < 0 || index >= names.length) { sb.append("UNKNOWN("); sb.append(index); final String name = names.get(key, null); if (name == null) { sb.append("UNKNOWN(0x"); sb.append(Integer.toHexString(key)); sb.append(")"); } else { sb.append(names[index]); sb.append(name); } } Loading
core/tests/coretests/res/xml/power_profile_test.xml 0 → 100644 +123 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2022 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <device name="Android"> <!-- This is the battery capacity in mAh --> <item name="battery.capacity">3000</item> <!-- Number of cores each CPU cluster contains --> <array name="cpu.clusters.cores"> <value>4</value> <!-- Cluster 0 has 4 cores (cpu0, cpu1, cpu2, cpu3) --> <value>4</value> <!-- Cluster 1 has 4 cores (cpu4, cpu5, cpu5, cpu7) --> </array> <!-- Power consumption when CPU is suspended --> <item name="cpu.suspend">5</item> <!-- Additional power consumption when CPU is in a kernel idle loop --> <item name="cpu.idle">1.11</item> <!-- Additional power consumption by CPU excluding cluster and core when running --> <item name="cpu.active">2.55</item> <!-- Additional power consumption by CPU cluster0 itself when running excluding cores in it --> <item name="cpu.cluster_power.cluster0">2.11</item> <!-- Additional power consumption by CPU cluster1 itself when running excluding cores in it --> <item name="cpu.cluster_power.cluster1">2.22</item> <!-- Different CPU speeds as reported in /sys/devices/system/cpu/cpu0/cpufreq/stats/scaling_available_frequencies --> <array name="cpu.core_speeds.cluster0"> <value>300000</value> <!-- 300 MHz CPU speed --> <value>1000000</value> <!-- 1000 MHz CPU speed --> <value>2000000</value> <!-- 2000 MHz CPU speed --> </array> <!-- Different CPU speeds as reported in /sys/devices/system/cpu/cpu4/cpufreq/stats/scaling_available_frequencies --> <array name="cpu.core_speeds.cluster1"> <value>300000</value> <!-- 300 MHz CPU speed --> <value>1000000</value> <!-- 1000 MHz CPU speed --> <value>2500000</value> <!-- 2500 MHz CPU speed --> <value>3000000</value> <!-- 3000 MHz CPU speed --> </array> <!-- Additional power used by a CPU from cluster 0 when running at different speeds. Currently this measurement also includes cluster cost. --> <array name="cpu.core_power.cluster0"> <value>10</value> <!-- 300 MHz CPU speed --> <value>20</value> <!-- 1000 MHz CPU speed --> <value>30</value> <!-- 1900 MHz CPU speed --> </array> <!-- Additional power used by a CPU from cluster 1 when running at different speeds. Currently this measurement also includes cluster cost. --> <array name="cpu.core_power.cluster1"> <value>25</value> <!-- 300 MHz CPU speed --> <value>35</value> <!-- 1000 MHz CPU speed --> <value>50</value> <!-- 2500 MHz CPU speed --> <value>60</value> <!-- 3000 MHz CPU speed --> </array> <!-- Power used by display unit in ambient display mode, including back lighting--> <item name="ambient.on">0.5</item> <!-- Additional power used when screen is turned on at minimum brightness --> <item name="screen.on">100</item> <!-- Additional power used when screen is at maximum brightness, compared to screen at minimum brightness --> <item name="screen.full">800</item> <!-- Average power used by the camera flash module when on --> <item name="camera.flashlight">500</item> <!-- Average power use by the camera subsystem for a typical camera application. Intended as a rough estimate for an application running a preview and capturing approximately 10 full-resolution pictures per minute. --> <item name="camera.avg">600</item> <!-- Additional power used by the audio hardware, probably due to DSP --> <item name="audio">100.0</item> <!-- Additional power used by the video hardware, probably due to DSP --> <item name="video">150.0</item> <!-- ~50mA --> <!-- Additional power used when GPS is acquiring a signal --> <item name="gps.on">10</item> <!-- Additional power used when cellular radio is transmitting/receiving --> <item name="radio.active">60</item> <!-- Additional power used when cellular radio is paging the tower --> <item name="radio.scanning">3</item> <!-- Additional power used when the cellular radio is on. Multi-value entry, one per signal strength (no signal, weak, moderate, strong) --> <array name="radio.on"> <!-- Strength 0 to BINS-1 --> <value>6</value> <!-- none --> <value>5</value> <!-- poor --> <value>4</value> <!-- moderate --> <value>3</value> <!-- good --> <value>3</value> <!-- great --> </array> <!-- Cellular modem related values. These constants are deprecated, but still supported and need to be tested --> <item name="modem.controller.sleep">123</item> <item name="modem.controller.idle">456</item> <item name="modem.controller.rx">789</item> <array name="modem.controller.tx"> <!-- Strength 0 to 4 --> <value>10</value> <value>20</value> <value>30</value> <value>40</value> <value>50</value> </array> </device> No newline at end of file
core/tests/coretests/src/com/android/internal/os/PowerProfileTest.java +40 −1 Original line number Diff line number Diff line Loading @@ -57,11 +57,13 @@ public class PowerProfileTest extends TestCase { @Before public void setUp() { mContext = InstrumentationRegistry.getContext(); mProfile = new PowerProfile(mContext, true); mProfile = new PowerProfile(mContext); } @Test public void testPowerProfile() { mProfile.forceInitForTesting(mContext, R.xml.power_profile_test); assertEquals(2, mProfile.getNumCpuClusters()); assertEquals(4, mProfile.getNumCoresInCpuCluster(0)); assertEquals(4, mProfile.getNumCoresInCpuCluster(1)); Loading @@ -83,6 +85,43 @@ public class PowerProfileTest extends TestCase { mProfile.getAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0)); assertEquals(100.0, mProfile.getAveragePower(PowerProfile.POWER_AUDIO)); assertEquals(150.0, mProfile.getAveragePower(PowerProfile.POWER_VIDEO)); assertEquals(123.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP)); assertEquals(456.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE)); assertEquals(789.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX)); assertEquals(10.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 0)); assertEquals(20.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 1)); assertEquals(30.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 2)); assertEquals(40.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 3)); assertEquals(50.0, mProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, 4)); // Deprecated Modem constants should work with current format. assertEquals(123.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_SLEEP)); assertEquals(456.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_IDLE)); assertEquals(789.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_DRAIN_TYPE_RX)); assertEquals(10.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_0)); assertEquals(20.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_1)); assertEquals(30.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_2)); assertEquals(40.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_3)); assertEquals(50.0, mProfile.getAverageBatteryDrainMa( PowerProfile.SUBSYSTEM_MODEM | ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX | ModemPowerProfile.MODEM_TX_LEVEL_4)); } @Test Loading