Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e13c4c0b authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

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
parent 1717eb1d
Loading
Loading
Loading
Loading
+44 −20
Original line number Diff line number Diff line
@@ -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];
@@ -1906,9 +1931,8 @@ public abstract class BatteryStats implements Parcelable {

        sb.setLength(0);
        sb.append(prefix);
        sb.append("  Radio data uptime when unplugged: ");
        sb.append(getRadioDataUptime() / 1000);
        sb.append(" ms");
        sb.append("  Mobile radio active time: ");
        formatTimeMs(sb, getMobileRadioActiveTime(batteryRealtime, which) / 1000);
        pw.println(sb.toString());

        sb.setLength(0);
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ interface IBatteryStats {
    void noteScreenOff();
    void noteInputEvent();
    void noteUserActivity(int uid, int event);
    void noteDataConnectionActive(String label, boolean active);
    void notePhoneOn();
    void notePhoneOff();
    void notePhoneSignalStrength(in SignalStrength signalStrength);
@@ -63,6 +64,7 @@ interface IBatteryStats {
    void noteWifiStopped(in WorkSource ws);
    void noteBluetoothOn();
    void noteBluetoothOff();
    void noteBluetoothActiveState(int actType);
    void noteFullWifiLockAcquired(int uid);
    void noteFullWifiLockReleased(int uid);
    void noteWifiScanStarted(int uid);
+2 −1
Original line number Diff line number Diff line
@@ -640,7 +640,8 @@ public class BatteryStatsHelper {
        final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
        final long mobileData = mobileRx + mobileTx;

        final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000;
        final long radioDataUptimeMs
                = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType) / 1000;
        final double mobilePps = radioDataUptimeMs != 0
                ? mobileData / (double)radioDataUptimeMs
                : (((double)MOBILE_BPS) / 8 / 2048);
+95 −64
Original line number Diff line number Diff line
@@ -55,11 +55,9 @@ import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.JournaledFile;
import com.google.android.collect.Sets;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -88,7 +86,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

    // Current on-disk Parcel version
    private static final int VERSION = 79 + (USE_OLD_HISTORY ? 1000 : 0);
    private static final int VERSION = 84 + (USE_OLD_HISTORY ? 1000 : 0);

    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS = 2000;
@@ -276,6 +274,13 @@ public final class BatteryStatsImpl extends BatteryStats {
    boolean mBluetoothOn;
    StopwatchTimer mBluetoothOnTimer;

    int mBluetoothActiveType = -1;
    final StopwatchTimer[] mBluetoothActiveTimer =
            new StopwatchTimer[NUM_BLUETOOTH_ACTIVE_TYPES];

    boolean mMobileRadioActive;
    StopwatchTimer mMobileRadioActiveTimer;

    /** Bluetooth headset object */
    BluetoothHeadset mBtHeadset;

@@ -310,9 +315,6 @@ public final class BatteryStatsImpl extends BatteryStats {

    long mLastWriteTime = 0; // Milliseconds

    private long mRadioDataUptime;
    private long mRadioDataStart;

    private int mBluetoothPingCount;
    private int mBluetoothPingStart = -1;

@@ -1432,44 +1434,6 @@ public final class BatteryStatsImpl extends BatteryStats {
        return kwlt;
    }

    /**
     * Radio uptime in microseconds when transferring data. This value is very approximate.
     * @return
     */
    private long getCurrentRadioDataUptime() {
        try {
            File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
            if (!awakeTimeFile.exists()) return 0;
            BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
            String line = br.readLine();
            br.close();
            return Long.parseLong(line) * 1000;
        } catch (NumberFormatException nfe) {
            // Nothing
        } catch (IOException ioe) {
            // Nothing
        }
        return 0;
    }

    /**
     * @deprecated use getRadioDataUptime
     */
    public long getRadioDataUptimeMs() {
        return getRadioDataUptime() / 1000;
    }

    /**
     * Returns the duration that the cell radio was up for data transfers.
     */
    public long getRadioDataUptime() {
        if (mRadioDataStart == -1) {
            return mRadioDataUptime;
        } else {
            return getCurrentRadioDataUptime() - mRadioDataStart;
        }
    }

    private int getCurrentBluetoothPingCount() {
        if (mBtHeadset != null) {
            List<BluetoothDevice> 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<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i] = new StopwatchTimer(null, -500-i, null, mUnpluggables);
        }
        mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
        mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
        mOnBattery = mOnBatteryInternal = false;
@@ -5225,9 +5233,13 @@ public final class BatteryStatsImpl extends BatteryStats {
            mNetworkByteActivityCounters[i].reset(false);
            mNetworkPacketActivityCounters[i].reset(false);
        }
        mMobileRadioActiveTimer.reset(this, false);
        mWifiOnTimer.reset(this, false);
        mGlobalWifiRunningTimer.reset(this, false);
        mBluetoothOnTimer.reset(this, false);
        for (int i=0; i<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i].reset(this, false);
        }

        for (int i=0; i<mUidStats.size(); i++) {
            if (mUidStats.valueAt(i).reset()) {
@@ -6119,12 +6131,17 @@ public final class BatteryStatsImpl extends BatteryStats {
            mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
            mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
        }
        mMobileRadioActive = false;
        mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
        mWifiOn = false;
        mWifiOnTimer.readSummaryFromParcelLocked(in);
        mGlobalWifiRunning = false;
        mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
        mBluetoothOn = false;
        mBluetoothOnTimer.readSummaryFromParcelLocked(in);
        for (int i=0; i<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i].readSummaryFromParcelLocked(in);
        }

        int NKW = in.readInt();
        if (NKW > 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<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
        }

        out.writeInt(mKernelWakelockStats.size());
        for (Map.Entry<String, SamplingTimer> 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<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i] = new StopwatchTimer(null, -500-i,
                    null, mUnpluggables, in);
        }
        mUptime = in.readLong();
        mUptimeStart = in.readLong();
        mLastUptime = 0;
@@ -6604,9 +6631,6 @@ public final class BatteryStatsImpl extends BatteryStats {
        mDischargeAmountScreenOffSinceCharge = in.readInt();
        mLastWriteTime = in.readLong();

        mRadioDataUptime = in.readLong();
        mRadioDataStart = -1;

        mBluetoothPingCount = in.readInt();
        mBluetoothPingStart = -1;

@@ -6685,9 +6709,13 @@ public final class BatteryStatsImpl extends BatteryStats {
            mNetworkByteActivityCounters[i].writeToParcel(out);
            mNetworkPacketActivityCounters[i].writeToParcel(out);
        }
        mMobileRadioActiveTimer.writeToParcel(out, batteryRealtime);
        mWifiOnTimer.writeToParcel(out, batteryRealtime);
        mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
        mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
        for (int i=0; i<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
            mBluetoothActiveTimer[i].writeToParcel(out, batteryRealtime);
        }
        out.writeLong(mUptime);
        out.writeLong(mUptimeStart);
        out.writeLong(mRealtime);
@@ -6709,9 +6737,6 @@ public final class BatteryStatsImpl extends BatteryStats {
        out.writeInt(mDischargeAmountScreenOffSinceCharge);
        out.writeLong(mLastWriteTime);

        // Write radio uptime for data
        out.writeLong(getRadioDataUptime());

        out.writeInt(getBluetoothPingCount());

        if (inclUids) {
@@ -6786,12 +6811,18 @@ public final class BatteryStatsImpl extends BatteryStats {
                pr.println("*** Data connection type #" + i + ":");
                mPhoneDataConnectionsTimer[i].logState(pr, "  ");
            }
            pr.println("*** Mobile network active timer:");
            mMobileRadioActiveTimer.logState(pr, "  ");
            pr.println("*** Wifi timer:");
            mWifiOnTimer.logState(pr, "  ");
            pr.println("*** WifiRunning timer:");
            mGlobalWifiRunningTimer.logState(pr, "  ");
            pr.println("*** Bluetooth timer:");
            mBluetoothOnTimer.logState(pr, "  ");
            for (int i=0; i<NUM_BLUETOOTH_ACTIVE_TYPES; i++) {
                pr.println("*** Bluetooth active type #" + i + ":");
                mBluetoothActiveTimer[i].logState(pr, "  ");
            }
        }
        super.dumpLocked(context, pw, isUnpluggedOnly, reqUid, historyOnly);
    }
+1 −1
Original line number Diff line number Diff line
@@ -2352,7 +2352,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        if (ConnectivityManager.isNetworkTypeMobile(type)) {
            timeout = Settings.Global.getInt(mContext.getContentResolver(),
                                             Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
                                             0);
                                             5);
            // Canonicalize mobile network type
            type = ConnectivityManager.TYPE_MOBILE;
        } else if (ConnectivityManager.TYPE_WIFI == type) {
Loading