Merge "Add a flag to specify whether to read detail data or not."
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index 95efb4c..cc970b9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -36,10 +36,12 @@
 
     private final List<NetworkCycleDataForUid> mData;
     private final int mUid;
+    private final boolean mRetrieveDetail;
 
     private NetworkCycleDataForUidLoader(Builder builder) {
         super(builder);
         mUid = builder.mUid;
+        mRetrieveDetail = builder.mRetrieveDetail;
         mData = new ArrayList<NetworkCycleDataForUid>();
     }
 
@@ -50,13 +52,15 @@
                 mNetworkType, mSubId, start, end, mUid);
             final long total = getTotalUsage(stats);
             if (total > 0L) {
-                final long foreground = getForegroundUsage(start, end);
                 final NetworkCycleDataForUid.Builder builder = new NetworkCycleDataForUid.Builder();
-                builder.setBackgroundUsage(total - foreground)
-                    .setForegroundUsage(foreground)
-                    .setStartTime(start)
+                builder.setStartTime(start)
                     .setEndTime(end)
                     .setTotalUsage(total);
+                if (mRetrieveDetail) {
+                    final long foreground = getForegroundUsage(start, end);
+                    builder.setBackgroundUsage(total - foreground)
+                        .setForegroundUsage(foreground);
+                }
                 mData.add(builder.build());
             }
         } catch (Exception e) {
@@ -88,6 +92,7 @@
             extends NetworkCycleDataLoader.Builder<T> {
 
         private int mUid;
+        private boolean mRetrieveDetail = true;
 
         public Builder(Context context) {
             super(context);
@@ -97,6 +102,11 @@
             mUid = uid;
             return this;
         }
+
+        public Builder<T> setRetrieveDetail(boolean retrieveDetail) {
+            mRetrieveDetail = retrieveDetail;
+            return this;
+        }
     }
 
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
index cc936d2..b1c2c3a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
@@ -22,6 +22,7 @@
 import android.app.usage.NetworkStats;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
@@ -34,6 +35,8 @@
 import android.text.format.DateUtils;
 import android.util.Pair;
 
+import com.android.settingslib.NetworkPolicyEditor;
+
 import java.time.ZonedDateTime;
 import java.util.Iterator;
 
@@ -55,7 +58,6 @@
 
     protected NetworkCycleDataLoader(Builder<?> builder) {
         super(builder.mContext);
-        mPolicy = builder.mPolicy;
         mSubId = builder.mSubId;
         mNetworkType = builder.mNetworkType;
         mNetworkTemplate = builder.mNetworkTemplate;
@@ -63,6 +65,10 @@
             builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
         mNetworkStatsService = INetworkStatsService.Stub.asInterface(
             ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        final NetworkPolicyEditor policyEditor =
+            new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
+        policyEditor.read();
+        mPolicy = policyEditor.getPolicy(mNetworkTemplate);
     }
 
     @Override
@@ -115,7 +121,8 @@
 
             long cycleEnd = historyEnd;
             while (cycleEnd > historyStart) {
-                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
+                final long cycleStart = Math.max(
+                    historyStart, cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4));
                 recordUsage(cycleStart, cycleEnd);
                 cycleEnd = cycleStart;
             }
@@ -154,7 +161,6 @@
 
     public static abstract class Builder<T extends NetworkCycleDataLoader> {
         private final Context mContext;
-        private NetworkPolicy mPolicy;
         private String mSubId;
         private int mNetworkType;
         private NetworkTemplate mNetworkTemplate;
@@ -163,27 +169,38 @@
             mContext = context;
         }
 
-        public Builder<T> setNetworkPolicy(NetworkPolicy policy) {
-            mPolicy = policy;
-            return this;
-        }
-
         public Builder<T> setSubscriberId(String subId) {
             mSubId = subId;
             return this;
         }
 
-        public Builder<T> setNetworkType(int networkType) {
-            mNetworkType = networkType;
-            return this;
-        }
-
         public Builder<T> setNetworkTemplate(NetworkTemplate template) {
             mNetworkTemplate = template;
+            setNetworkType();
             return this;
         }
 
         public abstract T build();
+
+        private void setNetworkType() {
+            if (mNetworkTemplate != null) {
+                final int matchRule = mNetworkTemplate.getMatchRule();
+                switch (matchRule) {
+                    case NetworkTemplate.MATCH_MOBILE:
+                    case NetworkTemplate.MATCH_MOBILE_WILDCARD:
+                        mNetworkType = ConnectivityManager.TYPE_MOBILE;
+                        break;
+                    case NetworkTemplate.MATCH_WIFI:
+                        mNetworkType = ConnectivityManager.TYPE_WIFI;
+                        break;
+                    case NetworkTemplate.MATCH_ETHERNET:
+                        mNetworkType = ConnectivityManager.TYPE_ETHERNET;
+                        break;
+                    default:
+                        mNetworkType = ConnectivityManager.TYPE_MOBILE;
+                }
+            }
+        }
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
index 3dc110d..cad88b1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
@@ -22,6 +22,8 @@
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.os.RemoteException;
 import android.text.format.DateUtils;
 
@@ -39,6 +41,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
 
     private NetworkCycleChartDataLoader mLoader;
@@ -48,6 +52,9 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test
@@ -57,7 +64,7 @@
         final int networkType = ConnectivityManager.TYPE_MOBILE;
         final String subId = "TestSubscriber";
         mLoader = NetworkCycleChartDataLoader.builder(mContext)
-            .setNetworkType(networkType).setSubscriberId(subId).build();
+            .setSubscriberId(subId).build();
 
         mLoader.recordUsage(start, end);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index 53fe451..2314f27 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -16,12 +16,21 @@
 
 package com.android.settingslib.net;
 
+import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
+import static android.net.NetworkStats.TAG_NONE;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.text.format.DateUtils;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
@@ -38,6 +47,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
 
     private NetworkCycleDataForUidLoader mLoader;
@@ -47,20 +58,42 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test
-    public void recordUsage_shouldQueryNetworkDetailsForUid() {
+    public void recordUsage_shouldQueryNetworkDetailsForUidAndForegroundState() {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
         final int networkType = ConnectivityManager.TYPE_MOBILE;
         final String subId = "TestSubscriber";
         final int uid = 1;
-        mLoader = NetworkCycleDataForUidLoader.builder(mContext)
-            .setUid(uid).setNetworkType(networkType).setSubscriberId(subId).build();
+        mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
+            .setUid(uid).setSubscriberId(subId).build());
+        doReturn(1024L).when(mLoader).getTotalUsage(any());
 
         mLoader.recordUsage(start, end);
 
         verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, uid);
+        verify(mNetworkStatsManager).queryDetailsForUidTagState(
+            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
+    }
+
+    @Test
+    public void recordUsage_retrieveDetailIsFalse_shouldNotQueryNetworkForegroundState() {
+        final long end = System.currentTimeMillis();
+        final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
+        final int networkType = ConnectivityManager.TYPE_MOBILE;
+        final String subId = "TestSubscriber";
+        final int uid = 1;
+        mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
+            .setRetrieveDetail(false).setUid(uid).setSubscriberId(subId).build());
+        doReturn(1024L).when(mLoader).getTotalUsage(any());
+
+        mLoader.recordUsage(start, end);
+        verify(mNetworkStatsManager, never()).queryDetailsForUidTagState(
+            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
index be7f1bb..9d60a97 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
@@ -30,6 +30,7 @@
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
@@ -55,6 +56,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
     @Mock
     private NetworkPolicy mPolicy;
@@ -62,9 +65,6 @@
     private Iterator<Range<ZonedDateTime>> mIterator;
     @Mock
     private INetworkStatsService mNetworkStatsService;
-    @Mock
-    private NetworkCycleDataLoader.Builder mBuilder;
-
 
     private NetworkCycleDataTestLoader mLoader;
 
@@ -73,7 +73,10 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
         when(mPolicy.cycleIterator()).thenReturn(mIterator);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test