Merge "[MS19.1] Fix several hidden API dependencies"
diff --git a/framework-t/src/android/app/usage/NetworkStats.java b/framework-t/src/android/app/usage/NetworkStats.java
index 216a4a0..f684a4d 100644
--- a/framework-t/src/android/app/usage/NetworkStats.java
+++ b/framework-t/src/android/app/usage/NetworkStats.java
@@ -24,13 +24,15 @@
 import android.net.NetworkTemplate;
 import android.net.TrafficStats;
 import android.os.RemoteException;
-import android.util.IntArray;
 import android.util.Log;
 
+import com.android.net.module.util.CollectionUtils;
+
 import dalvik.system.CloseGuard;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 
 /**
  * Class providing enumeration over buckets of network usage statistics. {@link NetworkStats} objects
@@ -568,7 +570,7 @@
         //       the filtering logic below can be removed.
         int[] uids = mSession.getRelevantUids();
         // Filtering of uids with empty history.
-        IntArray filteredUids = new IntArray(uids.length);
+        final ArrayList<Integer> filteredUids = new ArrayList<>();
         for (int uid : uids) {
             try {
                 NetworkStatsHistory history = mSession.getHistoryIntervalForUid(mTemplate, uid,
@@ -581,7 +583,7 @@
                 Log.w(TAG, "Error while getting history of uid " + uid, e);
             }
         }
-        mUids = filteredUids.toArray();
+        mUids = CollectionUtils.toIntArray(filteredUids);
         mUidOrUidIndex = -1;
         stepHistory();
     }
diff --git a/framework-t/src/android/net/NetworkStats.java b/framework-t/src/android/net/NetworkStats.java
index 1986b83..181a594 100644
--- a/framework-t/src/android/net/NetworkStats.java
+++ b/framework-t/src/android/net/NetworkStats.java
@@ -31,7 +31,7 @@
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
+import com.android.net.module.util.CollectionUtils;
 
 import libcore.util.EmptyArray;
 
@@ -1185,7 +1185,7 @@
      * @hide
      */
     public void removeUids(int[] uids) {
-        filter(e -> !ArrayUtils.contains(uids, e.uid));
+        filter(e -> !CollectionUtils.contains(uids, e.uid));
     }
 
     /**
@@ -1218,7 +1218,7 @@
         filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
                 && (limitTag == TAG_ALL || limitTag == e.tag)
                 && (limitIfaces == INTERFACES_ALL
-                    || ArrayUtils.contains(limitIfaces, e.iface)));
+                    || CollectionUtils.contains(limitIfaces, e.iface)));
     }
 
     /**
diff --git a/framework-t/src/android/net/NetworkStatsCollection.java b/framework-t/src/android/net/NetworkStatsCollection.java
index 8d1347e..7935d28 100644
--- a/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/framework-t/src/android/net/NetworkStatsCollection.java
@@ -40,21 +40,17 @@
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
-import android.util.IntArray;
-import android.util.MathUtils;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
 import android.util.Range;
-import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastDataInput;
 import com.android.internal.util.FastDataOutput;
 import com.android.internal.util.FileRotator;
-import com.android.internal.util.IndentingPrintWriter;
-
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkStatsUtils;
 
 import libcore.io.IoUtils;
 
@@ -196,11 +192,11 @@
 
     public int[] getRelevantUids(@NetworkStatsAccess.Level int accessLevel,
                 final int callerUid) {
-        IntArray uids = new IntArray();
+        final ArrayList<Integer> uids = new ArrayList<>();
         for (int i = 0; i < mStats.size(); i++) {
             final Key key = mStats.keyAt(i);
             if (NetworkStatsAccess.isAccessibleToUser(key.uid, callerUid, accessLevel)) {
-                int j = uids.binarySearch(key.uid);
+                int j = Collections.binarySearch(uids, new Integer(key.uid));
 
                 if (j < 0) {
                     j = ~j;
@@ -208,7 +204,7 @@
                 }
             }
         }
-        return uids.toArray();
+        return CollectionUtils.toIntArray(uids);
     }
 
     /**
@@ -225,7 +221,8 @@
 
         // 180 days of history should be enough for anyone; if we end up needing
         // more, we'll dynamically grow the history object.
-        final int bucketEstimate = (int) MathUtils.constrain(((end - start) / mBucketDuration), 0,
+        final int bucketEstimate = (int) NetworkStatsUtils.constrain(
+                ((end - start) / mBucketDuration), 0,
                 (180 * DateUtils.DAY_IN_MILLIS) / mBucketDuration);
         final NetworkStatsHistory combined = new NetworkStatsHistory(
                 mBucketDuration, bucketEstimate, fields);
@@ -316,7 +313,7 @@
 
             final long deltaTotal = combined.getTotalBytes() - beforeTotal;
             if (deltaTotal != 0) {
-                Slog.d(TAG, "Augmented network usage by " + deltaTotal + " bytes");
+                Log.d(TAG, "Augmented network usage by " + deltaTotal + " bytes");
             }
 
             // Finally we can slice data as originally requested
@@ -489,11 +486,11 @@
 
     private void write(DataOutput out) throws IOException {
         // cluster key lists grouped by ident
-        final HashMap<NetworkIdentitySet, ArrayList<Key>> keysByIdent = Maps.newHashMap();
+        final HashMap<NetworkIdentitySet, ArrayList<Key>> keysByIdent = new HashMap<>();
         for (Key key : mStats.keySet()) {
             ArrayList<Key> keys = keysByIdent.get(key.ident);
             if (keys == null) {
-                keys = Lists.newArrayList();
+                keys = new ArrayList<>();
                 keysByIdent.put(key.ident, keys);
             }
             keys.add(key);
@@ -640,12 +637,12 @@
      * {@link TrafficStats#UID_REMOVED}.
      */
     public void removeUids(int[] uids) {
-        final ArrayList<Key> knownKeys = Lists.newArrayList();
+        final ArrayList<Key> knownKeys = new ArrayList<>();
         knownKeys.addAll(mStats.keySet());
 
         // migrate all UID stats into special "removed" bucket
         for (Key key : knownKeys) {
-            if (ArrayUtils.contains(uids, key.uid)) {
+            if (CollectionUtils.contains(uids, key.uid)) {
                 // only migrate combined TAG_NONE history
                 if (key.tag == TAG_NONE) {
                     final NetworkStatsHistory uidHistory = mStats.get(key);
@@ -672,7 +669,7 @@
     }
 
     private ArrayList<Key> getSortedKeys() {
-        final ArrayList<Key> keys = Lists.newArrayList();
+        final ArrayList<Key> keys = new ArrayList<>();
         keys.addAll(mStats.keySet());
         Collections.sort(keys);
         return keys;
diff --git a/framework-t/src/android/net/NetworkStatsHistory.java b/framework-t/src/android/net/NetworkStatsHistory.java
index 3eef4ee..428bc6d 100644
--- a/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/framework-t/src/android/net/NetworkStatsHistory.java
@@ -28,7 +28,6 @@
 import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 
-import static com.android.internal.util.ArrayUtils.total;
 import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
 
 import android.compat.annotation.UnsupportedAppUsage;
@@ -37,10 +36,11 @@
 import android.os.Parcelable;
 import android.service.NetworkStatsHistoryBucketProto;
 import android.service.NetworkStatsHistoryProto;
-import android.util.MathUtils;
+import android.util.IndentingPrintWriter;
 import android.util.proto.ProtoOutputStream;
 
-import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.NetworkStatsUtils;
 
 import libcore.util.EmptyArray;
 
@@ -174,7 +174,7 @@
                 txPackets = new long[bucketStart.length];
                 operations = new long[bucketStart.length];
                 bucketCount = bucketStart.length;
-                totalBytes = total(rxBytes) + total(txBytes);
+                totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
                 break;
             }
             case VERSION_ADD_PACKETS:
@@ -189,7 +189,7 @@
                 txPackets = readVarLongArray(in);
                 operations = readVarLongArray(in);
                 bucketCount = bucketStart.length;
-                totalBytes = total(rxBytes) + total(txBytes);
+                totalBytes = CollectionUtils.total(rxBytes) + CollectionUtils.total(txBytes);
                 break;
             }
             default: {
@@ -267,7 +267,7 @@
         } else {
             index -= 1;
         }
-        return MathUtils.constrain(index, 0, bucketCount - 1);
+        return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
     }
 
     /**
@@ -281,7 +281,7 @@
         } else {
             index += 1;
         }
-        return MathUtils.constrain(index, 0, bucketCount - 1);
+        return NetworkStatsUtils.constrain(index, 0, bucketCount - 1);
     }
 
     /**
@@ -349,6 +349,9 @@
 
         // create any buckets needed by this range
         ensureBuckets(start, end);
+        // Return fast if there is still no entry. This would typically happen when the start,
+        // end or duration are not valid values, e.g. start > end, negative duration value, etc.
+        if (bucketCount == 0) return;
 
         // distribute data usage into buckets
         long duration = end - start;
@@ -560,6 +563,9 @@
         entry.txPackets = txPackets != null ? 0 : UNKNOWN;
         entry.operations = operations != null ? 0 : UNKNOWN;
 
+        // Return fast if there is no entry.
+        if (bucketCount == 0) return entry;
+
         final int startIndex = getIndexAfter(end);
         for (int i = startIndex; i >= 0; i--) {
             final long curStart = bucketStart[i];
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index 5da8e25..9fa777d 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -49,7 +49,7 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 
-import com.android.internal.util.ArrayUtils;
+import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.NetworkIdentityUtils;
 import com.android.net.module.util.NetworkStatsUtils;
 
@@ -703,7 +703,7 @@
      */
     public boolean matchesSubscriberId(@Nullable String subscriberId) {
         return mSubscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
-                || ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
+                || CollectionUtils.contains(mMatchSubscriberIds, subscriberId);
     }
 
     /**
@@ -723,8 +723,8 @@
             // TODO: consider matching against WiMAX subscriber identity
             return true;
         } else {
-            return ident.mType == TYPE_MOBILE && !ArrayUtils.isEmpty(mMatchSubscriberIds)
-                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
+            return ident.mType == TYPE_MOBILE && !CollectionUtils.isEmpty(mMatchSubscriberIds)
+                    && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
                     && matchesCollapsedRatType(ident);
         }
     }
@@ -835,8 +835,8 @@
      */
     private boolean matchesCarrier(NetworkIdentity ident) {
         return ident.mSubscriberId != null
-                && !ArrayUtils.isEmpty(mMatchSubscriberIds)
-                && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
+                && !CollectionUtils.isEmpty(mMatchSubscriberIds)
+                && CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
     }
 
     private boolean matchesMobileWildcard(NetworkIdentity ident) {
@@ -953,7 +953,7 @@
         if (template.mSubscriberId == null) return template;
 
         for (String[] merged : mergedList) {
-            if (ArrayUtils.contains(merged, template.mSubscriberId)) {
+            if (CollectionUtils.contains(merged, template.mSubscriberId)) {
                 // Requested template subscriber is part of the merge group; return
                 // a template that matches all merged subscribers.
                 return new NetworkTemplate(template.mMatchRule, merged[0], merged,