Track activity foreground CPU usage for battery stats.

Track the foreground CPU time of an activity so that we can tell if apps are
spending more time in the background compared to foreground.
Update power profile values for screen backlight and GPS.
Fix some javadoc bugs (milliseconds vs. microseconds).
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 358a546..528def5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -307,6 +307,13 @@
              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
              */
             public abstract int getStarts(int which);
+
+            /**
+             * Returns the cpu time spent in microseconds while the process was in the foreground.
+             * @param which one of STATS_TOTAL, STATS_LAST, STATS_CURRENT or STATS_UNPLUGGED
+             * @return foreground cpu time in microseconds
+             */
+            public abstract long getForegroundTime(int which);
         }
 
         /**
@@ -364,7 +371,7 @@
     public abstract int getStartCount();
     
     /**
-     * Returns the time in milliseconds that the screen has been on while the device was
+     * Returns the time in microseconds that the screen has been on while the device was
      * running on battery.
      * 
      * {@hide}
@@ -384,7 +391,7 @@
     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
     
     /**
-     * Returns the time in milliseconds that the screen has been on with
+     * Returns the time in microseconds that the screen has been on with
      * the given brightness
      * 
      * {@hide}
@@ -395,7 +402,7 @@
     public abstract int getInputEventCount(int which);
     
     /**
-     * Returns the time in milliseconds that the phone has been on while the device was
+     * Returns the time in microseconds that the phone has been on while the device was
      * running on battery.
      * 
      * {@hide}
@@ -415,7 +422,7 @@
     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
     
     /**
-     * Returns the time in milliseconds that the phone has been running with
+     * Returns the time in microseconds that the phone has been running with
      * the given signal strength.
      * 
      * {@hide}
@@ -443,7 +450,7 @@
     public static final int NUM_DATA_CONNECTION_TYPES = 5;
     
     /**
-     * Returns the time in milliseconds that the phone has been running with
+     * Returns the time in microseconds that the phone has been running with
      * the given data connection.
      * 
      * {@hide}
@@ -460,7 +467,7 @@
     public abstract int getPhoneDataConnectionCount(int dataType, int which);
 
     /**
-     * Returns the time in milliseconds that wifi has been on while the device was
+     * Returns the time in microseconds that wifi has been on while the device was
      * running on battery.
      * 
      * {@hide}
@@ -468,7 +475,7 @@
     public abstract long getWifiOnTime(long batteryRealtime, int which);
 
     /**
-     * Returns the time in milliseconds that wifi has been on and the driver has
+     * Returns the time in microseconds that wifi has been on and the driver has
      * been in the running state while the device was running on battery.
      *
      * {@hide}
@@ -476,7 +483,7 @@
     public abstract long getWifiRunningTime(long batteryRealtime, int which);
 
     /**
-     * Returns the time in milliseconds that bluetooth has been on while the device was
+     * Returns the time in microseconds that bluetooth has been on while the device was
      * running on battery.
      * 
      * {@hide}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 51f3b02..99a381c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -53,7 +53,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS' 
 
     // Current on-disk Parcel version
-    private static final int VERSION = 37;
+    private static final int VERSION = 38;
 
     private final File mFile;
     private final File mBackupFile;
@@ -1342,11 +1342,13 @@
         public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
             return mPackageStats;
         }
-        
+
+        @Override
         public int getUid() {
             return mUid;
         }
-        
+
+        @Override
         public long getTcpBytesReceived(int which) {
             if (which == STATS_LAST) {
                 return mLoadedTcpBytesReceived;
@@ -1365,7 +1367,8 @@
             return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
                     ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
         }
-        
+
+        @Override
         public long getTcpBytesSent(int which) {
             if (which == STATS_LAST) {
                 return mLoadedTcpBytesSent;
@@ -1754,7 +1757,8 @@
             public Timer getSensorTime() {
                 return mTimer;
             }
-            
+
+            @Override
             public int getHandle() {
                 return mHandle;
             }
@@ -1780,6 +1784,11 @@
             int mStarts;
 
             /**
+             * Amount of time the process was running in the foreground.
+             */
+            long mForegroundTime;
+
+            /**
              * The amount of user time loaded from a previous save.
              */
             long mLoadedUserTime;
@@ -1795,6 +1804,11 @@
             int mLoadedStarts;
 
             /**
+             * The amount of foreground time loaded from a previous save.
+             */
+            long mLoadedForegroundTime;
+
+            /**
              * The amount of user time loaded from the previous run.
              */
             long mLastUserTime;
@@ -1810,6 +1824,11 @@
             int mLastStarts;
 
             /**
+             * The amount of foreground time loaded from the previous run
+             */
+            long mLastForegroundTime;
+
+            /**
              * The amount of user time when last unplugged.
              */
             long mUnpluggedUserTime;
@@ -1824,6 +1843,11 @@
              */
             int mUnpluggedStarts;
 
+            /**
+             * The amount of foreground time since unplugged.
+             */
+            long mUnpluggedForegroundTime;
+
             Proc() {
                 mUnpluggables.add(this);
             }
@@ -1832,6 +1856,7 @@
                 mUnpluggedUserTime = mUserTime;
                 mUnpluggedSystemTime = mSystemTime;
                 mUnpluggedStarts = mStarts;
+                mUnpluggedForegroundTime = mForegroundTime;
             }
 
             public void plug(long batteryUptime, long batteryRealtime) {
@@ -1843,30 +1868,38 @@
                 
                 out.writeLong(mUserTime);
                 out.writeLong(mSystemTime);
+                out.writeLong(mForegroundTime);
                 out.writeInt(mStarts);
                 out.writeLong(mLoadedUserTime);
                 out.writeLong(mLoadedSystemTime);
+                out.writeLong(mLoadedForegroundTime);
                 out.writeInt(mLoadedStarts);
                 out.writeLong(mLastUserTime);
                 out.writeLong(mLastSystemTime);
+                out.writeLong(mLastForegroundTime);
                 out.writeInt(mLastStarts);
                 out.writeLong(mUnpluggedUserTime);
                 out.writeLong(mUnpluggedSystemTime);
+                out.writeLong(mUnpluggedForegroundTime);
                 out.writeInt(mUnpluggedStarts);
             }
 
             void readFromParcelLocked(Parcel in) {
                 mUserTime = in.readLong();
                 mSystemTime = in.readLong();
+                mForegroundTime = in.readLong();
                 mStarts = in.readInt();
                 mLoadedUserTime = in.readLong();
                 mLoadedSystemTime = in.readLong();
+                mLoadedForegroundTime = in.readLong();
                 mLoadedStarts = in.readInt();
                 mLastUserTime = in.readLong();
                 mLastSystemTime = in.readLong();
+                mLastForegroundTime = in.readLong();
                 mLastStarts = in.readInt();
                 mUnpluggedUserTime = in.readLong();
                 mUnpluggedSystemTime = in.readLong();
+                mUnpluggedForegroundTime = in.readLong();
                 mUnpluggedStarts = in.readInt();
             }
 
@@ -1879,6 +1912,10 @@
                 mSystemTime += stime;
             }
 
+            public void addForegroundTimeLocked(long ttime) {
+                mForegroundTime += ttime;
+            }
+
             public void incStartsLocked() {
                 mStarts++;
             }
@@ -1916,6 +1953,22 @@
             }
 
             @Override
+            public long getForegroundTime(int which) {
+                long val;
+                if (which == STATS_LAST) {
+                    val = mLastForegroundTime;
+                } else {
+                    val = mForegroundTime;
+                    if (which == STATS_CURRENT) {
+                        val -= mLoadedForegroundTime;
+                    } else if (which == STATS_UNPLUGGED) {
+                        val -= mUnpluggedForegroundTime;
+                    }
+                }
+                return val;
+            }
+
+            @Override
             public int getStarts(int which) {
                 int val;
                 if (which == STATS_LAST) {
diff --git a/core/res/res/xml/power_profile_default.xml b/core/res/res/xml/power_profile_default.xml
index d265b46..ceecb1a 100644
--- a/core/res/res/xml/power_profile_default.xml
+++ b/core/res/res/xml/power_profile_default.xml
@@ -22,7 +22,7 @@
   <item name="screen.on">30</item>
   <item name="bluetooth.active">103</item>
   <item name="bluetooth.on">5</item>
-  <item name="screen.full">144</item>
+  <item name="screen.full">114</item>
   <item name="wifi.on">23</item>
   <item name="wifi.active">200</item>
   <item name="wifi.scan">200</item>
@@ -33,4 +33,5 @@
   <item name="dsp.video">100</item>
   <item name="radio.on">3</item>
   <item name="radio.active">175</item>
+  <item name="gps.on">120</item>
 </device>
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index 55adabb..58f8980 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -54,7 +54,10 @@
         PROC_SPACE_TERM|PROC_OUT_LONG                   // 14: stime
     };
 
+    /** Stores user time and system time in 100ths of a second. */
     private final long[] mProcessStatsData = new long[2];
+    /** Stores user time and system time in 100ths of a second. */
+    private final long[] mSinglePidStatsData = new long[2];
 
     private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
         PROC_SPACE_TERM,
@@ -418,7 +421,18 @@
         
         return pids;
     }
-    
+
+    public long getCpuTimeForPid(int pid) {
+        final String statFile = "/proc/" + pid + "/stat";
+        final long[] statsData = mSinglePidStatsData;
+        if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
+                null, statsData, null)) {
+            long time = statsData[0] + statsData[1];
+            return time;
+        }
+        return 0;
+    }
+
     final public int getLastUserTime() {
         return mRelUserTime;
     }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3b26cb7..9650790 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -62,6 +62,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -1438,7 +1439,7 @@
         synchronized (mProcessStatsThread) {
             final long now = SystemClock.uptimeMillis();
             boolean haveNewCpuStats = false;
-            
+
             if (MONITOR_CPU_USAGE &&
                     mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
                 mLastCpuTime = now;
@@ -2063,6 +2064,25 @@
         if (prev != null) {
             prev.resumeKeyDispatchingLocked();
         }
+
+        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
+            long diff = 0;
+            synchronized (mProcessStatsThread) {
+                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
+            }
+            if (diff > 0) {
+                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
+                synchronized (bsi) {
+                    BatteryStatsImpl.Uid.Proc ps =
+                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
+                            prev.info.packageName);
+                    if (ps != null) {
+                        ps.addForegroundTimeLocked(diff);
+                    }
+                }
+            }
+        }
+        prev.cpuTimeAtResume = 0; // reset it
     }
 
     /**
@@ -2095,6 +2115,17 @@
         next.resumeKeyDispatchingLocked();
         ensureActivitiesVisibleLocked(null, 0);
         mWindowManager.executeAppTransition();
+
+        // Mark the point when the activity is resuming
+        // TODO: To be more accurate, the mark should be before the onCreate,
+        //       not after the onResume. But for subsequent starts, onResume is fine.
+        if (next.app != null) {
+            synchronized (mProcessStatsThread) {
+                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
+            }
+        } else {
+            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
+        }
     }
 
     /**
diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java
index 1789687..944ea02 100644
--- a/services/java/com/android/server/am/HistoryRecord.java
+++ b/services/java/com/android/server/am/HistoryRecord.java
@@ -66,6 +66,7 @@
     int theme;              // resource identifier of activity's theme.
     TaskRecord task;        // the task this is in.
     long startTime;         // when we starting launching this activity
+    long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
     Configuration configuration; // configuration activity was last running in
     HistoryRecord resultTo; // who started this entry, so will get our reply
     final String resultWho; // additional identifier for use by resultTo.