Merge "BatteryStats: Update external stats individually." into mnc-dev

This commit is contained in:
Adam Lesinski
2015-06-19 01:22:52 +00:00
committed by Android (Google) Code Review
2 changed files with 97 additions and 41 deletions

View File

@@ -95,8 +95,8 @@ import java.util.concurrent.locks.ReentrantLock;
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 final class BatteryStatsImpl extends BatteryStats {
public interface ExternalStatsSync {
void scheduleSync(String reason);
void scheduleWifiSync(String reason);
}
public final MyHandler mHandler;
@@ -3490,7 +3491,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = true;
mWifiOnTimer.startRunningLocked(elapsedRealtime);
scheduleSyncExternalStatsLocked("wifi-off");
scheduleSyncExternalWifiStatsLocked("wifi-off");
}
}
@@ -3504,7 +3505,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtime);
scheduleSyncExternalStatsLocked("wifi-on");
scheduleSyncExternalWifiStatsLocked("wifi-on");
}
}
@@ -3756,7 +3757,7 @@ public final class BatteryStatsImpl extends BatteryStats {
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 @@ public final class BatteryStatsImpl extends BatteryStats {
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 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mWifiState = wifiState;
mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
scheduleSyncExternalStatsLocked("wifi-state");
scheduleSyncExternalWifiStatsLocked("wifi-state");
}
}
@@ -7542,6 +7543,10 @@ public final class BatteryStatsImpl extends BatteryStats {
* @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 @@ public final class BatteryStatsImpl extends BatteryStats {
* 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 @@ public final class BatteryStatsImpl extends BatteryStats {
* @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 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
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;

View File

@@ -71,9 +71,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
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 final class BatteryStatsService extends IBatteryStats.Stub
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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@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 final class BatteryStatsService extends IBatteryStats.Stub
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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
//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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
//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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
* 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub
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();
}
if ((updateFlags & UPDATE_RADIO) != 0) {
mStats.updateMobileRadioStateLocked(elapsedRealtime);
}
if ((updateFlags & UPDATE_WIFI) != 0) {
mStats.updateWifiStateLocked(wifiEnergyInfo);
}
if ((updateFlags & UPDATE_BT) != 0) {
mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
}
mStats.updateCpuTimeLocked();
mStats.updateKernelWakelocksLocked();
mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
mStats.updateWifiStateLocked(wifiEnergyInfo);
mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
}
}
}