Merge "Add tracking of uid process states in battery stats."
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 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 @@
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 @@
*
* @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 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 @@
}
}
}
-
- 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 @@
}
}
+ 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 @@
}
}
- 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(": ");
+ 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)");
- }
+ 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 @@
}
}
+ 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 @@
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 @@
}
// 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 @@
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.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 @@
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 @@
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 @@
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 @@
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 @@
/**
* 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 @@
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 @@
}
@Override
- public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() {
+ public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
return mSensorStats;
}
@@ -4035,6 +4074,21 @@
}
}
+ 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 @@
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 @@
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 @@
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 @@
}
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 @@
} 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 @@
} 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 @@
*/
int mUnpluggedStarts;
+ /**
+ * Current process state.
+ */
+ int mProcessState = PROCESS_STATE_NONE;
+
SamplingCounter[] mSpeedBins;
ArrayList<ExcessivePower> mExcessivePower;
@@ -5485,6 +5585,49 @@
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 @@
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 @@
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 @@
} 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 @@
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();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e10c48f..053fb5a 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -138,7 +138,6 @@
import android.content.pm.ServiceInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
-import android.graphics.Bitmap;
import android.net.Proxy;
import android.net.ProxyInfo;
import android.net.Uri;
@@ -2997,12 +2996,10 @@
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
- BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
- synchronized (bs) {
- if (bs.isOnBattery()) {
- bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
- }
+ if (app.isolated) {
+ mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
}
+ mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
@@ -3052,14 +3049,13 @@
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
- mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
- app.processName, app.info.uid);
- if (app.isolated) {
- mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
- }
} catch (RuntimeException e) {
// XXX do better error recovery.
app.setPid(0);
+ mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
+ if (app.isolated) {
+ mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+ }
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
@@ -5121,8 +5117,7 @@
mPidsSelfLocked.remove(pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
- mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
- app.processName, app.info.uid);
+ mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
@@ -5166,8 +5161,7 @@
mHeavyWeightProcess.userId, 0));
mHeavyWeightProcess = null;
}
- mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
- app.processName, app.info.uid);
+ mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
@@ -13285,8 +13279,7 @@
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
- mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
- app.processName, app.info.uid);
+ mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
@@ -16039,7 +16032,7 @@
app.notCachedSinceIdle = false;
}
if (!doingAll) {
- setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
+ setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
} else {
app.procStateChanged = true;
}
@@ -16092,9 +16085,15 @@
return success;
}
- private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
- if (proc.thread != null && proc.baseProcessTracker != null) {
- proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
+ private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
+ if (proc.thread != null) {
+ if (proc.baseProcessTracker != null) {
+ proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
+ }
+ if (proc.repProcState >= 0) {
+ mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
+ proc.repProcState);
+ }
}
}
@@ -16149,7 +16148,7 @@
ActivityRecord act = mStackSupervisor.resumedAppLocked();
String pkg;
int uid;
- if (act != null && !act.sleeping) {
+ if (act != null) {
pkg = act.packageName;
uid = act.info.applicationInfo.uid;
} else {
@@ -16430,7 +16429,7 @@
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (allChanged || app.procStateChanged) {
- setProcessTrackerState(app, trackerMemFactor, now);
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
app.procStateChanged = false;
}
if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
@@ -16521,7 +16520,7 @@
for (int i=N-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
if (allChanged || app.procStateChanged) {
- setProcessTrackerState(app, trackerMemFactor, now);
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
app.procStateChanged = false;
}
if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 5c5e3e3..da444f9 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -33,7 +33,6 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
-import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Slog;
@@ -166,6 +165,27 @@
}
}
+ public void noteProcessStart(String name, int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteProcessStartLocked(name, uid);
+ }
+ }
+
+ public void noteProcessState(String name, int uid, int state) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteProcessStateLocked(name, uid, state);
+ }
+ }
+
+ public void noteProcessFinish(String name, int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteProcessFinishLocked(name, uid);
+ }
+ }
+
public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
boolean unimportantForLogging) {
enforceCallingPermission();