Merge "Make ARM TVs running 32-bit userspace boot on V with new kernels." into main
diff --git a/framework-t/src/android/net/TrafficStats.java b/framework-t/src/android/net/TrafficStats.java
index caf3152..81f2cf9 100644
--- a/framework-t/src/android/net/TrafficStats.java
+++ b/framework-t/src/android/net/TrafficStats.java
@@ -184,7 +184,9 @@
@GuardedBy("TrafficStats.class")
private static INetworkStatsService sStatsService;
- @GuardedBy("TrafficStats.class")
+
+ // The variable will only be accessed in the test, which is effectively
+ // single-threaded.
private static INetworkStatsService sStatsServiceForTest = null;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
@@ -209,9 +211,7 @@
*/
@VisibleForTesting(visibility = PRIVATE)
public static void setServiceForTest(INetworkStatsService statsService) {
- synchronized (TrafficStats.class) {
- sStatsServiceForTest = statsService;
- }
+ sStatsServiceForTest = statsService;
}
/**
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 0d0f6fc..f3b97bc 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -121,7 +121,6 @@
import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION;
import static android.os.Process.INVALID_UID;
import static android.os.Process.VPN_UID;
-import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static android.system.OsConstants.ETH_P_ALL;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
@@ -149,6 +148,7 @@
import static com.android.server.connectivity.ConnectivityFlags.CELLULAR_DATA_INACTIVITY_TIMEOUT;
import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS;
import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING;
+import static com.android.server.connectivity.ConnectivityFlags.NAMESPACE_TETHERING_BOOT;
import static com.android.server.connectivity.ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS;
import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI;
import static com.android.server.connectivity.ConnectivityFlags.WIFI_DATA_INACTIVITY_TIMEOUT;
@@ -1615,13 +1615,13 @@
/** Returns the data inactivity timeout to be used for cellular networks */
public int getDefaultCellularDataInactivityTimeout() {
- return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING,
+ return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT,
CELLULAR_DATA_INACTIVITY_TIMEOUT, 10);
}
/** Returns the data inactivity timeout to be used for WiFi networks */
public int getDefaultWifiDataInactivityTimeout() {
- return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING,
+ return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT,
WIFI_DATA_INACTIVITY_TIMEOUT, 15);
}
diff --git a/service/src/com/android/server/connectivity/ConnectivityFlags.java b/service/src/com/android/server/connectivity/ConnectivityFlags.java
index 93335f1..136ea81 100644
--- a/service/src/com/android/server/connectivity/ConnectivityFlags.java
+++ b/service/src/com/android/server/connectivity/ConnectivityFlags.java
@@ -26,6 +26,11 @@
*/
public final class ConnectivityFlags {
/**
+ * Boot namespace for this module. Values from this should only be read at boot.
+ */
+ public static final String NAMESPACE_TETHERING_BOOT = "tethering_boot";
+
+ /**
* Minimum module version at which to avoid rematching all requests when a network request is
* registered, and rematch only the registered requests instead.
*/
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
index 781a04e..dfb2053 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
@@ -150,6 +150,8 @@
return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer);
case NetlinkConstants.RTM_NEWNDUSEROPT:
return (NetlinkMessage) NduseroptMessage.parse(nlmsghdr, byteBuffer);
+ case NetlinkConstants.RTM_NEWPREFIX:
+ return (NetlinkMessage) RtNetlinkPrefixMessage.parse(nlmsghdr, byteBuffer);
default: return null;
}
}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkPrefixMessage.java b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkPrefixMessage.java
new file mode 100644
index 0000000..30c63fb
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkPrefixMessage.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 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 com.android.net.module.util.netlink;
+
+import android.net.IpPrefix;
+import android.system.OsConstants;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import java.net.Inet6Address;
+import java.nio.ByteBuffer;
+
+/**
+ * A NetlinkMessage subclass for rtnetlink address messages.
+ *
+ * RtNetlinkPrefixMessage.parse() must be called with a ByteBuffer that contains exactly one
+ * netlink message.
+ *
+ * see also:
+ *
+ * include/uapi/linux/rtnetlink.h
+ *
+ * @hide
+ */
+public class RtNetlinkPrefixMessage extends NetlinkMessage {
+ public static final short PREFIX_ADDRESS = 1;
+ public static final short PREFIX_CACHEINFO = 2;
+
+ @NonNull
+ private StructPrefixMsg mPrefixmsg;
+ @NonNull
+ private IpPrefix mPrefix;
+ private long mPreferredLifetime;
+ private long mValidLifetime;
+
+ @VisibleForTesting
+ public RtNetlinkPrefixMessage(@NonNull final StructNlMsgHdr header,
+ @NonNull final StructPrefixMsg prefixmsg,
+ @NonNull final IpPrefix prefix,
+ long preferred, long valid) {
+ super(header);
+ mPrefixmsg = prefixmsg;
+ mPrefix = prefix;
+ mPreferredLifetime = preferred;
+ mValidLifetime = valid;
+ }
+
+ private RtNetlinkPrefixMessage(@NonNull StructNlMsgHdr header) {
+ this(header, null, null, 0 /* preferredLifetime */, 0 /* validLifetime */);
+ }
+
+ @NonNull
+ public StructPrefixMsg getPrefixMsg() {
+ return mPrefixmsg;
+ }
+
+ @NonNull
+ public IpPrefix getPrefix() {
+ return mPrefix;
+ }
+
+ public long getPreferredLifetime() {
+ return mPreferredLifetime;
+ }
+
+ public long getValidLifetime() {
+ return mValidLifetime;
+ }
+
+ /**
+ * Parse rtnetlink prefix message from {@link ByteBuffer}. This method must be called with a
+ * ByteBuffer that contains exactly one netlink message.
+ *
+ * RTM_NEWPREFIX Message Format:
+ * +----------+- - -+-------------+- - -+---------------------+-----------------------+
+ * | nlmsghdr | Pad | prefixmsg | Pad | PREFIX_ADDRESS attr | PREFIX_CACHEINFO attr |
+ * +----------+- - -+-------------+- - -+---------------------+-----------------------+
+ *
+ * @param header netlink message header.
+ * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes.
+ */
+ @Nullable
+ public static RtNetlinkPrefixMessage parse(@NonNull final StructNlMsgHdr header,
+ @NonNull final ByteBuffer byteBuffer) {
+ try {
+ final RtNetlinkPrefixMessage msg = new RtNetlinkPrefixMessage(header);
+ msg.mPrefixmsg = StructPrefixMsg.parse(byteBuffer);
+
+ // PREFIX_ADDRESS
+ final int baseOffset = byteBuffer.position();
+ StructNlAttr nlAttr = StructNlAttr.findNextAttrOfType(PREFIX_ADDRESS, byteBuffer);
+ if (nlAttr == null) return null;
+ final Inet6Address addr = (Inet6Address) nlAttr.getValueAsInetAddress();
+ if (addr == null) return null;
+ msg.mPrefix = new IpPrefix(addr, msg.mPrefixmsg.prefix_len);
+
+ // PREFIX_CACHEINFO
+ byteBuffer.position(baseOffset);
+ nlAttr = StructNlAttr.findNextAttrOfType(PREFIX_CACHEINFO, byteBuffer);
+ if (nlAttr == null) return null;
+ final ByteBuffer buffer = nlAttr.getValueAsByteBuffer();
+ if (buffer == null) return null;
+ final StructPrefixCacheInfo cacheinfo = StructPrefixCacheInfo.parse(buffer);
+ msg.mPreferredLifetime = cacheinfo.preferred_time;
+ msg.mValidLifetime = cacheinfo.valid_time;
+
+ return msg;
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Write a rtnetlink prefix message to {@link ByteBuffer}.
+ */
+ @VisibleForTesting
+ protected void pack(ByteBuffer byteBuffer) {
+ getHeader().pack(byteBuffer);
+ mPrefixmsg.pack(byteBuffer);
+
+ // PREFIX_ADDRESS attribute
+ final StructNlAttr prefixAddress =
+ new StructNlAttr(PREFIX_ADDRESS, mPrefix.getRawAddress());
+ prefixAddress.pack(byteBuffer);
+
+ // PREFIX_CACHEINFO attribute
+ final StructPrefixCacheInfo cacheinfo =
+ new StructPrefixCacheInfo(mPreferredLifetime, mValidLifetime);
+ final StructNlAttr prefixCacheinfo =
+ new StructNlAttr(PREFIX_CACHEINFO, cacheinfo.writeToBytes());
+ prefixCacheinfo.pack(byteBuffer);
+ }
+
+ @Override
+ public String toString() {
+ return "RtNetlinkPrefixMessage{ "
+ + "nlmsghdr{" + mHeader.toString(OsConstants.NETLINK_ROUTE) + "}, "
+ + "prefixmsg{" + mPrefixmsg.toString() + "}, "
+ + "IP Prefix{" + mPrefix + "}, "
+ + "preferred lifetime{" + mPreferredLifetime + "}, "
+ + "valid lifetime{" + mValidLifetime + "} "
+ + "}";
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
index 4ed3afd..7244803 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
@@ -183,17 +183,17 @@
@Test
fun testGetIndexForValue() {
- val sparseArray = SparseArray<String>();
- sparseArray.put(5, "hello");
- sparseArray.put(10, "abcd");
- sparseArray.put(20, null);
+ val sparseArray = SparseArray<String>()
+ sparseArray.put(5, "hello")
+ sparseArray.put(10, "abcd")
+ sparseArray.put(20, null)
- val value1 = "abcd";
+ val value1 = "abcd"
val value1Copy = String(value1.toCharArray())
- val value2 = null;
+ val value2 = null
- assertEquals(1, CollectionUtils.getIndexForValue(sparseArray, value1));
- assertEquals(1, CollectionUtils.getIndexForValue(sparseArray, value1Copy));
- assertEquals(2, CollectionUtils.getIndexForValue(sparseArray, value2));
+ assertEquals(1, CollectionUtils.getIndexForValue(sparseArray, value1))
+ assertEquals(1, CollectionUtils.getIndexForValue(sparseArray, value1Copy))
+ assertEquals(2, CollectionUtils.getIndexForValue(sparseArray, value2))
}
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkPrefixMessageTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkPrefixMessageTest.java
new file mode 100644
index 0000000..b1779cb
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkPrefixMessageTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2024 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 com.android.net.module.util.netlink;
+
+import static android.system.OsConstants.NETLINK_ROUTE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.IpPrefix;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RtNetlinkPrefixMessageTest {
+ private static final IpPrefix TEST_PREFIX = new IpPrefix("2001:db8:1:1::/64");
+
+ // An example of the full RTM_NEWPREFIX message.
+ private static final String RTM_NEWPREFIX_HEX =
+ "3C000000340000000000000000000000" // struct nlmsghr
+ + "0A0000002F00000003400300" // struct prefixmsg
+ + "1400010020010DB8000100010000000000000000" // PREFIX_ADDRESS
+ + "0C000200803A0900008D2700"; // PREFIX_CACHEINFO
+
+ private ByteBuffer toByteBuffer(final String hexString) {
+ return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString));
+ }
+
+ @Test
+ public void testParseRtmNewPrefix() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkPrefixMessage);
+ final RtNetlinkPrefixMessage prefixmsg = (RtNetlinkPrefixMessage) msg;
+
+ final StructNlMsgHdr hdr = prefixmsg.getHeader();
+ assertNotNull(hdr);
+ assertEquals(60, hdr.nlmsg_len);
+ assertEquals(NetlinkConstants.RTM_NEWPREFIX, hdr.nlmsg_type);
+ assertEquals(0, hdr.nlmsg_flags);
+ assertEquals(0, hdr.nlmsg_seq);
+ assertEquals(0, hdr.nlmsg_pid);
+
+ final StructPrefixMsg prefixmsgHdr = prefixmsg.getPrefixMsg();
+ assertNotNull(prefixmsgHdr);
+ assertEquals((byte) OsConstants.AF_INET6, prefixmsgHdr.prefix_family);
+ assertEquals(3, prefixmsgHdr.prefix_type);
+ assertEquals(64, prefixmsgHdr.prefix_len);
+ assertEquals(0x03, prefixmsgHdr.prefix_flags);
+ assertEquals(0x2F, prefixmsgHdr.prefix_ifindex);
+
+ assertEquals(prefixmsg.getPrefix(), TEST_PREFIX);
+ assertEquals(604800L, prefixmsg.getPreferredLifetime());
+ assertEquals(2592000L, prefixmsg.getValidLifetime());
+ }
+
+ @Test
+ public void testPackRtmNewPrefix() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkPrefixMessage);
+ final RtNetlinkPrefixMessage prefixmsg = (RtNetlinkPrefixMessage) msg;
+
+ final ByteBuffer packBuffer = ByteBuffer.allocate(60);
+ packBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ prefixmsg.pack(packBuffer);
+ assertEquals(RTM_NEWPREFIX_HEX, HexDump.toHexString(packBuffer.array()));
+ }
+
+ private static final String RTM_NEWPREFIX_WITHOUT_PREFIX_ADDRESS_HEX =
+ "24000000340000000000000000000000" // struct nlmsghr
+ + "0A0000002F00000003400300" // struct prefixmsg
+ + "0C000200803A0900008D2700"; // PREFIX_CACHEINFO
+
+ @Test
+ public void testParseRtmNewPrefix_withoutPrefixAddressAttribute() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_WITHOUT_PREFIX_ADDRESS_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNull(msg);
+ }
+
+ private static final String RTM_NEWPREFIX_WITHOUT_PREFIX_CACHEINFO_HEX =
+ "30000000340000000000000000000000" // struct nlmsghr
+ + "0A0000002F00000003400300" // struct prefixmsg
+ + "140001002A0079E10ABCF6050000000000000000"; // PREFIX_ADDRESS
+
+ @Test
+ public void testParseRtmNewPrefix_withoutPrefixCacheinfoAttribute() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_WITHOUT_PREFIX_CACHEINFO_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNull(msg);
+ }
+
+ private static final String RTM_NEWPREFIX_TRUNCATED_PREFIX_ADDRESS_HEX =
+ "3C000000340000000000000000000000" // struct nlmsghr
+ + "0A0000002F00000003400300" // struct prefixmsg
+ + "140001002A0079E10ABCF605000000000000" // PREFIX_ADDRESS (truncated)
+ + "0C000200803A0900008D2700"; // PREFIX_CACHEINFO
+
+ @Test
+ public void testParseRtmNewPrefix_truncatedPrefixAddressAttribute() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_TRUNCATED_PREFIX_ADDRESS_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNull(msg);
+ }
+
+ private static final String RTM_NEWPREFIX_TRUNCATED_PREFIX_CACHEINFO_HEX =
+ "3C000000340000000000000000000000" // struct nlmsghr
+ + "0A0000002F00000003400300" // struct prefixmsg
+ + "140001002A0079E10ABCF6050000000000000000" // PREFIX_ADDRESS
+ + "0C000200803A0900008D"; // PREFIX_CACHEINFO (truncated)
+
+ @Test
+ public void testParseRtmNewPrefix_truncatedPrefixCacheinfoAttribute() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_TRUNCATED_PREFIX_CACHEINFO_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNull(msg);
+ }
+
+ @Test
+ public void testToString() {
+ final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWPREFIX_HEX);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer, NETLINK_ROUTE);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkPrefixMessage);
+ final RtNetlinkPrefixMessage prefixmsg = (RtNetlinkPrefixMessage) msg;
+ final String expected = "RtNetlinkPrefixMessage{ "
+ + "nlmsghdr{StructNlMsgHdr{ nlmsg_len{60}, nlmsg_type{52(RTM_NEWPREFIX)}, "
+ + "nlmsg_flags{0()}, nlmsg_seq{0}, nlmsg_pid{0} }}, "
+ + "prefixmsg{prefix_family: 10, prefix_ifindex: 47, prefix_type: 3, "
+ + "prefix_len: 64, prefix_flags: 3}, "
+ + "IP Prefix{2001:db8:1:1::/64}, "
+ + "preferred lifetime{604800}, valid lifetime{2592000} }";
+ assertEquals(expected, prefixmsg.toString());
+ }
+}
diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
index 2a26ef8..86aa8f1 100644
--- a/staticlibs/testutils/Android.bp
+++ b/staticlibs/testutils/Android.bp
@@ -98,6 +98,7 @@
"cts",
"mts-networking",
"mts-tethering",
+ "mcts-tethering",
],
device_common_data: [":ConnectivityTestPreparer"],
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
index 10adee0..65daf57 100644
--- a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java
@@ -114,7 +114,7 @@
} catch (ClassNotFoundException e) {
/* not vulnerable if hidden API no longer available */
return;
- } catch (NoSuchMethodException e) {
+ } catch (NoSuchMethodException | NoSuchMethodError e) {
/* not vulnerable if hidden API no longer available */
return;
} catch (RemoteException e) {