From e13c4c0b664dabdc069ca8f9601d96a337eb02f9 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 11 Feb 2014 17:18:35 -0800 Subject: [PATCH] Start tracking radio up time. We now always turn on network state tracking for mobile, and push this information down to battery stats. In battery stats we use this to both log the changes in the history and keep track of the total time the mobile radio was active. Power computation is switched over to using this information to help determine power use, which will hopefully make it more accurate (not counting inaccuracies in knowing when it actually goes down). Note yet done is aggregating this data per-uid, to better emphasize which apps are causing the radio to be up. Right now we just spread the total time across all uids weighted by the total number of packets they have sent and received. Also put in the battery stats infrastructure for bluetooth to address issue #12973036: Improve power_profile.xml Change-Id: I39d11b7ff6ae4f336f253d1cba308d8569de7e0d --- core/java/android/os/BatteryStats.java | 64 ++++--- .../android/internal/app/IBatteryStats.aidl | 2 + .../internal/os/BatteryStatsHelper.java | 3 +- .../android/internal/os/BatteryStatsImpl.java | 159 +++++++++++------- .../android/server/ConnectivityService.java | 2 +- .../server/NetworkManagementService.java | 22 ++- .../server/am/BatteryStatsService.java | 16 +- 7 files changed, 179 insertions(+), 89 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 345ff821bfcbe..a9b60730c75ca 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -549,8 +549,9 @@ public abstract class BatteryStats implements Parcelable { public static final int STATE_SENSOR_ON_FLAG = 1<<30; public static final int STATE_GPS_ON_FLAG = 1<<29; public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28; - public static final int STATE_WIFI_SCAN_FLAG = 1<<29; + public static final int STATE_WIFI_SCAN_FLAG = 1<<27; public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26; + public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25; public static final int STATE_WIFI_RUNNING_FLAG = 1<<24; // These are on the lower bits used for the command; if they change // we need to write another int of data. @@ -882,6 +883,15 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getPhoneSignalStrengthCount(int strengthBin, int which); + /** + * Returns the time in microseconds that the mobile network has been active + * (in a high power state). + * + * {@hide} + */ + public abstract long getMobileRadioActiveTime(long batteryRealtime, int which); + + public static final int DATA_CONNECTION_NONE = 0; public static final int DATA_CONNECTION_GPRS = 1; public static final int DATA_CONNECTION_EDGE = 2; @@ -933,6 +943,7 @@ public abstract class BatteryStats implements Parcelable { new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"), new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"), new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"), + new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"), new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"), new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"), new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"), @@ -993,6 +1004,33 @@ public abstract class BatteryStats implements Parcelable { public abstract int getBluetoothPingCount(); + public static final int BLUETOOTH_INACTIVE = 0; + public static final int BLUETOOTH_ACTIVE_LOW = 1; + public static final int BLUETOOTH_ACTIVE_MEDIUM = 2; + public static final int BLUETOOTH_ACTIVE_HIGH = 3; + + static final String[] BLUETOOTH_ACTIVE_NAMES = { + "none", "low", "med", "high" + }; + + public static final int NUM_BLUETOOTH_ACTIVE_TYPES = BLUETOOTH_ACTIVE_HIGH+1; + + /** + * Returns the time in microseconds that Bluetooth has been running in the + * given active state. + * + * {@hide} + */ + public abstract long getBluetoothActiveTime(int activeType, + long batteryRealtime, int which); + + /** + * Returns the number of times the Bluetooth has entered the given active state. + * + * {@hide} + */ + public abstract int getBluetoothActiveCount(int activeType, int which); + public static final int NETWORK_MOBILE_RX_DATA = 0; public static final int NETWORK_MOBILE_TX_DATA = 1; public static final int NETWORK_WIFI_RX_DATA = 2; @@ -1025,19 +1063,6 @@ public abstract class BatteryStats implements Parcelable { */ public abstract long getBatteryUptime(long curTime); - /** - * @deprecated use getRadioDataUptime - */ - public long getRadioDataUptimeMs() { - return getRadioDataUptime() / 1000; - } - - /** - * Returns the time that the radio was on for data transfers. - * @return the uptime in microseconds while unplugged - */ - public abstract long getRadioDataUptime(); - /** * Returns the current battery realtime in microseconds. * @@ -1374,7 +1399,7 @@ public abstract class BatteryStats implements Parcelable { wifiRunningTime / 1000, bluetoothOnTime / 1000, mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes, fullWakeLockTimeTotal, partialWakeLockTimeTotal, - getInputEventCount(which)); + getInputEventCount(which), getMobileRadioActiveTime(batteryRealtime, which)); // Dump screen brightness stats Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; @@ -1395,7 +1420,7 @@ public abstract class BatteryStats implements Parcelable { args[i] = getPhoneSignalStrengthCount(i, which); } dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args); - + // Dump network type stats args = new Object[NUM_DATA_CONNECTION_TYPES]; for (int i=0; i deviceList = mBtHeadset.getConnectedDevices(); @@ -1520,14 +1484,16 @@ public final class BatteryStatsImpl extends BatteryStats { } // Part of initial delta int that specifies the time delta. - static final int DELTA_TIME_MASK = 0xfffff; - static final int DELTA_TIME_LONG = 0xfffff; // The delta is a following long - static final int DELTA_TIME_INT = 0xffffe; // The delta is a following int - static final int DELTA_TIME_ABS = 0xffffd; // Following is an entire abs update. + static final int DELTA_TIME_MASK = 0x7ffff; + static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long + static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int + static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. // Flag in delta int: a new battery level int follows. - static final int DELTA_BATTERY_LEVEL_FLAG = 0x00100000; + static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; // Flag in delta int: a new full state and battery status int follows. - static final int DELTA_STATE_FLAG = 0x00200000; + static final int DELTA_STATE_FLAG = 0x00100000; + // Flag in delta int: a new full state2 int follows. + static final int DELTA_STATE2_FLAG = 0x00200000; // Flag in delta int: contains a wakelock tag. static final int DELTA_WAKELOCK_FLAG = 0x00400000; // Flag in delta int: contains an event description. @@ -1963,10 +1929,6 @@ public final class BatteryStatsImpl extends BatteryStats { mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime); } - // Track radio awake time - mRadioDataStart = getCurrentRadioDataUptime(); - mRadioDataUptime = 0; - // Track bt headset ping count mBluetoothPingStart = getCurrentBluetoothPingCount(); mBluetoothPingCount = 0; @@ -1977,10 +1939,6 @@ public final class BatteryStatsImpl extends BatteryStats { mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime); } - // Track radio awake time - mRadioDataUptime = getRadioDataUptime(); - mRadioDataStart = -1; - // Track bt headset ping count mBluetoothPingCount = getBluetoothPingCount(); mBluetoothPingStart = -1; @@ -2378,6 +2336,27 @@ public final class BatteryStatsImpl extends BatteryStats { getUidStatsLocked(uid).noteUserActivityLocked(event); } + public void noteDataConnectionActive(String label, boolean active) { + try { + int type = Integer.parseInt(label); + if (ConnectivityManager.isNetworkTypeMobile(type)) { + if (mMobileRadioActive != active) { + if (active) mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; + else mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecordLocked(SystemClock.elapsedRealtime()); + mMobileRadioActive = active; + if (active) mMobileRadioActiveTimer.startRunningLocked(this); + else mMobileRadioActiveTimer.stopRunningLocked(this); + } + } + } catch (NumberFormatException e) { + Slog.w(TAG, "Bad data connection label: " + label, e); + return; + } + } + public void notePhoneOnLocked() { if (!mPhoneOn) { mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG; @@ -2763,6 +2742,17 @@ public final class BatteryStatsImpl extends BatteryStats { } } + public void noteBluetoothActiveStateLocked(int actType) { + if (DEBUG) Log.i(TAG, "Bluetooth active -> " + actType); + if (mBluetoothActiveType != actType) { + if (mBluetoothActiveType >= 0) { + mBluetoothActiveTimer[mBluetoothActiveType].stopRunningLocked(this); + } + mBluetoothActiveType = actType; + mBluetoothActiveTimer[actType].startRunningLocked(this); + } + } + int mWifiFullLockNesting = 0; public void noteFullWifiLockAcquiredLocked(int uid) { @@ -2971,6 +2961,10 @@ public final class BatteryStatsImpl extends BatteryStats { return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); } + @Override public long getMobileRadioActiveTime(long batteryRealtime, int which) { + return mMobileRadioActiveTimer.getTotalTimeLocked(batteryRealtime, which); + } + @Override public long getWifiOnTime(long batteryRealtime, int which) { return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which); } @@ -2983,6 +2977,16 @@ public final class BatteryStatsImpl extends BatteryStats { return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); } + @Override public long getBluetoothActiveTime(int actType, + long batteryRealtime, int which) { + return mBluetoothActiveTimer[actType].getTotalTimeLocked( + batteryRealtime, which); + } + + @Override public int getBluetoothActiveCount(int actType, int which) { + return mBluetoothActiveTimer[actType].getCountLocked(which); + } + @Override public long getNetworkActivityBytes(int type, int which) { if (type >= 0 && type < mNetworkByteActivityCounters.length) { @@ -4966,9 +4970,13 @@ public final class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables); mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables); } + mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables); mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); + for (int i=0; i 10000) { @@ -6340,9 +6357,13 @@ public final class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); } + mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL); mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); + for (int i=0; i ent : mKernelWakelockStats.entrySet()) { @@ -6574,12 +6595,18 @@ public final class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); } + mMobileRadioActive = false; + mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables, in); mWifiOn = false; mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mGlobalWifiRunning = false; mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mBluetoothOn = false; mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); + for (int i=0; i