Fix issue #3154576: battery stats checkin should include UID -> packages+ map

Includes some other small fixes to battery collection and a few
other things.

Output of package info looks like this:

5,0,i,uid,1000,com.android.settings
5,0,i,uid,1000,com.android.providers.subscribedfeeds
5,0,i,uid,1000,com.android.providers.settings
5,0,i,uid,1000,com.android.server.vpn
5,0,i,uid,1000,android
5,0,i,uid,1000,com.android.systemui
5,0,i,uid,1000,com.google.android.backup
5,0,i,uid,1001,com.android.phone
5,0,i,uid,1001,com.android.providers.telephony
5,0,i,uid,1022,com.android.nfc
5,0,i,uid,10021,com.google.android.location
5,0,i,uid,10021,com.google.android.syncadapters.calendar
5,0,i,uid,10021,com.google.android.gsf
5,0,i,uid,10021,com.google.android.syncadapters.contacts
5,0,i,uid,10026,com.android.providers.downloads.ui
5,0,i,uid,10026,com.android.providers.media
5,0,i,uid,10026,com.android.providers.drm
5,0,i,uid,10026,com.android.providers.downloads
5,0,i,uid,10032,com.android.launcher
5,0,i,uid,10039,com.google.android.gm
5,0,i,uid,10041,com.google.android.gallery3d
5,0,i,uid,10049,com.android.providers.calendar

Change-Id: I9e38f254eef146339113ad270f5c6e8b60fb7a1d
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index abc88e8..490cbe4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -190,6 +190,7 @@
     StopwatchTimer mVideoOnTimer;
     
     int mPhoneSignalStrengthBin = -1;
+    int mPhoneSignalStrengthBinRaw = -1;
     final StopwatchTimer[] mPhoneSignalStrengthsTimer = 
             new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
 
@@ -250,6 +251,8 @@
     private int mBluetoothPingStart = -1;
 
     private int mPhoneServiceState = -1;
+    private int mPhoneServiceStateRaw = -1;
+    private int mPhoneSimStateRaw = -1;
 
     /*
      * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
@@ -1643,40 +1646,54 @@
         }
     }
 
-    /**
-     * Telephony stack updates the phone state.
-     * @param state phone state from ServiceState.getState()
-     */
-    public void notePhoneStateLocked(int state) {
-        boolean scanning = false;
+    private int fixPhoneServiceState(int state, int signalBin) {
+        if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
+            // In this case we will always be STATE_OUT_OF_SERVICE, so need
+            // to infer that we are scanning from other data.
+            if (state == ServiceState.STATE_OUT_OF_SERVICE
+                    && signalBin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                state = ServiceState.STATE_IN_SERVICE;
+            }
+        }
 
-        int bin = mPhoneSignalStrengthBin;
+        return state;
+    }
+
+    private void updateAllPhoneStateLocked(int state, int simState, int bin) {
+        boolean scanning = false;
+        boolean newHistory = false;
+
+        mPhoneServiceStateRaw = state;
+        mPhoneSimStateRaw = simState;
+        mPhoneSignalStrengthBinRaw = bin;
+
+        if (simState == TelephonyManager.SIM_STATE_ABSENT) {
+            // In this case we will always be STATE_OUT_OF_SERVICE, so need
+            // to infer that we are scanning from other data.
+            if (state == ServiceState.STATE_OUT_OF_SERVICE
+                    && bin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                state = ServiceState.STATE_IN_SERVICE;
+            }
+        }
 
         // If the phone is powered off, stop all timers.
         if (state == ServiceState.STATE_POWER_OFF) {
-            stopAllSignalStrengthTimersLocked(-1);
+            bin = -1;
 
-        // If we're back in service or continuing in service, restart the old timer.
-        } if (state == ServiceState.STATE_IN_SERVICE) {
-            if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-            if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
-            }
+        // If we are in service, make sure the correct signal string timer is running.
+        } else if (state == ServiceState.STATE_IN_SERVICE) {
+            // Bin will be changed below.
 
         // If we're out of service, we are in the lowest signal strength
         // bin and have the scanning bit set.
         } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
             scanning = true;
-            mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-            stopAllSignalStrengthTimersLocked(mPhoneSignalStrengthBin);
-            if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
-            }
+            bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
             if (!mPhoneSignalScanningTimer.isRunningLocked()) {
                 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
+                newHistory = true;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
                 mPhoneSignalScanningTimer.startRunningLocked(this);
             }
         }
@@ -1687,7 +1704,7 @@
                 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                newHistory = true;
                 mPhoneSignalScanningTimer.stopRunningLocked(this);
             }
         }
@@ -1695,21 +1712,48 @@
         if (mPhoneServiceState != state) {
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
                     | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: "
+            if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            newHistory = true;
             mPhoneServiceState = state;
         }
+
+        if (mPhoneSignalStrengthBin != bin) {
+            if (mPhoneSignalStrengthBin >= 0) {
+                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
+            }
+            if (bin >= 0) {
+                if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
+                    mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+                }
+                mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
+                        | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
+                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
+                        + Integer.toHexString(mHistoryCur.states));
+                newHistory = true;
+            } else {
+                stopAllSignalStrengthTimersLocked(-1);
+            }
+            mPhoneSignalStrengthBin = bin;
+        }
+
+        if (newHistory) {
+            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+        }
+    }
+
+    /**
+     * Telephony stack updates the phone state.
+     * @param state phone state from ServiceState.getState()
+     */
+    public void notePhoneStateLocked(int state, int simState) {
+        updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
     }
 
     public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
         // Bin the strength.
         int bin;
-        if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
-                || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
-            // Ignore any signal strength changes when radio was turned off or out of service.
-            return;
-        }
+
         if (!signalStrength.isGsm()) {
             int dBm = signalStrength.getCdmaDbm();
             if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
@@ -1725,18 +1769,8 @@
             else if (asu >= 4)  bin = SIGNAL_STRENGTH_MODERATE;
             else bin = SIGNAL_STRENGTH_POOR;
         }
-        if (mPhoneSignalStrengthBin != bin) {
-            mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
-                    | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
-            if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
-                    + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
-            if (mPhoneSignalStrengthBin >= 0) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
-            }
-            mPhoneSignalStrengthBin = bin;
-            mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
-        }
+
+        updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
     }
     
     public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
@@ -3971,6 +4005,9 @@
             mKernelWakelockStats.clear();
         }
         
+        mLowDischargeAmountSinceCharge = 0;
+        mHighDischargeAmountSinceCharge = 0;
+
         clearHistoryLocked();
     }
     
@@ -3992,12 +4029,10 @@
                 // level to a now very high level).
                 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
                         || level >= 95
-                        || (mDischargeCurrentLevel < 30 && level >= 90)) {
+                        || (mDischargeCurrentLevel < 20 && level >= 80)) {
                     doWrite = true;
                     resetAllStatsLocked();
                     mDischargeStartLevel = level;
-                    mLowDischargeAmountSinceCharge = 0;
-                    mHighDischargeAmountSinceCharge = 0;
                 }
                 updateKernelWakelocksLocked();
                 mHistoryCur.batteryLevel = (byte)level;
@@ -4087,11 +4122,13 @@
                 mHistoryCur.batteryPlugType = (byte)plugType;
                 changed = true;
             }
-            if (mHistoryCur.batteryTemperature != temp) {
+            if (temp >= (mHistoryCur.batteryTemperature+10)
+                    || temp <= (mHistoryCur.batteryTemperature-10)) {
                 mHistoryCur.batteryTemperature = (char)temp;
                 changed = true;
             }
-            if (mHistoryCur.batteryVoltage != volt) {
+            if (volt > (mHistoryCur.batteryVoltage+20)
+                    || volt < (mHistoryCur.batteryVoltage-20)) {
                 mHistoryCur.batteryVoltage = (char)volt;
                 changed = true;
             }
@@ -4287,20 +4324,28 @@
     }
     
     public int getDischargeCurrentLevelLocked() {
-            return mDischargeCurrentLevel;
+        return mDischargeCurrentLevel;
     }
 
     @Override
     public int getLowDischargeAmountSinceCharge() {
         synchronized(this) {
-            return mLowDischargeAmountSinceCharge;
+            int val = mLowDischargeAmountSinceCharge;
+            if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
+                val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
+            }
+            return val;
         }
     }
 
     @Override
     public int getHighDischargeAmountSinceCharge() {
         synchronized(this) {
-            return mHighDischargeAmountSinceCharge;
+            int val = mHighDischargeAmountSinceCharge;
+            if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
+                val += mDischargeUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
         }
     }
 
@@ -4802,8 +4847,8 @@
         out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
         out.writeInt(mDischargeUnplugLevel);
         out.writeInt(mDischargeCurrentLevel);
-        out.writeInt(mLowDischargeAmountSinceCharge);
-        out.writeInt(mHighDischargeAmountSinceCharge);
+        out.writeInt(getLowDischargeAmountSinceCharge());
+        out.writeInt(getHighDischargeAmountSinceCharge());
         
         mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {