Merge "BatteryStats: Update external stats individually." into mnc-dev
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 94737c7..229079f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -95,8 +95,8 @@
public final class BatteryStatsImpl extends BatteryStats {
private static final String TAG = "BatteryStatsImpl";
private static final boolean DEBUG = false;
- private static final boolean DEBUG_ENERGY = false;
- public static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY || false;
+ public static final boolean DEBUG_ENERGY = false;
+ private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY || false;
private static final boolean DEBUG_HISTORY = false;
private static final boolean USE_OLD_HISTORY = false; // for debugging.
@@ -182,6 +182,7 @@
public interface ExternalStatsSync {
void scheduleSync(String reason);
+ void scheduleWifiSync(String reason);
}
public final MyHandler mHandler;
@@ -3490,7 +3491,7 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = true;
mWifiOnTimer.startRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-off");
+ scheduleSyncExternalWifiStatsLocked("wifi-off");
}
}
@@ -3504,7 +3505,7 @@
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-on");
+ scheduleSyncExternalWifiStatsLocked("wifi-on");
}
}
@@ -3756,7 +3757,7 @@
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
}
- scheduleSyncExternalStatsLocked("wifi-running");
+ scheduleSyncExternalWifiStatsLocked("wifi-running");
} else {
Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
}
@@ -3795,7 +3796,7 @@
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
}
- scheduleSyncExternalStatsLocked("wifi-stopped");
+ scheduleSyncExternalWifiStatsLocked("wifi-stopped");
} else {
Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
}
@@ -3810,7 +3811,7 @@
}
mWifiState = wifiState;
mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
- scheduleSyncExternalStatsLocked("wifi-state");
+ scheduleSyncExternalWifiStatsLocked("wifi-state");
}
}
@@ -7542,6 +7543,10 @@
* @param info The energy information from the WiFi controller.
*/
public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating wifi stats");
+ }
+
final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
NetworkStats delta = null;
try {
@@ -7739,6 +7744,10 @@
* Distribute Cell radio energy info and network traffic to apps.
*/
public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating mobile radio stats");
+ }
+
NetworkStats delta = null;
try {
if (!ArrayUtils.isEmpty(mMobileIfaces)) {
@@ -7811,6 +7820,10 @@
* @param info The energy information from the bluetooth controller.
*/
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating bluetooth stats");
+ }
+
if (info != null && mOnBatteryInternal) {
mHasBluetoothEnergyReporting = true;
mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
@@ -8233,6 +8246,12 @@
}
}
+ private void scheduleSyncExternalWifiStatsLocked(String reason) {
+ if (mExternalSync != null) {
+ mExternalSync.scheduleWifiSync(reason);
+ }
+ }
+
// This should probably be exposed in the API, though it's not critical
public static final int BATTERY_PLUGGED_NONE = 0;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index ee1ee1c..3854e51 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -71,9 +71,16 @@
Context mContext;
PowerManagerInternal mPowerManagerInternal;
+ final int UPDATE_CPU = 0x01;
+ final int UPDATE_WIFI = 0x02;
+ final int UPDATE_RADIO = 0x04;
+ final int UPDATE_BT = 0x08;
+ final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
+
class BatteryStatsHandler extends Handler implements BatteryStatsImpl.ExternalStatsSync {
public static final int MSG_SYNC_EXTERNAL_STATS = 1;
public static final int MSG_WRITE_TO_DISK = 2;
+ private int mUpdateFlags = 0;
public BatteryStatsHandler(Looper looper) {
super(looper);
@@ -83,11 +90,17 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SYNC_EXTERNAL_STATS:
- updateExternalStats((String)msg.obj, false);
+ final int updateFlags;
+ synchronized (this) {
+ removeMessages(MSG_SYNC_EXTERNAL_STATS);
+ updateFlags = mUpdateFlags;
+ mUpdateFlags = 0;
+ }
+ updateExternalStats((String)msg.obj, updateFlags);
break;
case MSG_WRITE_TO_DISK:
- updateExternalStats("write", true);
+ updateExternalStats("write", UPDATE_ALL);
synchronized (mStats) {
mStats.writeAsyncLocked();
}
@@ -97,9 +110,20 @@
@Override
public void scheduleSync(String reason) {
- if (!hasMessages(MSG_SYNC_EXTERNAL_STATS)) {
- Message msg = Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason);
- sendMessage(msg);
+ scheduleSyncImpl(reason, UPDATE_ALL);
+ }
+
+ @Override
+ public void scheduleWifiSync(String reason) {
+ scheduleSyncImpl(reason, UPDATE_WIFI);
+ }
+
+ private void scheduleSyncImpl(String reason, int updateFlags) {
+ synchronized (this) {
+ if (mUpdateFlags == 0) {
+ sendMessage(Message.obtain(this, MSG_SYNC_EXTERNAL_STATS, reason));
+ }
+ mUpdateFlags |= updateFlags;
}
}
}
@@ -137,7 +161,7 @@
public void shutdown() {
Slog.w("BatteryStats", "Writing battery stats before shutdown...");
- updateExternalStats("shutdown", true);
+ updateExternalStats("shutdown", UPDATE_ALL);
synchronized (mStats) {
mStats.shutdownLocked();
}
@@ -237,7 +261,7 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -252,7 +276,7 @@
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
- updateExternalStats("get-stats", true);
+ updateExternalStats("get-stats", UPDATE_ALL);
synchronized (mStats) {
mStats.writeToParcel(out, 0);
}
@@ -603,8 +627,10 @@
// There was a change in WiFi power state.
// Collect data now for the past activity.
- mHandler.scheduleSync("wifi-data");
synchronized (mStats) {
+ if (mStats.isOnBattery()) {
+ mHandler.scheduleWifiSync("wifi-data");
+ }
mStats.noteWifiRadioPowerState(powerState, tsNanos);
}
}
@@ -807,7 +833,7 @@
// Sync external stats first as the battery has changed states. If we don't sync
// immediately here, we may not collect the relevant data later.
- updateExternalStats("battery-state", true);
+ updateExternalStats("battery-state", UPDATE_ALL);
synchronized (mStats) {
mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
}
@@ -961,9 +987,9 @@
pw.println("Battery stats reset.");
noOutput = true;
}
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} else if ("--write".equals(arg)) {
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
synchronized (mStats) {
mStats.writeSyncLocked();
pw.println("Battery stats written.");
@@ -1027,7 +1053,7 @@
flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
}
// Fetch data from external sources and update the BatteryStatsImpl object with them.
- updateExternalStats("dump", true);
+ updateExternalStats("dump", UPDATE_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1215,15 +1241,12 @@
* We first grab a lock specific to this method, then once all the data has been collected,
* we grab the mStats lock and update the data.
*
- * TODO(adamlesinski): When we start distributing bluetooth data to apps, we'll want to
- * separate these external stats so that they can be collected individually and on different
- * intervals.
- *
* @param reason The reason why this collection was requested. Useful for debugging.
- * @param force If false, some stats may decide not to be collected for efficiency as their
- * results aren't needed immediately. When true, collect all stats unconditionally.
+ * @param updateFlags Which external stats to update. Can be a combination of
+ * {@link #UPDATE_CPU}, {@link #UPDATE_RADIO}, {@link #UPDATE_WIFI},
+ * and {@link #UPDATE_BT}.
*/
- void updateExternalStats(String reason, boolean force) {
+ void updateExternalStats(final String reason, final int updateFlags) {
synchronized (mExternalStatsLock) {
if (mContext == null) {
// We haven't started yet (which means the BatteryStatsImpl object has
@@ -1231,32 +1254,46 @@
return;
}
- final WifiActivityEnergyInfo wifiEnergyInfo = pullWifiEnergyInfoLocked();
- final BluetoothActivityEnergyInfo bluetoothEnergyInfo;
- if (force) {
+ if (BatteryStatsImpl.DEBUG_ENERGY) {
+ Slog.d(TAG, "Updating external stats: reason=" + reason);
+ }
+
+ WifiActivityEnergyInfo wifiEnergyInfo = null;
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ wifiEnergyInfo = pullWifiEnergyInfoLocked();
+ }
+
+ BluetoothActivityEnergyInfo bluetoothEnergyInfo = null;
+ if ((updateFlags & UPDATE_BT) != 0) {
// We only pull bluetooth stats when we have to, as we are not distributing its
// use amongst apps and the sampling frequency does not matter.
bluetoothEnergyInfo = pullBluetoothEnergyInfoLocked();
- } else {
- bluetoothEnergyInfo = null;
}
synchronized (mStats) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
if (mStats.mRecordAllHistory) {
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- final long uptime = SystemClock.uptimeMillis();
mStats.addHistoryEventLocked(elapsedRealtime, uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
}
- if (BatteryStatsImpl.DEBUG_ENERGY_CPU) {
- Slog.d(TAG, "Updating cpu time from external: " + reason);
+ if ((updateFlags & UPDATE_CPU) != 0) {
+ mStats.updateCpuTimeLocked();
+ mStats.updateKernelWakelocksLocked();
}
- mStats.updateCpuTimeLocked();
- mStats.updateKernelWakelocksLocked();
- mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
- mStats.updateWifiStateLocked(wifiEnergyInfo);
- mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
+
+ if ((updateFlags & UPDATE_RADIO) != 0) {
+ mStats.updateMobileRadioStateLocked(elapsedRealtime);
+ }
+
+ if ((updateFlags & UPDATE_WIFI) != 0) {
+ mStats.updateWifiStateLocked(wifiEnergyInfo);
+ }
+
+ if ((updateFlags & UPDATE_BT) != 0) {
+ mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
+ }
}
}
}