Merge "Add low latency and high bandwidth network capabilities"
diff --git a/tests/cts/net/native/Android.bp b/tests/cts/net/native/Android.bp
index 1d1c18e..153ff51 100644
--- a/tests/cts/net/native/Android.bp
+++ b/tests/cts/net/native/Android.bp
@@ -43,6 +43,7 @@
static_libs: [
"libbpf_android",
"libgtest",
+ "libmodules-utils-build",
],
// Tag this module as a cts test artifact
diff --git a/tests/cts/net/native/src/BpfCompatTest.cpp b/tests/cts/net/native/src/BpfCompatTest.cpp
index 874bad4..97ecb9e 100644
--- a/tests/cts/net/native/src/BpfCompatTest.cpp
+++ b/tests/cts/net/native/src/BpfCompatTest.cpp
@@ -21,6 +21,8 @@
#include <gtest/gtest.h>
+#include "android-modules-utils/sdk_level.h"
+
#include "libbpf_android.h"
using namespace android::bpf;
@@ -33,11 +35,17 @@
EXPECT_EQ(28, readSectionUint("size_of_bpf_prog_def", elfFile, 0));
}
-TEST(BpfTest, bpfStructSizeTest) {
+TEST(BpfTest, bpfStructSizeTestPreT) {
+ if (android::modules::sdklevel::IsAtLeastT()) GTEST_SKIP() << "T+ device.";
doBpfStructSizeTest("/system/etc/bpf/netd.o");
doBpfStructSizeTest("/system/etc/bpf/clatd.o");
}
+TEST(BpfTest, bpfStructSizeTest) {
+ doBpfStructSizeTest("/system/etc/bpf/gpu_mem.o");
+ doBpfStructSizeTest("/system/etc/bpf/time_in_state.o");
+}
+
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 80c2db4..53e4ab7 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -168,6 +168,7 @@
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRuleKt;
+import com.android.testutils.DumpTestUtils;
import com.android.testutils.RecorderCallback.CallbackEntry;
import com.android.testutils.TestHttpServer;
import com.android.testutils.TestNetworkTracker;
@@ -3021,6 +3022,13 @@
}
}
+ @Test
+ public void testDump() throws Exception {
+ final String dumpOutput = DumpTestUtils.dumpServiceWithShellPermission(
+ Context.CONNECTIVITY_SERVICE, "--short");
+ assertTrue(dumpOutput, dumpOutput.contains("Active default network"));
+ }
+
private void unregisterRegisteredCallbacks() {
for (NetworkCallback callback: mRegisteredCallbacks) {
mCm.unregisterNetworkCallback(callback);
diff --git a/tests/unit/java/android/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
index 2e82986..c27ee93 100644
--- a/tests/unit/java/android/net/NetworkStatsCollectionTest.java
+++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
@@ -38,11 +38,13 @@
import static org.junit.Assert.fail;
import android.content.res.Resources;
+import android.net.NetworkStatsCollection.Key;
import android.os.Process;
import android.os.UserHandle;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
+import android.util.ArrayMap;
import android.util.RecurrenceRule;
import androidx.test.InstrumentationRegistry;
@@ -73,6 +75,7 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Tests for {@link NetworkStatsCollection}.
@@ -530,6 +533,52 @@
assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0));
}
+ @Test
+ public void testBuilder() {
+ final Map<Key, NetworkStatsHistory> expectedEntries = new ArrayMap<>();
+ final NetworkStats.Entry entry = new NetworkStats.Entry();
+ final NetworkIdentitySet ident = new NetworkIdentitySet();
+ final Key key1 = new Key(ident, 0, 0, 0);
+ final Key key2 = new Key(ident, 1, 0, 0);
+ final long bucketDuration = 10;
+
+ final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 10, 40,
+ 4, 50, 5, 60);
+ final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 10, 3,
+ 41, 7, 1, 0);
+
+ NetworkStatsHistory history1 = new NetworkStatsHistory.Builder(10, 5)
+ .addEntry(entry1)
+ .addEntry(entry2)
+ .build();
+
+ NetworkStatsHistory history2 = new NetworkStatsHistory(10, 5);
+
+ NetworkStatsCollection actualCollection = new NetworkStatsCollection.Builder(bucketDuration)
+ .addEntry(key1, history1)
+ .addEntry(key2, history2)
+ .build();
+
+ // The builder will omit any entry with empty history. Thus, history2
+ // is not expected in the result collection.
+ expectedEntries.put(key1, history1);
+
+ final Map<Key, NetworkStatsHistory> actualEntries = actualCollection.getEntries();
+
+ assertEquals(expectedEntries.size(), actualEntries.size());
+ for (Key expectedKey : expectedEntries.keySet()) {
+ final NetworkStatsHistory expectedHistory = expectedEntries.get(expectedKey);
+
+ final NetworkStatsHistory actualHistory = actualEntries.get(expectedKey);
+ assertNotNull(actualHistory);
+
+ assertEquals(expectedHistory.getEntries(), actualHistory.getEntries());
+
+ actualEntries.remove(expectedKey);
+ }
+ assertEquals(0, actualEntries.size());
+ }
+
/**
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
* testing purposes.
@@ -587,6 +636,14 @@
actual.txBytes, actual.txPackets, 0L));
}
+ private static void assertEntry(NetworkStatsHistory.Entry expected,
+ NetworkStatsHistory.Entry actual) {
+ assertEntry(new NetworkStats.Entry(actual.rxBytes, actual.rxPackets,
+ actual.txBytes, actual.txPackets, 0L),
+ new NetworkStats.Entry(actual.rxBytes, actual.rxPackets,
+ actual.txBytes, actual.txPackets, 0L));
+ }
+
private static void assertEntry(NetworkStats.Entry expected,
NetworkStats.Entry actual) {
assertEquals("unexpected rxBytes", expected.rxBytes, actual.rxBytes);
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
index 6a7da9e..66dcf6d 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -42,7 +42,6 @@
import android.net.NetworkStats;
import android.net.NetworkStatsAccess;
import android.net.NetworkTemplate;
-import android.net.netstats.IUsageCallback;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
@@ -101,7 +100,7 @@
private ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
@Mock private IBinder mUsageCallbackBinder;
- @Mock private IUsageCallback mUsageCallback;
+ private TestableUsageCallback mUsageCallback;
@Before
public void setUp() throws Exception {
@@ -119,20 +118,27 @@
mActiveIfaces = new ArrayMap<>();
mActiveUidIfaces = new ArrayMap<>();
- Mockito.when(mUsageCallback.asBinder()).thenReturn(mUsageCallbackBinder);
+ mUsageCallback = new TestableUsageCallback(mUsageCallbackBinder);
}
@Test
public void testRegister_thresholdTooLow_setsDefaultThreshold() throws Exception {
- long thresholdTooLowBytes = 1L;
- DataUsageRequest inputRequest = new DataUsageRequest(
+ final long thresholdTooLowBytes = 1L;
+ final DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
- Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
- assertTrue(request.requestId > 0);
- assertTrue(Objects.equals(sTemplateWifi, request.template));
- assertEquals(THRESHOLD_BYTES, request.thresholdInBytes);
+ final DataUsageRequest requestByApp = mStatsObservers.register(inputRequest, mUsageCallback,
+ UID_RED, NetworkStatsAccess.Level.DEVICE);
+ assertTrue(requestByApp.requestId > 0);
+ assertTrue(Objects.equals(sTemplateWifi, requestByApp.template));
+ assertEquals(THRESHOLD_BYTES, requestByApp.thresholdInBytes);
+
+ // Verify the threshold requested by system uid won't be overridden.
+ final DataUsageRequest requestBySystem = mStatsObservers.register(inputRequest,
+ mUsageCallback, Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
+ assertTrue(requestBySystem.requestId > 0);
+ assertTrue(Objects.equals(sTemplateWifi, requestBySystem.template));
+ assertEquals(1, requestBySystem.thresholdInBytes);
}
@Test
@@ -304,7 +310,7 @@
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
waitForObserverToIdle();
- Mockito.verify(mUsageCallback).onThresholdReached(any());
+ mUsageCallback.expectOnThresholdReached(request);
}
@Test
@@ -337,7 +343,7 @@
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
waitForObserverToIdle();
- Mockito.verify(mUsageCallback).onThresholdReached(any());
+ mUsageCallback.expectOnThresholdReached(request);
}
@Test
@@ -402,7 +408,7 @@
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
waitForObserverToIdle();
- Mockito.verify(mUsageCallback).onThresholdReached(any());
+ mUsageCallback.expectOnThresholdReached(request);
}
@Test
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 94a4f3d..ea35c31 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -1292,7 +1292,7 @@
// Wait for the caller to invoke expectOnThresholdReached.
- mUsageCallback.expectOnThresholdReached();
+ mUsageCallback.expectOnThresholdReached(request);
// Allow binder to disconnect
when(mUsageCallbackBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()))
@@ -1302,7 +1302,7 @@
mService.unregisterUsageRequest(request);
// Wait for the caller to invoke expectOnCallbackReleased.
- mUsageCallback.expectOnCallbackReleased();
+ mUsageCallback.expectOnCallbackReleased(request);
// Make sure that the caller binder gets disconnected
verify(mUsageCallbackBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
diff --git a/tests/unit/java/com/android/server/net/TestableUsageCallback.kt b/tests/unit/java/com/android/server/net/TestableUsageCallback.kt
index 44f588c..1917ec3 100644
--- a/tests/unit/java/com/android/server/net/TestableUsageCallback.kt
+++ b/tests/unit/java/com/android/server/net/TestableUsageCallback.kt
@@ -21,37 +21,34 @@
import android.os.IBinder
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
-import kotlin.test.assertEquals
import kotlin.test.fail
private const val DEFAULT_TIMEOUT_MS = 200L
// TODO: Move the class to static libs once all downstream have IUsageCallback definition.
-open class TestableUsageCallback(private val binder: IBinder) : IUsageCallback.Stub() {
- sealed class CallbackType {
- object OnThresholdReached : CallbackType()
- object OnCallbackReleased : CallbackType()
+class TestableUsageCallback(private val binder: IBinder) : IUsageCallback.Stub() {
+ sealed class CallbackType(val request: DataUsageRequest) {
+ class OnThresholdReached(request: DataUsageRequest) : CallbackType(request)
+ class OnCallbackReleased(request: DataUsageRequest) : CallbackType(request)
}
// TODO: Change to use ArrayTrackRecord once moved into to the module.
private val history = LinkedBlockingQueue<CallbackType>()
override fun onThresholdReached(request: DataUsageRequest) {
- history.add(CallbackType.OnThresholdReached)
+ history.add(CallbackType.OnThresholdReached(request))
}
override fun onCallbackReleased(request: DataUsageRequest) {
- history.add(CallbackType.OnCallbackReleased)
+ history.add(CallbackType.OnCallbackReleased(request))
}
- fun expectOnThresholdReached() {
- assertEquals(CallbackType.OnThresholdReached,
- history.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS))
+ fun expectOnThresholdReached(request: DataUsageRequest) {
+ expectCallback<CallbackType.OnThresholdReached>(request, DEFAULT_TIMEOUT_MS)
}
- fun expectOnCallbackReleased() {
- assertEquals(CallbackType.OnCallbackReleased,
- history.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS))
+ fun expectOnCallbackReleased(request: DataUsageRequest) {
+ expectCallback<CallbackType.OnCallbackReleased>(request, DEFAULT_TIMEOUT_MS)
}
@JvmOverloads
@@ -60,6 +57,22 @@
cb?.let { fail("Expected no callback but got $cb") }
}
+ // Expects a callback of the specified request on the specified network within the timeout.
+ // If no callback arrives, or a different callback arrives, fail.
+ private inline fun <reified T : CallbackType> expectCallback(
+ expectedRequest: DataUsageRequest,
+ timeoutMs: Long
+ ) {
+ history.poll(timeoutMs, TimeUnit.MILLISECONDS).let {
+ if (it !is T || it.request != expectedRequest) {
+ fail("Unexpected callback : $it," +
+ " expected ${T::class} with Request[$expectedRequest]")
+ } else {
+ it
+ }
+ }
+ }
+
override fun asBinder(): IBinder {
return binder
}