Merge "Injecting network ip provision stats into statsd" into rvc-dev
diff --git a/Android.bp b/Android.bp
index a671567..6ccbd18 100644
--- a/Android.bp
+++ b/Android.bp
@@ -90,6 +90,7 @@
"netd_aidl_interface-java",
"netlink-client",
"networkstack-client",
+ "net-utils-framework-common",
"datastallprotosnano",
"statsprotos",
"captiveportal-lib",
diff --git a/common/moduleutils/src/android/net/shared/NetdUtils.java b/common/moduleutils/src/android/net/shared/NetdUtils.java
index 0137bb7..5fa29c9 100644
--- a/common/moduleutils/src/android/net/shared/NetdUtils.java
+++ b/common/moduleutils/src/android/net/shared/NetdUtils.java
@@ -17,6 +17,7 @@
package android.net.shared;
import static android.net.RouteInfo.RTN_UNICAST;
+import static android.system.OsConstants.EBUSY;
import android.net.INetd;
import android.net.IpPrefix;
@@ -24,6 +25,8 @@
import android.net.TetherConfigParcel;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
+import android.os.SystemClock;
+import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@@ -33,6 +36,8 @@
* @hide
*/
public class NetdUtils {
+ private static final String TAG = NetdUtils.class.getSimpleName();
+
/** Start tethering. */
public static void tetherStart(final INetd netd, final boolean usingLegacyDnsProxy,
final String[] dhcpRange) throws RemoteException, ServiceSpecificException {
@@ -45,14 +50,46 @@
/** Setup interface for tethering. */
public static void tetherInterface(final INetd netd, final String iface, final IpPrefix dest)
throws RemoteException, ServiceSpecificException {
- netd.tetherInterfaceAdd(iface);
+ tetherInterface(netd, iface, dest, 20 /* maxAttempts */, 50 /* pollingIntervalMs */);
+ }
- netd.networkAddInterface(INetd.LOCAL_NET_ID, iface);
+ /** Setup interface with configurable retries for tethering. */
+ public static void tetherInterface(final INetd netd, final String iface, final IpPrefix dest,
+ int maxAttempts, int pollingIntervalMs)
+ throws RemoteException, ServiceSpecificException {
+ netd.tetherInterfaceAdd(iface);
+ networkAddInterface(netd, iface, maxAttempts, pollingIntervalMs);
List<RouteInfo> routes = new ArrayList<>();
routes.add(new RouteInfo(dest, null, iface, RTN_UNICAST));
RouteUtils.addRoutesToLocalNetwork(netd, iface, routes);
}
+ /**
+ * Retry Netd#networkAddInterface for EBUSY error code.
+ * If the same interface (e.g., wlan0) is in client mode and then switches to tethered mode.
+ * There can be a race where puts the interface into the local network but interface is still
+ * in use in netd because the ConnectivityService thread hasn't processed the disconnect yet.
+ * See b/158269544 for detail.
+ */
+ private static void networkAddInterface(final INetd netd, final String iface,
+ int maxAttempts, int pollingIntervalMs)
+ throws ServiceSpecificException, RemoteException {
+ for (int i = 1; i <= maxAttempts; i++) {
+ try {
+ netd.networkAddInterface(INetd.LOCAL_NET_ID, iface);
+ return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == EBUSY && i < maxAttempts) {
+ SystemClock.sleep(pollingIntervalMs);
+ continue;
+ }
+
+ Log.e(TAG, "Retry Netd#networkAddInterface failure: " + e);
+ throw e;
+ }
+ }
+ }
+
/** Reset interface for tethering. */
public static void untetherInterface(final INetd netd, String iface)
throws RemoteException, ServiceSpecificException {
diff --git a/jarjar-rules-shared.txt b/jarjar-rules-shared.txt
index 7953f93..c4f4602 100644
--- a/jarjar-rules-shared.txt
+++ b/jarjar-rules-shared.txt
@@ -3,8 +3,8 @@
rule com.android.internal.util.** android.net.networkstack.util.@1
-rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1
-rule android.net.shared.InetAddressUtils* android.net.networkstack.shared.InetAddressUtils@1
+# Classes from net-utils-framework-common
+rule com.android.net.module.util.** com.android.networkstack.util.@1
# Ignore DhcpResultsParcelable, but jarjar DhcpResults
# TODO: move DhcpResults into services.net and delete from here
diff --git a/src/android/net/dhcp/DhcpLease.java b/src/android/net/dhcp/DhcpLease.java
index 3226f28..0b9cd7c 100644
--- a/src/android/net/dhcp/DhcpLease.java
+++ b/src/android/net/dhcp/DhcpLease.java
@@ -16,7 +16,7 @@
package android.net.dhcp;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
import android.net.MacAddress;
import android.os.SystemClock;
diff --git a/src/android/net/dhcp/DhcpLeaseRepository.java b/src/android/net/dhcp/DhcpLeaseRepository.java
index b7a2572..8420996 100644
--- a/src/android/net/dhcp/DhcpLeaseRepository.java
+++ b/src/android/net/dhcp/DhcpLeaseRepository.java
@@ -18,10 +18,10 @@
import static android.net.dhcp.DhcpLease.EXPIRATION_NEVER;
import static android.net.dhcp.DhcpLease.inet4AddrToString;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_BITS;
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
index d022973..3915740 100644
--- a/src/android/net/dhcp/DhcpPacket.java
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -22,7 +22,6 @@
import android.net.DhcpResults;
import android.net.LinkAddress;
import android.net.metrics.DhcpErrorEvent;
-import android.net.shared.Inet4AddressUtils;
import android.os.Build;
import android.os.SystemProperties;
import android.system.OsConstants;
@@ -31,6 +30,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.net.module.util.Inet4AddressUtils;
import com.android.networkstack.apishim.common.ShimUtils;
import java.io.UnsupportedEncodingException;
diff --git a/src/android/net/dhcp/DhcpServer.java b/src/android/net/dhcp/DhcpServer.java
index 55b1f28..6c95b5a 100644
--- a/src/android/net/dhcp/DhcpServer.java
+++ b/src/android/net/dhcp/DhcpServer.java
@@ -23,8 +23,6 @@
import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION;
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static android.system.OsConstants.AF_INET;
@@ -36,6 +34,8 @@
import static android.system.OsConstants.SO_REUSEADDR;
import static com.android.internal.util.TrafficStatsConstants.TAG_SYSTEM_DHCP_SERVER;
+import static com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress;
+import static com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address;
import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
diff --git a/src/android/net/dhcp/DhcpServingParams.java b/src/android/net/dhcp/DhcpServingParams.java
index 77cdf7a..97db6ae 100644
--- a/src/android/net/dhcp/DhcpServingParams.java
+++ b/src/android/net/dhcp/DhcpServingParams.java
@@ -16,9 +16,8 @@
package android.net.dhcp;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
+import static com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
import static com.android.server.util.NetworkStackConstants.IPV4_MAX_MTU;
import static com.android.server.util.NetworkStackConstants.IPV4_MIN_MTU;
@@ -27,12 +26,13 @@
import android.net.IpPrefix;
import android.net.LinkAddress;
-import android.net.shared.Inet4AddressUtils;
import android.util.ArraySet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.net.module.util.Inet4AddressUtils;
+
import java.net.Inet4Address;
import java.util.Arrays;
import java.util.Collections;
diff --git a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
index c1596ea..9b1be06 100644
--- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
@@ -16,8 +16,8 @@
package com.android.server.connectivity.ipmemorystore;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import android.content.ContentValues;
import android.content.Context;
diff --git a/src/com/android/server/util/NetworkStackConstants.java b/src/com/android/server/util/NetworkStackConstants.java
index dbba7f3..6ecc84c 100644
--- a/src/com/android/server/util/NetworkStackConstants.java
+++ b/src/com/android/server/util/NetworkStackConstants.java
@@ -16,7 +16,7 @@
package com.android.server.util;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import java.net.Inet4Address;
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index e924d3a..1a985a9 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -92,7 +92,11 @@
test_suites: ["device-tests", "mts"],
test_config: "AndroidTest_Coverage.xml",
defaults: ["NetworkStackIntegrationTestsJniDefaults"],
- static_libs: ["NetworkStackTestsLib", "NetworkStackIntegrationTestsLib"],
+ static_libs: [
+ "NetworkStackTestsLib",
+ "NetworkStackIntegrationTestsLib",
+ "NetworkStaticLibTestsLib",
+ ],
compile_multilib: "both",
manifest: "AndroidManifest_coverage.xml",
}
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
index 77c7db6..38eb84e 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -26,13 +26,13 @@
import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable;
import static android.net.ipmemorystore.Status.SUCCESS;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
import static android.system.OsConstants.ETH_P_IPV6;
import static android.system.OsConstants.IFA_F_TEMPORARY;
import static android.system.OsConstants.IPPROTO_ICMPV6;
import static android.system.OsConstants.IPPROTO_TCP;
+import static com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress;
+import static com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address;
import static com.android.server.util.NetworkStackConstants.ARP_REPLY;
import static com.android.server.util.NetworkStackConstants.ARP_REQUEST;
import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN;
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java
index d85d059..6e969ec 100644
--- a/tests/unit/src/android/net/apf/ApfTest.java
+++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -51,7 +51,6 @@
import android.net.ip.IpClient.IpClientCallbacksWrapper;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.RaEvent;
-import android.net.shared.Inet4AddressUtils;
import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.ConditionVariable;
@@ -67,6 +66,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.HexDump;
+import com.android.net.module.util.Inet4AddressUtils;
import com.android.networkstack.apishim.NetworkInformationShimImpl;
import com.android.server.networkstack.tests.R;
import com.android.server.util.NetworkStackConstants;
diff --git a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
index 3a6a890..81685ef 100644
--- a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -20,8 +20,8 @@
import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
import static org.junit.Assert.assertEquals;
diff --git a/tests/unit/src/android/net/dhcp/DhcpLeaseTest.kt b/tests/unit/src/android/net/dhcp/DhcpLeaseTest.kt
index 2971f65..743418c 100644
--- a/tests/unit/src/android/net/dhcp/DhcpLeaseTest.kt
+++ b/tests/unit/src/android/net/dhcp/DhcpLeaseTest.kt
@@ -18,7 +18,7 @@
import android.net.InetAddresses.parseNumericAddress
import android.net.MacAddress
-import android.net.shared.Inet4AddressUtils.intToInet4AddressHTH
+import com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.testutils.assertFieldCountEquals
diff --git a/tests/unit/src/android/net/dhcp/DhcpPacketTest.java b/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
index c565238..9d2a630 100644
--- a/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
@@ -34,8 +34,9 @@
import static android.net.dhcp.DhcpPacket.INADDR_ANY;
import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
import static android.net.dhcp.DhcpPacket.ParseException;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
+
+import static com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress;
+import static com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
diff --git a/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/tests/unit/src/android/net/dhcp/DhcpServerTest.java
index 2e8a3c2..d313b94 100644
--- a/tests/unit/src/android/net/dhcp/DhcpServerTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpServerTest.java
@@ -23,9 +23,10 @@
import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
import static android.net.dhcp.DhcpServer.CMD_RECEIVE_PACKET;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION;
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -51,12 +52,12 @@
import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
import android.net.dhcp.DhcpServer.Clock;
import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.shared.Inet4AddressUtils;
import android.net.util.SharedLog;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
+import com.android.net.module.util.Inet4AddressUtils;
import com.android.testutils.HandlerUtilsKt;
import org.junit.After;
diff --git a/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java b/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
index 1ce2f82..6506eba 100644
--- a/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
+++ b/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
@@ -18,7 +18,8 @@
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
+
+import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -28,11 +29,11 @@
import android.annotation.Nullable;
import android.net.LinkAddress;
import android.net.dhcp.DhcpServingParams.InvalidParameterException;
-import android.net.shared.Inet4AddressUtils;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.Inet4AddressUtils;
import com.android.testutils.MiscAssertsKt;
import org.junit.Before;
diff --git a/tests/unit/src/android/net/shared/Inet4AddressUtilsTest.java b/tests/unit/src/android/net/shared/Inet4AddressUtilsTest.java
deleted file mode 100644
index 35f8c79..0000000
--- a/tests/unit/src/android/net/shared/Inet4AddressUtilsTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.shared;
-
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getImplicitNetmask;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTL;
-import static android.net.shared.Inet4AddressUtils.netmaskToPrefixLength;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTL;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.junit.Assert.fail;
-
-import android.net.InetAddresses;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.Inet4Address;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class Inet4AddressUtilsTest {
-
- @Test
- public void testInet4AddressToIntHTL() {
- assertEquals(0, inet4AddressToIntHTL(ipv4Address("0.0.0.0")));
- assertEquals(0x000080ff, inet4AddressToIntHTL(ipv4Address("255.128.0.0")));
- assertEquals(0x0080ff0a, inet4AddressToIntHTL(ipv4Address("10.255.128.0")));
- assertEquals(0x00feff0a, inet4AddressToIntHTL(ipv4Address("10.255.254.0")));
- assertEquals(0xfeffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.254")));
- assertEquals(0xffffa8c0, inet4AddressToIntHTL(ipv4Address("192.168.255.255")));
- }
-
- @Test
- public void testIntToInet4AddressHTL() {
- assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTL(0));
- assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTL(0x000080ff));
- assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTL(0x0080ff0a));
- assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTL(0x00feff0a));
- assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTL(0xfeffa8c0));
- assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTL(0xffffa8c0));
- }
-
- @Test
- public void testInet4AddressToIntHTH() {
- assertEquals(0, inet4AddressToIntHTH(ipv4Address("0.0.0.0")));
- assertEquals(0xff800000, inet4AddressToIntHTH(ipv4Address("255.128.0.0")));
- assertEquals(0x0aff8000, inet4AddressToIntHTH(ipv4Address("10.255.128.0")));
- assertEquals(0x0afffe00, inet4AddressToIntHTH(ipv4Address("10.255.254.0")));
- assertEquals(0xc0a8fffe, inet4AddressToIntHTH(ipv4Address("192.168.255.254")));
- assertEquals(0xc0a8ffff, inet4AddressToIntHTH(ipv4Address("192.168.255.255")));
- }
-
- @Test
- public void testIntToInet4AddressHTH() {
- assertEquals(ipv4Address("0.0.0.0"), intToInet4AddressHTH(0));
- assertEquals(ipv4Address("255.128.0.0"), intToInet4AddressHTH(0xff800000));
- assertEquals(ipv4Address("10.255.128.0"), intToInet4AddressHTH(0x0aff8000));
- assertEquals(ipv4Address("10.255.254.0"), intToInet4AddressHTH(0x0afffe00));
- assertEquals(ipv4Address("192.168.255.254"), intToInet4AddressHTH(0xc0a8fffe));
- assertEquals(ipv4Address("192.168.255.255"), intToInet4AddressHTH(0xc0a8ffff));
- }
-
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTL() {
- assertEquals(0, prefixLengthToV4NetmaskIntHTL(0));
- assertEquals(0x000080ff /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTL(9));
- assertEquals(0x0080ffff /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTL(17));
- assertEquals(0x00feffff /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTL(23));
- assertEquals(0xfeffffff /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTL(31));
- assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTL(32));
- }
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTH() {
- assertEquals(0, prefixLengthToV4NetmaskIntHTH(0));
- assertEquals(0xff800000 /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTH(9));
- assertEquals(0xffff8000 /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTH(17));
- assertEquals(0xfffffe00 /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTH(23));
- assertEquals(0xfffffffe /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTH(31));
- assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTH(32));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPrefixLengthToV4NetmaskIntHTH_NegativeLength() {
- prefixLengthToV4NetmaskIntHTH(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testPrefixLengthToV4NetmaskIntHTH_LengthTooLarge() {
- prefixLengthToV4NetmaskIntHTH(33);
- }
-
- private void checkAddressMasking(String expectedAddr, String addr, int prefixLength) {
- final int prefix = prefixLengthToV4NetmaskIntHTH(prefixLength);
- final int addrInt = inet4AddressToIntHTH(ipv4Address(addr));
- assertEquals(ipv4Address(expectedAddr), intToInet4AddressHTH(prefix & addrInt));
- }
-
- @Test
- public void testPrefixLengthToV4NetmaskIntHTH_MaskAddr() {
- checkAddressMasking("192.168.0.0", "192.168.128.1", 16);
- checkAddressMasking("255.240.0.0", "255.255.255.255", 12);
- checkAddressMasking("255.255.255.255", "255.255.255.255", 32);
- checkAddressMasking("0.0.0.0", "255.255.255.255", 0);
- }
-
- @Test
- public void testGetImplicitNetmask() {
- assertEquals(8, getImplicitNetmask(ipv4Address("4.2.2.2")));
- assertEquals(8, getImplicitNetmask(ipv4Address("10.5.6.7")));
- assertEquals(16, getImplicitNetmask(ipv4Address("173.194.72.105")));
- assertEquals(16, getImplicitNetmask(ipv4Address("172.23.68.145")));
- assertEquals(24, getImplicitNetmask(ipv4Address("192.0.2.1")));
- assertEquals(24, getImplicitNetmask(ipv4Address("192.168.5.1")));
- assertEquals(32, getImplicitNetmask(ipv4Address("224.0.0.1")));
- assertEquals(32, getImplicitNetmask(ipv4Address("255.6.7.8")));
- }
-
- private void assertInvalidNetworkMask(Inet4Address addr) {
- try {
- netmaskToPrefixLength(addr);
- fail("Invalid netmask " + addr.getHostAddress() + " did not cause exception");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testNetmaskToPrefixLength() {
- assertEquals(0, netmaskToPrefixLength(ipv4Address("0.0.0.0")));
- assertEquals(9, netmaskToPrefixLength(ipv4Address("255.128.0.0")));
- assertEquals(17, netmaskToPrefixLength(ipv4Address("255.255.128.0")));
- assertEquals(23, netmaskToPrefixLength(ipv4Address("255.255.254.0")));
- assertEquals(31, netmaskToPrefixLength(ipv4Address("255.255.255.254")));
- assertEquals(32, netmaskToPrefixLength(ipv4Address("255.255.255.255")));
-
- assertInvalidNetworkMask(ipv4Address("0.0.0.1"));
- assertInvalidNetworkMask(ipv4Address("255.255.255.253"));
- assertInvalidNetworkMask(ipv4Address("255.255.0.255"));
- }
-
- @Test
- public void testGetPrefixMaskAsAddress() {
- assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress());
- assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress());
- assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress());
- assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress());
- }
-
- @Test
- public void testGetBroadcastAddress() {
- assertEquals("192.168.15.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 20).getHostAddress());
- assertEquals("192.255.255.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 8).getHostAddress());
- assertEquals("192.168.0.123",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 32).getHostAddress());
- assertEquals("255.255.255.255",
- getBroadcastAddress(ipv4Address("192.168.0.123"), 0).getHostAddress());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetBroadcastAddress_PrefixTooLarge() {
- getBroadcastAddress(ipv4Address("192.168.0.123"), 33);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetBroadcastAddress_NegativePrefix() {
- getBroadcastAddress(ipv4Address("192.168.0.123"), -1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetPrefixMaskAsAddress_PrefixTooLarge() {
- getPrefixMaskAsInet4Address(33);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testGetPrefixMaskAsAddress_NegativePrefix() {
- getPrefixMaskAsInet4Address(-1);
- }
-
- private Inet4Address ipv4Address(String addr) {
- return (Inet4Address) InetAddresses.parseNumericAddress(addr);
- }
-}
diff --git a/tests/unit/src/android/net/shared/NetdUtilsTest.java b/tests/unit/src/android/net/shared/NetdUtilsTest.java
new file mode 100644
index 0000000..f3ef53a
--- /dev/null
+++ b/tests/unit/src/android/net/shared/NetdUtilsTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.shared;
+
+import static android.net.INetd.LOCAL_NET_ID;
+import static android.system.OsConstants.EBUSY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.net.INetd;
+import android.net.IpPrefix;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class NetdUtilsTest {
+ private static final String IFACE_NAME = "testnet1";
+ private static final IpPrefix TEST_IPPREFIX = new IpPrefix("192.168.42.1/24");
+
+ @Mock private INetd mNetd;
+
+ @Before public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private void setNetworkAddInterfaceOutcome(final Exception cause, int numLoops)
+ throws Exception {
+ // This cannot be an int because local variables referenced from a lambda expression must
+ // be final or effectively final.
+ final Counter myCounter = new Counter();
+ doAnswer((invocation) -> {
+ myCounter.count();
+ if (myCounter.isCounterReached(numLoops)) {
+ if (cause == null) return null;
+
+ throw cause;
+ }
+
+ throw new ServiceSpecificException(EBUSY);
+ }).when(mNetd).networkAddInterface(LOCAL_NET_ID, IFACE_NAME);
+ }
+
+ class Counter {
+ private int mValue = 0;
+
+ private void count() {
+ mValue++;
+ }
+
+ private boolean isCounterReached(int target) {
+ return mValue >= target;
+ }
+ }
+
+ private void verifyTetherInterfaceSucceeds(int expectedTries) throws Exception {
+ setNetworkAddInterfaceOutcome(null, expectedTries);
+
+ NetdUtils.tetherInterface(mNetd, IFACE_NAME, TEST_IPPREFIX);
+ verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
+ verify(mNetd, times(expectedTries)).networkAddInterface(LOCAL_NET_ID, IFACE_NAME);
+ verify(mNetd, times(2)).networkAddRoute(eq(LOCAL_NET_ID), eq(IFACE_NAME), any(), any());
+ verifyNoMoreInteractions(mNetd);
+ reset(mNetd);
+ }
+
+ @Test
+ public void testTetherInterfaceSuccessful() throws Exception {
+ // Expect #networkAddInterface successful at first tries.
+ verifyTetherInterfaceSucceeds(1);
+
+ // Expect #networkAddInterface successful after 10 tries.
+ verifyTetherInterfaceSucceeds(10);
+ }
+
+ private void runTetherInterfaceWithServiceSpecificException(int expectedTries,
+ int expectedCode) throws Exception {
+ setNetworkAddInterfaceOutcome(new ServiceSpecificException(expectedCode), expectedTries);
+
+ try {
+ NetdUtils.tetherInterface(mNetd, IFACE_NAME, TEST_IPPREFIX, 20, 0);
+ fail("Expect throw ServiceSpecificException");
+ } catch (ServiceSpecificException e) {
+ assertEquals(e.errorCode, expectedCode);
+ }
+
+ verifyNetworkAddInterfaceFails(expectedTries);
+ reset(mNetd);
+ }
+
+ private void runTetherInterfaceWithRemoteException(int expectedTries) throws Exception {
+ setNetworkAddInterfaceOutcome(new RemoteException(), expectedTries);
+
+ try {
+ NetdUtils.tetherInterface(mNetd, IFACE_NAME, TEST_IPPREFIX, 20, 0);
+ fail("Expect throw RemoteException");
+ } catch (RemoteException e) { }
+
+ verifyNetworkAddInterfaceFails(expectedTries);
+ reset(mNetd);
+ }
+
+ private void verifyNetworkAddInterfaceFails(int expectedTries) throws Exception {
+ verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
+ verify(mNetd, times(expectedTries)).networkAddInterface(LOCAL_NET_ID, IFACE_NAME);
+ verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), any(), any());
+ verifyNoMoreInteractions(mNetd);
+ }
+
+ @Test
+ public void testTetherInterfaceFailOnNetworkAddInterface() throws Exception {
+ // Test throwing ServiceSpecificException with EBUSY failure.
+ runTetherInterfaceWithServiceSpecificException(20, EBUSY);
+
+ // Test throwing ServiceSpecificException with unexpectedError.
+ final int unexpectedError = 999;
+ runTetherInterfaceWithServiceSpecificException(1, unexpectedError);
+
+ // Test throwing ServiceSpecificException with unexpectedError after 7 tries.
+ runTetherInterfaceWithServiceSpecificException(7, unexpectedError);
+
+ // Test throwing RemoteException.
+ runTetherInterfaceWithRemoteException(1);
+
+ // Test throwing RemoteException after 3 tries.
+ runTetherInterfaceWithRemoteException(3);
+ }
+}
diff --git a/tests/unit/src/com/android/networkstack/metrics/DataStallStatsUtilsTest.kt b/tests/unit/src/com/android/networkstack/metrics/DataStallStatsUtilsTest.kt
index 4c62071..578e6ca 100644
--- a/tests/unit/src/com/android/networkstack/metrics/DataStallStatsUtilsTest.kt
+++ b/tests/unit/src/com/android/networkstack/metrics/DataStallStatsUtilsTest.kt
@@ -16,18 +16,33 @@
package com.android.networkstack.metrics
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.captiveportal.CaptivePortalProbeResult
+import android.net.metrics.ValidationProbeEvent
+import android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS
+import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
+import com.android.server.connectivity.nano.CellularData
import com.android.server.connectivity.nano.DataStallEventProto
+import com.android.server.connectivity.nano.DnsEvent
+import com.google.protobuf.nano.MessageNano
+import java.util.Arrays
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import android.net.metrics.ValidationProbeEvent
+import org.mockito.ArgumentMatchers.eq
@RunWith(AndroidJUnit4::class)
@SmallTest
class DataStallStatsUtilsTest {
+ private val TEST_ELAPSED_TIME_MS = 123456789L
+ private val TEST_MCCMNC = "123456"
+ private val TEST_SIGNAL_STRENGTH = -100
+ private val RETURN_CODE_DNS_TIMEOUT = 255
+
@Test
fun testProbeResultToEnum() {
assertEquals(DataStallStatsUtils.probeResultToEnum(null), DataStallEventProto.INVALID)
@@ -53,4 +68,61 @@
CaptivePortalProbeResult.PORTAL_CODE, ValidationProbeEvent.PROBE_HTTPS)),
DataStallEventProto.PORTAL)
}
+
+ @Test
+ fun testWrite() {
+ val session = mockitoSession().spyStatic(NetworkStackStatsLog::class.java).startMocking()
+ val stats = DataStallDetectionStats.Builder()
+ .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
+ .setNetworkType(TRANSPORT_CELLULAR)
+ .setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */,
+ true /* roaming */,
+ TEST_MCCMNC /* networkMccmnc */,
+ TEST_MCCMNC /* simMccmnc */,
+ TEST_SIGNAL_STRENGTH /* signalStrength */)
+ .setTcpFailRate(90)
+ .setTcpSentSinceLastRecv(10)
+ generateTimeoutDnsEvent(stats, count = 5)
+ DataStallStatsUtils.write(stats.build(), CaptivePortalProbeResult.PARTIAL)
+
+ verify { NetworkStackStatsLog.write(
+ eq(NetworkStackStatsLog.DATA_STALL_EVENT),
+ eq(DATA_STALL_EVALUATION_TYPE_DNS),
+ eq(DataStallEventProto.PARTIAL),
+ eq(TRANSPORT_CELLULAR),
+ eq(DataStallDetectionStats.emptyWifiInfoIfNull(null)),
+ eq(makeTestCellDataNano()),
+ eq(makeTestDnsTimeoutNano(5)),
+ eq(90) /* tcpFailRate */,
+ eq(10) /* tcpSentSinceLastRecv */) }
+
+ session.finishMocking()
+ }
+
+ private fun makeTestDnsTimeoutNano(timeoutCount: Int): ByteArray? {
+ // Make an expected nano dns message.
+ val event = DnsEvent()
+ event.dnsReturnCode = IntArray(timeoutCount)
+ event.dnsTime = LongArray(timeoutCount)
+ Arrays.fill(event.dnsReturnCode, RETURN_CODE_DNS_TIMEOUT)
+ Arrays.fill(event.dnsTime, TEST_ELAPSED_TIME_MS)
+ return MessageNano.toByteArray(event)
+ }
+
+ private fun makeTestCellDataNano(): ByteArray? {
+ // Make an expected nano cell data message.
+ val data = CellularData()
+ data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_LTE
+ data.networkMccmnc = TEST_MCCMNC
+ data.simMccmnc = TEST_MCCMNC
+ data.isRoaming = true
+ data.signalStrength = TEST_SIGNAL_STRENGTH
+ return MessageNano.toByteArray(data)
+ }
+
+ private fun generateTimeoutDnsEvent(stats: DataStallDetectionStats.Builder, count: Int) {
+ repeat(count) {
+ stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, TEST_ELAPSED_TIME_MS)
+ }
+ }
}
diff --git a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt b/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
index 9de828f..c054b3a 100644
--- a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
+++ b/tests/unit/src/com/android/server/NetworkStackServiceTest.kt
@@ -29,11 +29,11 @@
import android.net.dhcp.IDhcpServerCallbacks
import android.net.ip.IIpClientCallbacks
import android.net.ip.IpClient
-import android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH
import android.os.Build
import android.os.IBinder
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH
import com.android.server.NetworkStackService.Dependencies
import com.android.server.NetworkStackService.NetworkStackConnector
import com.android.server.NetworkStackService.PermissionChecker