diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-07-09 16:13:01 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2014-07-09 20:04:03 -0700 |
commit | 61659e5daaea80104d4d0fd567e78b5f757b5df4 (patch) | |
tree | 7a61cc57948338836d6fa57f46888dc6776382fc /core/java | |
parent | 6b1e88e5d09a88dd77e631918aa7122a95a7ff4b (diff) | |
download | frameworks_base-61659e5daaea80104d4d0fd567e78b5f757b5df4.zip frameworks_base-61659e5daaea80104d4d0fd567e78b5f757b5df4.tar.gz frameworks_base-61659e5daaea80104d4d0fd567e78b5f757b5df4.tar.bz2 |
Add tracking of uid process states in battery stats.
We now keep track of how long each uid had processes in
various states: foreground, active, running. This is based
on a collapse of the various activity manager process states
into these three bins.
You'll see these in a checkin like this:
8,10013,l,st,61504,61504,83109
Also fix issue #16021555: App showing up as on "top" even
when the screen is off. This is "fixed" by just saying we
always report the current app at the top of the activity stack,
regardless of the state of the screen.
Change-Id: I1204904225101243eb00b43425d9806bffdd2ab9
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/os/BatteryStats.java | 148 | ||||
-rw-r--r-- | core/java/com/android/internal/app/IBatteryStats.aidl | 4 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsHelper.java | 10 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 348 |
4 files changed, 354 insertions, 156 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 21d60c5..d0a6f08 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -115,6 +115,11 @@ public abstract class BatteryStats implements Parcelable { public static final int WIFI_BATCHED_SCAN = 11; /** + * A constant indicating a process state timer + */ + public static final int PROCESS_STATE = 12; + + /** * Include all of the data in the stats, including previously saved data. */ public static final int STATS_SINCE_CHARGED = 0; @@ -150,6 +155,7 @@ public abstract class BatteryStats implements Parcelable { private static final String SENSOR_DATA = "sr"; private static final String VIBRATOR_DATA = "vib"; private static final String FOREGROUND_DATA = "fg"; + private static final String STATE_TIME_DATA = "st"; private static final String WAKELOCK_DATA = "wl"; private static final String KERNEL_WAKELOCK_DATA = "kwl"; private static final String WAKEUP_REASON_DATA = "wr"; @@ -278,7 +284,7 @@ public abstract class BatteryStats implements Parcelable { * * @return a Map from Integer sensor ids to Uid.Sensor objects. */ - public abstract Map<Integer, ? extends Sensor> getSensorStats(); + public abstract SparseArray<? extends Sensor> getSensorStats(); /** * Returns a mapping containing active process data. @@ -328,6 +334,22 @@ public abstract class BatteryStats implements Parcelable { public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which); public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which); public abstract Timer getForegroundActivityTimer(); + + // Time this uid has any processes in foreground state. + public static final int PROCESS_STATE_FOREGROUND = 0; + // Time this uid has any process in active state (not cached). + public static final int PROCESS_STATE_ACTIVE = 1; + // Time this uid has any processes running at all. + public static final int PROCESS_STATE_RUNNING = 2; + // Total number of process states we track. + public static final int NUM_PROCESS_STATE = 3; + + static final String[] PROCESS_STATE_NAMES = { + "Foreground", "Active", "Running" + }; + + public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); + public abstract Timer getVibratorOnTimer(); public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5; @@ -2082,22 +2104,20 @@ public abstract class BatteryStats implements Parcelable { } } } - - Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); - if (sensors.size() > 0) { - for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent - : sensors.entrySet()) { - Uid.Sensor se = ent.getValue(); - int sensorNumber = ent.getKey(); - Timer timer = se.getSensorTime(); - if (timer != null) { - // Convert from microseconds to milliseconds with rounding - long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; - int count = timer.getCountLocked(which); - if (totalTime != 0) { - dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); - } - } + + SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); + int NSE = sensors.size(); + for (int ise=0; ise<NSE; ise++) { + Uid.Sensor se = sensors.valueAt(ise); + int sensorNumber = sensors.keyAt(ise); + Timer timer = se.getSensorTime(); + if (timer != null) { + // Convert from microseconds to milliseconds with rounding + long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; + int count = timer.getCountLocked(which); + if (totalTime != 0) { + dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count); + } } } @@ -2121,6 +2141,16 @@ public abstract class BatteryStats implements Parcelable { } } + Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE]; + long totalStateTime = 0; + for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) { + totalStateTime += u.getProcessStateTime(ips, rawRealtime, which); + stateTimes[ips] = (totalStateTime + 500) / 1000; + } + if (totalStateTime > 0) { + dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes); + } + Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); if (processStats.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent @@ -2968,45 +2998,43 @@ public abstract class BatteryStats implements Parcelable { } } - Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); - if (sensors.size() > 0) { - for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent - : sensors.entrySet()) { - Uid.Sensor se = ent.getValue(); - int sensorNumber = ent.getKey(); - sb.setLength(0); - sb.append(prefix); - sb.append(" Sensor "); - int handle = se.getHandle(); - if (handle == Uid.Sensor.GPS) { - sb.append("GPS"); - } else { - sb.append(handle); - } - sb.append(": "); - - Timer timer = se.getSensorTime(); - if (timer != null) { - // Convert from microseconds to milliseconds with rounding - long totalTime = (timer.getTotalTimeLocked( - rawRealtime, which) + 500) / 1000; - int count = timer.getCountLocked(which); - //timer.logState(); - if (totalTime != 0) { - formatTimeMs(sb, totalTime); - sb.append("realtime ("); - sb.append(count); - sb.append(" times)"); - } else { - sb.append("(not used)"); - } + SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats(); + int NSE = sensors.size(); + for (int ise=0; ise<NSE; ise++) { + Uid.Sensor se = sensors.valueAt(ise); + int sensorNumber = sensors.keyAt(ise); + sb.setLength(0); + sb.append(prefix); + sb.append(" Sensor "); + int handle = se.getHandle(); + if (handle == Uid.Sensor.GPS) { + sb.append("GPS"); + } else { + sb.append(handle); + } + sb.append(": "); + + Timer timer = se.getSensorTime(); + if (timer != null) { + // Convert from microseconds to milliseconds with rounding + long totalTime = (timer.getTotalTimeLocked( + rawRealtime, which) + 500) / 1000; + int count = timer.getCountLocked(which); + //timer.logState(); + if (totalTime != 0) { + formatTimeMs(sb, totalTime); + sb.append("realtime ("); + sb.append(count); + sb.append(" times)"); } else { sb.append("(not used)"); } - - pw.println(sb.toString()); - uidActivity = true; + } else { + sb.append("(not used)"); } + + pw.println(sb.toString()); + uidActivity = true; } Timer vibTimer = u.getVibratorOnTimer(); @@ -3047,6 +3075,22 @@ public abstract class BatteryStats implements Parcelable { } } + long totalStateTime = 0; + for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) { + long time = u.getProcessStateTime(ips, rawRealtime, which); + if (time > 0) { + totalStateTime += time; + sb.setLength(0); + sb.append(prefix); + sb.append(" "); + sb.append(Uid.PROCESS_STATE_NAMES[ips]); + sb.append(" for: "); + formatTimeMs(sb, (totalStateTime + 500) / 1000); + pw.println(sb.toString()); + uidActivity = true; + } + } + Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); if (processStats.size() > 0) { for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index ae9b515..98a5843 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -44,6 +44,10 @@ interface IBatteryStats { void noteEvent(int code, String name, int uid); + void noteProcessStart(String name, int uid); + void noteProcessState(String name, int uid, int state); + void noteProcessFinish(String name, int uid); + void noteStartWakelock(int uid, int pid, String name, String historyName, int type, boolean unimportantForLogging); void noteStopWakelock(int uid, int pid, String name, String historyName, int type); diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 469aa6f..273de61 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -440,11 +440,11 @@ public class BatteryStatsHelper { } // Process Sensor usage - Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); - for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry - : sensorStats.entrySet()) { - Uid.Sensor sensor = sensorEntry.getValue(); - int sensorHandle = sensor.getHandle(); + SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); + int NSE = sensorStats.size(); + for (int ise=0; ise<NSE; ise++) { + Uid.Sensor sensor = sensorStats.valueAt(ise); + int sensorHandle = sensorStats.keyAt(ise); BatteryStats.Timer timer = sensor.getSensorTime(); long sensorTime = timer.getTotalTimeLocked(mRawRealtime, which) / 1000; double multiplier = 0; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 49d11dc..6ca048e 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -19,6 +19,7 @@ package com.android.internal.os; import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; +import android.app.ActivityManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.content.Context; @@ -43,6 +44,7 @@ import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; +import android.util.ArrayMap; import android.util.Log; import android.util.LogWriter; import android.util.PrintWriterPrinter; @@ -89,7 +91,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 108 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 109 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -2328,6 +2330,38 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); } + public void noteProcessStartLocked(String name, int uid) { + uid = mapUid(uid); + if (isOnBattery()) { + Uid u = getUidStatsLocked(uid); + u.getProcessStatsLocked(name).incStartsLocked(); + } + if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { + return; + } + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); + } + + public void noteProcessStateLocked(String name, int uid, int state) { + uid = mapUid(uid); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime); + } + + public void noteProcessFinishLocked(String name, int uid) { + uid = mapUid(uid); + if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { + return; + } + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); + getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE, + elapsedRealtime); + } + private void requestWakelockCpuUpdate() { if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); @@ -3765,7 +3799,7 @@ public final class BatteryStatsImpl extends BatteryStats { boolean mWifiScanStarted; StopwatchTimer mWifiScanTimer; - private static final int NO_BATCHED_SCAN_STARTED = -1; + static final int NO_BATCHED_SCAN_STARTED = -1; int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; StopwatchTimer[] mWifiBatchedScanTimer; @@ -3780,6 +3814,10 @@ public final class BatteryStatsImpl extends BatteryStats { StopwatchTimer mForegroundActivityTimer; + static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE; + int mProcessState = PROCESS_STATE_NONE; + StopwatchTimer[] mProcessStateTimer; + BatchTimer mVibratorOnTimer; Counter[] mUserActivityCounters; @@ -3792,22 +3830,22 @@ public final class BatteryStatsImpl extends BatteryStats { /** * The statistics we have collected for this uid's wake locks. */ - final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>(); + final ArrayMap<String, Wakelock> mWakelockStats = new ArrayMap<String, Wakelock>(); /** * The statistics we have collected for this uid's sensor activations. */ - final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>(); + final SparseArray<Sensor> mSensorStats = new SparseArray<Sensor>(); /** * The statistics we have collected for this uid's processes. */ - final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>(); + final ArrayMap<String, Proc> mProcessStats = new ArrayMap<String, Proc>(); /** * The statistics we have collected for this uid's processes. */ - final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>(); + final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<String, Pkg>(); /** * The transient wake stats we have collected for this uid's pids. @@ -3825,6 +3863,7 @@ public final class BatteryStatsImpl extends BatteryStats { mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, mWifiMulticastTimers, mOnBatteryTimeBase); + mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; } @Override @@ -3833,7 +3872,7 @@ public final class BatteryStatsImpl extends BatteryStats { } @Override - public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() { + public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { return mSensorStats; } @@ -4035,6 +4074,21 @@ public final class BatteryStatsImpl extends BatteryStats { } } + void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) { + if (mProcessState == state) return; + + if (mProcessState != PROCESS_STATE_NONE) { + mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); + } + mProcessState = state; + if (state != PROCESS_STATE_NONE) { + if (mProcessStateTimer[state] == null) { + makeProcessState(state, null); + } + mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs); + } + } + public BatchTimer createVibratorOnTimerLocked() { if (mVibratorOnTimer == null) { mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase); @@ -4114,6 +4168,27 @@ public final class BatteryStatsImpl extends BatteryStats { return mForegroundActivityTimer; } + void makeProcessState(int i, Parcel in) { + if (i < 0 || i >= NUM_PROCESS_STATE) return; + + if (in == null) { + mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null, + mOnBatteryTimeBase); + } else { + mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null, + mOnBatteryTimeBase, in); + } + } + + @Override + public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { + if (state < 0 || state >= NUM_PROCESS_STATE) return 0; + if (mProcessStateTimer[state] == null) { + return 0; + } + return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); + } + @Override public Timer getVibratorOnTimer() { return mVibratorOnTimer; @@ -4281,6 +4356,14 @@ public final class BatteryStatsImpl extends BatteryStats { if (mForegroundActivityTimer != null) { active |= !mForegroundActivityTimer.reset(false); } + if (mProcessStateTimer != null) { + for (int i = 0; i < NUM_PROCESS_STATE; i++) { + if (mProcessStateTimer[i] != null) { + active |= !mProcessStateTimer[i].reset(false); + } + } + active |= (mProcessState != PROCESS_STATE_NONE); + } if (mVibratorOnTimer != null) { if (mVibratorOnTimer.reset(false)) { mVibratorOnTimer.detach(); @@ -4305,37 +4388,30 @@ public final class BatteryStatsImpl extends BatteryStats { mMobileRadioActiveCount.reset(false); } - if (mWakelockStats.size() > 0) { - Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<String, Wakelock> wakelockEntry = it.next(); - Wakelock wl = wakelockEntry.getValue(); - if (wl.reset()) { - it.remove(); - } else { - active = true; - } + for (int iw=mWakelockStats.size()-1; iw>=0; iw--) { + Wakelock wl = mWakelockStats.valueAt(iw); + if (wl.reset()) { + mWakelockStats.removeAt(iw); + } else { + active = true; } } - if (mSensorStats.size() > 0) { - Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<Integer, Sensor> sensorEntry = it.next(); - Sensor s = sensorEntry.getValue(); - if (s.reset()) { - it.remove(); - } else { - active = true; - } + for (int ise=mSensorStats.size()-1; ise>=0; ise--) { + Sensor s = mSensorStats.valueAt(ise); + if (s.reset()) { + mSensorStats.removeAt(ise); + } else { + active = true; } } - if (mProcessStats.size() > 0) { - Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<String, Proc> procEntry = it.next(); - procEntry.getValue().detach(); + for (int ip=mProcessStats.size()-1; ip>=0; ip--) { + Proc proc = mProcessStats.valueAt(ip); + if (proc.mProcessState == PROCESS_STATE_NONE) { + proc.detach(); + mProcessStats.removeAt(ip); + } else { + active = true; } - mProcessStats.clear(); } if (mPids.size() > 0) { for (int i=mPids.size()-1; i>=0; i--) { @@ -4413,24 +4489,27 @@ public final class BatteryStatsImpl extends BatteryStats { } void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { - out.writeInt(mWakelockStats.size()); - for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { - out.writeString(wakelockEntry.getKey()); - Uid.Wakelock wakelock = wakelockEntry.getValue(); + int NW = mWakelockStats.size(); + out.writeInt(NW); + for (int iw=0; iw<NW; iw++) { + out.writeString(mWakelockStats.keyAt(iw)); + Uid.Wakelock wakelock = mWakelockStats.valueAt(iw); wakelock.writeToParcelLocked(out, elapsedRealtimeUs); } - out.writeInt(mSensorStats.size()); - for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { - out.writeInt(sensorEntry.getKey()); - Uid.Sensor sensor = sensorEntry.getValue(); + int NSE = mSensorStats.size(); + out.writeInt(NSE); + for (int ise=0; ise<NSE; ise++) { + out.writeInt(mSensorStats.keyAt(ise)); + Uid.Sensor sensor = mSensorStats.valueAt(ise); sensor.writeToParcelLocked(out, elapsedRealtimeUs); } - out.writeInt(mProcessStats.size()); - for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) { - out.writeString(procEntry.getKey()); - Uid.Proc proc = procEntry.getValue(); + int NP = mProcessStats.size(); + out.writeInt(NP); + for (int ip=0; ip<NP; ip++) { + out.writeString(mProcessStats.keyAt(ip)); + Uid.Proc proc = mProcessStats.valueAt(ip); proc.writeToParcelLocked(out); } @@ -4491,6 +4570,14 @@ public final class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + for (int i = 0; i < NUM_PROCESS_STATE; i++) { + if (mProcessStateTimer[i] != null) { + out.writeInt(1); + mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); + } else { + out.writeInt(0); + } + } if (mVibratorOnTimer != null) { out.writeInt(1); mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); @@ -4614,6 +4701,14 @@ public final class BatteryStatsImpl extends BatteryStats { } else { mForegroundActivityTimer = null; } + mProcessState = PROCESS_STATE_NONE; + for (int i = 0; i < NUM_PROCESS_STATE; i++) { + if (in.readInt() != 0) { + makeProcessState(i, in); + } else { + mProcessStateTimer[i] = null; + } + } if (in.readInt() != 0) { mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in); } else { @@ -4871,6 +4966,11 @@ public final class BatteryStatsImpl extends BatteryStats { */ int mUnpluggedStarts; + /** + * Current process state. + */ + int mProcessState = PROCESS_STATE_NONE; + SamplingCounter[] mSpeedBins; ArrayList<ExcessivePower> mExcessivePower; @@ -5485,6 +5585,49 @@ public final class BatteryStatsImpl extends BatteryStats { return ps; } + public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) { + int procState; + if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { + procState = PROCESS_STATE_FOREGROUND; + } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) { + procState = PROCESS_STATE_ACTIVE; + } else { + procState = PROCESS_STATE_RUNNING; + } + updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs); + } + + public void updateRealProcessStateLocked(String procName, int procState, + long elapsedRealtimeMs) { + Proc proc = getProcessStatsLocked(procName); + if (proc.mProcessState != procState) { + boolean changed; + if (procState < proc.mProcessState) { + // Has this process become more important? If so, + // we may need to change the uid if the currrent uid proc state + // is not as important as what we are now setting. + changed = mProcessState > procState; + } else { + // Has this process become less important? If so, + // we may need to change the uid if the current uid proc state + // is the same importance as the old setting. + changed = mProcessState == proc.mProcessState; + } + proc.mProcessState = procState; + if (changed) { + // uid's state may have changed; compute what the new state should be. + int uidProcState = PROCESS_STATE_NONE; + for (int ip=mProcessStats.size()-1; ip>=0; ip--) { + proc = mProcessStats.valueAt(ip); + if (proc.mProcessState < uidProcState) { + uidProcState = proc.mProcessState; + } + } + updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs); + } + } + } + public SparseArray<? extends Pid> getPidStats() { return mPids; } @@ -6782,7 +6925,8 @@ public final class BatteryStatsImpl extends BatteryStats { Uid wifiUid = mUidStats.get(Process.WIFI_UID); if (wifiUid != null) { long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); - for (Uid.Proc proc : wifiUid.mProcessStats.values()) { + for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) { + Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip); long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which); for (int i=0; i<mUidStats.size(); i++) { Uid uid = mUidStats.valueAt(i); @@ -7239,6 +7383,13 @@ public final class BatteryStatsImpl extends BatteryStats { if (in.readInt() != 0) { u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); } + u.mProcessState = Uid.PROCESS_STATE_NONE; + for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { + if (in.readInt() != 0) { + u.makeProcessState(i, null); + u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); + } + } if (in.readInt() != 0) { u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); } @@ -7505,6 +7656,14 @@ public final class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { + if (u.mProcessStateTimer[i] != null) { + out.writeInt(1); + u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); + } + } if (u.mVibratorOnTimer != null) { out.writeInt(1); u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); @@ -7535,71 +7694,62 @@ public final class BatteryStatsImpl extends BatteryStats { int NW = u.mWakelockStats.size(); out.writeInt(NW); - if (NW > 0) { - for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent - : u.mWakelockStats.entrySet()) { - out.writeString(ent.getKey()); - Uid.Wakelock wl = ent.getValue(); - if (wl.mTimerFull != null) { - out.writeInt(1); - wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); - } else { - out.writeInt(0); - } - if (wl.mTimerPartial != null) { - out.writeInt(1); - wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); - } else { - out.writeInt(0); - } - if (wl.mTimerWindow != null) { - out.writeInt(1); - wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); - } else { - out.writeInt(0); - } + for (int iw=0; iw<NW; iw++) { + out.writeString(u.mWakelockStats.keyAt(iw)); + Uid.Wakelock wl = u.mWakelockStats.valueAt(iw); + if (wl.mTimerFull != null) { + out.writeInt(1); + wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); + } + if (wl.mTimerPartial != null) { + out.writeInt(1); + wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); + } + if (wl.mTimerWindow != null) { + out.writeInt(1); + wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); } } int NSE = u.mSensorStats.size(); out.writeInt(NSE); - if (NSE > 0) { - for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent - : u.mSensorStats.entrySet()) { - out.writeInt(ent.getKey()); - Uid.Sensor se = ent.getValue(); - if (se.mTimer != null) { - out.writeInt(1); - se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); - } else { - out.writeInt(0); - } + for (int ise=0; ise<NSE; ise++) { + out.writeInt(u.mSensorStats.keyAt(ise)); + Uid.Sensor se = u.mSensorStats.valueAt(ise); + if (se.mTimer != null) { + out.writeInt(1); + se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); } } int NP = u.mProcessStats.size(); out.writeInt(NP); - if (NP > 0) { - for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent - : u.mProcessStats.entrySet()) { - out.writeString(ent.getKey()); - Uid.Proc ps = ent.getValue(); - out.writeLong(ps.mUserTime); - out.writeLong(ps.mSystemTime); - out.writeLong(ps.mForegroundTime); - out.writeInt(ps.mStarts); - final int N = ps.mSpeedBins.length; - out.writeInt(N); - for (int i=0; i<N; i++) { - if (ps.mSpeedBins[i] != null) { - out.writeInt(1); - ps.mSpeedBins[i].writeSummaryFromParcelLocked(out); - } else { - out.writeInt(0); - } + for (int ip=0; ip<NP; ip++) { + out.writeString(u.mProcessStats.keyAt(ip)); + Uid.Proc ps = u.mProcessStats.valueAt(ip); + out.writeLong(ps.mUserTime); + out.writeLong(ps.mSystemTime); + out.writeLong(ps.mForegroundTime); + out.writeInt(ps.mStarts); + final int N = ps.mSpeedBins.length; + out.writeInt(N); + for (int i=0; i<N; i++) { + if (ps.mSpeedBins[i] != null) { + out.writeInt(1); + ps.mSpeedBins[i].writeSummaryFromParcelLocked(out); + } else { + out.writeInt(0); } - ps.writeExcessivePowerToParcelLocked(out); } + ps.writeExcessivePowerToParcelLocked(out); } NP = u.mPackageStats.size(); |