PowerProfile.java解析power_profile.xml的数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/su749520/article/details/83340832

1. PowerProfile.java

这个文件主要目的是为了power_profile.xml的配置信息,尤其是配置的电流信息

frameworks/base/core/java/com/android/internal/os/PowerProfile.java

/*
 * Copyright (C) 2009 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.
 */

package com.android.internal.os;


import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;

import com.android.internal.util.XmlUtils;

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import android.util.Log;

/**
 * Reports power consumption values for various device activities. Reads values from an XML file.
 * Customize the XML file for different devices.
 * [hidden]
 */
public class PowerProfile {

    /**
     * No power consumption, or accounted for elsewhere.
     */
    public static final String POWER_NONE = "none";

    /**
     * Power consumption when CPU is in power collapse mode.
     */
    public static final String POWER_CPU_IDLE = "cpu.idle";

    /**
     * Power consumption when CPU is awake (when a wake lock is held).  This
     * should be 0 on devices that can go into full CPU power collapse even
     * when a wake lock is held.  Otherwise, this is the power consumption in
     * addition to POWER_CPU_IDLE due to a wake lock being held but with no
     * CPU activity.
     */
    public static final String POWER_CPU_AWAKE = "cpu.awake";

    /**
     * Power consumption when CPU is in power collapse mode.
     */
    @Deprecated
    public static final String POWER_CPU_ACTIVE = "cpu.active";

    /**
     * Power consumption when WiFi driver is scanning for networks.
     */
    public static final String POWER_WIFI_SCAN = "wifi.scan";

    /**
     * Power consumption when WiFi driver is on.
     */
    public static final String POWER_WIFI_ON = "wifi.on";

    /**
     * Power consumption when WiFi driver is transmitting/receiving.
     */
    public static final String POWER_WIFI_ACTIVE = "wifi.active";

    //
    // Updated power constants. These are not estimated, they are real world
    // currents and voltages for the underlying bluetooth and wifi controllers.
    //

    public static final String POWER_WIFI_CONTROLLER_IDLE = "wifi.controller.idle";
    public static final String POWER_WIFI_CONTROLLER_RX = "wifi.controller.rx";
    public static final String POWER_WIFI_CONTROLLER_TX = "wifi.controller.tx";
    public static final String POWER_WIFI_CONTROLLER_TX_LEVELS = "wifi.controller.tx_levels";
    public static final String POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE = "wifi.controller.voltage";

    public static final String POWER_BLUETOOTH_CONTROLLER_IDLE = "bluetooth.controller.idle";
    public static final String POWER_BLUETOOTH_CONTROLLER_RX = "bluetooth.controller.rx";
    public static final String POWER_BLUETOOTH_CONTROLLER_TX = "bluetooth.controller.tx";
    public static final String POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE =
            "bluetooth.controller.voltage";

    public static final String POWER_MODEM_CONTROLLER_IDLE = "modem.controller.idle";
    public static final String POWER_MODEM_CONTROLLER_RX = "modem.controller.rx";
    public static final String POWER_MODEM_CONTROLLER_TX = "modem.controller.tx";
    public static final String POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE =
            "modem.controller.voltage";

    /**
     * Power consumption when GPS is on.
     */
    public static final String POWER_GPS_ON = "gps.on";

    /**
     * Power consumption when Bluetooth driver is on.
     * @deprecated
     */
    @Deprecated
    public static final String POWER_BLUETOOTH_ON = "bluetooth.on";

    /**
     * Power consumption when Bluetooth driver is transmitting/receiving.
     * @deprecated
     */
    @Deprecated
    public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";

    /**
     * Power consumption when Bluetooth driver gets an AT command.
     * @deprecated
     */
    @Deprecated
    public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";


    /**
     * Power consumption when screen is on, not including the backlight power.
     */
    public static final String POWER_SCREEN_ON = "screen.on";

    /**
     * Power consumption when cell radio is on but not on a call.
     */
    public static final String POWER_RADIO_ON = "radio.on";

    /**
     * Power consumption when cell radio is hunting for a signal.
     */
    public static final String POWER_RADIO_SCANNING = "radio.scanning";

    /**
     * Power consumption when talking on the phone.
     */
    public static final String POWER_RADIO_ACTIVE = "radio.active";

    /**
     * Power consumption at full backlight brightness. If the backlight is at
     * 50% brightness, then this should be multiplied by 0.5
     */
    public static final String POWER_SCREEN_FULL = "screen.full";

    /**
     * Power consumed by the audio hardware when playing back audio content. This is in addition
     * to the CPU power, probably due to a DSP and / or amplifier.
     */
    public static final String POWER_AUDIO = "dsp.audio";

    /**
     * Power consumed by any media hardware when playing back video content. This is in addition
     * to the CPU power, probably due to a DSP.
     */
    public static final String POWER_VIDEO = "dsp.video";

    /**
     * Average power consumption when camera flashlight is on.
     */
    public static final String POWER_FLASHLIGHT = "camera.flashlight";

    /**
     * Average power consumption when the camera is on over all standard use cases.
     *
     * TODO: Add more fine-grained camera power metrics.
     */
    public static final String POWER_CAMERA = "camera.avg";

    @Deprecated
    public static final String POWER_CPU_SPEEDS = "cpu.speeds";

    /**
     * Power consumed by wif batched scaning.  Broken down into bins by
     * Channels Scanned per Hour.  May do 1-720 scans per hour of 1-100 channels
     * for a range of 1-72,000.  Going logrithmic (1-8, 9-64, 65-512, 513-4096, 4097-)!
     */
    public static final String POWER_WIFI_BATCHED_SCAN = "wifi.batchedscan";

    /**
     * Battery capacity in milliAmpHour (mAh).
     */
    public static final String POWER_BATTERY_CAPACITY = "battery.capacity";

    static final HashMap<String, Object> sPowerMap = new HashMap<>();

    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";

    public PowerProfile(Context context) {
        // Read the XML file for the given profile (normally only one per
        // device)
        if (sPowerMap.size() == 0) {
            readPowerValuesFromXml(context);
        }
        initCpuClusters();
    }

    /**
     * 解析 power_profile.xml文件
     */
    private void readPowerValuesFromXml(Context context) {
        int id = com.android.internal.R.xml.power_profile;
        final Resources resources = context.getResources();
        XmlResourceParser parser = resources.getXml(id);
        boolean parsingArray = false;
        ArrayList<Double> array = new ArrayList<Double>();
        String arrayName = null;

        try {
            XmlUtils.beginDocument(parser, TAG_DEVICE);

            while (true) {
                XmlUtils.nextElement(parser);

                String element = parser.getName();
                if (element == null) break;

                if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
                    // Finish array
                    sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
                    parsingArray = false;
                }
                if (element.equals(TAG_ARRAY)) {
                    parsingArray = true;
                    array.clear();
                    arrayName = parser.getAttributeValue(null, ATTR_NAME);
                } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
                    String name = null;
                    if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
                    if (parser.next() == XmlPullParser.TEXT) {
                        String power = parser.getText();
                        double value = 0;
                        try {
                            value = Double.valueOf(power);
                        } catch (NumberFormatException nfe) {
                        }
                        if (element.equals(TAG_ITEM)) {
                            sPowerMap.put(name, value);
                        } else if (parsingArray) {
                            array.add(value);
                        }
                    }
                }
            }
            if (parsingArray) {
                sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
            }
        } catch (XmlPullParserException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            parser.close();
        }

        // Now collect other config variables.
        int[] configResIds = new int[]{
                com.android.internal.R.integer.config_bluetooth_idle_cur_ma,
                com.android.internal.R.integer.config_bluetooth_rx_cur_ma,
                com.android.internal.R.integer.config_bluetooth_tx_cur_ma,
                com.android.internal.R.integer.config_bluetooth_operating_voltage_mv,
                com.android.internal.R.integer.config_wifi_idle_receive_cur_ma,
                com.android.internal.R.integer.config_wifi_active_rx_cur_ma,
                com.android.internal.R.integer.config_wifi_tx_cur_ma,
                com.android.internal.R.integer.config_wifi_operating_voltage_mv,
        };

        String[] configResIdKeys = new String[]{
                POWER_BLUETOOTH_CONTROLLER_IDLE,
                POWER_BLUETOOTH_CONTROLLER_RX,
                POWER_BLUETOOTH_CONTROLLER_TX,
                POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE,
                POWER_WIFI_CONTROLLER_IDLE,
                POWER_WIFI_CONTROLLER_RX,
                POWER_WIFI_CONTROLLER_TX,
                POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE,
        };

        for (int i = 0; i < configResIds.length; i++) {
            String key = configResIdKeys[i];
            // if we already have some of these parameters in power_profile.xml, ignore the
            // value in config.xml
            if ((sPowerMap.containsKey(key) && (Double) sPowerMap.get(key) > 0)) {
                continue;
            }
            int value = resources.getInteger(configResIds[i]);
            if (value > 0) {
                sPowerMap.put(key, (double) value);
            }
        }

        for (Entry<String, Object> item : sPowerMap.entrySet()) {
            Log.d("CpuPowerCalculator", "sPowerMap key = " + item.getKey() + ", value = " + item.getValue());
        }
    }

    // CPU 群簇信息
    private CpuClusterKey[] mCpuClusters;

    private static final String POWER_CPU_CLUSTER_CORE_COUNT = "cpu.clusters.cores";
    private static final String POWER_CPU_CLUSTER_SPEED_PREFIX = "cpu.speeds.cluster";
    private static final String POWER_CPU_CLUSTER_ACTIVE_PREFIX = "cpu.active.cluster";

    @SuppressWarnings("deprecated")
    private void initCpuClusters() {
        // Figure out how many CPU clusters we're dealing with
        /*
        <array name="cpu.clusters.cores">
            <value>4</value>
            <value>4</value>
        </array>
        */
        final Object obj = sPowerMap.get(POWER_CPU_CLUSTER_CORE_COUNT); // 获取CPU核数信息
        if (obj == null || !(obj instanceof Double[])) {
            // Default to single.
            mCpuClusters = new CpuClusterKey[1];
            mCpuClusters[0] = new CpuClusterKey(POWER_CPU_SPEEDS, POWER_CPU_ACTIVE, 1);

        } else {
            // 例如 定义了 2 组 Double[]的数据,每组Double[]为4
            final Double[] array = (Double[]) obj;
            // 对 CPU 群簇信息 进行分组
            mCpuClusters = new CpuClusterKey[array.length];

            for (int cluster = 0/* 从CPU 群簇 0 开始*/; cluster < array.length/* array.length = 2 */; cluster++) {
                // 计算每个CPU 群簇信息的核数,实际中可以得到分为2个CPU 群簇,每个群簇有4和CPU核数
                // Math.round(array[cluster]) = Math.round(array[0]) = Math.round(4) = 4
                // Math.round(array[cluster]) = Math.round(array[1]) = Math.round(4) = 4
                int numCpusInCluster = (int) Math.round(array[cluster]);

                mCpuClusters[cluster] = new CpuClusterKey(
                        POWER_CPU_CLUSTER_SPEED_PREFIX + cluster,
                        POWER_CPU_CLUSTER_ACTIVE_PREFIX + cluster,
                        numCpusInCluster);
            }
        }
    }

    public static class CpuClusterKey {
        private final String timeKey;
        private final String powerKey;
        private final int numCpus;

        // timeKey CPU 群簇的频率档位 cpu.speeds.cluster[0或1]
        // powerKey CPU 群簇的频率单位对应的耗电信息 cpu.active.cluster[0或1]
        // numCpus CPU 群簇的核数信息
        private CpuClusterKey(String timeKey, String powerKey, int numCpus) {
            this.timeKey = timeKey;
            this.powerKey = powerKey;
            this.numCpus = numCpus;
        }
    }

    /**
     * 获取CPU 群簇的长度大小
     */
    public int getNumCpuClusters() {
        return mCpuClusters.length;
    }

    /**
     * 获取CPU 群簇[下标].核数数量长度大小
     * 例如 cluster 0 has cpu0, cpu1, cpu2, cpu3
     */
    public int getNumCoresInCpuCluster(int index) {
        return mCpuClusters[index].numCpus;
    }

    /**
     * 获取CPU 群簇[下标].可用频率档位数量长度大小
     * 例如 cluster 0 has 156 、400、MHz CPU speed
     */
    public int getNumSpeedStepsInCpuCluster(int index) {
        Object value = sPowerMap.get(mCpuClusters[index].timeKey);
        if (value != null && value instanceof Double[]) {
            return ((Double[])value).length;
        }
        return 1; // Only one speed
    }

    /**
     * 获取cpu.active.cluster[cluster].[step] 对应下标的CPU耗电信息
     * 例如cpu.active.cluster0下第0下标的电流为100 mA
     */
    public double getAveragePowerForCpu(int cluster, int step) {
        if (cluster >= 0 && cluster < mCpuClusters.length) {
            return getAveragePower(mCpuClusters[cluster].powerKey, step);
        }
        return 0;
    }

    /**
     * Returns the average current in mA consumed by the subsystem, or the given
     * default value if the subsystem has no recorded value.
     * @param type the subsystem type
     * @param defaultValue the value to return if the subsystem has no recorded value.
     * @return the average current in milliAmps.
     */
    /**
     * 获取key值为type下对应的电流,非平均电流误导
     */
    public double getAveragePowerOrDefault(String type, double defaultValue) {
        if (sPowerMap.containsKey(type)) {
            Object data = sPowerMap.get(type);
            if (data instanceof Double[]) {
                // 这个接口实际获取的是cpu.active.cluster[type]下第0下标的电流
                return ((Double[])data)[0];
            } else {
                // 获取对应type下配置的电流
                return (Double) sPowerMap.get(type);
            }
        } else {
            return defaultValue;
        }
    }

    /**
     * Returns the average current in mA consumed by the subsystem
     * @param type the subsystem type
     * @return the average current in milliAmps.
     */
    /**
     * 获取key值为type下对应的电流,非平均电流误导
     */
    public double getAveragePower(String type) {
        return getAveragePowerOrDefault(type, 0);
    }
    
    /**
     * Returns the average current in mA consumed by the subsystem for the given level.
     * @param type the subsystem type
     * @param level the level of power at which the subsystem is running. For instance, the
     *  signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
     *  If there is no data for multiple levels, the level is ignored.
     * @return the average current in milliAmps.
     */
    /**
     * 获取平均电流
     * 如果type类型是数组,则获取对应数组下标level的对应电流,记录
     * 例如<array name="cpu.active.cluster0"> <value>100</value>
     * 如果type类是普通子项,直接返回电流即可
     * 例如<item name="cpu.idle">6</item>
     * 
     */
    public double getAveragePower(String type, int level) {
        if (sPowerMap.containsKey(type)) {
            Object data = sPowerMap.get(type);
            if (data instanceof Double[]) {
                final Double[] values = (Double[]) data;
                if (values.length > level && level >= 0) {
                    return values[level];
                } else if (level < 0 || values.length == 0) {
                    return 0;
                } else {
                    return values[values.length - 1];
                }
            } else {
                return (Double) data;
            }
        } else {
            return 0;
        }
    }

    /**
     * Returns the battery capacity, if available, in milli Amp Hours. If not available,
     * it returns zero.
     * @return the battery capacity in mAh
     */
    /**
     * 获取电池容量
     */
    public double getBatteryCapacity() {
        return getAveragePower(POWER_BATTERY_CAPACITY);
    }
}

解析对象-power_profile.xml

源码路径

frameworks/base/core/res/res/xml/power_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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">
  <!-- Most values are the incremental current used by a feature,
       in mA (measured at nominal voltage).
       The default values are deliberately incorrect dummy values.
       OEM's must measure and provide actual values before
       shipping a device.
       Example real-world values are given in comments, but they
       are totally dependent on the platform and can vary
       significantly, so should be measured on the shipping platform
       with a power meter. -->
  <item name="none">0</item>
  <item name="screen.on">223</item>  <!-- ~200mA -->
  <item name="screen.full">350</item>  <!-- ~300mA -->
  <item name="bluetooth.active">66</item> <!-- Bluetooth data transfer, ~10mA -->
  <item name="bluetooth.on">1</item>  <!-- Bluetooth on & connectable, but not connected, ~0.1mA -->
  <item name="wifi.on">2.1</item>  <!-- ~3mA -->
  <item name="wifi.active">200</item>  <!-- WIFI data transfer, ~200mA -->
  <item name="wifi.scan">100</item>  <!-- WIFI network scanning, ~100mA -->
  <item name="dsp.audio">100</item> <!-- ~10mA -->
  <item name="dsp.video">50</item> <!-- ~50mA -->
  <item name="camera.flashlight">142</item> <!-- Avg. power for camera flash, ~160mA -->
  <item name="camera.avg">599</item> <!-- Avg. power use of camera in standard usecases, ~550mA -->

  <!-- Radio related values. For modems without energy reporting support in firmware, use
       radio.active, radio.scanning, and radio.on. -->
  <item name="radio.active">200</item> <!-- ~200mA -->
  <item name="radio.scanning">10</item> <!-- cellular radio scanning for signal, ~10mA -->
  <item name="gps.on">50</item> <!-- ~50mA -->

  <!-- Current consumed by the radio at different signal strengths, when paging -->
  <array name="radio.on"> <!-- Strength 0 to BINS-1 -->
      <value>2</value> <!-- ~2mA -->
      <value>1</value> <!-- ~1mA -->
  </array>

  <!-- Radio related values. For modems WITH energy reporting support in firmware, use
       modem.controller.idle, modem.controller.tx, modem.controller.rx, modem.controller.voltage.
       -->
  <item name="modem.controller.idle">0</item>
  <item name="modem.controller.rx">0</item>
  <item name="modem.controller.tx">0</item>
  <item name="modem.controller.voltage">0</item>

  <!-- A list of heterogeneous CPU clusters, where the value for each cluster represents the
       number of CPU cores for that cluster.

       Ex:
       <array name="cpu.clusters.cores">
         <value>4</value> // cluster 0 has cpu0, cpu1, cpu2, cpu3
         <value>2</value> // cluster 1 has cpu4, cpu5
       </array> -->
  <array name="cpu.clusters.cores">
      <value>4</value>
      <value>4</value>
  </array>

    <!-- Different CPU speeds for cluster 0 as reported in
       /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state.

       There must be one of these for each cluster, labeled:
       cpu.speeds.cluster0, cpu.speeds.cluster1, etc...-->
  <array name="cpu.speeds.cluster0">
      <value>156000</value> <!-- 156 MHz CPU speed -->
      <value>286000</value> <!-- 286 MHz CPU speed -->
      <value>338000</value> <!-- 338 MHz CPU speed -->
      <value>494000</value> <!-- 494 MHz CPU speed -->
      <value>598000</value> <!-- 598 MHz CPU speed -->
      <value>663000</value> <!-- 663 MHz CPU speed -->
      <value>689000</value> <!-- 689 MHz CPU speed -->
      <value>819000</value> <!-- 819 MHz CPU speed -->
      <value>871000</value> <!-- 871 MHz CPU speed -->
      <value>910000</value> <!-- 910 MHz CPU speed -->
      <value>1001000</value> <!-- 1001 MHz CPU speed -->
      <value>1027000</value> <!-- 1027 MHz CPU speed -->
      <value>1196000</value> <!-- 1196 MHz CPU speed -->
      <value>1352000</value> <!-- 1352 MHz CPU speed -->
      <value>1430000</value> <!-- 1430 MHz CPU speed -->
      <value>1508000</value> <!-- 1508 MHz CPU speed -->
  </array>

  <array name="cpu.speeds.cluster1">
      <value>156000</value> <!-- 156 MHz CPU speed -->
      <value>286000</value> <!-- 286 MHz CPU speed -->
      <value>338000</value> <!-- 338 MHz CPU speed -->
      <value>494000</value> <!-- 494 MHz CPU speed -->
      <value>598000</value> <!-- 598 MHz CPU speed -->
      <value>663000</value> <!-- 663 MHz CPU speed -->
      <value>689000</value> <!-- 689 MHz CPU speed -->
      <value>819000</value> <!-- 819 MHz CPU speed -->
      <value>871000</value> <!-- 871 MHz CPU speed -->
      <value>910000</value> <!-- 910 MHz CPU speed -->
      <value>1001000</value> <!-- 1001 MHz CPU speed -->
      <value>1027000</value> <!-- 1027 MHz CPU speed -->
      <value>1196000</value> <!-- 1196 MHz CPU speed -->
      <value>1352000</value> <!-- 1352 MHz CPU speed -->
      <value>1430000</value> <!-- 1430 MHz CPU speed -->
      <value>1508000</value> <!-- 1508 MHz CPU speed -->
  </array>

  <!-- Current when CPU is idle -->
  <item name="cpu.idle">6</item>
  <!-- Current at each CPU speed, as per 'cpu.speeds' -->
  <array name="cpu.active">
      <value>100</value>
  </array>

  <!-- Current at each CPU speed for cluster 0, as per 'cpu.speeds.cluster0'.
       Like cpu.speeds.cluster0, there must be one of these present for
       each heterogeneous CPU cluster. -->
  <array name="cpu.active.cluster0">
      <value>100</value>
      <value>113</value>
      <value>124</value>
      <value>135</value>
      <value>146</value>
      <value>151</value>
      <value>162</value>
      <value>171</value>
      <value>182</value>
      <value>193</value>
      <value>201</value>
      <value>213</value>
      <value>222</value>
      <value>231</value>
      <value>241</value>
      <value>250</value>
  </array>

  <array name="cpu.active.cluster1">
      <value>100</value>
      <value>113</value>
      <value>124</value>
      <value>135</value>
      <value>146</value>
      <value>151</value>
      <value>162</value>
      <value>171</value>
      <value>182</value>
      <value>193</value>
      <value>201</value>
      <value>213</value>
      <value>222</value>
      <value>231</value>
      <value>241</value>
      <value>250</value>
  </array>

  <!-- This is the battery capacity in mAh (measured at nominal voltage) -->
  <item name="battery.capacity">3500</item>

  <!-- Wifi related values. -->
  <!-- Idle Receive current for wifi radio in mA. 0 by default-->
  <item name="wifi.controller.idle">0</item>
  <!-- Rx current for wifi radio in mA. 0 by default-->
  <item name="wifi.controller.rx">0</item>
  <!-- Tx current for wifi radio in mA. 0 by default-->
  <item name="wifi.controller.tx">0</item>
  <!-- Current at each of the wifi Tx levels in mA. The number of tx levels varies per device
       and is available only of wifi chipsets which support the tx level reporting. Use
        wifi.tx for other chipsets. none by default -->
  <array name="wifi.controller.tx_levels"> <!-- mA -->
  </array>
  <!-- Operating volatage for wifi radio in mV. 0 by default-->
  <item name="wifi.controller.voltage">0</item>

  <array name="wifi.batchedscan"> <!-- mA -->
      <value>.2</value> <!-- 1-8/hr -->
      <value>2</value>  <!-- 9-64/hr -->
      <value>20</value>   <!-- 65-512/hr -->
      <value>200</value>    <!-- 513-4,096/hr -->
      <value>500</value>    <!-- 4097-/hr -->
  </array>

</device>

猜你喜欢

转载自blog.csdn.net/su749520/article/details/83340832