Merge "Ignore broken tests"
diff --git a/Android.bp b/Android.bp
index 0116237..fd66974 100644
--- a/Android.bp
+++ b/Android.bp
@@ -63,6 +63,7 @@
         "androidx.lifecycle_lifecycle-extensions",
         "guava",
         "jsr305",
+        "net-utils-framework-common",
         "settings-contextual-card-protos-lite",
         "settings-log-bridge-protos-lite",
         "contextualcards",
diff --git a/src/com/android/settings/datausage/CycleAdapter.java b/src/com/android/settings/datausage/CycleAdapter.java
index 74d27be..1292d00 100644
--- a/src/com/android/settings/datausage/CycleAdapter.java
+++ b/src/com/android/settings/datausage/CycleAdapter.java
@@ -13,14 +13,17 @@
  */
 package com.android.settings.datausage;
 
+import android.annotation.NonNull;
+import android.app.usage.NetworkStats;
 import android.content.Context;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
 import android.text.format.DateUtils;
 import android.util.Pair;
+import android.util.Range;
 import android.widget.AdapterView;
 
+import com.android.net.module.util.NetworkStatsUtils;
 import com.android.settings.Utils;
 import com.android.settingslib.net.ChartData;
 import com.android.settingslib.net.NetworkCycleData;
@@ -62,9 +65,43 @@
         return 0;
     }
 
+    protected static long getTotalBytesForTimeRange(List<NetworkStats.Bucket> stats,
+            Range<Long> range) {
+        long bytes = 0L;
+        for (NetworkStats.Bucket bucket : stats) {
+            final Range<Long> bucketSpan = new Range<>(
+                    bucket.getStartTimeStamp(), bucket.getEndTimeStamp());
+            // Only record bytes that overlapped with the given time range. For partially
+            // overlapped bucket, record rational bytes assuming the traffic is uniform
+            // distributed within the bucket.
+            try {
+                final Range<Long> overlapped = range.intersect(bucketSpan);
+                final long totalOfBucket = bucket.getRxBytes() + bucket.getTxBytes();
+                bytes += NetworkStatsUtils.multiplySafeByRational(totalOfBucket,
+                        overlapped.getUpper() - overlapped.getLower(),
+                        bucketSpan.getUpper() - bucketSpan.getLower());
+            } catch (IllegalArgumentException e) {
+                // Range disjoint, ignore.
+                continue;
+            }
+        }
+        return bytes;
+    }
+
+    @NonNull
+    private Range getTimeRangeOf(@NonNull List<NetworkStats.Bucket> stats) {
+        long start = Long.MAX_VALUE;
+        long end = Long.MIN_VALUE;
+        for (NetworkStats.Bucket bucket : stats) {
+            start = Math.min(start, bucket.getStartTimeStamp());
+            end = Math.max(end, bucket.getEndTimeStamp());
+        }
+        return new Range(start, end);
+    }
+
     /**
      * Rebuild list based on {@link NetworkPolicy} and available
-     * {@link NetworkStatsHistory} data. Always selects the newest item,
+     * {@link List<NetworkStats.Bucket>} data. Always selects the newest item,
      * updating the inspection range on chartData.
      */
     @Deprecated
@@ -75,19 +112,20 @@
         clear();
 
         final Context context = getContext();
-        NetworkStatsHistory.Entry entry = null;
 
-        long historyStart = Long.MAX_VALUE;
-        long historyEnd = Long.MIN_VALUE;
-        if (chartData != null) {
-            historyStart = chartData.network.getStart();
-            historyEnd = chartData.network.getEnd();
+        long historyStart;
+        long historyEnd;
+        try {
+            final Range<Long> historyTimeRange = getTimeRangeOf(chartData.network);
+            historyStart = historyTimeRange.getLower();
+            historyEnd = historyTimeRange.getUpper();
+        } catch (IllegalArgumentException e) {
+            // Empty history.
+            final long now = System.currentTimeMillis();
+            historyStart = now;
+            historyEnd = now + 1;
         }
 
-        final long now = System.currentTimeMillis();
-        if (historyStart == Long.MAX_VALUE) historyStart = now;
-        if (historyEnd == Long.MIN_VALUE) historyEnd = now + 1;
-
         boolean hasCycles = false;
         if (policy != null) {
             final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = NetworkPolicyManager
@@ -99,8 +137,9 @@
 
                 final boolean includeCycle;
                 if (chartData != null) {
-                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
-                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
+                    final long bytesInCycle = getTotalBytesForTimeRange(chartData.network,
+                            new Range<>(cycleStart, cycleEnd));
+                    includeCycle = bytesInCycle > 0;
                 } else {
                     includeCycle = true;
                 }
@@ -120,8 +159,9 @@
 
                 final boolean includeCycle;
                 if (chartData != null) {
-                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
-                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
+                    final long bytesInCycle = getTotalBytesForTimeRange(chartData.network,
+                            new Range<>(cycleStart, cycleEnd));
+                    includeCycle = bytesInCycle > 0;
                 } else {
                     includeCycle = true;
                 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
index d442d4e..c83ec49 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
@@ -60,7 +60,6 @@
 import com.android.wifitrackerlib.WifiPickerTracker;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -71,7 +70,6 @@
 import org.robolectric.shadows.ShadowToast;
 
 @RunWith(RobolectricTestRunner.class)
-@Ignore
 public class WifiSettingsTest {
 
     private static final int NUM_NETWORKS = 4;
@@ -94,6 +92,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mock(UserManager.class));
 
         mWifiSettings = spy(new WifiSettings());
         doReturn(mContext).when(mWifiSettings).getContext();