Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4c244ce authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Introduce modem element to power_profile.xml

Also, introduce ModemPowerProfile to handle the data in the modem
element.

Bug: 207697945
Test: atest PowerProfileTest

Change-Id: I6f692106309644a1b9a6d4ad2adc9eb08a598b26
parent 68f254af
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -81,9 +81,17 @@ public class SparseDoubleArray implements Cloneable {
     * if no such mapping has been made.
     */
    public double get(int key) {
        return get(key, 0);
    }

    /**
     * Gets the double mapped from the specified key, or the specified value
     * if no such mapping has been made.
     */
    public double get(int key, double valueIfKeyNotFound) {
        final int index = mValues.indexOfKey(key);
        if (index < 0) {
            return 0.0d;
            return valueIfKeyNotFound;
        }
        return valueAt(index);
    }
@@ -137,6 +145,13 @@ public class SparseDoubleArray implements Cloneable {
        return Double.longBitsToDouble(mValues.valueAt(index));
    }

    /**
     * Removes all key-value mappings from this SparseDoubleArray.
     */
    public void clear() {
        mValues.clear();
    }

    /**
     * {@inheritDoc}
     *
+12 −0
Original line number Diff line number Diff line
@@ -16026,6 +16026,18 @@ public class BatteryStatsImpl extends BatteryStats {
        iPw.decreaseIndent();
    }
    /**
     * Dump Power Profile
     */
    @GuardedBy("this")
    public void dumpPowerProfileLocked(PrintWriter pw) {
        final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, "    ");
        iPw.printf("Power Profile: \n");
        iPw.increaseIndent();
        mPowerProfile.dump(iPw);
        iPw.decreaseIndent();
    }
    final ReentrantLock mWriteLock = new ReentrantLock();
    @GuardedBy("this")
+161 −9
Original line number Diff line number Diff line
@@ -17,24 +17,31 @@
package com.android.internal.os;


import android.annotation.LongDef;
import android.annotation.StringDef;
import android.annotation.XmlRes;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.power.ModemPowerProfile;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
@@ -258,6 +265,35 @@ public class PowerProfile {
    @Retention(RetentionPolicy.SOURCE)
    public @interface PowerGroup {}

    /**
     * Constants for generating a 64bit power constant key.
     *
     * The bitfields of a key describes what its corresponding power constant represents:
     * [63:40] - RESERVED
     * [39:32] - {@link Subsystem} (max count = 16).
     * [31:0] - per Subsystem fields, see {@link ModemPowerProfile}.
     *
     */
    private static final int SUBSYSTEM_SHIFT = 32;
    private static final long SUBSYSTEM_MASK = 0xF << SUBSYSTEM_SHIFT;
    /**
     * Power constant not associated with a subsystem.
     */
    public static final long SUBSYSTEM_NONE = 0 << SUBSYSTEM_SHIFT;
    /**
     * Modem power constant.
     */
    public static final long SUBSYSTEM_MODEM = 1 << SUBSYSTEM_SHIFT;

    @LongDef(prefix = { "SUBSYSTEM_" }, value = {
            SUBSYSTEM_NONE,
            SUBSYSTEM_MODEM,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Subsystem {}

    private static final long SUBSYSTEM_FIELDS_MASK = 0xFFFFFFFF;

    /**
     * A map from Power Use Item to its power consumption.
     */
@@ -268,12 +304,16 @@ public class PowerProfile {
     */
    static final HashMap<String, Double[]> sPowerArrayMap = new HashMap<>();

    static final ModemPowerProfile sModemPowerProfile = new ModemPowerProfile();

    private static final String TAG_DEVICE = "device";
    private static final String TAG_ITEM = "item";
    private static final String TAG_ARRAY = "array";
    private static final String TAG_ARRAYITEM = "value";
    private static final String ATTR_NAME = "name";

    private static final String TAG_MODEM = "modem";

    private static final Object sLock = new Object();

    @VisibleForTesting
@@ -289,19 +329,40 @@ public class PowerProfile {
    public PowerProfile(Context context, boolean forTest) {
        // Read the XML file for the given profile (normally only one per device)
        synchronized (sLock) {
            final int xmlId = forTest ? com.android.internal.R.xml.power_profile_test
                    : com.android.internal.R.xml.power_profile;
            initLocked(context, xmlId);
        }
    }

    /**
     * Reinitialize the PowerProfile with the provided XML.
     * WARNING: use only for testing!
     */
    @VisibleForTesting
    public void forceInitForTesting(Context context, @XmlRes int xmlId) {
        synchronized (sLock) {
            sPowerItemMap.clear();
            sPowerArrayMap.clear();
            sModemPowerProfile.clear();
            initLocked(context, xmlId);
        }

    }

    @GuardedBy("sLock")
    private void initLocked(Context context, @XmlRes int xmlId) {
        if (sPowerItemMap.size() == 0 && sPowerArrayMap.size() == 0) {
                readPowerValuesFromXml(context, forTest);
            readPowerValuesFromXml(context, xmlId);
        }
        initCpuClusters();
        initDisplays();
        }
        initModem();
    }

    private void readPowerValuesFromXml(Context context, boolean forTest) {
        final int id = forTest ? com.android.internal.R.xml.power_profile_test :
                com.android.internal.R.xml.power_profile;
    private void readPowerValuesFromXml(Context context, @XmlRes int xmlId) {
        final Resources resources = context.getResources();
        XmlResourceParser parser = resources.getXml(id);
        XmlResourceParser parser = resources.getXml(xmlId);
        boolean parsingArray = false;
        ArrayList<Double> array = new ArrayList<>();
        String arrayName = null;
@@ -340,6 +401,8 @@ public class PowerProfile {
                            array.add(value);
                        }
                    }
                } else if (element.equals(TAG_MODEM)) {
                    sModemPowerProfile.parseFromXml(parser);
                }
            }
            if (parsingArray) {
@@ -515,6 +578,39 @@ public class PowerProfile {
        return mNumDisplays;
    }

    private void initModem() {
        handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_SLEEP,
                POWER_MODEM_CONTROLLER_SLEEP, 0);
        handleDeprecatedModemConstant(ModemPowerProfile.MODEM_DRAIN_TYPE_IDLE,
                POWER_MODEM_CONTROLLER_SLEEP, 0);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_RX,
                POWER_MODEM_CONTROLLER_RX, 0);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX
                        | ModemPowerProfile.MODEM_TX_LEVEL_0, POWER_MODEM_CONTROLLER_TX, 0);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX
                        | ModemPowerProfile.MODEM_TX_LEVEL_1, POWER_MODEM_CONTROLLER_TX, 1);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX
                        | ModemPowerProfile.MODEM_TX_LEVEL_2, POWER_MODEM_CONTROLLER_TX, 2);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX
                        | ModemPowerProfile.MODEM_TX_LEVEL_3, POWER_MODEM_CONTROLLER_TX, 3);
        handleDeprecatedModemConstant(
                ModemPowerProfile.MODEM_RAT_TYPE_DEFAULT | ModemPowerProfile.MODEM_DRAIN_TYPE_TX
                        | ModemPowerProfile.MODEM_TX_LEVEL_4, POWER_MODEM_CONTROLLER_TX, 4);
    }

    private void handleDeprecatedModemConstant(int key, String deprecatedKey, int level) {
        final double drain = sModemPowerProfile.getAverageBatteryDrainMa(key);
        if (!Double.isNaN(drain)) return; // Value already set, don't overwrite it.

        final double deprecatedDrain = getAveragePower(deprecatedKey, level);
        sModemPowerProfile.setPowerConstant(key, Double.toString(deprecatedDrain));
    }

    /**
     * Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
     * default value if the subsystem has no recorded value.
@@ -559,6 +655,43 @@ public class PowerProfile {
        return getAveragePowerOrDefault(type, 0);
    }

    /**
     * Returns the average current in mA consumed by a subsystem's specified operation, or the given
     * default value if the subsystem has no recorded value.
     *
     * @param key that describes a subsystem's battery draining operation
     *            The key is built from multiple constant, see {@link Subsystem} and
     *            {@link ModemPowerProfile}.
     * @param defaultValue the value to return if the subsystem has no recorded value.
     * @return the average current in milliAmps.
     */
    public double getAverageBatteryDrainOrDefaultMa(long key, double defaultValue) {
        final long subsystemType = key & SUBSYSTEM_MASK;
        final int subsystemFields = (int) (key & SUBSYSTEM_FIELDS_MASK);

        final double value;
        if (subsystemType == SUBSYSTEM_MODEM) {
            value = sModemPowerProfile.getAverageBatteryDrainMa(subsystemFields);
        } else {
            value = Double.NaN;
        }

        if (Double.isNaN(value)) return defaultValue;
        return value;
    }

    /**
     * Returns the average current in mA consumed by a subsystem's specified operation.
     *
     * @param key that describes a subsystem's battery draining operation
     *            The key is built from multiple constant, see {@link Subsystem} and
     *            {@link ModemPowerProfile}.
     * @return the average current in milliAmps.
     */
    public double getAverageBatteryDrainMa(long key) {
        return getAverageBatteryDrainOrDefaultMa(key, 0);
    }

    /**
     * Returns the average current in mA consumed by the subsystem for the given level.
     *
@@ -784,6 +917,25 @@ public class PowerProfile {
                PowerProfileProto.BATTERY_CAPACITY);
    }

    /**
     * Dump the PowerProfile values.
     */
    public void dump(PrintWriter pw) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
        sPowerItemMap.forEach((key, value) -> {
            ipw.print(key, value);
            ipw.println();
        });
        sPowerArrayMap.forEach((key, value) -> {
            ipw.print(key, Arrays.toString(value));
            ipw.println();
        });
        ipw.println("Modem values:");
        ipw.increaseIndent();
        sModemPowerProfile.dump(ipw);
        ipw.decreaseIndent();
    }

    // Writes items in sPowerItemMap to proto if exists.
    private void writePowerConstantToProto(ProtoOutputStream proto, String key, long fieldId) {
        if (sPowerItemMap.containsKey(key)) {
+442 −0

File added.

Preview size limit exceeded, changes collapsed.

+43 −12
Original line number Diff line number Diff line
@@ -144,17 +144,49 @@
    <value>2</value>    <!-- 4097-/hr -->
  </array>

  <!-- Cellular modem related values. Default is 0.-->
  <item name="modem.controller.sleep">0</item>
  <item name="modem.controller.idle">0</item>
  <item name="modem.controller.rx">0</item>
  <array name="modem.controller.tx"> <!-- Strength 0 to 4 -->
    <value>0</value>
    <value>0</value>
    <value>0</value>
    <value>0</value>
    <value>0</value>
  </array>
  <!-- Cellular modem related values.-->
  <modem>
    <!-- Modem sleep drain current value in mA. -->
    <sleep>0</sleep>
    <!-- Modem idle drain current value in mA. -->
    <idle>0</idle>
    <!-- Modem active drain current values.
         Multiple <active /> can be defined to specify current drain for different modes of
         operation.
         Available attributes:
             rat - Specify the current drain for a Radio Access Technology.
                   Available options are "LTE", "NR" and "DEFAULT".
                   <active rat="default" /> will be used for any usage that does not match any other
                   defined <active /> rat.

             nrFrequency - Specify the current drain for a frequency level while NR is active.
                           Available options are "LOW", "MID", "HIGH", "MMWAVE", and "DEFAULT",
                           where,
                           "LOW" indicated <1GHz frequencies,
                           "MID" indicates 1GHz to 3GHz frequencies,
                           "HIGH" indicates 3GHz to 6GHz frequencies,
                           "MMWAVE"indicates >6GHz frequencies.
                           <active rat="NR" nrFrequency="default"/> will be used for any usage that
                           does not match any other defined <active rat="NR" /> nrFrequency.
    -->
    <active rat="DEFAULT">
      <!-- Transmit current drain in mA. -->
      <receive>0</receive>

      <!-- Transmit current drains in mA. Must be defined for all levels (0 to 4) -->
      <transmit level="0">0</transmit>
      <transmit level="1">0</transmit>
      <transmit level="2">0</transmit>
      <transmit level="3">0</transmit>
      <transmit level="4">0</transmit>
    </active>
    <!-- Additional <active /> may be defined.
         Example:
             <active rat="LTE"> ... </active>
             <active rat="NR" nrFrequency="MMWAVE"> ... </active>
             <active rat="NR" nrFrequency="DEFAULT"> ... </active>
    -->
  </modem>
  <item name="modem.controller.voltage">0</item>

  <!-- GPS related values. Default is 0.-->
@@ -163,5 +195,4 @@
    <value>0</value>
  </array>
  <item name="gps.voltage">0</item>

</device>
Loading