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

* commit 'e4a5951925f16f18dae91ed65567e96528f17fee':
  Fix issue #3154576: battery stats checkin should include UID -> packages+ map
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 46fa114..41ab0f0 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -152,6 +152,7 @@
      * pm list permission-groups
      * pm list permissions
      * pm list features
+     * pm list libraries
      * pm list instrumentation
      */
     private void runList() {
@@ -169,6 +170,8 @@
             runListPermissions();
         } else if ("features".equals(type)) {
             runListFeatures();
+        } else if ("libraries".equals(type)) {
+            runListLibraries();
         } else if ("instrumentation".equals(type)) {
             runListInstrumentation();
         } else {
@@ -181,6 +184,8 @@
      * Lists all the installed packages.
      */
     private void runListPackages(boolean showApplicationPackage) {
+        int getFlags = 0;
+        boolean listDisabled = false, listEnabled = false;
         try {
             String opt;
             while ((opt=nextOption()) != null) {
@@ -190,6 +195,12 @@
                     showApplicationPackage = true;
                 } else if (opt.equals("-f")) {
                     showApplicationPackage = true;
+                } else if (opt.equals("-d")) {
+                    listDisabled = true;
+                } else if (opt.equals("-e")) {
+                    listEnabled = true;
+                } else if (opt.equals("-u")) {
+                    getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
                 } else {
                     System.err.println("Error: Unknown option: " + opt);
                     showUsage();
@@ -202,18 +213,26 @@
             return;
         }
 
+        String filter = nextArg();
+
         try {
-            List<PackageInfo> packages = mPm.getInstalledPackages(0 /* all */);
+            List<PackageInfo> packages = mPm.getInstalledPackages(getFlags);
 
             int count = packages.size();
             for (int p = 0 ; p < count ; p++) {
                 PackageInfo info = packages.get(p);
-                System.out.print("package:");
-                if (showApplicationPackage) {
-                    System.out.print(info.applicationInfo.sourceDir);
-                    System.out.print("=");
+                if (filter != null && !info.packageName.contains(filter)) {
+                    continue;
                 }
-                System.out.println(info.packageName);
+                if ((!listDisabled || !info.applicationInfo.enabled) &&
+                        (!listEnabled || info.applicationInfo.enabled)) {
+                    System.out.print("package:");
+                    if (showApplicationPackage) {
+                        System.out.print(info.applicationInfo.sourceDir);
+                        System.out.print("=");
+                    }
+                    System.out.println(info.packageName);
+                }
             }
         } catch (RemoteException e) {
             System.err.println(e.toString());
@@ -260,6 +279,42 @@
     }
 
     /**
+     * Lists all of the libraries supported by the current device.
+     *
+     * pm list libraries
+     */
+    private void runListLibraries() {
+        try {
+            List<String> list = new ArrayList<String>();
+            String[] rawList = mPm.getSystemSharedLibraryNames();
+            for (int i=0; i<rawList.length; i++) {
+                list.add(rawList[i]);
+            }
+
+
+            // Sort by name
+            Collections.sort(list, new Comparator<String>() {
+                public int compare(String o1, String o2) {
+                    if (o1 == o2) return 0;
+                    if (o1 == null) return -1;
+                    if (o2 == null) return 1;
+                    return o1.compareTo(o2);
+                }
+            });
+
+            int count = (list != null) ? list.size() : 0;
+            for (int p = 0; p < count; p++) {
+                String lib = list.get(p);
+                System.out.print("library:");
+                System.out.println(lib);
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
+    /**
      * Lists all of the installed instrumentation, or all for a given package
      *
      * pm list instrumentation [package] [-f]
@@ -882,11 +937,12 @@
 
     private static void showUsage() {
         System.err.println("usage: pm [list|path|install|uninstall]");
-        System.err.println("       pm list packages [-f]");
+        System.err.println("       pm list packages [-f] [-d] [-e] [-u] [FILTER]");
         System.err.println("       pm list permission-groups");
         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
         System.err.println("       pm list features");
+        System.err.println("       pm list libraries");
         System.err.println("       pm path PACKAGE");
         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
@@ -894,8 +950,12 @@
         System.err.println("       pm disable PACKAGE_OR_COMPONENT");
         System.err.println("       pm setInstallLocation [0/auto] [1/internal] [2/external]");
         System.err.println("");
-        System.err.println("The list packages command prints all packages.  Options:");
+        System.err.println("The list packages command prints all packages, optionally only");
+        System.err.println("those whose package name contains the text in FILTER.  Options:");
         System.err.println("  -f: see their associated file.");
+        System.err.println("  -d: filter to include disbled packages.");
+        System.err.println("  -e: filter to include enabled packages.");
+        System.err.println("  -u: also include uninstalled packages.");
         System.err.println("");
         System.err.println("The list permission-groups command prints all known");
         System.err.println("permission groups.");
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ff3656c..ee3bbfa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -195,7 +195,7 @@
         pi.versionName = p.mVersionName;
         pi.sharedUserId = p.mSharedUserId;
         pi.sharedUserLabel = p.mSharedUserLabel;
-        pi.applicationInfo = p.applicationInfo;
+        pi.applicationInfo = generateApplicationInfo(p, flags);
         pi.installLocation = p.installLocation;
         pi.firstInstallTime = firstInstallTime;
         pi.lastUpdateTime = lastUpdateTime;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index d67e6f5..e4485d1 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -17,9 +17,12 @@
 package android.os;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Formatter;
+import java.util.List;
 import java.util.Map;
 
+import android.content.pm.ApplicationInfo;
 import android.util.Log;
 import android.util.Printer;
 import android.util.SparseArray;
@@ -120,6 +123,7 @@
     private static final long BYTES_PER_GB = 1073741824; //1024^3
     
 
+    private static final String UID_DATA = "uid";
     private static final String APK_DATA = "apk";
     private static final String PROCESS_DATA = "pr";
     private static final String SENSOR_DATA = "sr";
@@ -1460,7 +1464,7 @@
 
         for (int iu=0; iu<NU; iu++) {
             final int uid = uidStats.keyAt(iu);
-            if (reqUid >= 0 && uid != reqUid) {
+            if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
                 continue;
             }
             
@@ -1877,7 +1881,7 @@
     }
     
     @SuppressWarnings("unused")
-    public void dumpCheckinLocked(PrintWriter pw, String[] args) {
+    public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
         boolean isUnpluggedOnly = false;
         
         for (String arg : args) {
@@ -1887,6 +1891,33 @@
             }
         }
         
+        if (apps != null) {
+            SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
+            for (int i=0; i<apps.size(); i++) {
+                ApplicationInfo ai = apps.get(i);
+                ArrayList<String> pkgs = uids.get(ai.uid);
+                if (pkgs == null) {
+                    pkgs = new ArrayList<String>();
+                    uids.put(ai.uid, pkgs);
+                }
+                pkgs.add(ai.packageName);
+            }
+            SparseArray<? extends Uid> uidStats = getUidStats();
+            final int NU = uidStats.size();
+            String[] lineArgs = new String[2];
+            for (int i=0; i<NU; i++) {
+                int uid = uidStats.keyAt(i);
+                ArrayList<String> pkgs = uids.get(uid);
+                if (pkgs != null) {
+                    for (int j=0; j<pkgs.size(); j++) {
+                        lineArgs[0] = Integer.toString(uid);
+                        lineArgs[1] = pkgs.get(j);
+                        dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
+                                (Object[])lineArgs);
+                    }
+                }
+            }
+        }
         if (isUnpluggedOnly) {
             dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
         }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index fb4dff8..258e760 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.
@@ -1645,40 +1648,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);
             }
         }
@@ -1689,7 +1706,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);
             }
         }
@@ -1697,21 +1714,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;
@@ -1727,18 +1771,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) {
@@ -3973,6 +4007,9 @@
             mKernelWakelockStats.clear();
         }
         
+        mLowDischargeAmountSinceCharge = 0;
+        mHighDischargeAmountSinceCharge = 0;
+
         clearHistoryLocked();
     }
     
@@ -3994,12 +4031,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;
@@ -4089,11 +4124,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;
             }
@@ -4289,20 +4326,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;
         }
     }
 
@@ -4804,8 +4849,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++) {
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
index 9608b9a..4a0856a 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -30,6 +30,7 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.Handler;
 import android.util.Log;
 import android.view.View;
 import android.view.Window;
@@ -53,6 +54,17 @@
     View mNoAppsText;
     IntentFilter mBroadcastIntentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
 
+    Handler mHandler = new Handler();
+    Runnable mCleanup = new Runnable() {
+        public void run() {
+            // dump extra memory we're hanging on to
+            for (TextView icon: mIcons) {
+                icon.setCompoundDrawables(null, null, null, null);
+                icon.setTag(null);
+            }
+        }
+    };
+
     private int mIconSize;
 
     public RecentApplicationsDialog(Context context) {
@@ -144,6 +156,8 @@
 
         // receive broadcasts
         getContext().registerReceiver(mBroadcastReceiver, mBroadcastIntentFilter);
+
+        mHandler.removeCallbacks(mCleanup);
     }
 
     /**
@@ -153,18 +167,14 @@
     public void onStop() {
         super.onStop();
 
-        // dump extra memory we're hanging on to
-        for (TextView icon: mIcons) {
-            icon.setCompoundDrawables(null, null, null, null);
-            icon.setTag(null);
-        }
-
         if (sStatusBar != null) {
             sStatusBar.disable(StatusBarManager.DISABLE_NONE);
         }
 
         // stop receiving broadcasts
         getContext().unregisterReceiver(mBroadcastReceiver);
+
+        mHandler.postDelayed(mCleanup, 100);
      }
 
     /**
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4520f18..be3cd75 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -5699,9 +5699,6 @@
         res.removedInfo.removedPackage = packageName;
         // Remove existing system package
         removePackageLI(oldPkg, true);
-        synchronized (mPackages) {
-            res.removedInfo.removedUid = mSettings.disableSystemPackageLP(packageName);
-        }
 
         // Successfully disabled the old package. Now proceed with re-installation
         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 73a5435..367c4cf 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -18,6 +18,7 @@
 
 import android.bluetooth.BluetoothHeadset;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -25,6 +26,7 @@
 import android.os.ServiceManager;
 import android.os.WorkSource;
 import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
 import android.util.Slog;
 
 import com.android.internal.app.IBatteryStats;
@@ -33,6 +35,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * All information we are collecting about things that can happen that impact
@@ -213,8 +216,9 @@
 
     public void notePhoneState(int state) {
         enforceCallingPermission();
+        int simState = TelephonyManager.getDefault().getSimState();
         synchronized (mStats) {
-            mStats.notePhoneStateLocked(state);
+            mStats.notePhoneStateLocked(state, simState);
         }
     }
 
@@ -413,19 +417,28 @@
     
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        synchronized (mStats) {
-            boolean isCheckin = false;
-            if (args != null) {
-                for (String arg : args) {
-                    if ("--checkin".equals(arg)) {
-                        isCheckin = true;
-                    } else if ("--reset".equals(arg)) {
+        boolean isCheckin = false;
+        if (args != null) {
+            for (String arg : args) {
+                if ("--checkin".equals(arg)) {
+                    isCheckin = true;
+                } else if ("--reset".equals(arg)) {
+                    synchronized (mStats) {
                         mStats.resetAllStatsLocked();
+                        pw.println("Battery stats reset.");
                     }
                 }
             }
-            if (isCheckin) mStats.dumpCheckinLocked(pw, args);
-            else mStats.dumpLocked(pw);
+        }
+        if (isCheckin) {
+            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
+            synchronized (mStats) {
+                mStats.dumpCheckinLocked(pw, args, apps);
+            }
+        } else {
+            synchronized (mStats) {
+                mStats.dumpLocked(pw);
+            }
         }
     }
 }