Merge "Expose app resume times to the ApplicationProvider."
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index a6658cc..d207a0a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1471,6 +1471,24 @@
     }
 
     /**
+     * Returns the usage statistics of each installed package.
+     *
+     * @hide
+     */
+    public PkgUsageStats[] getAllPackageUsageStats() {
+        try {
+            IUsageStats usageStatsService = IUsageStats.Stub.asInterface(
+                    ServiceManager.getService("usagestats"));
+            if (usageStatsService != null) {
+                return usageStatsService.getAllPkgUsageStats();
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not query usage stats", e);
+        }
+        return new PkgUsageStats[0];
+    }
+
+    /**
      * @param userid the user's id. Zero indicates the default user 
      * @hide
      */
diff --git a/core/java/com/android/internal/os/PkgUsageStats.java b/core/java/com/android/internal/os/PkgUsageStats.java
index 1ac191b..8c2c405 100755
--- a/core/java/com/android/internal/os/PkgUsageStats.java
+++ b/core/java/com/android/internal/os/PkgUsageStats.java
@@ -19,6 +19,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * implementation of PkgUsageStats associated with an
  * application package.
@@ -28,6 +31,7 @@
     public String packageName;
     public int launchCount;
     public long usageTime;
+    public Map<String, Long> componentResumeTimes;
     
     public static final Parcelable.Creator<PkgUsageStats> CREATOR
     = new Parcelable.Creator<PkgUsageStats>() {
@@ -46,31 +50,45 @@
         + " " + packageName + "}";
     }
     
-    public PkgUsageStats(String pkgName, int count, long time) {
+    public PkgUsageStats(String pkgName, int count, long time, Map<String, Long> lastResumeTimes) {
         packageName = pkgName;
         launchCount = count;
         usageTime = time;
+        componentResumeTimes = new HashMap<String, Long>(lastResumeTimes);
     }
     
     public PkgUsageStats(Parcel source) {
         packageName = source.readString();
         launchCount = source.readInt();
         usageTime = source.readLong();
+        final int N = source.readInt();
+        componentResumeTimes = new HashMap<String, Long>(N);
+        for (int i = 0; i < N; i++) {
+            String component = source.readString();
+            long lastResumeTime = source.readLong();
+            componentResumeTimes.put(component, lastResumeTime);
+        }
     }
     
     public PkgUsageStats(PkgUsageStats pStats) {
         packageName = pStats.packageName;
         launchCount = pStats.launchCount;
         usageTime = pStats.usageTime;
+        componentResumeTimes = new HashMap<String, Long>(pStats.componentResumeTimes);
     }
 
     public int describeContents() {
         return 0;
     }
 
-    public void writeToParcel(Parcel dest, int parcelableFlags){
+    public void writeToParcel(Parcel dest, int parcelableFlags) {
         dest.writeString(packageName);
         dest.writeInt(launchCount);
         dest.writeLong(usageTime);
+        dest.writeInt(componentResumeTimes.size());
+        for (Map.Entry<String, Long> ent : componentResumeTimes.entrySet()) {
+            dest.writeString(ent.getKey());
+            dest.writeLong(ent.getValue());
+        }
     }
 }
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index 6e8f248..12c8ccf 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -63,7 +63,7 @@
     private static final String TAG = "UsageStats";
     
     // Current on-disk Parcel version
-    private static final int VERSION = 1005;
+    private static final int VERSION = 1006;
 
     private static final int CHECKIN_VERSION = 4;
     
@@ -145,6 +145,8 @@
         final HashMap<String, TimeStats> mLaunchTimes
                 = new HashMap<String, TimeStats>();
         int mLaunchCount;
+        final HashMap<String, Long> mLastResumeTimes
+                = new HashMap<String, Long>();
         long mUsageTime;
         long mPausedTime;
         long mResumedTime;
@@ -160,20 +162,28 @@
             if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount
                     + ", Usage time:" + mUsageTime);
             
-            final int N = in.readInt();
-            if (localLOGV) Slog.v(TAG, "Reading comps: " + N);
-            for (int i=0; i<N; i++) {
+            final int numTimeStats = in.readInt();
+            if (localLOGV) Slog.v(TAG, "Reading comps: " + numTimeStats);
+            for (int i=0; i<numTimeStats; i++) {
                 String comp = in.readString();
                 if (localLOGV) Slog.v(TAG, "Component: " + comp);
                 TimeStats times = new TimeStats(in);
                 mLaunchTimes.put(comp, times);
             }
+            final int numResumeTimes = in.readInt();
+            if (localLOGV) Slog.v(TAG, "Reading last resume times: " + numResumeTimes);
+            for (int i=0; i<numResumeTimes; i++) {
+                String comp = in.readString();
+                if (localLOGV) Slog.v(TAG, "Component: " + comp);
+                mLastResumeTimes.put(comp, in.readLong());
+            }
         }
-        
-        void updateResume(boolean launched) {
+
+        void updateResume(String comp, boolean launched) {
             if (launched) {
                 mLaunchCount ++;
             }
+            mLastResumeTimes.put(comp, System.currentTimeMillis());
             mResumedTime = SystemClock.elapsedRealtime();
         }
         
@@ -203,20 +213,29 @@
         void writeToParcel(Parcel out) {
             out.writeInt(mLaunchCount);
             out.writeLong(mUsageTime);
-            final int N = mLaunchTimes.size();
-            out.writeInt(N);
-            if (N > 0) {
+            final int numTimeStats = mLaunchTimes.size();
+            out.writeInt(numTimeStats);
+            if (numTimeStats > 0) {
                 for (Map.Entry<String, TimeStats> ent : mLaunchTimes.entrySet()) {
                     out.writeString(ent.getKey());
                     TimeStats times = ent.getValue();
                     times.writeToParcel(out);
                 }
             }
+            final int numResumeTimes = mLastResumeTimes.size();
+            out.writeInt(numResumeTimes);
+            if (numResumeTimes > 0) {
+                for (Map.Entry<String, Long> ent : mLastResumeTimes.entrySet()) {
+                    out.writeString(ent.getKey());
+                    out.writeLong(ent.getValue());
+                }
+            }
         }
         
         void clear() {
             mLaunchTimes.clear();
             mLaunchCount = 0;
+            mLastResumeTimes.clear();
             mUsageTime = 0;
         }
     }
@@ -546,7 +565,7 @@
                 pus = new PkgUsageStatsExtended();
                 mStats.put(pkgName, pus);
             }
-            pus.updateResume(!samePackage);
+            pus.updateResume(mLastResumedComp, !samePackage);
             if (!sameComp) {
                 pus.addLaunchCount(mLastResumedComp);
             }
@@ -624,7 +643,8 @@
             if (pus == null) {
                return null;
             }
-            return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime);
+            return new PkgUsageStats(pkgName, pus.mLaunchCount, pus.mUsageTime,
+                    pus.mLastResumeTimes);
         }
     }
     
@@ -641,7 +661,8 @@
             int i = 0;
             for (String key: keys) {
                 PkgUsageStatsExtended pus = mStats.get(key);
-                retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime);
+                retArr[i] = new PkgUsageStats(key, pus.mLaunchCount, pus.mUsageTime,
+                        pus.mLastResumeTimes);
                 i++;
             }
             return retArr;