Merge changes from topics "setter_getter_fix", "use_header_block"
* changes:
cronet: Use HeaderBlock for getHeaders API
cronet: Address Setter/Getter related API linter issues
diff --git a/Tethering/common/TetheringLib/cronet_enabled/api/current.txt b/Tethering/common/TetheringLib/cronet_enabled/api/current.txt
index ccbde93..98d02c3 100644
--- a/Tethering/common/TetheringLib/cronet_enabled/api/current.txt
+++ b/Tethering/common/TetheringLib/cronet_enabled/api/current.txt
@@ -178,6 +178,7 @@
public class QuicOptions {
method @NonNull public java.util.Set<java.lang.String> getAllowedQuicHosts();
method @Nullable public String getHandshakeUserAgent();
+ method @Nullable public java.time.Duration getIdleConnectionTimeout();
method @Nullable public Integer getInMemoryServerConfigsCacheSize();
}
diff --git a/framework-t/src/android/net/NetworkIdentity.java b/framework-t/src/android/net/NetworkIdentity.java
index edfd21c..947a092 100644
--- a/framework-t/src/android/net/NetworkIdentity.java
+++ b/framework-t/src/android/net/NetworkIdentity.java
@@ -32,6 +32,7 @@
import android.net.wifi.WifiInfo;
import android.service.NetworkIdentityProto;
import android.telephony.TelephonyManager;
+import android.util.Log;
import android.util.proto.ProtoOutputStream;
import com.android.net.module.util.BitUtils;
@@ -406,10 +407,18 @@
setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities()));
if (mType == TYPE_WIFI) {
- final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
- .getTransportInfo();
+ final NetworkCapabilities nc = snapshot.getNetworkCapabilities();
+ final TransportInfo transportInfo = nc.getTransportInfo();
if (transportInfo instanceof WifiInfo) {
final WifiInfo info = (WifiInfo) transportInfo;
+ // Log.wtf to catch trying to set a null wifiNetworkKey into NetworkIdentity.
+ // See b/266598304. The problematic data that has null wifi network key is
+ // thrown out when storing data, which is handled by the service.
+ if (info.getNetworkKey() == null) {
+ Log.wtf(TAG, "WifiInfo contains a null wifiNetworkKey and it will"
+ + " be set into NetworkIdentity, netId=" + snapshot.getNetwork()
+ + "NetworkCapabilities=" + nc);
+ }
setWifiNetworkKey(info.getNetworkKey());
}
} else if (mType == TYPE_TEST) {
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index 55fcc4a..d90bd8d 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -700,7 +700,15 @@
* to know details about the key.
*/
private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) {
- Objects.requireNonNull(wifiNetworkKey);
+ // Note that this code accepts null wifi network keys because of a past bug where wifi
+ // code was sending a null network key for some connected networks, which isn't expected
+ // and ended up stored in the data on many devices.
+ // A null network key in the data matches a wildcard template (one where
+ // {@code mMatchWifiNetworkKeys} is empty), but not one where {@code MatchWifiNetworkKeys}
+ // contains null. See b/266598304.
+ if (wifiNetworkKey == null) {
+ return CollectionUtils.isEmpty(mMatchWifiNetworkKeys);
+ }
return CollectionUtils.isEmpty(mMatchWifiNetworkKeys)
|| CollectionUtils.contains(mMatchWifiNetworkKeys, wifiNetworkKey);
}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 8b70a94..c92e9a9 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -22,6 +22,8 @@
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -1343,8 +1345,9 @@
* @return true if the MdnsDiscoveryManager feature is enabled.
*/
public boolean isMdnsDiscoveryManagerEnabled(Context context) {
- return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY,
- MDNS_DISCOVERY_MANAGER_VERSION, false /* defaultEnabled */);
+ return isAtLeastU() || DeviceConfigUtils.isFeatureEnabled(context,
+ NAMESPACE_CONNECTIVITY, MDNS_DISCOVERY_MANAGER_VERSION,
+ false /* defaultEnabled */);
}
/**
@@ -1354,8 +1357,8 @@
* @return true if the MdnsAdvertiser feature is enabled.
*/
public boolean isMdnsAdvertiserEnabled(Context context) {
- return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY,
- MDNS_ADVERTISER_VERSION, false /* defaultEnabled */);
+ return isAtLeastU() || DeviceConfigUtils.isFeatureEnabled(context,
+ NAMESPACE_CONNECTIVITY, MDNS_ADVERTISER_VERSION, false /* defaultEnabled */);
}
/**
diff --git a/service-t/src/com/android/server/net/NetworkStatsFactory.java b/service-t/src/com/android/server/net/NetworkStatsFactory.java
index e0abdf1..5952eae 100644
--- a/service-t/src/com/android/server/net/NetworkStatsFactory.java
+++ b/service-t/src/com/android/server/net/NetworkStatsFactory.java
@@ -34,8 +34,6 @@
import java.io.IOException;
import java.net.ProtocolException;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -147,36 +145,6 @@
}
/**
- * Get a set of interfaces containing specified ifaces and stacked interfaces.
- *
- * <p>The added stacked interfaces are ifaces stacked on top of the specified ones, or ifaces
- * on which the specified ones are stacked. Stacked interfaces are those noted with
- * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
- * is called are guaranteed to be included.
- */
- public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
- if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
- return null;
- }
-
- HashSet<String> relatedIfaces = new HashSet<>(Arrays.asList(requiredIfaces));
- // ConcurrentHashMap's EntrySet iterators are "guaranteed to traverse
- // elements as they existed upon construction exactly once, and may
- // (but are not guaranteed to) reflect any modifications subsequent to construction".
- // This is enough here.
- for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
- if (relatedIfaces.contains(entry.getKey())) {
- relatedIfaces.add(entry.getValue());
- } else if (relatedIfaces.contains(entry.getValue())) {
- relatedIfaces.add(entry.getKey());
- }
- }
-
- String[] outArray = new String[relatedIfaces.size()];
- return relatedIfaces.toArray(outArray);
- }
-
- /**
* Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
* @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map)
*/
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index 9176ec2..961337d 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -106,6 +106,7 @@
import android.net.TetherStatsParcel;
import android.net.TetheringManager;
import android.net.TrafficStats;
+import android.net.TransportInfo;
import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
import android.net.netstats.IUsageCallback;
@@ -113,6 +114,7 @@
import android.net.netstats.provider.INetworkStatsProvider;
import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.net.netstats.provider.NetworkStatsProvider;
+import android.net.wifi.WifiInfo;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -537,7 +539,8 @@
BroadcastOptions.makeBasic())
.setDeliveryGroupPolicy(
ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT)
- .setDeferUntilActive(true)
+ .setDeferralPolicy(
+ ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE)
.toBundle();
} catch (UnsupportedApiLevelException e) {
Log.wtf(TAG, "Using unsupported API" + e);
@@ -1729,11 +1732,7 @@
PermissionUtils.enforceNetworkStackPermission(mContext);
try {
final String[] ifaceArray = getAllIfacesSinceBoot(transport);
- // TODO(b/215633405) : mMobileIfaces and mWifiIfaces already contain the stacked
- // interfaces, so this is not useful, remove it.
- final String[] ifacesToQuery =
- mStatsFactory.augmentWithStackedInterfaces(ifaceArray);
- final NetworkStats stats = getNetworkStatsUidDetail(ifacesToQuery);
+ final NetworkStats stats = getNetworkStatsUidDetail(ifaceArray);
// Clear the interfaces of the stats before returning, so callers won't get this
// 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
@@ -2125,6 +2124,14 @@
final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
isDefault, ratType);
+ // If WifiInfo contains a null network key then this identity should not be added into
+ // the network identity set. See b/266598304.
+ final TransportInfo transportInfo = snapshot.getNetworkCapabilities()
+ .getTransportInfo();
+ if (transportInfo instanceof WifiInfo) {
+ final WifiInfo info = (WifiInfo) transportInfo;
+ if (info.getNetworkKey() == null) continue;
+ }
// Traffic occurring on the base interface is always counted for
// both total usage and UID details.
final String baseIface = snapshot.getLinkProperties().getInterfaceName();
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 4c55afe..5f51971 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3133,7 +3133,7 @@
optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT);
optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION,
createDeliveryGroupKeyForConnectivityAction(info));
- optsShim.setDeferUntilActive(true);
+ optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE);
} catch (UnsupportedApiLevelException e) {
Log.wtf(TAG, "Using unsupported API" + e);
}
diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
index 7c24c95..dc22369 100644
--- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt
@@ -37,8 +37,6 @@
import android.net.cts.NetworkValidationTestUtil.setHttpsUrlDeviceConfig
import android.net.cts.NetworkValidationTestUtil.setUrlExpirationDeviceConfig
import android.net.cts.util.CtsNetUtils
-import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL
-import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL
import android.platform.test.annotations.AppModeFull
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
@@ -47,28 +45,30 @@
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.runner.AndroidJUnit4
import com.android.modules.utils.build.SdkLevel.isAtLeastR
+import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL
+import com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL
import com.android.testutils.DeviceConfigRule
-import com.android.testutils.RecorderCallback
+import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
import com.android.testutils.TestHttpServer
import com.android.testutils.TestHttpServer.Request
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.runAsShell
import fi.iki.elonen.NanoHTTPD.Response.Status
-import junit.framework.AssertionFailedError
-import org.junit.After
-import org.junit.Assume.assumeTrue
-import org.junit.Assume.assumeFalse
-import org.junit.Before
-import org.junit.BeforeClass
-import org.junit.Rule
-import org.junit.runner.RunWith
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
+import junit.framework.AssertionFailedError
import kotlin.test.Test
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
+import org.junit.After
+import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Rule
+import org.junit.runner.RunWith
private const val TEST_HTTPS_URL_PATH = "/https_path"
private const val TEST_HTTP_URL_PATH = "/http_path"
@@ -151,8 +151,8 @@
.build()
val cellCb = TestableNetworkCallback(timeoutMs = TEST_TIMEOUT_MS)
cm.registerNetworkCallback(cellReq, cellCb)
- val cb = cellCb.eventuallyExpectOrNull<RecorderCallback.CallbackEntry.CapabilitiesChanged> {
- it.network == cellNetwork && it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
+ val cb = cellCb.poll { it.network == cellNetwork &&
+ it is CapabilitiesChanged && it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
}
assertNotNull(cb, "Mobile network $cellNetwork has no access to the internet. " +
"Check the mobile data connection.")
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 7985dc4..0bb6000 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -2434,11 +2434,11 @@
runWithShellPermissionIdentity(() -> registerDefaultNetworkCallbackForUid(
otherUid, otherUidCallback, handler), NETWORK_SETTINGS);
- final Network defaultNetwork = mCm.getActiveNetwork();
+ final Network defaultNetwork = myUidCallback.expect(CallbackEntry.AVAILABLE).getNetwork();
final List<DetailedBlockedStatusCallback> allCallbacks =
List.of(myUidCallback, otherUidCallback);
for (DetailedBlockedStatusCallback callback : allCallbacks) {
- callback.expectAvailableCallbacksWithBlockedReasonNone(defaultNetwork);
+ callback.eventuallyExpectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
}
final Range<Integer> myUidRange = new Range<>(myUid, myUid);
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 408c546..9b589d8 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -19,6 +19,8 @@
import android.app.compat.CompatChanges
import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
+import android.net.InetAddresses.parseNumericAddress
+import android.net.LinkAddress
import android.net.LinkProperties
import android.net.LocalSocket
import android.net.LocalSocketAddress
@@ -27,6 +29,7 @@
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
import android.net.NetworkCapabilities.TRANSPORT_TEST
import android.net.NetworkRequest
import android.net.TestNetworkInterface
@@ -62,18 +65,28 @@
import android.os.HandlerThread
import android.os.Process.myTid
import android.platform.test.annotations.AppModeFull
+import android.system.ErrnoException
+import android.system.Os
+import android.system.OsConstants.AF_INET6
+import android.system.OsConstants.ENETUNREACH
+import android.system.OsConstants.IPPROTO_UDP
+import android.system.OsConstants.SOCK_DGRAM
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.PollingCheck
import com.android.compatibility.common.util.PropertyUtil
+import com.android.modules.utils.build.SdkLevel.isAtLeastU
import com.android.net.module.util.ArrayTrackRecord
import com.android.net.module.util.TrackRecord
import com.android.networkstack.apishim.NsdShimImpl
import com.android.networkstack.apishim.common.NsdShim
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
+import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
import com.android.testutils.TestableNetworkAgent
+import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk30
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk33
@@ -82,6 +95,7 @@
import com.android.testutils.waitForIdle
import java.io.File
import java.io.IOException
+import java.net.NetworkInterface
import java.net.ServerSocket
import java.nio.charset.StandardCharsets
import java.util.Random
@@ -353,24 +367,56 @@
.build(), cb)
val agent = registerTestNetworkAgent(iface.interfaceName)
val network = agent.network ?: fail("Registered agent should have a network")
+
+ cb.eventuallyExpect<LinkPropertiesChanged>(TIMEOUT_MS) {
+ it.lp.linkAddresses.isNotEmpty()
+ }
+
// The network has no INTERNET capability, so will be marked validated immediately
- cb.expectAvailableThenValidatedCallbacks(network, TIMEOUT_MS)
+ // It does not matter if validated capabilities come before/after the link addresses change
+ cb.eventuallyExpect<CapabilitiesChanged>(TIMEOUT_MS, from = 0) {
+ it.caps.hasCapability(NET_CAPABILITY_VALIDATED)
+ }
return TestTapNetwork(iface, cb, agent, network)
}
private fun registerTestNetworkAgent(ifaceName: String): TestableNetworkAgent {
+ val lp = LinkProperties().apply {
+ interfaceName = ifaceName
+ }
+
val agent = TestableNetworkAgent(context, handlerThread.looper,
NetworkCapabilities().apply {
removeCapability(NET_CAPABILITY_TRUSTED)
addTransportType(TRANSPORT_TEST)
setNetworkSpecifier(TestNetworkSpecifier(ifaceName))
- },
- LinkProperties().apply {
- interfaceName = ifaceName
- },
- NetworkAgentConfig.Builder().build())
- agent.register()
+ }, lp, NetworkAgentConfig.Builder().build())
+ val network = agent.register()
agent.markConnected()
+ agent.expectCallback<OnNetworkCreated>()
+
+ // Wait until the link-local address can be used. Address flags are not available without
+ // elevated permissions, so check that bindSocket works.
+ PollingCheck.check("No usable v6 address on interface after $TIMEOUT_MS ms", TIMEOUT_MS) {
+ val sock = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
+ tryTest {
+ network.bindSocket(sock)
+ Os.connect(sock, parseNumericAddress("ff02::fb%$ifaceName"), 12345)
+ true
+ }.catch<ErrnoException> {
+ if (it.errno != ENETUNREACH) {
+ throw it
+ }
+ false
+ } cleanup {
+ Os.close(sock)
+ }
+ }
+
+ lp.setLinkAddresses(NetworkInterface.getByName(ifaceName).interfaceAddresses.map {
+ LinkAddress(it.address, it.networkPrefixLength.toInt())
+ })
+ agent.sendLinkProperties(lp)
return agent
}
@@ -378,8 +424,9 @@
fun tearDown() {
if (TestUtils.shouldTestTApis()) {
runAsShell(MANAGE_TEST_NETWORKS) {
- testNetwork1.close(cm)
- testNetwork2.close(cm)
+ // Avoid throwing here if initializing failed in setUp
+ if (this::testNetwork1.isInitialized) testNetwork1.close(cm)
+ if (this::testNetwork2.isInitialized) testNetwork2.close(cm)
}
}
handlerThread.waitForIdle(TIMEOUT_MS)
@@ -465,7 +512,12 @@
assertTrue(resolvedService.attributes.containsKey("nullBinaryDataAttr"))
assertNull(resolvedService.attributes["nullBinaryDataAttr"])
assertTrue(resolvedService.attributes.containsKey("emptyBinaryDataAttr"))
- assertNull(resolvedService.attributes["emptyBinaryDataAttr"])
+ // TODO: change the check to target SDK U when this is what the code implements
+ if (isAtLeastU()) {
+ assertArrayEquals(byteArrayOf(), resolvedService.attributes["emptyBinaryDataAttr"])
+ } else {
+ assertNull(resolvedService.attributes["emptyBinaryDataAttr"])
+ }
assertEquals(localPort, resolvedService.port)
// Unregister the service
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index edbcea9..fc25fd8 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -130,10 +130,17 @@
mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
val identWifiImsi1Key1 = buildNetworkIdentity(
mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
+ // This identity with a null wifiNetworkKey is to test matchesWifiNetworkKey won't crash
+ // the system when a null wifiNetworkKey is provided, which happens because of a bug in wifi
+ // and it should still match the wifi wildcard template. See b/266598304.
+ val identWifiNullKey = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(null /* subscriberId */,
+ null /* wifiNetworkKey */), true, 0)
templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
templateWifiWildcard.assertMatches(identWifiImsiNullKey1)
templateWifiWildcard.assertMatches(identWifiImsi1Key1)
+ templateWifiWildcard.assertMatches(identWifiNullKey)
}
@Test
@@ -148,6 +155,9 @@
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
val templateWifiKeyAllImsi1 = NetworkTemplate.Builder(MATCH_WIFI)
.setSubscriberIds(setOf(TEST_IMSI1)).build()
+ val templateNullWifiKey = NetworkTemplate(MATCH_WIFI,
+ emptyArray<String>() /* subscriberIds */, arrayOf(null) /* wifiNetworkKeys */,
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
false, TelephonyManager.NETWORK_TYPE_UMTS)
@@ -159,6 +169,12 @@
mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_WIFI_KEY1), true, 0)
val identWifiImsi1Key2 = buildNetworkIdentity(
mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY2), true, 0)
+ // This identity with a null wifiNetworkKey is to test the matchesWifiNetworkKey won't crash
+ // the system when a null wifiNetworkKey is provided, which would happen in some unknown
+ // cases, see b/266598304.
+ val identWifiNullKey = buildNetworkIdentity(
+ mockContext, buildWifiNetworkState(null /* subscriberId */,
+ null /* wifiNetworkKey */), true, 0)
// Verify that template with WiFi Network Key only matches any subscriberId and
// specific WiFi Network Key.
@@ -191,6 +207,12 @@
templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key1)
templateWifiKeyAllImsi1.assertDoesNotMatch(identWifiImsi2Key1)
templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key2)
+
+ // Test a network identity with null wifiNetworkKey won't crash.
+ // It should not match a template with wifiNetworkKeys is non-null.
+ // Also, it should not match a template with wifiNetworkKeys that contains null.
+ templateWifiKey1.assertDoesNotMatch(identWifiNullKey)
+ templateNullWifiKey.assertDoesNotMatch(identWifiNullKey)
}
@Test
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 1a358b2..c1c6a8a 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -864,7 +864,8 @@
verify(mBroadcastOptionsShim).setDeliveryGroupMatchingKey(
eq(CONNECTIVITY_ACTION),
eq(createDeliveryGroupKeyForConnectivityAction(ni)));
- verify(mBroadcastOptionsShim).setDeferUntilActive(eq(true));
+ verify(mBroadcastOptionsShim).setDeferralPolicy(
+ eq(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE));
} catch (UnsupportedApiLevelException e) {
throw new RuntimeException(e);
}
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 2d87728..1f965d9 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -25,6 +25,8 @@
import static android.net.ConnectivityManager.NetworkCallback;
import static android.net.INetd.IF_STATE_DOWN;
import static android.net.INetd.IF_STATE_UP;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.VpnManager.TYPE_VPN_PLATFORM;
import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS;
@@ -36,6 +38,8 @@
import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO;
import static android.os.Build.VERSION_CODES.S_V2;
import static android.os.UserHandle.PER_USER_RANGE;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.server.connectivity.Vpn.AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
@@ -107,6 +111,7 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.RouteInfo;
+import android.net.TelephonyNetworkSpecifier;
import android.net.UidRangeParcel;
import android.net.VpnManager;
import android.net.VpnProfileState;
@@ -126,6 +131,7 @@
import android.net.ipsec.ike.exceptions.IkeNonProtocolException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.net.ipsec.ike.exceptions.IkeTimeoutException;
+import android.net.wifi.WifiInfo;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.ConditionVariable;
@@ -139,6 +145,10 @@
import android.os.test.TestLooper;
import android.provider.Settings;
import android.security.Credentials;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
@@ -265,6 +275,9 @@
private static final Range<Integer> PRIMARY_USER_RANGE = uidRangeForUser(PRIMARY_USER.id);
// Same as IkeSessionParams#IKE_NATT_KEEPALIVE_DELAY_SEC_DEFAULT
private static final int IKE_NATT_KEEPALIVE_DELAY_SEC_DEFAULT = 10;
+ private static final int TEST_KEEPALIVE_TIMER = 800;
+ private static final int TEST_SUB_ID = 1234;
+
@Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
@Mock private UserManager mUserManager;
@Mock private PackageManager mPackageManager;
@@ -278,6 +291,10 @@
@Mock private Vpn.VpnNetworkAgentWrapper mMockNetworkAgent;
@Mock private ConnectivityManager mConnectivityManager;
@Mock private ConnectivityDiagnosticsManager mCdm;
+ @Mock private TelephonyManager mTelephonyManager;
+ @Mock private TelephonyManager mTmPerSub;
+ @Mock private CarrierConfigManager mConfigManager;
+ @Mock private SubscriptionManager mSubscriptionManager;
@Mock private IpSecService mIpSecService;
@Mock private VpnProfileStore mVpnProfileStore;
@Mock private ScheduledThreadPoolExecutor mExecutor;
@@ -286,7 +303,6 @@
private final VpnProfile mVpnProfile;
private IpSecManager mIpSecManager;
-
private TestDeps mTestDeps;
public VpnTest() throws Exception {
@@ -322,6 +338,11 @@
mockService(IpSecManager.class, Context.IPSEC_SERVICE, mIpSecManager);
mockService(ConnectivityDiagnosticsManager.class, Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
mCdm);
+ mockService(TelephonyManager.class, Context.TELEPHONY_SERVICE, mTelephonyManager);
+ mockService(CarrierConfigManager.class, Context.CARRIER_CONFIG_SERVICE, mConfigManager);
+ mockService(SubscriptionManager.class, Context.TELEPHONY_SUBSCRIPTION_SERVICE,
+ mSubscriptionManager);
+ doReturn(mTmPerSub).when(mTelephonyManager).createForSubscriptionId(anyInt());
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
.thenReturn(Resources.getSystem().getString(
R.string.config_customVpnAlwaysOnDisconnectedDialogComponent));
@@ -1924,7 +1945,7 @@
}
@Test
- public void testMigrateIkeSessionFromIkeTunnConnParams_AutoTimerNoTimer()
+ public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer()
throws Exception {
doTestMigrateIkeSession_FromIkeTunnConnParams(
false /* isAutomaticIpVersionSelectionEnabled */,
@@ -1933,21 +1954,21 @@
}
@Test
- public void testMigrateIkeSessionFromIkeTunnConnParams_AutoTimerTimerSet()
+ public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet()
throws Exception {
doTestMigrateIkeSession_FromIkeTunnConnParams(
false /* isAutomaticIpVersionSelectionEnabled */,
true /* isAutomaticNattKeepaliveTimerEnabled */,
- 800 /* keepaliveTimeout */);
+ TEST_KEEPALIVE_TIMER);
}
@Test
- public void testMigrateIkeSessionFromIkeTunnConnParams_AutoIp()
+ public void testMigrateIkeSession_FromIkeTunnConnParams_AutoIp()
throws Exception {
doTestMigrateIkeSession_FromIkeTunnConnParams(
true /* isAutomaticIpVersionSelectionEnabled */,
false /* isAutomaticNattKeepaliveTimerEnabled */,
- TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveTimeout */);
+ TEST_KEEPALIVE_TIMEOUT_UNSET);
}
@Test
@@ -2016,9 +2037,12 @@
verifySetupPlatformVpn(profile,
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
false /* mtuSupportsIpv6 */);
- // Mock new network comes up and the cleanup task is cancelled
+ // Simulate a new network coming up
vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
+ verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt());
+ vpnSnapShot.nwCb.onCapabilitiesChanged(
+ TEST_NETWORK_2, new NetworkCapabilities.Builder().build());
// Verify MOBIKE is triggered
verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2,
expectedIpVersion, expectedEncapType, expectedKeepalive);
@@ -2026,6 +2050,102 @@
vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
}
+ private void mockCarrierConfig(int subId, int keepaliveTimer, int simStatus) {
+ final SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
+ doReturn(subId).when(subscriptionInfo).getSubscriptionId();
+ doReturn(List.of(subscriptionInfo)).when(mSubscriptionManager)
+ .getActiveSubscriptionInfoList();
+
+ doReturn(simStatus).when(mTmPerSub).getSimApplicationState();
+
+ final PersistableBundle persistableBundle = new PersistableBundle();
+ persistableBundle.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, keepaliveTimer);
+ // For CarrierConfigManager.isConfigForIdentifiedCarrier check
+ persistableBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ doReturn(persistableBundle).when(mConfigManager).getConfigForSubId(subId);
+ }
+
+ private CarrierConfigManager.CarrierConfigChangeListener getCarrierConfigListener() {
+ final ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+ verify(mConfigManager).registerCarrierConfigChangeListener(any(), listenerCaptor.capture());
+
+ return listenerCaptor.getValue();
+ }
+
+ @Test
+ public void testNattKeepaliveTimerFromCarrierConfig_noSubId() throws Exception {
+ doTestNattKeepaliveTimerFromCarrierConfig(new NetworkCapabilities(),
+ TelephonyManager.SIM_STATE_LOADED, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+ }
+
+ @Test
+ public void testNattKeepaliveTimerFromCarrierConfig_simAbsent() throws Exception {
+ doTestNattKeepaliveTimerFromCarrierConfig(new NetworkCapabilities.Builder().build(),
+ TelephonyManager.SIM_STATE_ABSENT, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+ }
+
+ @Test
+ public void testNattKeepaliveTimerFromCarrierConfig() throws Exception {
+ final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
+ .setSubscriptionId(TEST_SUB_ID)
+ .build())
+ .build();
+ doTestNattKeepaliveTimerFromCarrierConfig(nc,
+ TelephonyManager.SIM_STATE_LOADED, TEST_KEEPALIVE_TIMER);
+ }
+
+ @Test
+ public void testNattKeepaliveTimerFromCarrierConfig_NotCell() throws Exception {
+ final NetworkCapabilities nc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .setTransportInfo(new WifiInfo.Builder().build())
+ .build();
+ doTestNattKeepaliveTimerFromCarrierConfig(nc,
+ TelephonyManager.SIM_STATE_LOADED, AUTOMATIC_KEEPALIVE_DELAY_SECONDS);
+ }
+
+ private void doTestNattKeepaliveTimerFromCarrierConfig(NetworkCapabilities nc, int simState,
+ int expectedKeepaliveTimer) throws Exception {
+ final Ikev2VpnProfile ikeProfile =
+ new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY)
+ .setAuthPsk(TEST_VPN_PSK)
+ .setBypassable(true /* isBypassable */)
+ .setAutomaticNattKeepaliveTimerEnabled(true)
+ .build();
+
+ final PlatformVpnSnapshot vpnSnapShot =
+ verifySetupPlatformVpn(ikeProfile.toVpnProfile(),
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
+ false /* mtuSupportsIpv6 */);
+
+ final CarrierConfigManager.CarrierConfigChangeListener listener =
+ getCarrierConfigListener();
+
+ // Simulate a new network coming up
+ vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
+ // Migration will not be started until receiving network capabilities change.
+ verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt());
+
+ reset(mIkeSessionWrapper);
+ mockCarrierConfig(TEST_SUB_ID, TEST_KEEPALIVE_TIMER, simState);
+ vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, nc);
+ verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2,
+ ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, expectedKeepaliveTimer);
+
+ reset(mExecutor);
+ reset(mIkeSessionWrapper);
+
+ // Trigger carrier config change
+ listener.onCarrierConfigChanged(1 /* logicalSlotIndex */, TEST_SUB_ID,
+ -1 /* carrierId */, -1 /* specificCarrierId */);
+ verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2,
+ ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, expectedKeepaliveTimer);
+ }
+
@Test
public void testStartPlatformVpn_mtuDoesNotSupportIpv6() throws Exception {
final PlatformVpnSnapshot vpnSnapShot =
@@ -2051,7 +2171,10 @@
// Mock new network comes up and the cleanup task is cancelled
vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
verify(mScheduledFuture).cancel(anyBoolean());
+ verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt());
+ vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2,
+ new NetworkCapabilities.Builder().build());
// Verify MOBIKE is triggered
verify(mIkeSessionWrapper).setNetwork(eq(TEST_NETWORK_2),
eq(ESP_IP_VERSION_AUTO) /* ipVersion */,
@@ -2146,7 +2269,11 @@
// Mock network switch
vpnSnapShot.nwCb.onLost(TEST_NETWORK);
vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
+ // The old IKE Session will not be killed until receiving network capabilities change.
+ verify(mIkeSessionWrapper, never()).kill();
+ vpnSnapShot.nwCb.onCapabilitiesChanged(
+ TEST_NETWORK_2, new NetworkCapabilities.Builder().build());
// Verify the old IKE Session is killed
verify(mIkeSessionWrapper).kill();
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 13a6a6f..8046263 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -82,7 +82,6 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -395,10 +394,6 @@
verify(mNetd).registerUnsolicitedEventListener(alertObserver.capture());
mAlertObserver = alertObserver.getValue();
- // Make augmentWithStackedInterfaces returns the interfaces that was passed to it.
- doAnswer(inv -> ((String[]) inv.getArgument(0)).clone())
- .when(mStatsFactory).augmentWithStackedInterfaces(any());
-
// Catch TetheringEventCallback during systemReady().
ArgumentCaptor<TetheringManager.TetheringEventCallback> tetheringEventCbCaptor =
ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class);