热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PowerProfile.java与power_profile.xml

转载自http:blog.csdn.netgreen1900articledetails42427871现在诸多关于电池管理的应用做的极其绚烂,可实现如耗电应用排行、剩余时间计算、

转载自http://blog.csdn.net/green1900/article/details/42427871

   现在诸多关于电池管理的应用做的极其绚烂,可实现如耗电应用排行、剩余时间计算、关闭耗电程序以节省电量等功能,这两天对此模块进行了研究,总结如下。

        首先解释下各软硬件耗电量的计算。假设设备(如WIFI)单位时间内消耗的电量为w,运行时间为t,则其在这段时间内的耗电量为W=w*t。根据物理学中的知识,电功率(即所谓电量)计算公式为W=UIt,其中U为电压值,I为电流值,t为运行时间。由于在一部机器中,电压值U是恒定不变的(一般如此),因此可以忽略掉参数U,单独通过电流及时间即可表示电量(比如电池容量为2000mA、2500mA等,以mA为单位进行恒量)。根据以上描述,只要我们获得了某程序或某设备运行的时间,以及其运行时所需要电流值,则可以计算出其消耗的电量(以上理论会在代码中体现)。

        某程序或硬件设备的运行时间可以分别通过BatteryStats.Uid.Proc和BatteryStatsImpl中的相关接口获得(后文分析代码时会见到),本文主要讲下电流值(即单位时间消耗电量)的获取。

        1. PowerProfile.Java

        OK,不多废话,直接给出系统中提供的接口--./frameworks/base/core/java/com/Android/internal/os/PowerProfile.java。此类提供了如下接口:

        (1)public double getAveragePower(String type)

        此方法返回在type子系统下消耗的电流值,单位为mA。type可取PowerProfile中定义的常量值,包括POWER_CPU_IDLE(CPU空闲时),POWER_CPU_ACTIVE(CPU处于活动时),POWER_WIFI_ON(WIFI开启时)等各种状态。例如,如下调用getAveragePower(POWER_CPU_ACTIVE)将返回CPU处于活动时的电流值;getAveragePower(POWER_WIFI_ON)将返回维持WIFI启动状态所需的电流值。结合之前的描述,假设WIFI开启的时间为t(假设此段时间未使用WIFI传输数据,因为WIFI传输数据需要额外的电能消耗),那么在此段时间内WIFI所消耗的电量为W=t*getAveragePower(POWER_WIFI_ON)。

        type可取如下值:

/** 
 * 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 POWERR_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. 
 */  
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";  
/** 
 * Power consumption when GPS is on. 
 */  
public static final String POWER_GPS_ON = "gps.on";  
/** 
 * Power consumption when Bluetooth driver is on. 
 */  
public static final String POWER_BLUETOOTH_ON = "bluetooth.on";  
/** 
 * Power consumption when Bluetooth driver is transmitting/receiving. 
 */  
public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";  
/** 
 * Power consumption when Bluetooth driver gets an AT command. 
 */  
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"; 

代码段1 PowerProfile.java中定义的子系统类型

        (2) public double getAveragePower(String type, int level)

        相比于方法(1),此接口需要传入参数level,现在来解释下level的含义。我们知道,android系统中CPU可以以多种速度运行(假设分别为600MHz,800MHz,1GHZ等),速度不同时CPU消耗的电量也不同,参数level即代表不同的运行频率,显然,方法getAveragePower(String type, int level)将返回type子系统在CPU运行速度级别为level时单位时间内所消耗的电量(即电流值)。

        (3)public double getBatteryCapacity()       获取电池总电量。

        (4)public int getNumSpeedSteps()        获取CPU可以以几种速度运行。

        2. power_profile.xml

        事实上,通过阅读PowerProfile.java代码及相关注释即可知,此类中各接口返回的电流等数值都是通过读取power_profile.xml文件获得的,即各种子系统消耗的电量值、CPU运行速度值、总电量等信息都是以固定值的形式存储在power_profile.xml中。由于硬件之间的差异,各子系统耗电信息是不同的,因此此文件需要各生产厂商进行定制。android系统原生的power_profile.xml文件的存放路径为:frameworks/base/core/java/com/android/internal/os/PowerProfile.java,经过各硬件厂商定制后,存放路径可能发生变化,如三星某型号的power_profile.xml路径:device/samsung/maguro/overlay/frameworks/base/core/res/res/xml/power_profile.xml,其内容如下:

<device name="Android">  
    
  <item name="none">0item>  
  <item name="screen.on">200item>   
  <item name="bluetooth.active">150item>  
  <item name="bluetooth.on">1item>  
  <item name="bluetooth.at">1item>   
  <item name="screen.full">160item>   
  <item name="wifi.on">1item>      
  <item name="wifi.active">150item>      
  <item name="wifi.scan">200item>      
  <item name="dsp.audio">150item>  
  <item name="dsp.video">200item>  
  <item name="radio.active">150item>  
  <item name="gps.on">55item>  
  <item name="battery.capacity">1750item>  
  <item name="radio.scanning">90item>   
    
   <array name="radio.on">   
      <value>3.0value>  
      <value>3.0value>  
  array>  
  <array name="cpu.speeds">  
    <value>350000value>      
    <value>700000value>      
    <value>920000value>      
    <value>1200000value>      
  array>  
    
  <item name="cpu.idle">7item>  
    
  <item name="cpu.awake">20item>  
    
  <array name="cpu.active">  
      <value>120value>  
      <value>228value>  
      <value>299value>  
      <value>397value>  
  array>  
device>  

代码段2 power_profile.xml内容

显然,从power_profile.xml可知,此型号机器可以以3.5MHz、7.0MHz、9.2MHz、1.2GHz四种速度运行(定义),且在此四种运行速度下CPU的耗电量分别为120mAh,228mAh,299mAh及397mAh()。通过对比代码段1可知,PowerProfile.java中定义的常量即对应于power_profile.xml中各属性名。因此,PowerProfile.java只是用于读取power_profile.xml的接口而已,后者才是存储系统耗电信息的核心文件。

        通过上述分析可知,android系统对于电池电量信息统计还是提供了数据与接口的(本人菜鸟,之前一直认为耗电及剩余时间信息是由先前一定时间内的耗电量统计而来的,分析了settings中的电池相关的代码后才知是有据可依的)。根据PowerProfile.java及power_profile.xml,我们可以计算出各应用或设备的耗电量、电池剩余时间等信息,相关内容将在后续文章中描述。

 PowerProfile.java源码

  1 /*
  2  * Copyright (C) 2009 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.internal.os;
 18 
 19 
 20 import android.content.Context;
 21 import android.content.res.XmlResourceParser;
 22 
 23 import com.android.internal.util.XmlUtils;
 24 
 25 import org.xmlpull.v1.XmlPullParser;
 26 import org.xmlpull.v1.XmlPullParserException;
 27 
 28 import java.io.IOException;
 29 import java.util.ArrayList;
 30 import java.util.HashMap;
 31 
 32 /**
 33  * Reports power consumption values for various device activities. Reads values from an XML file.
 34  * Customize the XML file for different devices.
 35  * [hidden]
 36  */
 37 public class PowerProfile {
 38 
 39     /**
 40      * No power consumption, or accounted for elsewhere.
 41      */
 42     public static final String POWER_NOnE= "none";
 43 
 44     /**
 45      * Power consumption when CPU is in power collapse mode.
 46      */
 47     public static final String POWER_CPU_IDLE = "cpu.idle";
 48 
 49     /**
 50      * Power consumption when CPU is in power collapse mode.
 51      */
 52     public static final String POWER_CPU_ACTIVE = "cpu.active";
 53 
 54     /**
 55      * Power consumption when WiFi driver is scanning for networks.
 56      */
 57     public static final String POWER_WIFI_SCAN = "wifi.scan";
 58 
 59     /**
 60      * Power consumption when WiFi driver is on.
 61      */
 62     public static final String POWER_WIFI_ON = "wifi.on";
 63 
 64     /**
 65      * Power consumption when WiFi driver is transmitting/receiving.
 66      */
 67     public static final String POWER_WIFI_ACTIVE = "wifi.active";
 68 
 69     /**
 70      * Power consumption when GPS is on.
 71      */
 72     public static final String POWER_GPS_ON = "gps.on";
 73 
 74     /**
 75      * Power consumption when Bluetooth driver is on.
 76      */
 77     public static final String POWER_BLUETOOTH_ON = "bluetooth.on";
 78 
 79     /**
 80      * Power consumption when Bluetooth driver is transmitting/receiving.
 81      */
 82     public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
 83 
 84     /**
 85      * Power consumption when Bluetooth driver gets an AT command.
 86      */
 87     public static final String POWER_BLUETOOTH_AT_CMD = "bluetooth.at";
 88 
 89     /**
 90      * Power consumption when screen is on, not including the backlight power.
 91      */
 92     public static final String POWER_SCREEN_ON = "screen.on";
 93 
 94     /**
 95      * Power consumption when cell radio is on but not on a call.
 96      */
 97     public static final String POWER_RADIO_ON = "radio.on";
 98 
 99     /**
100      * Power consumption when cell radio is hunting for a signal.
101      */
102     public static final String POWER_RADIO_SCANNING = "radio.scanning";
103 
104     /**
105      * Power consumption when talking on the phone.
106      */
107     public static final String POWER_RADIO_ACTIVE = "radio.active";
108 
109     /**
110      * Power consumption at full backlight brightness. If the backlight is at
111      * 50% brightness, then this should be multiplied by 0.5
112      */
113     public static final String POWER_SCREEN_FULL = "screen.full";
114 
115     /**
116      * Power consumed by the audio hardware when playing back audio content. This is in addition
117      * to the CPU power, probably due to a DSP and / or amplifier.
118      */
119     public static final String POWER_AUDIO = "dsp.audio";
120 
121     /**
122      * Power consumed by any media hardware when playing back video content. This is in addition
123      * to the CPU power, probably due to a DSP.
124      */
125     public static final String POWER_VIDEO = "dsp.video";
126 
127     public static final String POWER_CPU_SPEEDS = "cpu.speeds";
128 
129     static final HashMap sPowerMap = new HashMap();
130 
131     private static final String TAG_DEVICE = "device";
132     private static final String TAG_ITEM = "item";
133     private static final String TAG_ARRAY = "array";
134     private static final String TAG_ARRAYITEM = "value";
135     private static final String ATTR_NAME = "name";
136 
137     public PowerProfile(Context context) {
138         // Read the XML file for the given profile (normally only one per
139         // device)
140         if (sPowerMap.size() == 0) {
141             readPowerValuesFromXml(context);
142         }
143     }
144 
145     private void readPowerValuesFromXml(Context context) {
146         int id = com.android.internal.R.xml.power_profile;
147         XmlResourceParser parser = context.getResources().getXml(id);
148         boolean parsingArray = false;
149         ArrayList array = new ArrayList();
150         String arrayName = null;
151 
152         try {
153             XmlUtils.beginDocument(parser, TAG_DEVICE);
154 
155             while (true) {
156                 XmlUtils.nextElement(parser);
157 
158                 String element = parser.getName();
159                 if (element == null) break;
160                 
161                 if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
162                     // Finish array
163                     sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
164                     parsingArray = false;
165                 }
166                 if (element.equals(TAG_ARRAY)) {
167                     parsingArray = true;
168                     array.clear();
169                     arrayName = parser.getAttributeValue(null, ATTR_NAME);
170                 } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
171                     String name = null;
172                     if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
173                     if (parser.next() == XmlPullParser.TEXT) {
174                         String power = parser.getText();
175                         double value = 0;
176                         try {
177                             value = Double.valueOf(power);
178                         } catch (NumberFormatException nfe) {
179                         }
180                         if (element.equals(TAG_ITEM)) {
181                             sPowerMap.put(name, value);
182                         } else if (parsingArray) {
183                             array.add(value);
184                         }
185                     }
186                 }
187             }
188             if (parsingArray) {
189                 sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
190             }
191         } catch (XmlPullParserException e) {
192             throw new RuntimeException(e);
193         } catch (IOException e) {
194             throw new RuntimeException(e);
195         } finally {
196             parser.close();
197         }
198     }
199 
200     /**
201      * Returns the average current in mA consumed by the subsystem 
202      * @param type the subsystem type
203      * @return the average current in milliAmps.
204      */
205     public double getAveragePower(String type) {
206         if (sPowerMap.containsKey(type)) {
207             Object data = sPowerMap.get(type);
208             if (data instanceof Double[]) {
209                 return ((Double[])data)[0];
210             } else {
211                 return (Double) sPowerMap.get(type);
212             }
213         } else {
214             return 0;
215         }
216     }
217     
218     /**
219      * Returns the average current in mA consumed by the subsystem for the given level.
220      * @param type the subsystem type
221      * @param level the level of power at which the subsystem is running. For instance, the
222      *  signal strength of the cell network between 0 and 4 (if there are 4 bars max.)
223      *  If there is no data for multiple levels, the level is ignored.
224      * @return the average current in milliAmps.
225      */
226     public double getAveragePower(String type, int level) {
227         if (sPowerMap.containsKey(type)) {
228             Object data = sPowerMap.get(type);
229             if (data instanceof Double[]) {
230                 final Double[] values = (Double[]) data;
231                 if (values.length > level && level >= 0) {
232                     return values[level];
233                 } else if (level <0) {
234                     return 0;
235                 } else {
236                     return values[values.length - 1];
237                 }
238             } else {
239                 return (Double) data;
240             }
241         } else {
242             return 0;
243         }
244     }
245 
246     public int getNumSpeedSteps() {
247         Object value = sPowerMap.get(POWER_CPU_SPEEDS);
248         if (value != null && value instanceof Double[]) {
249             return ((Double[])value).length;
250         }
251         return 1; // Only one speed
252     }
253 }

PowerProfile.java与power_profile.xml


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
author-avatar
天天多派对_272
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有