Expose time-interval detail query on INetworkStatsSession

Also, force polling when a session is opened for NetworkStatsManager.

Bug: 21864554
Bug: 21754685
Change-Id: I24ea822c2d5bc1421ec7ee65d0cfe27cf02dd69e
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java
index 1079f1a..9d5eabb 100644
--- a/core/java/android/app/usage/NetworkStats.java
+++ b/core/java/android/app/usage/NetworkStats.java
@@ -309,12 +309,10 @@
 
     /**
      * Collects device summary results into a Bucket.
-     * @param startTime
-     * @param endTime
      * @throws RemoteException
      */
-    Bucket getDeviceSummaryForNetwork(long startTime, long endTime) throws RemoteException {
-        mSummary = mSession.getDeviceSummaryForNetwork(mTemplate, startTime, endTime);
+    Bucket getDeviceSummaryForNetwork() throws RemoteException {
+        mSummary = mSession.getDeviceSummaryForNetwork(mTemplate, mStartTimeStamp, mEndTimeStamp);
 
         // Setting enumeration index beyond end to avoid accidental enumeration over data that does
         // not belong to the calling user.
@@ -325,12 +323,10 @@
 
     /**
      * Collects summary results and sets summary enumeration mode.
-     * @param startTime
-     * @param endTime
      * @throws RemoteException
      */
-    void startSummaryEnumeration(long startTime, long endTime) throws RemoteException {
-        mSummary = mSession.getSummaryForAllUid(mTemplate, startTime, endTime, false);
+    void startSummaryEnumeration() throws RemoteException {
+        mSummary = mSession.getSummaryForAllUid(mTemplate, mStartTimeStamp, mEndTimeStamp, false);
 
         mEnumerationIndex = 0;
     }
@@ -341,8 +337,9 @@
     void startHistoryEnumeration(int uid) {
         mHistory = null;
         try {
-            mHistory = mSession.getHistoryForUid(mTemplate, uid, android.net.NetworkStats.SET_ALL,
-                    android.net.NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
+            mHistory = mSession.getHistoryIntervalForUid(mTemplate, uid,
+                    android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
+                    NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
             setSingleUid(uid);
         } catch (RemoteException e) {
             Log.w(TAG, e);
@@ -368,9 +365,9 @@
             stepUid();
             mHistory = null;
             try {
-                mHistory = mSession.getHistoryForUid(mTemplate, getUid(),
+                mHistory = mSession.getHistoryIntervalForUid(mTemplate, getUid(),
                         android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
-                        NetworkStatsHistory.FIELD_ALL);
+                        NetworkStatsHistory.FIELD_ALL, mStartTimeStamp, mEndTimeStamp);
             } catch (RemoteException e) {
                 Log.w(TAG, e);
                 // Leaving mHistory null
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 2ae0181..2886cda 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -97,7 +97,7 @@
 
         Bucket bucket = null;
         NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime);
-        bucket = stats.getDeviceSummaryForNetwork(startTime, endTime);
+        bucket = stats.getDeviceSummaryForNetwork();
 
         stats.close();
         return bucket;
@@ -106,7 +106,7 @@
     /**
      * Query network usage statistics summaries. Result is summarised data usage for all uids
      * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
-     * This means the bucket's start and end timestamp are going to be the same as the 'startTime' 
+     * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
      * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
      * {@link NetworkStats.Bucket#UID_ALL}.
      *
@@ -130,7 +130,7 @@
 
         NetworkStats stats;
         stats = new NetworkStats(mContext, template, startTime, endTime);
-        stats.startSummaryEnumeration(startTime, endTime);
+        stats.startSummaryEnumeration();
 
         stats.close();
         return stats.getSummaryAggregate();
@@ -140,7 +140,7 @@
      * Query network usage statistics summaries. Result filtered to include only uids belonging to
      * calling user. Result is aggregated over time, hence all buckets will have the same start and
      * end timestamps. Not aggregated over state or uid. This means buckets' start and end
-     * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and 
+     * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and
      * uid are going to vary.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
@@ -163,7 +163,7 @@
 
         NetworkStats result;
         result = new NetworkStats(mContext, template, startTime, endTime);
-        result.startSummaryEnumeration(startTime, endTime);
+        result.startSummaryEnumeration();
 
         return result;
     }
@@ -173,6 +173,9 @@
      * Result is aggregated over state but not aggregated over time. This means buckets' start and
      * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going
      * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -205,6 +208,9 @@
      * calling user. Result is aggregated over state but not aggregated over time or uid. This means
      * buckets' start and end timestamps are going to be between 'startTime' and 'endTime'
      * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary.
+     * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
+     * interpolate across partial buckets. Since bucket length is in the order of hours, this
+     * method cannot be used to measure data usage on a fine grained time scale.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
diff --git a/core/java/android/net/INetworkStatsSession.aidl b/core/java/android/net/INetworkStatsSession.aidl
index 7bcb043..5229a3b 100644
--- a/core/java/android/net/INetworkStatsSession.aidl
+++ b/core/java/android/net/INetworkStatsSession.aidl
@@ -35,6 +35,8 @@
     NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
     /** Return historical network layer stats for specific UID traffic that matches template. */
     NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields);
+    /** Return historical network layer stats for specific UID traffic that matches template. */
+    NetworkStatsHistory getHistoryIntervalForUid(in NetworkTemplate template, int uid, int set, int tag, int fields, long start, long end);
 
     /** Return array of uids that have stats and are accessible to the calling user */
     int[] getRelevantUids();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 0035d01..8449348 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -436,13 +436,26 @@
 
     @Override
     public INetworkStatsSession openSession() {
-        return openSessionForUsageStats(null);
+        return createSession(null, /* poll on create */ false);
     }
 
     @Override
     public INetworkStatsSession openSessionForUsageStats(final String callingPackage) {
+        return createSession(callingPackage, /* poll on create */ true);
+    }
+
+    private INetworkStatsSession createSession(final String callingPackage, boolean pollOnCreate) {
         assertBandwidthControlEnabled();
 
+        if (pollOnCreate) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                performPoll(FLAG_PERSIST_ALL);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
         // return an IBinder which holds strong references to any loaded stats
         // for its lifetime; when caller closes only weak references remain.
 
@@ -526,6 +539,19 @@
             }
 
             @Override
+            public NetworkStatsHistory getHistoryIntervalForUid(
+                    NetworkTemplate template, int uid, int set, int tag, int fields,
+                    long start, long end) {
+                enforcePermissionForManagedAdmin(mCallingPackage);
+                if (tag == TAG_NONE) {
+                    return getUidComplete().getHistory(template, uid, set, tag, fields, start, end);
+                } else {
+                    return getUidTagComplete().getHistory(template, uid, set, tag, fields,
+                            start, end);
+                }
+            }
+
+            @Override
             public void close() {
                 mUidComplete = null;
                 mUidTagComplete = null;