Merge "Address review followup comments for NetworkStats" into main
This commit is contained in:
@@ -32,6 +32,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.modules.utils.build.SdkLevel;
|
||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
|
|
||||||
import libcore.util.EmptyArray;
|
import libcore.util.EmptyArray;
|
||||||
@@ -1245,18 +1246,21 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent
|
|||||||
* Return total statistics grouped by {@link #iface}; doesn't mutate the
|
* Return total statistics grouped by {@link #iface}; doesn't mutate the
|
||||||
* original structure.
|
* original structure.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated Use {@link #mapKeysNotNull(Function)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public NetworkStats groupedByIface() {
|
public NetworkStats groupedByIface() {
|
||||||
|
if (SdkLevel.isAtLeastV()) {
|
||||||
|
throw new UnsupportedOperationException("groupedByIface is not supported");
|
||||||
|
}
|
||||||
// Keep backward compatibility where the method filtered out tagged stats and keep the
|
// Keep backward compatibility where the method filtered out tagged stats and keep the
|
||||||
// operation counts as 0. The method used to deal with uid snapshot where tagged and
|
// operation counts as 0. The method used to deal with uid snapshot where tagged and
|
||||||
// non-tagged stats were mixed. And this method was also in Android O API list,
|
// non-tagged stats were mixed. And this method was also in Android O API list,
|
||||||
// so it is possible OEM can access it.
|
// so it is possible OEM can access it.
|
||||||
final NetworkStats copiedStats = this.clone();
|
|
||||||
copiedStats.filter(e -> e.getTag() == TAG_NONE);
|
|
||||||
|
|
||||||
final Entry temp = new Entry();
|
final Entry temp = new Entry();
|
||||||
final NetworkStats mappedStats = copiedStats.map(entry -> temp.setKeys(entry.getIface(),
|
final NetworkStats mappedStats = this.mapKeysNotNull(entry -> entry.getTag() != TAG_NONE
|
||||||
UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL));
|
? null : temp.setKeys(entry.getIface(), UID_ALL,
|
||||||
|
SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL));
|
||||||
|
|
||||||
for (int i = 0; i < mappedStats.size; i++) {
|
for (int i = 0; i < mappedStats.size; i++) {
|
||||||
mappedStats.operations[i] = 0L;
|
mappedStats.operations[i] = 0L;
|
||||||
@@ -1268,17 +1272,20 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent
|
|||||||
* Return total statistics grouped by {@link #uid}; doesn't mutate the
|
* Return total statistics grouped by {@link #uid}; doesn't mutate the
|
||||||
* original structure.
|
* original structure.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated Use {@link #mapKeysNotNull(Function)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public NetworkStats groupedByUid() {
|
public NetworkStats groupedByUid() {
|
||||||
|
if (SdkLevel.isAtLeastV()) {
|
||||||
|
throw new UnsupportedOperationException("groupedByUid is not supported");
|
||||||
|
}
|
||||||
// Keep backward compatibility where the method filtered out tagged stats. The method used
|
// Keep backward compatibility where the method filtered out tagged stats. The method used
|
||||||
// to deal with uid snapshot where tagged and non-tagged stats were mixed. And
|
// to deal with uid snapshot where tagged and non-tagged stats were mixed. And
|
||||||
// this method is also in Android O API list, so it is possible OEM can access it.
|
// this method is also in Android O API list, so it is possible OEM can access it.
|
||||||
final NetworkStats copiedStats = this.clone();
|
|
||||||
copiedStats.filter(e -> e.getTag() == TAG_NONE);
|
|
||||||
|
|
||||||
final Entry temp = new Entry();
|
final Entry temp = new Entry();
|
||||||
return copiedStats.map(entry -> temp.setKeys(IFACE_ALL,
|
return this.mapKeysNotNull(entry -> entry.getTag() != TAG_NONE
|
||||||
entry.getUid(), SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL));
|
? null : temp.setKeys(IFACE_ALL, entry.getUid(),
|
||||||
|
SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1304,14 +1311,14 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the interface name from all entries.
|
* Returns a copy of this NetworkStats, replacing iface with IFACE_ALL in all entries.
|
||||||
* This returns a newly constructed object instead of mutating the original structure.
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public NetworkStats clearInterfaces() {
|
public NetworkStats withoutInterfaces() {
|
||||||
final Entry temp = new Entry();
|
final Entry temp = new Entry();
|
||||||
return map(entry -> temp.setKeys(IFACE_ALL, entry.getUid(), entry.getSet(),
|
return mapKeysNotNull(entry -> temp.setKeys(IFACE_ALL, entry.getUid(), entry.getSet(),
|
||||||
entry.getTag(), entry.getMetered(), entry.getRoaming(), entry.getDefaultNetwork()));
|
entry.getTag(), entry.getMetered(), entry.getRoaming(), entry.getDefaultNetwork()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1321,13 +1328,16 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent
|
|||||||
* Note that because NetworkStats is more akin to a map than to a list,
|
* Note that because NetworkStats is more akin to a map than to a list,
|
||||||
* the entries will be grouped after they are mapped by the key fields,
|
* the entries will be grouped after they are mapped by the key fields,
|
||||||
* e.g. uid, set, tag, defaultNetwork.
|
* e.g. uid, set, tag, defaultNetwork.
|
||||||
* Value fields with the same keys will be added together.
|
* Only the key returned by the function is used ; values will be forcefully
|
||||||
|
* copied from the original entry. Entries that map to the same set of keys
|
||||||
|
* will be added together.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private NetworkStats map(@NonNull Function<Entry, Entry> f) {
|
private NetworkStats mapKeysNotNull(@NonNull Function<Entry, Entry> f) {
|
||||||
final NetworkStats ret = new NetworkStats(0, 1);
|
final NetworkStats ret = new NetworkStats(0, 1);
|
||||||
for (Entry e : this) {
|
for (Entry e : this) {
|
||||||
final NetworkStats.Entry transformed = f.apply(e);
|
final NetworkStats.Entry transformed = f.apply(e);
|
||||||
|
if (transformed == null) continue;
|
||||||
if (transformed == e) {
|
if (transformed == e) {
|
||||||
throw new IllegalStateException("A new entry must be created.");
|
throw new IllegalStateException("A new entry must be created.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1745,7 +1745,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
// information. This is because no caller needs this information for now, and it
|
// information. This is because no caller needs this information for now, and it
|
||||||
// makes it easier to change the implementation later by using the histories in the
|
// makes it easier to change the implementation later by using the histories in the
|
||||||
// recorder.
|
// recorder.
|
||||||
return stats.clearInterfaces();
|
return stats.withoutInterfaces();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.wtf(TAG, "Error compiling UID stats", e);
|
Log.wtf(TAG, "Error compiling UID stats", e);
|
||||||
return new NetworkStats(0L, 0);
|
return new NetworkStats(0L, 0);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import com.android.testutils.DevSdkIgnoreRunner;
|
|||||||
|
|
||||||
import com.google.android.collect.Sets;
|
import com.google.android.collect.Sets;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@@ -63,7 +64,8 @@ import java.util.Iterator;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
|
||||||
public class NetworkStatsTest {
|
public class NetworkStatsTest {
|
||||||
|
@Rule
|
||||||
|
public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
|
||||||
private static final String TEST_IFACE = "test0";
|
private static final String TEST_IFACE = "test0";
|
||||||
private static final String TEST_IFACE2 = "test2";
|
private static final String TEST_IFACE2 = "test2";
|
||||||
private static final int TEST_UID = 1001;
|
private static final int TEST_UID = 1001;
|
||||||
@@ -339,6 +341,7 @@ public class NetworkStatsTest {
|
|||||||
assertEquals(96L, uidRoaming.getTotalBytes());
|
assertEquals(96L, uidRoaming.getTotalBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
@Test
|
@Test
|
||||||
public void testGroupedByIfaceEmpty() throws Exception {
|
public void testGroupedByIfaceEmpty() throws Exception {
|
||||||
final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
|
final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
|
||||||
@@ -348,6 +351,7 @@ public class NetworkStatsTest {
|
|||||||
assertEquals(0, grouped.size());
|
assertEquals(0, grouped.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
@Test
|
@Test
|
||||||
public void testGroupedByIfaceAll() throws Exception {
|
public void testGroupedByIfaceAll() throws Exception {
|
||||||
final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
|
final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
|
||||||
@@ -366,6 +370,7 @@ public class NetworkStatsTest {
|
|||||||
DEFAULT_NETWORK_ALL, 384L, 24L, 0L, 6L, 0L);
|
DEFAULT_NETWORK_ALL, 384L, 24L, 0L, 6L, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
@Test
|
@Test
|
||||||
public void testGroupedByIface() throws Exception {
|
public void testGroupedByIface() throws Exception {
|
||||||
final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
|
final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
|
||||||
@@ -1068,7 +1073,7 @@ public class NetworkStatsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearInterfaces() {
|
public void testWithoutInterfaces() {
|
||||||
final NetworkStats stats = new NetworkStats(TEST_START, 1);
|
final NetworkStats stats = new NetworkStats(TEST_START, 1);
|
||||||
final NetworkStats.Entry entry1 = new NetworkStats.Entry(
|
final NetworkStats.Entry entry1 = new NetworkStats.Entry(
|
||||||
"test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
"test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||||
@@ -1093,10 +1098,10 @@ public class NetworkStatsTest {
|
|||||||
assertValues(stats, 2, "test3", 10101, SET_DEFAULT, 0xF0DD, METERED_NO,
|
assertValues(stats, 2, "test3", 10101, SET_DEFAULT, 0xF0DD, METERED_NO,
|
||||||
ROAMING_NO, DEFAULT_NETWORK_NO, 1, 2L, 3L, 4L, 5L);
|
ROAMING_NO, DEFAULT_NETWORK_NO, 1, 2L, 3L, 4L, 5L);
|
||||||
|
|
||||||
// Clear interfaces.
|
// Get stats without interfaces.
|
||||||
final NetworkStats ifaceClearedStats = stats.clearInterfaces();
|
final NetworkStats ifaceClearedStats = stats.withoutInterfaces();
|
||||||
|
|
||||||
// Verify that the interfaces are cleared, and key-duplicated items are merged.
|
// Verify that the interfaces do not exist, and key-duplicated items are merged.
|
||||||
assertEquals(2, ifaceClearedStats.size());
|
assertEquals(2, ifaceClearedStats.size());
|
||||||
assertValues(ifaceClearedStats, 0, null /* iface */, 10100, SET_DEFAULT, TAG_NONE,
|
assertValues(ifaceClearedStats, 0, null /* iface */, 10100, SET_DEFAULT, TAG_NONE,
|
||||||
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 50L, 100L, 20L, 0L);
|
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 50L, 100L, 20L, 0L);
|
||||||
|
|||||||
Reference in New Issue
Block a user