diff options
author | Amith Yamasani <yamasani@google.com> | 2009-08-21 13:11:37 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2009-09-20 16:03:50 -0700 |
commit | e43530ab571e901f94361078c7c1f970a0bd27f2 (patch) | |
tree | 2a2c528dab1a81064c63bbc1adbe77ba39eb66ac /core | |
parent | eb8aad7b2a99d3332a2fa6d8778356d634c47127 (diff) | |
download | frameworks_base-e43530ab571e901f94361078c7c1f970a0bd27f2.zip frameworks_base-e43530ab571e901f94361078c7c1f970a0bd27f2.tar.gz frameworks_base-e43530ab571e901f94361078c7c1f970a0bd27f2.tar.bz2 |
Track CPU speed stepping to get more accurate CPU cost per app.
More CPU speed stepping happening with newer devices, so we need
to qualify CPU time with the CPU speed, since power consumption
varies greatly by speed. Apps that peg the CPU should get a higher
penaltly.
Also, fix for 2062930: NPE at VolumePreference.onKey()
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/os/BatteryStats.java | 12 | ||||
-rw-r--r-- | core/java/android/preference/VolumePreference.java | 3 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 78 | ||||
-rw-r--r-- | core/java/com/android/internal/os/PowerProfile.java | 23 | ||||
-rw-r--r-- | core/res/res/xml/power_profile.xml | 15 |
5 files changed, 113 insertions, 18 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index e203fd5..a49a27a0 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -314,6 +314,15 @@ public abstract class BatteryStats implements Parcelable { * @return foreground cpu time in microseconds */ public abstract long getForegroundTime(int which); + + /** + * Returns the approximate cpu time spent in microseconds, at a certain CPU speed. + * @param speedStep the index of the CPU speed. This is not the actual speed of the + * CPU. + * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED + * @see BatteryStats#getCpuSpeedSteps() + */ + public abstract long getTimeAtCpuSpeedStep(int speedStep, int which); } /** @@ -573,6 +582,9 @@ public abstract class BatteryStats implements Parcelable { public abstract Map<String, ? extends Timer> getKernelWakelockStats(); + /** Returns the number of different speeds that the CPU can run at */ + public abstract int getCpuSpeedSteps(); + private final static void formatTimeRaw(StringBuilder out, long seconds) { long days = seconds / (60 * 60 * 24); if (days != 0) { diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index b337d28..a264594 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -121,6 +121,9 @@ public class VolumePreference extends SeekBarPreference implements if (mSeekBarVolumizer != null) { Dialog dialog = getDialog(); if (dialog != null && dialog.isShowing()) { + View view = dialog.getWindow().getDecorView() + .findViewById(com.android.internal.R.id.seekbar); + if (view != null) view.setOnKeyListener(null); // Stopped while dialog was showing, revert changes mSeekBarVolumizer.revertVolume(); } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 2da72df..35c66ba 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -56,7 +56,9 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 39; + private static final int VERSION = 40; + + private static int sNumSpeedSteps; private final File mFile; private final File mBackupFile; @@ -213,7 +215,7 @@ public final class BatteryStatsImpl extends BatteryStats { /** * State for keeping track of counting information. */ - public static final class Counter extends BatteryStats.Counter implements Unpluggable { + public static class Counter extends BatteryStats.Counter implements Unpluggable { int mCount; int mLoadedCount; int mLastCount; @@ -302,7 +304,22 @@ public final class BatteryStatsImpl extends BatteryStats { mUnpluggedCount = mPluggedCount = mCount; } } - + + public static class SamplingCounter extends Counter { + + SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { + super(unpluggables, in); + } + + SamplingCounter(ArrayList<Unpluggable> unpluggables) { + super(unpluggables); + } + + public void addCountLocked(long count) { + mCount += count; + } + } + /** * State for keeping track of timing information. */ @@ -1940,10 +1957,16 @@ public final class BatteryStatsImpl extends BatteryStats { */ long mUnpluggedForegroundTime; + SamplingCounter[] mSpeedBins; + Proc() { mUnpluggables.add(this); + mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; + for (int i = 0; i < mSpeedBins.length; i++) { + mSpeedBins[i] = new SamplingCounter(mUnpluggables); + } } - + public void unplug(long batteryUptime, long batteryRealtime) { mUnpluggedUserTime = mUserTime; mUnpluggedSystemTime = mSystemTime; @@ -1974,6 +1997,11 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeLong(mUnpluggedSystemTime); out.writeLong(mUnpluggedForegroundTime); out.writeInt(mUnpluggedStarts); + + out.writeInt(mSpeedBins.length); + for (int i = 0; i < mSpeedBins.length; i++) { + mSpeedBins[i].writeToParcel(out); + } } void readFromParcelLocked(Parcel in) { @@ -1993,6 +2021,12 @@ public final class BatteryStatsImpl extends BatteryStats { mUnpluggedSystemTime = in.readLong(); mUnpluggedForegroundTime = in.readLong(); mUnpluggedStarts = in.readInt(); + + int bins = in.readInt(); + mSpeedBins = new SamplingCounter[bins]; + for (int i = 0; i < bins; i++) { + mSpeedBins[i] = new SamplingCounter(mUnpluggables, in); + } } public BatteryStatsImpl getBatteryStats() { @@ -2075,6 +2109,22 @@ public final class BatteryStatsImpl extends BatteryStats { } return val; } + + /* Called by ActivityManagerService when CPU times are updated. */ + public void addSpeedStepTimes(long[] values) { + for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { + mSpeedBins[i].addCountLocked(values[i]); + } + } + + @Override + public long getTimeAtCpuSpeedStep(int speedStep, int which) { + if (speedStep < mSpeedBins.length) { + return mSpeedBins[speedStep].getCountLocked(which); + } else { + return 0; + } + } } /** @@ -2625,6 +2675,10 @@ public final class BatteryStatsImpl extends BatteryStats { readFromParcel(p); } + public void setNumSpeedSteps(int steps) { + if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; + } + @Override public int getStartCount() { return mStartCount; @@ -2853,6 +2907,11 @@ public final class BatteryStatsImpl extends BatteryStats { return mDischargeCurrentLevel; } + @Override + public int getCpuSpeedSteps() { + return sNumSpeedSteps; + } + /** * Retrieve the statistics object for a particular uid, creating if needed. */ @@ -3063,7 +3122,9 @@ public final class BatteryStatsImpl extends BatteryStats { getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); } } - + + sNumSpeedSteps = in.readInt(); + final int NU = in.readInt(); for (int iu = 0; iu < NU; iu++) { int uid = in.readInt(); @@ -3206,6 +3267,7 @@ public final class BatteryStatsImpl extends BatteryStats { } } + out.writeInt(sNumSpeedSteps); final int NU = mUidStats.size(); out.writeInt(NU); for (int iu = 0; iu < NU; iu++) { @@ -3404,6 +3466,8 @@ public final class BatteryStatsImpl extends BatteryStats { mFullTimers.clear(); mWindowTimers.clear(); + sNumSpeedSteps = in.readInt(); + int numUids = in.readInt(); mUidStats.clear(); for (int i = 0; i < numUids; i++) { @@ -3484,7 +3548,9 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeInt(0); } } - + + out.writeInt(sNumSpeedSteps); + int size = mUidStats.size(); out.writeInt(size); for (int i = 0; i < size; i++) { diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java index 94f703a..4b4b717 100644 --- a/core/java/com/android/internal/os/PowerProfile.java +++ b/core/java/com/android/internal/os/PowerProfile.java @@ -47,14 +47,9 @@ public class PowerProfile { public static final String POWER_CPU_IDLE = "cpu.idle"; /** - * Power consumption when CPU is running at normal speed. - */ - public static final String POWER_CPU_NORMAL = "cpu.normal"; - - /** - * Power consumption when CPU is running at full speed. + * Power consumption when CPU is in power collapse mode. */ - public static final String POWER_CPU_FULL = "cpu.full"; + public static final String POWER_CPU_ACTIVE = "cpu.active"; /** * Power consumption when WiFi driver is scanning for networks. @@ -124,6 +119,8 @@ public class PowerProfile { */ public static final String POWER_VIDEO = "dsp.video"; + public static final String POWER_CPU_SPEEDS = "cpu.speeds"; + static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>(); private static final String TAG_DEVICE = "device"; @@ -214,10 +211,10 @@ public class PowerProfile { } /** - * Returns the average current in mA consumed by the subsystem for the given level. + * 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.). + * 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. */ @@ -240,4 +237,12 @@ public class PowerProfile { return 0; } } + + public int getNumSpeedSteps() { + Object value = sPowerMap.get(POWER_CPU_SPEEDS); + if (value != null && value instanceof Double[]) { + return ((Double[])value).length; + } + return 1; // Only one speed + } } diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml index 859902e..710b71e 100644 --- a/core/res/res/xml/power_profile.xml +++ b/core/res/res/xml/power_profile.xml @@ -26,15 +26,24 @@ <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> + <!-- Current consumed by the radio at different signal strengths, when paging --> <array name="radio.on"> <!-- Strength 0 to BINS-1 --> <value>1</value> <value>0.1</value> </array> + <!-- Different CPU speeds as reported in + /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state --> + <array name="cpu.speeds"> + <value>400000</value> <!-- 400 MHz CPU speed --> + </array> + <!-- Power consumption when CPU is idle --> + <item name="cpu.idle">0.1</item> + <!-- Power consumption at different speeds --> + <array name="cpu.active"> + <value>0.2</value> + </array> </device> |