Merge change 3857 into donut
* changes: Allow arrays of values for power profile data.
This commit is contained in:
@@ -30,9 +30,11 @@ import android.util.PrintWriterPrinter;
|
||||
import android.util.Printer;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -53,7 +55,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
|
||||
|
||||
// Current on-disk Parcel version
|
||||
private static final int VERSION = 38;
|
||||
private static final int VERSION = 39;
|
||||
|
||||
private final File mFile;
|
||||
private final File mBackupFile;
|
||||
@@ -94,7 +96,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
boolean mScreenOn;
|
||||
StopwatchTimer mScreenOnTimer;
|
||||
|
||||
|
||||
int mScreenBrightnessBin = -1;
|
||||
final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
|
||||
@@ -137,10 +139,10 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
long mTrackBatteryUptimeStart;
|
||||
long mTrackBatteryPastRealtime;
|
||||
long mTrackBatteryRealtimeStart;
|
||||
|
||||
|
||||
long mUnpluggedBatteryUptime;
|
||||
long mUnpluggedBatteryRealtime;
|
||||
|
||||
|
||||
/*
|
||||
* These keep track of battery levels (1-100) at the last plug event and the last unplug event.
|
||||
*/
|
||||
@@ -149,6 +151,15 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
long mLastWriteTime = 0; // Milliseconds
|
||||
|
||||
// Mobile data transferred while on battery
|
||||
private long[] mMobileDataTx = new long[4];
|
||||
private long[] mMobileDataRx = new long[4];
|
||||
private long[] mTotalDataTx = new long[4];
|
||||
private long[] mTotalDataRx = new long[4];
|
||||
|
||||
private long mRadioDataUptime;
|
||||
private long mRadioDataStart;
|
||||
|
||||
/*
|
||||
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
|
||||
*/
|
||||
@@ -893,7 +904,40 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
return kwlt;
|
||||
}
|
||||
|
||||
|
||||
private void doDataPlug(long[] dataTransfer, long currentBytes) {
|
||||
dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
|
||||
dataTransfer[STATS_UNPLUGGED] = -1;
|
||||
}
|
||||
|
||||
private void doDataUnplug(long[] dataTransfer, long currentBytes) {
|
||||
dataTransfer[STATS_UNPLUGGED] = currentBytes;
|
||||
}
|
||||
|
||||
private long getCurrentRadioDataUptimeMs() {
|
||||
try {
|
||||
File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
|
||||
if (!awakeTimeFile.exists()) return 0;
|
||||
BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
|
||||
String line = br.readLine();
|
||||
br.close();
|
||||
return Long.parseLong(line);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// Nothing
|
||||
} catch (IOException ioe) {
|
||||
// Nothing
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getRadioDataUptimeMs() {
|
||||
if (mRadioDataStart == -1) {
|
||||
return mRadioDataUptime;
|
||||
} else {
|
||||
return getCurrentRadioDataUptimeMs() - mRadioDataStart;
|
||||
}
|
||||
}
|
||||
|
||||
public void doUnplug(long batteryUptime, long batteryRealtime) {
|
||||
for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
|
||||
Uid u = mUidStats.valueAt(iu);
|
||||
@@ -905,8 +949,16 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
|
||||
mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
|
||||
}
|
||||
// Track total mobile data
|
||||
doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
|
||||
doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
|
||||
doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
|
||||
doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
|
||||
// Track radio awake time
|
||||
mRadioDataStart = getCurrentRadioDataUptimeMs();
|
||||
mRadioDataUptime = 0;
|
||||
}
|
||||
|
||||
|
||||
public void doPlug(long batteryUptime, long batteryRealtime) {
|
||||
for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
|
||||
Uid u = mUidStats.valueAt(iu);
|
||||
@@ -922,8 +974,15 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
|
||||
mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
|
||||
}
|
||||
doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
|
||||
doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
|
||||
doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
|
||||
doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
|
||||
// Track radio awake time
|
||||
mRadioDataUptime = getRadioDataUptimeMs();
|
||||
mRadioDataStart = -1;
|
||||
}
|
||||
|
||||
|
||||
public void noteStartGps(int uid) {
|
||||
mUidStats.get(uid).noteStartGps();
|
||||
}
|
||||
@@ -931,7 +990,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
public void noteStopGps(int uid) {
|
||||
mUidStats.get(uid).noteStopGps();
|
||||
}
|
||||
|
||||
|
||||
public void noteScreenOnLocked() {
|
||||
if (!mScreenOn) {
|
||||
mScreenOn = true;
|
||||
@@ -1039,6 +1098,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
|
||||
if (mPhoneDataConnectionType != bin) {
|
||||
if (mPhoneDataConnectionType >= 0) {
|
||||
mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
|
||||
@@ -2701,7 +2761,44 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
public long getBatteryRealtime(long curTime) {
|
||||
return getBatteryRealtimeLocked(curTime);
|
||||
}
|
||||
|
||||
|
||||
private long getTcpBytes(long current, long[] dataBytes, int which) {
|
||||
if (which == STATS_LAST) {
|
||||
return dataBytes[STATS_LAST];
|
||||
} else {
|
||||
if (which == STATS_UNPLUGGED) {
|
||||
if (dataBytes[STATS_UNPLUGGED] < 0) {
|
||||
return dataBytes[STATS_LAST];
|
||||
} else {
|
||||
return current - dataBytes[STATS_UNPLUGGED];
|
||||
}
|
||||
} else if (which == STATS_TOTAL) {
|
||||
return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
|
||||
}
|
||||
return current - dataBytes[STATS_CURRENT];
|
||||
}
|
||||
}
|
||||
|
||||
/** Only STATS_UNPLUGGED works properly */
|
||||
public long getMobileTcpBytesSent(int which) {
|
||||
return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
|
||||
}
|
||||
|
||||
/** Only STATS_UNPLUGGED works properly */
|
||||
public long getMobileTcpBytesReceived(int which) {
|
||||
return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
|
||||
}
|
||||
|
||||
/** Only STATS_UNPLUGGED works properly */
|
||||
public long getTotalTcpBytesSent(int which) {
|
||||
return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
|
||||
}
|
||||
|
||||
/** Only STATS_UNPLUGGED works properly */
|
||||
public long getTotalTcpBytesReceived(int which) {
|
||||
return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDischargeStartLevel() {
|
||||
synchronized(this) {
|
||||
@@ -3227,6 +3324,18 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
mDischargeCurrentLevel = in.readInt();
|
||||
mLastWriteTime = in.readLong();
|
||||
|
||||
mMobileDataRx[STATS_LAST] = in.readLong();
|
||||
mMobileDataRx[STATS_UNPLUGGED] = -1;
|
||||
mMobileDataTx[STATS_LAST] = in.readLong();
|
||||
mMobileDataTx[STATS_UNPLUGGED] = -1;
|
||||
mTotalDataRx[STATS_LAST] = in.readLong();
|
||||
mTotalDataRx[STATS_UNPLUGGED] = -1;
|
||||
mTotalDataTx[STATS_LAST] = in.readLong();
|
||||
mTotalDataTx[STATS_UNPLUGGED] = -1;
|
||||
|
||||
mRadioDataUptime = in.readLong();
|
||||
mRadioDataStart = -1;
|
||||
|
||||
mKernelWakelockStats.clear();
|
||||
int NKW = in.readInt();
|
||||
for (int ikw = 0; ikw < NKW; ikw++) {
|
||||
@@ -3301,6 +3410,14 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
out.writeInt(mDischargeCurrentLevel);
|
||||
out.writeLong(mLastWriteTime);
|
||||
|
||||
out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
|
||||
out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
|
||||
out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
|
||||
out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
|
||||
|
||||
// Write radio uptime for data
|
||||
out.writeLong(getRadioDataUptimeMs());
|
||||
|
||||
out.writeInt(mKernelWakelockStats.size());
|
||||
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
|
||||
SamplingTimer kwlt = ent.getValue();
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
@@ -118,26 +119,28 @@ public class PowerProfile {
|
||||
*/
|
||||
public static final String POWER_VIDEO = "dsp.video";
|
||||
|
||||
static final HashMap<String, Double> sPowerMap = new HashMap<String, Double>();
|
||||
static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>();
|
||||
|
||||
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, CharSequence profile) {
|
||||
public PowerProfile(Context context) {
|
||||
// Read the XML file for the given profile (normally only one per
|
||||
// device)
|
||||
if (sPowerMap.size() == 0) {
|
||||
readPowerValuesFromXml(context, profile);
|
||||
readPowerValuesFromXml(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void readPowerValuesFromXml(Context context, CharSequence profile) {
|
||||
// FIXME
|
||||
//int id = context.getResources().getIdentifier(profile.toString(), "xml",
|
||||
// "com.android.internal");
|
||||
int id = com.android.internal.R.xml.power_profile_default;
|
||||
private void readPowerValuesFromXml(Context context) {
|
||||
int id = com.android.internal.R.xml.power_profile;
|
||||
XmlResourceParser parser = context.getResources().getXml(id);
|
||||
boolean parsingArray = false;
|
||||
ArrayList<Double> array = new ArrayList<Double>();
|
||||
String arrayName = null;
|
||||
|
||||
try {
|
||||
XmlUtils.beginDocument(parser, TAG_DEVICE);
|
||||
@@ -145,22 +148,39 @@ public class PowerProfile {
|
||||
while (true) {
|
||||
XmlUtils.nextElement(parser);
|
||||
|
||||
String element = parser.getName();
|
||||
if (element == null || !(element.equals(TAG_ITEM))) {
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
String 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_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);
|
||||
}
|
||||
}
|
||||
sPowerMap.put(name, value);
|
||||
}
|
||||
}
|
||||
if (parsingArray) {
|
||||
sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
@@ -177,7 +197,40 @@ public class PowerProfile {
|
||||
*/
|
||||
public double getAveragePower(String type) {
|
||||
if (sPowerMap.containsKey(type)) {
|
||||
return sPowerMap.get(type);
|
||||
Object data = sPowerMap.get(type);
|
||||
if (data instanceof Double[]) {
|
||||
return ((Double[])data)[0];
|
||||
} else {
|
||||
return (Double) sPowerMap.get(type);
|
||||
}
|
||||
} else {
|
||||
return 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.
|
||||
*/
|
||||
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) {
|
||||
return values[level];
|
||||
} else if (values.length < 0) {
|
||||
return values[0];
|
||||
} else {
|
||||
return values[values.length - 1];
|
||||
}
|
||||
} else {
|
||||
return (Double) data;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,19 +19,22 @@
|
||||
|
||||
<device name="Android">
|
||||
<item name="none">0</item>
|
||||
<item name="screen.on">30</item>
|
||||
<item name="bluetooth.active">103</item>
|
||||
<item name="bluetooth.on">5</item>
|
||||
<item name="screen.full">114</item>
|
||||
<item name="wifi.on">23</item>
|
||||
<item name="wifi.active">200</item>
|
||||
<item name="wifi.scan">200</item>
|
||||
<item name="cpu.idle">1.6</item>
|
||||
<item name="cpu.normal">100</item>
|
||||
<item name="cpu.full">140</item>
|
||||
<item name="dsp.audio">70</item>
|
||||
<item name="dsp.video">100</item>
|
||||
<item name="radio.on">3</item>
|
||||
<item name="radio.active">175</item>
|
||||
<item name="gps.on">120</item>
|
||||
<item name="screen.on">0.1</item>
|
||||
<item name="bluetooth.active">0.1</item>
|
||||
<item name="bluetooth.on">0.1</item>
|
||||
<item name="screen.full">0.1</item>
|
||||
<item name="wifi.on">0.1</item>
|
||||
<item name="wifi.active">0.1</item>
|
||||
<item name="wifi.scan">0.1</item>
|
||||
<item name="cpu.idle">0.1</item>
|
||||
<item name="cpu.normal">0.2</item>
|
||||
<item name="cpu.full">1</item>
|
||||
<item name="dsp.audio">0.1</item>
|
||||
<item name="dsp.video">0.1</item>
|
||||
<item name="radio.active">1</item>
|
||||
<item name="gps.on">1</item>
|
||||
<array name="radio.on"> <!-- Strength 0 to BINS-1 -->
|
||||
<value>1</value>
|
||||
<value>0.1</value>
|
||||
</array>
|
||||
</device>
|
||||
Reference in New Issue
Block a user