Snap for 8089010 from 124c75ec0a570c4c067cc38084ff3f7c60dd685b to mainline-mediaprovider-release

Change-Id: Ia997d611f611fe0a0de7d779e7f858db8ec0a6e5
diff --git a/common/framework/com/android/net/module/util/NetworkStatsUtils.java b/common/framework/com/android/net/module/util/NetworkStatsUtils.java
index 28ff770..c4d415e 100644
--- a/common/framework/com/android/net/module/util/NetworkStatsUtils.java
+++ b/common/framework/com/android/net/module/util/NetworkStatsUtils.java
@@ -16,12 +16,23 @@
 
 package com.android.net.module.util;
 
+import android.app.usage.NetworkStats;
+
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Various utilities used for NetworkStats related code.
  *
  * @hide
  */
 public class NetworkStatsUtils {
+    // These constants must be synced with the definition in android.net.NetworkStats.
+    // TODO: update to formal APIs once all downstreams have these APIs.
+    private static final int SET_ALL = -1;
+    private static final int METERED_ALL = -1;
+    private static final int ROAMING_ALL = -1;
+    private static final int DEFAULT_NETWORK_ALL = -1;
+
     /**
      * Safely multiple a value by a rational.
      * <p>
@@ -88,4 +99,77 @@
         if (low > high) throw new IllegalArgumentException("low(" + low + ") > high(" + high + ")");
         return amount < low ? low : (amount > high ? high : amount);
     }
+
+    /**
+     * Convert structure from android.app.usage.NetworkStats to android.net.NetworkStats.
+     */
+    public static android.net.NetworkStats fromPublicNetworkStats(
+            NetworkStats publiceNetworkStats) {
+        android.net.NetworkStats stats = new android.net.NetworkStats(0L, 0);
+        while (publiceNetworkStats.hasNextBucket()) {
+            NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+            publiceNetworkStats.getNextBucket(bucket);
+            final android.net.NetworkStats.Entry entry = fromBucket(bucket);
+            stats = stats.addEntry(entry);
+        }
+        return stats;
+    }
+
+    @VisibleForTesting
+    static android.net.NetworkStats.Entry fromBucket(NetworkStats.Bucket bucket) {
+        return new android.net.NetworkStats.Entry(
+                null /* IFACE_ALL */, bucket.getUid(), convertBucketState(bucket.getState()),
+                convertBucketTag(bucket.getTag()), convertBucketMetered(bucket.getMetered()),
+                convertBucketRoaming(bucket.getRoaming()),
+                convertBucketDefaultNetworkStatus(bucket.getDefaultNetworkStatus()),
+                bucket.getRxBytes(), bucket.getRxPackets(),
+                bucket.getTxBytes(), bucket.getTxPackets(), 0 /* operations */);
+    }
+
+    private static int convertBucketState(int networkStatsSet) {
+        switch (networkStatsSet) {
+            case NetworkStats.Bucket.STATE_ALL: return SET_ALL;
+            case NetworkStats.Bucket.STATE_DEFAULT: return android.net.NetworkStats.SET_DEFAULT;
+            case NetworkStats.Bucket.STATE_FOREGROUND:
+                return android.net.NetworkStats.SET_FOREGROUND;
+        }
+        return 0;
+    }
+
+    private static int convertBucketTag(int tag) {
+        switch (tag) {
+            case NetworkStats.Bucket.TAG_NONE: return android.net.NetworkStats.TAG_NONE;
+        }
+        return tag;
+    }
+
+    private static int convertBucketMetered(int metered) {
+        switch (metered) {
+            case NetworkStats.Bucket.METERED_ALL: return METERED_ALL;
+            case NetworkStats.Bucket.METERED_NO: return android.net.NetworkStats.METERED_NO;
+            case NetworkStats.Bucket.METERED_YES: return android.net.NetworkStats.METERED_YES;
+        }
+        return 0;
+    }
+
+    private static int convertBucketRoaming(int roaming) {
+        switch (roaming) {
+            case NetworkStats.Bucket.ROAMING_ALL: return ROAMING_ALL;
+            case NetworkStats.Bucket.ROAMING_NO: return android.net.NetworkStats.ROAMING_NO;
+            case NetworkStats.Bucket.ROAMING_YES: return android.net.NetworkStats.ROAMING_YES;
+        }
+        return 0;
+    }
+
+    private static int convertBucketDefaultNetworkStatus(int defaultNetworkStatus) {
+        switch (defaultNetworkStatus) {
+            case NetworkStats.Bucket.DEFAULT_NETWORK_ALL:
+                return DEFAULT_NETWORK_ALL;
+            case NetworkStats.Bucket.DEFAULT_NETWORK_NO:
+                return android.net.NetworkStats.DEFAULT_NETWORK_NO;
+            case NetworkStats.Bucket.DEFAULT_NETWORK_YES:
+                return android.net.NetworkStats.DEFAULT_NETWORK_YES;
+        }
+        return 0;
+    }
 }
diff --git a/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt b/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
index ff839fe..2785ea9 100644
--- a/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
+++ b/common/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
@@ -16,12 +16,16 @@
 
 package com.android.net.module.util
 
+import android.net.NetworkStats
+import android.text.TextUtils
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import org.junit.Test
 import org.junit.runner.RunWith
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
@@ -71,4 +75,68 @@
         assertEquals(11, NetworkStatsUtils.constrain(11, 11, 11))
         assertEquals(11, NetworkStatsUtils.constrain(1, 11, 11))
     }
+
+    @Test
+    fun testBucketToEntry() {
+        val bucket = makeMockBucket(android.app.usage.NetworkStats.Bucket.UID_ALL,
+                android.app.usage.NetworkStats.Bucket.TAG_NONE,
+                android.app.usage.NetworkStats.Bucket.STATE_DEFAULT,
+                android.app.usage.NetworkStats.Bucket.METERED_YES,
+                android.app.usage.NetworkStats.Bucket.ROAMING_NO,
+                android.app.usage.NetworkStats.Bucket.DEFAULT_NETWORK_ALL, 1024, 8, 2048, 12)
+        val entry = NetworkStatsUtils.fromBucket(bucket)
+        val expectedEntry = NetworkStats.Entry(null /* IFACE_ALL */, NetworkStats.UID_ALL,
+            NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE, NetworkStats.METERED_YES,
+            NetworkStats.ROAMING_NO, NetworkStats.DEFAULT_NETWORK_ALL, 1024, 8, 2048, 12,
+            0 /* operations */)
+
+        // TODO: Use assertEquals once all downstreams accept null iface in
+        // NetworkStats.Entry#equals.
+        assertEntryEquals(expectedEntry, entry)
+    }
+
+    private fun makeMockBucket(
+        uid: Int,
+        tag: Int,
+        state: Int,
+        metered: Int,
+        roaming: Int,
+        defaultNetwork: Int,
+        rxBytes: Long,
+        rxPackets: Long,
+        txBytes: Long,
+        txPackets: Long
+    ): android.app.usage.NetworkStats.Bucket {
+        val ret: android.app.usage.NetworkStats.Bucket =
+                mock(android.app.usage.NetworkStats.Bucket::class.java)
+        doReturn(uid).`when`(ret).getUid()
+        doReturn(tag).`when`(ret).getTag()
+        doReturn(state).`when`(ret).getState()
+        doReturn(metered).`when`(ret).getMetered()
+        doReturn(roaming).`when`(ret).getRoaming()
+        doReturn(defaultNetwork).`when`(ret).getDefaultNetworkStatus()
+        doReturn(rxBytes).`when`(ret).getRxBytes()
+        doReturn(rxPackets).`when`(ret).getRxPackets()
+        doReturn(txBytes).`when`(ret).getTxBytes()
+        doReturn(txPackets).`when`(ret).getTxPackets()
+        return ret
+    }
+
+    /**
+     * Assert that the two {@link NetworkStats.Entry} are equals.
+     */
+    private fun assertEntryEquals(left: NetworkStats.Entry, right: NetworkStats.Entry) {
+        TextUtils.equals(left.iface, right.iface)
+        assertEquals(left.uid, right.uid)
+        assertEquals(left.set, right.set)
+        assertEquals(left.tag, right.tag)
+        assertEquals(left.metered, right.metered)
+        assertEquals(left.roaming, right.roaming)
+        assertEquals(left.defaultNetwork, right.defaultNetwork)
+        assertEquals(left.rxBytes, right.rxBytes)
+        assertEquals(left.rxPackets, right.rxPackets)
+        assertEquals(left.txBytes, right.txBytes)
+        assertEquals(left.txPackets, right.txPackets)
+        assertEquals(left.operations, right.operations)
+    }
 }
\ No newline at end of file