Merge "API changes for addressing API Council comments." into tm-dev
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 2b70bcd..b709693 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -38,10 +38,11 @@
apex {
name: "com.android.tethering",
- defaults: ["ConnectivityApexDefaults"],
+ defaults: [
+ "ConnectivityApexDefaults",
+ "r-launched-apex-module",
+ ],
compile_multilib: "both",
- updatable: true,
- min_sdk_version: "30",
bootclasspath_fragments: [
"com.android.tethering-bootclasspath-fragment",
],
diff --git a/Tethering/src/android/net/ip/DadProxy.java b/Tethering/src/android/net/ip/DadProxy.java
index e2976b7..36ecfe3 100644
--- a/Tethering/src/android/net/ip/DadProxy.java
+++ b/Tethering/src/android/net/ip/DadProxy.java
@@ -16,11 +16,12 @@
package android.net.ip;
-import android.net.util.InterfaceParams;
import android.os.Handler;
import androidx.annotation.VisibleForTesting;
+import com.android.net.module.util.InterfaceParams;
+
/**
* Basic Duplicate address detection proxy.
*
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 2bb19db..acd2625 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -46,7 +46,6 @@
import android.net.dhcp.IDhcpServer;
import android.net.ip.IpNeighborMonitor.NeighborEvent;
import android.net.ip.RouterAdvertisementDaemon.RaParams;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.Looper;
@@ -63,11 +62,13 @@
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetdUtils;
import com.android.networkstack.tethering.BpfCoordinator;
import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
import com.android.networkstack.tethering.PrivateAddressCoordinator;
+import com.android.networkstack.tethering.TetheringConfiguration;
import com.android.networkstack.tethering.util.InterfaceSet;
import com.android.networkstack.tethering.util.PrefixUtils;
@@ -285,8 +286,8 @@
public IpServer(
String ifaceName, Looper looper, int interfaceType, SharedLog log,
INetd netd, @NonNull BpfCoordinator coordinator, Callback callback,
- boolean usingLegacyDhcp, boolean usingBpfOffload,
- PrivateAddressCoordinator addressCoordinator, Dependencies deps) {
+ TetheringConfiguration config, PrivateAddressCoordinator addressCoordinator,
+ Dependencies deps) {
super(ifaceName, looper);
mLog = log.forSubComponent(ifaceName);
mNetd = netd;
@@ -296,8 +297,8 @@
mIfaceName = ifaceName;
mInterfaceType = interfaceType;
mLinkProperties = new LinkProperties();
- mUsingLegacyDhcp = usingLegacyDhcp;
- mUsingBpfOffload = usingBpfOffload;
+ mUsingLegacyDhcp = config.useLegacyDhcpServer();
+ mUsingBpfOffload = config.isBpfOffloadEnabled();
mPrivateAddressCoordinator = addressCoordinator;
mDeps = deps;
resetLinkProperties();
diff --git a/Tethering/src/android/net/ip/NeighborPacketForwarder.java b/Tethering/src/android/net/ip/NeighborPacketForwarder.java
index 27e59a1..723bd63 100644
--- a/Tethering/src/android/net/ip/NeighborPacketForwarder.java
+++ b/Tethering/src/android/net/ip/NeighborPacketForwarder.java
@@ -24,13 +24,13 @@
import static android.system.OsConstants.SOCK_NONBLOCK;
import static android.system.OsConstants.SOCK_RAW;
-import android.net.util.InterfaceParams;
import android.net.util.SocketUtils;
import android.os.Handler;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.PacketReader;
import com.android.networkstack.tethering.util.TetheringUtils;
diff --git a/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java b/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
index 74f9369..c452e55 100644
--- a/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
+++ b/Tethering/src/android/net/ip/RouterAdvertisementDaemon.java
@@ -37,7 +37,6 @@
import android.net.LinkAddress;
import android.net.MacAddress;
import android.net.TrafficStats;
-import android.net.util.InterfaceParams;
import android.net.util.SocketUtils;
import android.system.ErrnoException;
import android.system.Os;
@@ -45,6 +44,7 @@
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.structs.Icmpv6Header;
import com.android.net.module.util.structs.LlaOption;
import com.android.net.module.util.structs.MtuOption;
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 6550de2..2ef1d5b 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -44,7 +44,6 @@
import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
import android.net.ip.IpServer;
import android.net.netstats.provider.NetworkStatsProvider;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.SystemClock;
@@ -64,8 +63,9 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
-import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.U32;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.netlink.ConntrackMessage;
@@ -1177,22 +1177,13 @@
}
}
- /**
- * Simple struct that only contains a u32. Must be public because Struct needs access to it.
- * TODO: make this a public inner class of Struct so anyone can use it as, e.g., Struct.U32?
- */
- public static class U32Struct extends Struct {
- @Struct.Field(order = 0, type = Struct.Type.U32)
- public long val;
- }
-
private void dumpCounters(@NonNull IndentingPrintWriter pw) {
if (!mDeps.isAtLeastS()) {
pw.println("No counter support");
return;
}
- try (BpfMap<U32Struct, U32Struct> map = new BpfMap<>(TETHER_ERROR_MAP_PATH,
- BpfMap.BPF_F_RDONLY, U32Struct.class, U32Struct.class)) {
+ try (BpfMap<U32, U32> map = new BpfMap<>(TETHER_ERROR_MAP_PATH, BpfMap.BPF_F_RDONLY,
+ U32.class, U32.class)) {
map.forEach((k, v) -> {
String counterName;
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfUtils.java b/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
index 77efb51..3d2dfaa 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfUtils.java
@@ -20,10 +20,9 @@
import static com.android.networkstack.tethering.util.TetheringUtils.getTetheringJniLibraryName;
-import android.net.util.InterfaceParams;
-
import androidx.annotation.NonNull;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.TcUtils;
import java.io.IOException;
diff --git a/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
index c1e7127..cc2422f 100644
--- a/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
@@ -90,11 +90,8 @@
mCachedAddresses.put(TETHERING_BLUETOOTH, new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS));
mCachedAddresses.put(TETHERING_WIFI_P2P, new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS));
- mTetheringPrefixes = new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16")));
- if (config.isSelectAllPrefixRangeEnabled()) {
- mTetheringPrefixes.add(new IpPrefix("172.16.0.0/12"));
- mTetheringPrefixes.add(new IpPrefix("10.0.0.0/8"));
- }
+ mTetheringPrefixes = new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16"),
+ new IpPrefix("172.16.0.0/12"), new IpPrefix("10.0.0.0/8")));
}
/**
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 301a682..bb9b6fb 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1533,16 +1533,28 @@
return mConfig;
}
- boolean hasTetherableConfiguration() {
- final TetheringConfiguration cfg = mConfig;
- final boolean hasDownstreamConfiguration =
- (cfg.tetherableUsbRegexs.length != 0)
- || (cfg.tetherableWifiRegexs.length != 0)
- || (cfg.tetherableBluetoothRegexs.length != 0);
- final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
- || cfg.chooseUpstreamAutomatically;
+ boolean hasAnySupportedDownstream() {
+ if ((mConfig.tetherableUsbRegexs.length != 0)
+ || (mConfig.tetherableWifiRegexs.length != 0)
+ || (mConfig.tetherableBluetoothRegexs.length != 0)) {
+ return true;
+ }
- return hasDownstreamConfiguration && hasUpstreamConfiguration;
+ // Before T, isTetheringSupported would return true if wifi, usb and bluetooth tethering are
+ // disabled (whole tethering settings would be hidden). This means tethering would also not
+ // support wifi p2p, ethernet tethering and mirrorlink. This is wrong but probably there are
+ // some devices in the field rely on this to disable tethering entirely.
+ if (!SdkLevel.isAtLeastT()) return false;
+
+ return (mConfig.tetherableWifiP2pRegexs.length != 0)
+ || (mConfig.tetherableNcmRegexs.length != 0)
+ || isEthernetSupported();
+ }
+
+ // TODO: using EtherentManager new API to check whether ethernet is supported when the API is
+ // ready to use.
+ private boolean isEthernetSupported() {
+ return mContext.getSystemService(Context.ETHERNET_SERVICE) != null;
}
void setUsbTethering(boolean enable, IIntResultListener listener) {
@@ -1745,7 +1757,7 @@
// TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
// Legacy DHCP server is disabled if passed an empty ranges array
- final String[] dhcpRanges = cfg.enableLegacyDhcpServer
+ final String[] dhcpRanges = cfg.useLegacyDhcpServer()
? cfg.legacyDhcpRanges : new String[0];
try {
NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
@@ -2463,7 +2475,7 @@
final boolean tetherEnabledInSettings = tetherSupported
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
- return tetherEnabledInSettings && hasTetherableConfiguration()
+ return tetherEnabledInSettings && hasAnySupportedDownstream()
&& !isProvisioningNeededButUnavailable();
}
@@ -2722,8 +2734,7 @@
mLog.i("adding IpServer for: " + iface);
final TetherState tetherState = new TetherState(
new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
- makeControlCallback(), mConfig.enableLegacyDhcpServer,
- mConfig.isBpfOffloadEnabled(), mPrivateAddressCoordinator,
+ makeControlCallback(), mConfig, mPrivateAddressCoordinator,
mDeps.getIpServerDependencies()), isNcm);
mTetherStates.put(iface, tetherState);
tetherState.ipServer.start();
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index dd0d567..eaf8589 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -99,13 +99,6 @@
"use_legacy_wifi_p2p_dedicated_ip";
/**
- * Flag use to enable select all prefix ranges feature.
- * TODO: Remove this flag if there are no problems after M-2020-12 rolls out.
- */
- public static final String TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES =
- "tether_enable_select_all_prefix_ranges";
-
- /**
* Experiment flag to force choosing upstreams automatically.
*
* This setting is intended to help force-enable the feature on OEM devices that disabled it
@@ -143,7 +136,6 @@
public final Collection<Integer> preferredUpstreamIfaceTypes;
public final String[] legacyDhcpRanges;
public final String[] defaultIPv4DNS;
- public final boolean enableLegacyDhcpServer;
public final String[] provisioningApp;
public final String provisioningAppNoUi;
@@ -152,12 +144,12 @@
public final int activeDataSubId;
+ private final boolean mEnableLegacyDhcpServer;
private final int mOffloadPollInterval;
// TODO: Add to TetheringConfigurationParcel if required.
private final boolean mEnableBpfOffload;
private final boolean mEnableWifiP2pDedicatedIp;
- private final boolean mEnableSelectAllPrefixRange;
private final int mUsbTetheringFunction;
protected final ContentResolver mContentResolver;
@@ -203,7 +195,7 @@
legacyDhcpRanges = getLegacyDhcpRanges(res);
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
mEnableBpfOffload = getEnableBpfOffload(res);
- enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
+ mEnableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
provisioningAppNoUi = getResourceString(res,
@@ -222,14 +214,14 @@
R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip,
false /* defaultValue */);
- // Flags should normally not be booleans, but this is a kill-switch flag that is only used
- // to turn off the feature, so binary rollback problems do not apply.
- mEnableSelectAllPrefixRange = getDeviceConfigBoolean(
- TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES, true /* defaultValue */);
-
configLog.log(toString());
}
+ /** Check whether using legacy dhcp server. */
+ public boolean useLegacyDhcpServer() {
+ return mEnableLegacyDhcpServer;
+ }
+
/** Check whether using ncm for usb tethering */
public boolean isUsingNcm() {
return mUsbTetheringFunction == TETHER_USB_NCM_FUNCTION;
@@ -313,14 +305,11 @@
pw.println(mEnableBpfOffload);
pw.print("enableLegacyDhcpServer: ");
- pw.println(enableLegacyDhcpServer);
+ pw.println(mEnableLegacyDhcpServer);
pw.print("enableWifiP2pDedicatedIp: ");
pw.println(mEnableWifiP2pDedicatedIp);
- pw.print("mEnableSelectAllPrefixRange: ");
- pw.println(mEnableSelectAllPrefixRange);
-
pw.print("mUsbTetheringFunction: ");
pw.println(isUsingNcm() ? "NCM" : "RNDIS");
}
@@ -342,7 +331,7 @@
sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
sj.add(String.format("enableBpfOffload:%s", mEnableBpfOffload));
- sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer));
+ sj.add(String.format("enableLegacyDhcpServer:%s", mEnableLegacyDhcpServer));
return String.format("TetheringConfiguration{%s}", sj.toString());
}
@@ -384,10 +373,6 @@
return mEnableBpfOffload;
}
- public boolean isSelectAllPrefixRangeEnabled() {
- return mEnableSelectAllPrefixRange;
- }
-
private int getUsbTetheringFunction(Resources res) {
final int valueFromRes = getResourceInteger(res, R.integer.config_tether_usb_functions,
TETHER_USB_RNDIS_FUNCTION /* defaultValue */);
@@ -596,7 +581,7 @@
parcel.legacyDhcpRanges = legacyDhcpRanges;
parcel.defaultIPv4DNS = defaultIPv4DNS;
- parcel.enableLegacyDhcpServer = enableLegacyDhcpServer;
+ parcel.enableLegacyDhcpServer = mEnableLegacyDhcpServer;
parcel.provisioningApp = provisioningApp;
parcel.provisioningAppNoUi = provisioningAppNoUi;
parcel.provisioningCheckPeriod = provisioningCheckPeriod;
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
index c1a747e..9224213 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
@@ -94,13 +94,6 @@
public abstract IpServer.Dependencies getIpServerDependencies();
/**
- * Indicates whether tethering is supported on the device.
- */
- public boolean isTetheringSupported() {
- return true;
- }
-
- /**
* Get a reference to the EntitlementManager to be used by tethering.
*/
public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
diff --git a/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java b/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
index ef254ff..4525568 100644
--- a/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
+++ b/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java
@@ -29,7 +29,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import android.app.UiAutomation;
import android.content.Context;
@@ -81,12 +80,8 @@
mUiAutomation.dropShellPermissionIdentity();
}
- private static final String TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES =
- "tether_enable_select_all_prefix_ranges";
@Test
public void testSwitchBasePrefixRangeWhenConflict() throws Exception {
- assumeTrue(isFeatureEnabled(TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES, true));
-
addressConflictTest(true);
}
diff --git a/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java b/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
index eb9cf71..ebf09ed 100644
--- a/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
+++ b/Tethering/tests/privileged/src/android/net/ip/DadProxyTest.java
@@ -30,7 +30,6 @@
import android.net.INetd;
import android.net.InetAddresses;
import android.net.MacAddress;
-import android.net.util.InterfaceParams;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -40,6 +39,7 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+import com.android.net.module.util.InterfaceParams;
import com.android.networkstack.tethering.util.TetheringUtils;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
diff --git a/Tethering/tests/privileged/src/android/net/ip/RouterAdvertisementDaemonTest.java b/Tethering/tests/privileged/src/android/net/ip/RouterAdvertisementDaemonTest.java
index 34f3e0e..328e3fb 100644
--- a/Tethering/tests/privileged/src/android/net/ip/RouterAdvertisementDaemonTest.java
+++ b/Tethering/tests/privileged/src/android/net/ip/RouterAdvertisementDaemonTest.java
@@ -44,7 +44,6 @@
import android.net.MacAddress;
import android.net.RouteInfo;
import android.net.ip.RouterAdvertisementDaemon.RaParams;
-import android.net.util.InterfaceParams;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -54,6 +53,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.Ipv6Utils;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.Struct;
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index a3c46c2..6488421 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -86,7 +86,6 @@
import android.net.ip.IpNeighborMonitor.NeighborEvent;
import android.net.ip.IpNeighborMonitor.NeighborEventConsumer;
import android.net.ip.RouterAdvertisementDaemon.RaParams;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Build;
import android.os.Handler;
@@ -100,6 +99,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
@@ -228,9 +228,11 @@
doReturn(mIpNeighborMonitor).when(mDependencies).getIpNeighborMonitor(any(), any(),
neighborCaptor.capture());
+ when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(usingBpfOffload);
+ when(mTetherConfig.useLegacyDhcpServer()).thenReturn(usingLegacyDhcp);
mIpServer = new IpServer(
IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator,
- mCallback, usingLegacyDhcp, usingBpfOffload, mAddressCoordinator, mDependencies);
+ mCallback, mTetherConfig, mAddressCoordinator, mDependencies);
mIpServer.start();
mNeighborEventConsumer = neighborCaptor.getValue();
@@ -281,7 +283,8 @@
when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
when(mAddressCoordinator.requestDownstreamAddress(any(), anyBoolean())).thenReturn(
mTestAddress);
- when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(true /* default value */);
+ when(mTetherConfig.isBpfOffloadEnabled()).thenReturn(DEFAULT_USING_BPF_OFFLOAD);
+ when(mTetherConfig.useLegacyDhcpServer()).thenReturn(false /* default value */);
mBpfDeps = new BpfCoordinator.Dependencies() {
@NonNull
@@ -360,8 +363,8 @@
when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
.thenReturn(mIpNeighborMonitor);
mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
- mNetd, mBpfCoordinator, mCallback, false /* usingLegacyDhcp */,
- DEFAULT_USING_BPF_OFFLOAD, mAddressCoordinator, mDependencies);
+ mNetd, mBpfCoordinator, mCallback, mTetherConfig, mAddressCoordinator,
+ mDependencies);
mIpServer.start();
mLooper.dispatchAll();
verify(mCallback).updateInterfaceState(
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 6c7a66d..c614046 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -84,7 +84,6 @@
import android.net.ip.ConntrackMonitor;
import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
import android.net.ip.IpServer;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Build;
import android.os.Handler;
@@ -98,6 +97,7 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java
index 6c98f2f..55d9852 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java
@@ -100,7 +100,6 @@
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mConnectivityMgr);
when(mConnectivityMgr.getAllNetworks()).thenReturn(mAllNetworks);
when(mConfig.shouldEnableWifiP2pDedicatedIp()).thenReturn(false);
- when(mConfig.isSelectAllPrefixRangeEnabled()).thenReturn(true);
setUpIpServers();
mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig));
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index c0c2ab9..e8bb315 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -95,7 +95,6 @@
@Mock private ModuleInfo mMi;
private Context mMockContext;
private boolean mHasTelephonyManager;
- private boolean mEnableLegacyDhcpServer;
private MockitoSession mMockingSession;
private MockContentResolver mContentResolver;
@@ -182,11 +181,9 @@
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip))
.thenReturn(false);
initializeBpfOffloadConfiguration(true, null /* unset */);
- initEnableSelectAllPrefixRangeFlag(null /* unset */);
mHasTelephonyManager = true;
mMockContext = new MockContext(mContext);
- mEnableLegacyDhcpServer = false;
mContentResolver = new MockContentResolver(mMockContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
@@ -398,7 +395,7 @@
final TetheringConfiguration enableByRes =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByRes.enableLegacyDhcpServer);
+ assertTrue(enableByRes.useLegacyDhcpServer());
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
@@ -408,7 +405,7 @@
final TetheringConfiguration enableByDevConfig =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(enableByDevConfig.enableLegacyDhcpServer);
+ assertTrue(enableByDevConfig.useLegacyDhcpServer());
}
@Test
@@ -422,7 +419,7 @@
final TetheringConfiguration cfg =
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(cfg.enableLegacyDhcpServer);
+ assertFalse(cfg.useLegacyDhcpServer());
}
@Test
@@ -490,32 +487,6 @@
assertTrue(testCfg.shouldEnableWifiP2pDedicatedIp());
}
- private void initEnableSelectAllPrefixRangeFlag(final String value) {
- doReturn(value).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES)));
- }
-
- @Test
- public void testSelectAllPrefixRangeFlag() throws Exception {
- // Test default value.
- final TetheringConfiguration defaultCfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(defaultCfg.isSelectAllPrefixRangeEnabled());
-
- // Test disable flag.
- initEnableSelectAllPrefixRangeFlag("false");
- final TetheringConfiguration testDisable = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertFalse(testDisable.isSelectAllPrefixRangeEnabled());
-
- // Test enable flag.
- initEnableSelectAllPrefixRangeFlag("true");
- final TetheringConfiguration testEnable = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
- assertTrue(testEnable.isSelectAllPrefixRangeEnabled());
- }
-
@Test
public void testChooseUpstreamAutomatically() throws Exception {
when(mResources.getBoolean(R.bool.config_tether_upstream_automatic))
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index e4dbc7d..0388758 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -152,7 +152,6 @@
import android.net.ip.IpNeighborMonitor;
import android.net.ip.IpServer;
import android.net.ip.RouterAdvertisementDaemon;
-import android.net.util.InterfaceParams;
import android.net.util.NetworkConstants;
import android.net.util.SharedLog;
import android.net.wifi.SoftApConfiguration;
@@ -185,6 +184,7 @@
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.InterfaceParams;
import com.android.networkstack.apishim.common.BluetoothPanShim;
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
@@ -297,6 +297,7 @@
private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim;
private TestConnectivityManager mCm;
+ private boolean mForceEthernetServiceUnavailable = false;
private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base) {
@@ -331,7 +332,11 @@
if (Context.USER_SERVICE.equals(name)) return mUserManager;
if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
- if (Context.ETHERNET_SERVICE.equals(name)) return mEm;
+ if (Context.ETHERNET_SERVICE.equals(name)) {
+ if (mForceEthernetServiceUnavailable) return null;
+
+ return mEm;
+ }
return super.getSystemService(name);
}
@@ -452,11 +457,6 @@
}
@Override
- public boolean isTetheringSupported() {
- return true;
- }
-
- @Override
public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
int subId) {
mConfig = spy(new FakeTetheringConfiguration(ctx, log, subId));
@@ -680,6 +680,7 @@
.thenReturn(new String[] {TEST_BT_REGEX});
when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
.thenReturn(new String[] {TEST_NCM_REGEX});
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true);
when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
new int[] {TYPE_WIFI, TYPE_MOBILE_DUN});
when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
@@ -2834,6 +2835,55 @@
runDualStackUsbTethering(TEST_RNDIS_IFNAME);
runStopUSBTethering();
}
+
+ @Test
+ public void testTetheringSupported() throws Exception {
+ setTetheringSupported(true /* supported */);
+ updateConfigAndVerifySupported(true /* supported */);
+
+ // Could disable tethering supported by settings.
+ Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 0);
+ updateConfigAndVerifySupported(false /* supported */);
+
+ // Could disable tethering supported by user restriction.
+ setTetheringSupported(true /* supported */);
+ when(mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(true);
+ updateConfigAndVerifySupported(false /* supported */);
+
+ // Tethering is supported if it has any supported downstream.
+ setTetheringSupported(true /* supported */);
+ when(mResources.getStringArray(R.array.config_tether_usb_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(true /* supported */);
+ when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(true /* supported */);
+
+
+ if (isAtLeastT()) {
+ when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(true /* supported */);
+ when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(true /* supported */);
+ when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(true /* supported */);
+ mForceEthernetServiceUnavailable = true;
+ updateConfigAndVerifySupported(false /* supported */);
+ } else {
+ when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
+ .thenReturn(new String[0]);
+ updateConfigAndVerifySupported(false /* supported */);
+ }
+ }
+
+ private void updateConfigAndVerifySupported(boolean supported) {
+ sendConfigurationChanged();
+ assertEquals(supported, mTethering.isTetheringSupported());
+ }
// TODO: Test that a request for hotspot mode doesn't interfere with an
// already operating tethering mode interface.
}
diff --git a/ethernet/Android.bp b/ethernet/Android.bp
new file mode 100644
index 0000000..36978c5
--- /dev/null
+++ b/ethernet/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 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.
+
+// TODO: delete once:
+// - The ethernet code has been moved to p/m/C.
+// - All dependencies in the tree are gone.
+java_library {
+ name: "ethernet-service",
+ installable: true,
+ srcs: [
+ "src/**/*.java",
+ ],
+}
+
diff --git a/ethernet/src/com/android/server/ethernet/stub/EthernetService.java b/ethernet/src/com/android/server/ethernet/stub/EthernetService.java
new file mode 100644
index 0000000..d0010c1
--- /dev/null
+++ b/ethernet/src/com/android/server/ethernet/stub/EthernetService.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.server.ethernet.stub;
+
+import android.content.Context;
+import android.os.Binder;
+
+/**
+ * Fake EthernetService class for branches that do not have the updatable EthernetService yet,
+ * to allow building the T service-connectivity before sources are moved to the branch.
+ * TODO: Once ethernet-service is no longer on the system server
+ * classpath, move these files from com.android.server.ethernet.stub
+ * to com.android.server.ethernet.
+ */
+public final class EthernetService extends Binder {
+ /** Create instance */
+ public static EthernetServiceImpl create(Context ctx) {
+ throw new RuntimeException("This is a stub class");
+ }
+}
diff --git a/ethernet/src/com/android/server/ethernet/stub/EthernetServiceImpl.java b/ethernet/src/com/android/server/ethernet/stub/EthernetServiceImpl.java
new file mode 100644
index 0000000..ff7aaf9
--- /dev/null
+++ b/ethernet/src/com/android/server/ethernet/stub/EthernetServiceImpl.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 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.server.ethernet.stub;
+
+/** Stub class for EthernetServiceImpl */
+public class EthernetServiceImpl {
+ /** Start service */
+ public void start() {
+ throw new RuntimeException("This is a stub class");
+ }
+}
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index 2ab69b8..f46d887 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -127,6 +127,7 @@
"//frameworks/base/tests/vcn",
"//frameworks/libs/net/common/testutils",
"//frameworks/libs/net/common/tests:__subpackages__",
+ "//frameworks/opt/net/ethernet/tests:__subpackages__",
"//frameworks/opt/telephony/tests/telephonytests",
"//packages/modules/CaptivePortalLogin/tests",
"//packages/modules/Connectivity/Tethering/tests:__subpackages__",
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
index 3d6fb3e..4fefa0a 100644
--- a/framework-t/api/current.txt
+++ b/framework-t/api/current.txt
@@ -61,6 +61,14 @@
package android.net {
+ public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ ctor public EthernetNetworkSpecifier(@NonNull String);
+ method public int describeContents();
+ method @Nullable public String getInterfaceName();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR;
+ }
+
public final class IpSecAlgorithm implements android.os.Parcelable {
ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[]);
ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[], int);
diff --git a/framework-t/api/module-lib-current.txt b/framework-t/api/module-lib-current.txt
index 59ca730..3eca521 100644
--- a/framework-t/api/module-lib-current.txt
+++ b/framework-t/api/module-lib-current.txt
@@ -31,6 +31,22 @@
method public static void registerServiceWrappers();
}
+ public class EthernetManager {
+ method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener);
+ method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener);
+ method public void setIncludeTestInterfaces(boolean);
+ field public static final int ROLE_CLIENT = 1; // 0x1
+ field public static final int ROLE_NONE = 0; // 0x0
+ field public static final int ROLE_SERVER = 2; // 0x2
+ field public static final int STATE_ABSENT = 0; // 0x0
+ field public static final int STATE_LINK_DOWN = 1; // 0x1
+ field public static final int STATE_LINK_UP = 2; // 0x2
+ }
+
+ public static interface EthernetManager.InterfaceStateListener {
+ method public void onInterfaceStateChanged(@NonNull String, int, int, @Nullable android.net.IpConfiguration);
+ }
+
public class IpSecManager {
field public static final int DIRECTION_FWD = 2; // 0x2
}
diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt
index 257ca8a..4739d8d 100644
--- a/framework-t/api/system-current.txt
+++ b/framework-t/api/system-current.txt
@@ -71,21 +71,21 @@
method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setSha256AccountKeyPublicAddress(@Nullable byte[]);
}
- public class FastPairAntispoofkeyDeviceMetadata {
+ public class FastPairAntispoofKeyDeviceMetadata {
}
- public static final class FastPairAntispoofkeyDeviceMetadata.Builder {
- ctor public FastPairAntispoofkeyDeviceMetadata.Builder();
- method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata build();
- method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata.Builder setAntiSpoofPublicKey(@Nullable byte[]);
- method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
+ public static final class FastPairAntispoofKeyDeviceMetadata.Builder {
+ ctor public FastPairAntispoofKeyDeviceMetadata.Builder();
+ method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata build();
+ method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata.Builder setAntiSpoofPublicKey(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairAntispoofKeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
}
public abstract class FastPairDataProviderBase {
ctor public FastPairDataProviderBase(@NonNull String);
method @Nullable public final android.os.IBinder getBinder();
method public abstract void onLoadFastPairAccountDevicesMetadata(@NonNull android.nearby.FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairAccountDevicesMetadataCallback);
- method public abstract void onLoadFastPairAntispoofkeyDeviceMetadata(@NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback);
+ method public abstract void onLoadFastPairAntispoofKeyDeviceMetadata(@NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofKeyDeviceMetadataRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofKeyDeviceMetadataCallback);
method public abstract void onLoadFastPairEligibleAccounts(@NonNull android.nearby.FastPairDataProviderBase.FastPairEligibleAccountsRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairEligibleAccountsCallback);
method public abstract void onManageFastPairAccount(@NonNull android.nearby.FastPairDataProviderBase.FastPairManageAccountRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairManageActionCallback);
method public abstract void onManageFastPairAccountDevice(@NonNull android.nearby.FastPairDataProviderBase.FastPairManageAccountDeviceRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairManageActionCallback);
@@ -106,12 +106,12 @@
method @NonNull public java.util.Collection<byte[]> getAccountKeys();
}
- public static interface FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback {
+ public static interface FastPairDataProviderBase.FastPairAntispoofKeyDeviceMetadataCallback {
method public void onError(int, @Nullable String);
- method public void onFastPairAntispoofkeyDeviceMetadataReceived(@NonNull android.nearby.FastPairAntispoofkeyDeviceMetadata);
+ method public void onFastPairAntispoofKeyDeviceMetadataReceived(@NonNull android.nearby.FastPairAntispoofKeyDeviceMetadata);
}
- public static class FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest {
+ public static class FastPairDataProviderBase.FastPairAntispoofKeyDeviceMetadataRequest {
method @NonNull public byte[] getModelId();
}
@@ -329,6 +329,8 @@
}
public class NearbyManager {
+ method public static boolean getFastPairScanEnabled(@NonNull android.content.Context, boolean);
+ method public static void setFastPairScanEnabled(@NonNull android.content.Context, boolean);
method public void startBroadcast(@NonNull android.nearby.BroadcastRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.BroadcastCallback);
method public void startScan(@NonNull android.nearby.ScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.ScanCallback);
method public void stopBroadcast(@NonNull android.nearby.BroadcastCallback);
@@ -494,6 +496,45 @@
package android.net {
+ public class EthernetManager {
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void connectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void disconnectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void updateConfiguration(@NonNull String, @NonNull android.net.EthernetNetworkUpdateRequest, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
+ }
+
+ public static interface EthernetManager.TetheredInterfaceCallback {
+ method public void onAvailable(@NonNull String);
+ method public void onUnavailable();
+ }
+
+ public static class EthernetManager.TetheredInterfaceRequest {
+ method public void release();
+ }
+
+ public final class EthernetNetworkManagementException extends java.lang.RuntimeException implements android.os.Parcelable {
+ ctor public EthernetNetworkManagementException(@NonNull String);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkManagementException> CREATOR;
+ }
+
+ public final class EthernetNetworkUpdateRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.net.IpConfiguration getIpConfiguration();
+ method @Nullable public android.net.NetworkCapabilities getNetworkCapabilities();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR;
+ }
+
+ public static final class EthernetNetworkUpdateRequest.Builder {
+ ctor public EthernetNetworkUpdateRequest.Builder();
+ ctor public EthernetNetworkUpdateRequest.Builder(@NonNull android.net.EthernetNetworkUpdateRequest);
+ method @NonNull public android.net.EthernetNetworkUpdateRequest build();
+ method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setIpConfiguration(@NonNull android.net.IpConfiguration);
+ method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
+ }
+
public class IpSecManager {
method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
diff --git a/framework/Android.bp b/framework/Android.bp
index 66b662b..f31a7d5 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -64,6 +64,7 @@
":framework-connectivity-sources",
":net-utils-framework-common-srcs",
":framework-connectivity-api-shared-srcs",
+ ":framework-connectivity-javastream-protos",
],
aidl: {
generate_get_transaction_name: true,
@@ -85,7 +86,7 @@
"net-utils-device-common",
],
static_libs: [
- "framework-connectivity-protos",
+ "modules-utils-backgroundthread",
"modules-utils-build",
"modules-utils-preconditions",
],
@@ -139,6 +140,7 @@
"//frameworks/base/tests/vcn",
"//frameworks/libs/net/common/testutils",
"//frameworks/libs/net/common/tests:__subpackages__",
+ "//frameworks/opt/net/ethernet/tests:__subpackages__",
"//frameworks/opt/telephony/tests/telephonytests",
"//packages/modules/CaptivePortalLogin/tests",
"//packages/modules/Connectivity/Tethering/tests:__subpackages__",
@@ -180,22 +182,36 @@
],
}
-// TODO: reduce size of this library; consider using
-// proto nano for example
-java_library {
+filegroup {
name: "framework-connectivity-protos",
- sdk_version: "module_current",
- min_sdk_version: "30",
- proto: {
- type: "lite",
- },
srcs: [
- "proto/**/*.*",
+ "proto/**/*.proto",
],
- static_libs: ["libprotobuf-java-lite"],
- apex_available: [
- "com.android.tethering",
+ visibility: ["//frameworks/base"],
+}
+
+gensrcs {
+ name: "framework-connectivity-javastream-protos",
+ depfile: true,
+
+ tools: [
+ "aprotoc",
+ "protoc-gen-javastream",
+ "soong_zip",
],
- lint: { strict_updatability_linting: true },
- visibility: ["//visibility:private"],
+
+ cmd: "mkdir -p $(genDir)/$(in) " +
+ "&& $(location aprotoc) " +
+ " --plugin=$(location protoc-gen-javastream) " +
+ " --dependency_out=$(depfile) " +
+ " --javastream_out=$(genDir)/$(in) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in) " +
+ "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
+
+ srcs: [
+ ":framework-connectivity-protos",
+ ],
+ output_extension: "srcjar",
}
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index b65c0ce..9fe6505 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -6,6 +6,8 @@
}
public class ConnectivityManager {
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void addUidToMeteredNetworkAllowList(int);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void addUidToMeteredNetworkDenyList(int);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void factoryReset();
method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
method @Nullable public android.net.ProxyInfo getGlobalProxy();
@@ -14,6 +16,8 @@
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities redactNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkAllowList(int);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkDenyList(int);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress);
@@ -28,11 +32,8 @@
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void swapActiveStatsMap();
method public void systemReady();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateFirewallRule(int, int, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateMeteredNetworkAllowList(int, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateMeteredNetworkDenyList(int, boolean);
field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index e8e1efa..68ca46d 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -5706,8 +5706,8 @@
}
/**
- * Sets whether the specified UID is allowed to use data on metered networks even when
- * background data is restricted.
+ * Adds the specified UID to the list of UIds that are allowed to use data on metered networks
+ * even when background data is restricted. The deny list takes precedence over the allow list.
*
* @param uid uid of target app
* @throws IllegalStateException if updating allow list failed.
@@ -5719,17 +5719,40 @@
android.Manifest.permission.NETWORK_STACK,
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
- public void updateMeteredNetworkAllowList(final int uid, final boolean add) {
+ public void addUidToMeteredNetworkAllowList(final int uid) {
try {
- mService.updateMeteredNetworkAllowList(uid, add);
+ mService.updateMeteredNetworkAllowList(uid, true /* add */);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
- * Sets whether the specified UID is prevented from using background data on metered networks.
- * Takes precedence over {@link #updateMeteredNetworkAllowList}.
+ * Removes the specified UID from the list of UIDs that are allowed to use background data on
+ * metered networks when background data is restricted. The deny list takes precedence over
+ * the allow list.
+ *
+ * @param uid uid of target app
+ * @throws IllegalStateException if updating allow list failed.
+ * @hide
+ */
+ @SystemApi(client = MODULE_LIBRARIES)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
+ public void removeUidFromMeteredNetworkAllowList(final int uid) {
+ try {
+ mService.updateMeteredNetworkAllowList(uid, false /* remove */);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Adds the specified UID to the list of UIDs that are not allowed to use background data on
+ * metered networks. Takes precedence over {@link #addUidToMeteredNetworkAllowList}.
*
* @param uid uid of target app
* @throws IllegalStateException if updating deny list failed.
@@ -5741,9 +5764,32 @@
android.Manifest.permission.NETWORK_STACK,
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
- public void updateMeteredNetworkDenyList(final int uid, final boolean add) {
+ public void addUidToMeteredNetworkDenyList(final int uid) {
try {
- mService.updateMeteredNetworkDenyList(uid, add);
+ mService.updateMeteredNetworkDenyList(uid, true /* add */);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Removes the specified UID from the list of UIds that can use use background data on metered
+ * networks if background data is not restricted. The deny list takes precedence over the
+ * allow list.
+ *
+ * @param uid uid of target app
+ * @throws IllegalStateException if updating deny list failed.
+ * @hide
+ */
+ @SystemApi(client = MODULE_LIBRARIES)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+ })
+ public void removeUidFromMeteredNetworkDenyList(final int uid) {
+ try {
+ mService.updateMeteredNetworkDenyList(uid, false /* remove */);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5818,27 +5864,4 @@
throw e.rethrowFromSystemServer();
}
}
-
- /**
- * Request to change the current active network stats map.
- * STOPSHIP: Remove this API before T sdk finalized, this API is temporary added for the
- * NetworkStatsFactory which is platform code but will be moved into connectivity (tethering)
- * mainline module.
- *
- * @throws IllegalStateException if swapping active stats map failed.
- * @hide
- */
- @SystemApi(client = MODULE_LIBRARIES)
- @RequiresPermission(anyOf = {
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_STACK,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
- })
- public void swapActiveStatsMap() {
- try {
- mService.swapActiveStatsMap();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
}
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index 23a3850..1e1f653 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -245,6 +245,4 @@
void setFirewallChainEnabled(int chain, boolean enable);
void replaceFirewallChain(int chain, in int[] uids);
-
- void swapActiveStatsMap();
}
diff --git a/framework/src/android/net/QosFilter.java b/framework/src/android/net/QosFilter.java
index 957c867..5c1c3cc 100644
--- a/framework/src/android/net/QosFilter.java
+++ b/framework/src/android/net/QosFilter.java
@@ -62,23 +62,31 @@
public abstract int validate();
/**
- * Determines whether or not the parameters is a match for the filter.
+ * Determines whether or not the parameters will be matched with source address and port of this
+ * filter.
*
- * @param address the local address
- * @param startPort the start of the port range
- * @param endPort the end of the port range
- * @return whether the parameters match the local address of the filter
+ * @param address the UE side address included in IP packet filter set of a QoS flow assigned
+ * on {@link Network}.
+ * @param startPort the start of UE side port range included in IP packet filter set of a QoS
+ * flow assigned on {@link Network}.
+ * @param endPort the end of UE side port range included in IP packet filter set of a QoS flow
+ * assigned on {@link Network}.
+ * @return whether the parameters match the UE side address and port of the filter
*/
public abstract boolean matchesLocalAddress(@NonNull InetAddress address,
int startPort, int endPort);
/**
- * Determines whether or not the parameters is a match for the filter.
+ * Determines whether or not the parameters will be matched with remote address and port of
+ * this filter.
*
- * @param address the remote address
- * @param startPort the start of the port range
- * @param endPort the end of the port range
- * @return whether the parameters match the remote address of the filter
+ * @param address the remote address included in IP packet filter set of a QoS flow
+ * assigned on {@link Network}.
+ * @param startPort the start of remote port range included in IP packet filter set of a
+ * QoS flow assigned on {@link Network}.
+ * @param endPort the end of the remote range included in IP packet filter set of a QoS
+ * flow assigned on {@link Network}.
+ * @return whether the parameters match the remote address and port of the filter
*/
public abstract boolean matchesRemoteAddress(@NonNull InetAddress address,
int startPort, int endPort);
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index 3cd5e13..f3dfb57 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -134,6 +134,46 @@
return -EPERM;
}
+ // Note that tagging the socket to AID_CLAT is only implemented in JNI ClatCoordinator.
+ // The process is not allowed to tag socket to AID_CLAT via tagSocket() which would cause
+ // process data usage accounting to be bypassed. Tagging AID_CLAT is used for avoiding counting
+ // CLAT traffic data usage twice. See packages/modules/Connectivity/service/jni/
+ // com_android_server_connectivity_ClatCoordinator.cpp
+ if (chargeUid == AID_CLAT) {
+ return -EPERM;
+ }
+
+ // The socket destroy listener only monitors on the group {INET_TCP, INET_UDP, INET6_TCP,
+ // INET6_UDP}. Tagging listener unsupported socket causes that the tag can't be removed from
+ // tag map automatically. Eventually, the tag map may run out of space because of dead tag
+ // entries. Note that although tagSocket() of net client has already denied the family which
+ // is neither AF_INET nor AF_INET6, the family validation is still added here just in case.
+ // See tagSocket in system/netd/client/NetdClient.cpp and
+ // TrafficController::makeSkDestroyListener in
+ // packages/modules/Connectivity/service/native/TrafficController.cpp
+ // TODO: remove this once the socket destroy listener can detect more types of socket destroy.
+ int socketFamily;
+ socklen_t familyLen = sizeof(socketFamily);
+ if (getsockopt(sockFd, SOL_SOCKET, SO_DOMAIN, &socketFamily, &familyLen)) {
+ ALOGE("Failed to getsockopt SO_DOMAIN: %s, fd: %d", strerror(errno), sockFd);
+ return -errno;
+ }
+ if (socketFamily != AF_INET && socketFamily != AF_INET6) {
+ ALOGE("Unsupported family: %d", socketFamily);
+ return -EAFNOSUPPORT;
+ }
+
+ int socketProto;
+ socklen_t protoLen = sizeof(socketProto);
+ if (getsockopt(sockFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &protoLen)) {
+ ALOGE("Failed to getsockopt SO_PROTOCOL: %s, fd: %d", strerror(errno), sockFd);
+ return -errno;
+ }
+ if (socketProto != IPPROTO_UDP && socketProto != IPPROTO_TCP) {
+ ALOGE("Unsupported protocol: %d", socketProto);
+ return -EPROTONOSUPPORT;
+ }
+
uint64_t sock_cookie = getSocketCookie(sockFd);
if (sock_cookie == NONEXISTENT_COOKIE) return -errno;
UidTagValue newKey = {.uid = (uint32_t)chargeUid, .tag = tag};
diff --git a/netd/BpfHandlerTest.cpp b/netd/BpfHandlerTest.cpp
index db59c7c..cd6b565 100644
--- a/netd/BpfHandlerTest.cpp
+++ b/netd/BpfHandlerTest.cpp
@@ -16,6 +16,7 @@
* BpfHandlerTest.cpp - unit tests for BpfHandler.cpp
*/
+#include <private/android_filesystem_config.h>
#include <sys/socket.h>
#include <gtest/gtest.h>
@@ -187,6 +188,20 @@
expectMapEmpty(mFakeCookieTagMap);
}
+TEST_F(BpfHandlerTest, TestTagSocketWithUnsupportedFamily) {
+ int packetSocket = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ EXPECT_LE(0, packetSocket);
+ EXPECT_NE(NONEXISTENT_COOKIE, getSocketCookie(packetSocket));
+ EXPECT_EQ(-EAFNOSUPPORT, mBh.tagSocket(packetSocket, TEST_TAG, TEST_UID, TEST_UID));
+}
+
+TEST_F(BpfHandlerTest, TestTagSocketWithUnsupportedProtocol) {
+ int rawSocket = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
+ EXPECT_LE(0, rawSocket);
+ EXPECT_NE(NONEXISTENT_COOKIE, getSocketCookie(rawSocket));
+ EXPECT_EQ(-EPROTONOSUPPORT, mBh.tagSocket(rawSocket, TEST_TAG, TEST_UID, TEST_UID));
+}
+
TEST_F(BpfHandlerTest, TestTagSocketWithoutPermission) {
int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
ASSERT_NE(-1, sock);
@@ -208,6 +223,12 @@
EXPECT_EQ(0, mBh.untagSocket(v6socket));
expectNoTag(sockCookie);
expectMapEmpty(mFakeCookieTagMap);
+
+ // Tag a socket to AID_CLAT other then realUid.
+ int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ ASSERT_NE(-1, sock);
+ ASSERT_EQ(-EPERM, mBh.tagSocket(sock, TEST_TAG, AID_CLAT, realUid));
+ expectMapEmpty(mFakeCookieTagMap);
}
TEST_F(BpfHandlerTest, TestUntagInvalidSocket) {
diff --git a/service-t/Android.bp b/service-t/Android.bp
index 3d9820d..8851554 100644
--- a/service-t/Android.bp
+++ b/service-t/Android.bp
@@ -30,6 +30,7 @@
min_sdk_version: "30",
srcs: [
"src/**/*.java",
+ ":ethernet-service-updatable-sources",
":services.connectivity-tiramisu-updatable-sources",
],
libs: [
@@ -38,7 +39,8 @@
"framework-connectivity-t-pre-jarjar",
"framework-tethering.stubs.module_lib",
"service-connectivity-pre-jarjar",
- "service-nearby",
+ "service-nearby-pre-jarjar",
+ "ServiceConnectivityResources",
"unsupportedappusage",
],
static_libs: [
diff --git a/service-t/src/com/android/server/ConnectivityServiceInitializer.java b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
index d11f0f2..7b1cd61 100644
--- a/service-t/src/com/android/server/ConnectivityServiceInitializer.java
+++ b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
@@ -20,6 +20,9 @@
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.ConstantsShim;
+import com.android.server.ethernet.EthernetService;
+import com.android.server.ethernet.EthernetServiceImpl;
import com.android.server.nearby.NearbyService;
/**
@@ -28,15 +31,19 @@
*/
public final class ConnectivityServiceInitializer extends SystemService {
private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
+ private final Context mContext;
private final ConnectivityService mConnectivity;
private final IpSecService mIpSecService;
private final NsdService mNsdService;
private final NearbyService mNearbyService;
+ private final EthernetServiceImpl mEthernetServiceImpl;
public ConnectivityServiceInitializer(Context context) {
super(context);
+ mContext = context;
// Load JNI libraries used by ConnectivityService and its dependencies
System.loadLibrary("service-connectivity");
+ mEthernetServiceImpl = createEthernetService(context);
mConnectivity = new ConnectivityService(context);
mIpSecService = createIpSecService(context);
mNsdService = createNsdService(context);
@@ -45,6 +52,12 @@
@Override
public void onStart() {
+ if (mConnectivity.deviceSupportsEthernet(mContext)) {
+ Log.i(TAG, "Registering " + Context.ETHERNET_SERVICE);
+ publishBinderService(Context.ETHERNET_SERVICE, mEthernetServiceImpl,
+ /* allowIsolated= */ false);
+ }
+
Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
/* allowIsolated= */ false);
@@ -60,10 +73,11 @@
}
if (mNearbyService != null) {
- Log.i(TAG, "Registering " + Context.NEARBY_SERVICE);
- publishBinderService(Context.NEARBY_SERVICE, mNearbyService,
+ Log.i(TAG, "Registering " + ConstantsShim.NEARBY_SERVICE);
+ publishBinderService(ConstantsShim.NEARBY_SERVICE, mNearbyService,
/* allowIsolated= */ false);
}
+
}
@Override
@@ -71,6 +85,10 @@
if (mNearbyService != null) {
mNearbyService.onBootPhase(phase);
}
+
+ if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && mEthernetServiceImpl != null) {
+ mEthernetServiceImpl.start();
+ }
}
/**
@@ -96,6 +114,24 @@
/** Return Nearby service instance or null if current SDK is lower than T */
private NearbyService createNearbyService(final Context context) {
if (!SdkLevel.isAtLeastT()) return null;
- return new NearbyService(context);
+ try {
+ return new NearbyService(context);
+ } catch (UnsupportedOperationException e) {
+ // Nearby is not yet supported in all branches
+ // TODO: remove catch clause when it is available.
+ Log.i(TAG, "Skipping unsupported service " + ConstantsShim.NEARBY_SERVICE);
+ return null;
+ }
+ }
+
+ /**
+ * Return EthernetServiceImpl instance or null if current SDK is lower than T or Ethernet
+ * service isn't necessary.
+ */
+ private EthernetServiceImpl createEthernetService(final Context context) {
+ if (!SdkLevel.isAtLeastT() || !mConnectivity.deviceSupportsEthernet(context)) {
+ return null;
+ }
+ return EthernetService.create(context);
}
}
diff --git a/service/Android.bp b/service/Android.bp
index 3e9ef1a..0b8b25f 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -114,6 +114,7 @@
"net-utils-device-common",
"net-utils-device-common-bpf",
"net-utils-device-common-netlink",
+ "net-utils-services-common",
"netd-client",
"networkstack-client",
"PlatformProperties",
@@ -159,7 +160,7 @@
static_libs: [
"service-connectivity-pre-jarjar",
"service-connectivity-tiramisu-pre-jarjar",
- "service-nearby",
+ "service-nearby-pre-jarjar",
],
jarjar_rules: ":connectivity-jarjar-rules",
apex_available: [
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index f8f86a2..faa9998 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -136,4 +136,36 @@
extreme adverse effects on performance of the new network.
-->
<bool translatable="false" name="config_cellular_radio_timesharing_capable">true</bool>
+
+ <!-- Configure ethernet tcp buffersizes in the form:
+ rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
+ <string translatable="false" name="config_ethernet_tcp_buffers">524288,1048576,3145728,524288,1048576,2097152</string>
+
+ <!-- Configuration of Ethernet interfaces in the following format:
+ <interface name|mac address>;[Network Capabilities];[IP config];[Override Transport]
+ Where
+ [Network Capabilities] Optional. A comma separated list of network capabilities.
+ Values must be from NetworkCapabilities#NET_CAPABILITY_* constants.
+ The NOT_ROAMING, NOT_CONGESTED and NOT_SUSPENDED capabilities are always
+ added automatically because this configuration provides no way to update
+ them dynamically.
+ [IP config] Optional. If empty or not specified - DHCP will be used, otherwise
+ use the following format to specify static IP configuration:
+ ip=<ip-address/mask> gateway=<ip-address> dns=<comma-sep-ip-addresses>
+ domains=<comma-sep-domains>
+ [Override Transport] Optional. An override network transport type to allow
+ the propagation of an interface type on the other end of a local Ethernet
+ interface. Value must be from NetworkCapabilities#TRANSPORT_* constants. If
+ left out, this will default to TRANSPORT_ETHERNET.
+ -->
+ <string-array translatable="false" name="config_ethernet_interfaces">
+ <!--
+ <item>eth1;12,13,14,15;ip=192.168.0.10/24 gateway=192.168.0.1 dns=4.4.4.4,8.8.8.8</item>
+ <item>eth2;;ip=192.168.0.11/24</item>
+ <item>eth3;12,13,14,15;ip=192.168.0.12/24;1</item>
+ -->
+ </string-array>
+
+ <!-- Regex of wired ethernet ifaces -->
+ <string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
</resources>
diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml
index e5010d7..9fa6a30 100644
--- a/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -37,6 +37,9 @@
<item type="drawable" name="stat_notify_wifi_in_range"/>
<item type="drawable" name="stat_notify_rssi_in_range"/>
<item type="bool" name="config_cellular_radio_timesharing_capable" />
+ <item type="string" name="config_ethernet_tcp_buffers"/>
+ <item type="array" name="config_ethernet_interfaces"/>
+ <item type="string" name="config_ethernet_iface_regex"/>
</policy>
</overlayable>
</resources>
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
index ee05df5..5d51fdd 100644
--- a/service/jarjar-rules.txt
+++ b/service/jarjar-rules.txt
@@ -92,7 +92,6 @@
rule android.net.util.KeepalivePacketDataUtil* com.android.connectivity.@0
# From connectivity-module-utils
-rule android.net.util.InterfaceParams* com.android.connectivity.@0
rule android.net.util.SharedLog* com.android.connectivity.@0
rule android.net.shared.** com.android.connectivity.@0
@@ -109,5 +108,8 @@
# From fast-pair-lite-protos
rule service.proto.** com.android.server.nearby.@0
+# From filegroup framework-connectivity-protos
+rule android.service.*Proto com.android.connectivity.@0
+
# Remaining are connectivity sources in com.android.server and com.android.server.connectivity:
# TODO: move to a subpackage of com.android.connectivity (such as com.android.connectivity.server)
diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
index ee512ec..4517b5c 100644
--- a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
+++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
@@ -18,6 +18,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <linux/if_tun.h>
#include <linux/ioctl.h>
#include <log/log.h>
@@ -27,7 +28,11 @@
#include <sys/wait.h>
#include <string>
+#include <bpf/BpfMap.h>
+#include <bpf/BpfUtils.h>
+#include <bpf_shared.h>
#include <netjniutils/netjniutils.h>
+#include <private/android_filesystem_config.h>
#include "libclat/bpfhelper.h"
#include "libclat/clatutils.h"
@@ -318,30 +323,13 @@
return -1;
}
- // 1. create a throwaway socket to reserve a file descriptor number
- int passedTunFd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (passedTunFd == -1) {
- throwIOException(env, "socket(ipv6/udp) for tun fd failed", errno);
- return -1;
- }
- int passedSockRead = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (passedSockRead == -1) {
- throwIOException(env, "socket(ipv6/udp) for read socket failed", errno);
- return -1;
- }
- int passedSockWrite = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (passedSockWrite == -1) {
- throwIOException(env, "socket(ipv6/udp) for write socket failed", errno);
- return -1;
- }
-
- // these are the FD we'll pass to clatd on the cli, so need it as a string
- char passedTunFdStr[INT32_STRLEN];
- char passedSockReadStr[INT32_STRLEN];
- char passedSockWriteStr[INT32_STRLEN];
- snprintf(passedTunFdStr, sizeof(passedTunFdStr), "%d", passedTunFd);
- snprintf(passedSockReadStr, sizeof(passedSockReadStr), "%d", passedSockRead);
- snprintf(passedSockWriteStr, sizeof(passedSockWriteStr), "%d", passedSockWrite);
+ // 1. these are the FD we'll pass to clatd on the cli, so need it as a string
+ char tunFdStr[INT32_STRLEN];
+ char sockReadStr[INT32_STRLEN];
+ char sockWriteStr[INT32_STRLEN];
+ snprintf(tunFdStr, sizeof(tunFdStr), "%d", tunFd);
+ snprintf(sockReadStr, sizeof(sockReadStr), "%d", readSock);
+ snprintf(sockWriteStr, sizeof(sockWriteStr), "%d", writeSock);
// 2. we're going to use this as argv[0] to clatd to make ps output more useful
std::string progname("clatd-");
@@ -353,9 +341,9 @@
"-p", pfx96Str.c_str(),
"-4", v4Str.c_str(),
"-6", v6Str.c_str(),
- "-t", passedTunFdStr,
- "-r", passedSockReadStr,
- "-w", passedSockWriteStr,
+ "-t", tunFdStr,
+ "-r", sockReadStr,
+ "-w", sockWriteStr,
nullptr};
// clang-format on
@@ -375,7 +363,9 @@
// 4. register dup2() action: this is what 'clears' the CLOEXEC flag
// on the tun fd that we want the child clatd process to inherit
- // (this will happen after the vfork, and before the execve)
+ // (this will happen after the vfork, and before the execve).
+ // Note that even though dup2(2) is a no-op if fd == new_fd but O_CLOEXEC flag will be removed.
+ // See implementation of bionic's posix_spawn_file_actions_adddup2().
posix_spawn_file_actions_t fa;
if (int ret = posix_spawn_file_actions_init(&fa)) {
posix_spawnattr_destroy(&attr);
@@ -383,19 +373,19 @@
return -1;
}
- if (int ret = posix_spawn_file_actions_adddup2(&fa, tunFd, passedTunFd)) {
+ if (int ret = posix_spawn_file_actions_adddup2(&fa, tunFd, tunFd)) {
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fa);
throwIOException(env, "posix_spawn_file_actions_adddup2 for tun fd failed", ret);
return -1;
}
- if (int ret = posix_spawn_file_actions_adddup2(&fa, readSock, passedSockRead)) {
+ if (int ret = posix_spawn_file_actions_adddup2(&fa, readSock, readSock)) {
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fa);
throwIOException(env, "posix_spawn_file_actions_adddup2 for read socket failed", ret);
return -1;
}
- if (int ret = posix_spawn_file_actions_adddup2(&fa, writeSock, passedSockWrite)) {
+ if (int ret = posix_spawn_file_actions_adddup2(&fa, writeSock, writeSock)) {
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fa);
throwIOException(env, "posix_spawn_file_actions_adddup2 for write socket failed", ret);
@@ -414,7 +404,7 @@
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&fa);
- // 5. Start BPF if any
+ // 6. Start BPF if any
if (!net::clat::initMaps()) {
net::clat::ClatdTracker tracker = {};
if (!initTracker(ifaceStr.c_str(), pfx96Str.c_str(), v4Str.c_str(), v6Str.c_str(),
@@ -488,6 +478,72 @@
stopClatdProcess(pid);
}
+static jlong com_android_server_connectivity_ClatCoordinator_tagSocketAsClat(
+ JNIEnv* env, jobject clazz, jobject sockJavaFd) {
+ int sockFd = netjniutils::GetNativeFileDescriptor(env, sockJavaFd);
+ if (sockFd < 0) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Invalid socket file descriptor");
+ return -1;
+ }
+
+ uint64_t sock_cookie = bpf::getSocketCookie(sockFd);
+ if (sock_cookie == bpf::NONEXISTENT_COOKIE) {
+ throwIOException(env, "get socket cookie failed", errno);
+ return -1;
+ }
+
+ bpf::BpfMap<uint64_t, UidTagValue> cookieTagMap;
+ auto res = cookieTagMap.init(COOKIE_TAG_MAP_PATH);
+ if (!res.ok()) {
+ throwIOException(env, "failed to init the cookieTagMap", res.error().code());
+ return -1;
+ }
+
+ // Tag raw socket with uid AID_CLAT and set tag as zero because tag is unused in bpf
+ // program for counting data usage in netd.c. Tagging socket is used to avoid counting
+ // duplicated clat traffic in bpf stat.
+ UidTagValue newKey = {.uid = (uint32_t)AID_CLAT, .tag = 0 /* unused */};
+ res = cookieTagMap.writeValue(sock_cookie, newKey, BPF_ANY);
+ if (!res.ok()) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Failed to tag the socket: %s, fd: %d",
+ strerror(res.error().code()), cookieTagMap.getMap().get());
+ return -1;
+ }
+
+ ALOGI("tag uid AID_CLAT to socket fd %d, cookie %" PRIu64 "", sockFd, sock_cookie);
+ return static_cast<jlong>(sock_cookie);
+}
+
+static void com_android_server_connectivity_ClatCoordinator_untagSocket(JNIEnv* env, jobject clazz,
+ jlong cookie) {
+ uint64_t sock_cookie = static_cast<uint64_t>(cookie);
+ if (sock_cookie == bpf::NONEXISTENT_COOKIE) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Invalid socket cookie");
+ return;
+ }
+
+ // The reason that deleting entry from cookie tag map directly is that the tag socket destroy
+ // listener only monitors on group INET_TCP, INET_UDP, INET6_TCP, INET6_UDP. The other socket
+ // types, ex: raw, are not able to be removed automatically by the listener.
+ // See TrafficController::makeSkDestroyListener.
+ bpf::BpfMap<uint64_t, UidTagValue> cookieTagMap;
+ auto res = cookieTagMap.init(COOKIE_TAG_MAP_PATH);
+ if (!res.ok()) {
+ throwIOException(env, "failed to init the cookieTagMap", res.error().code());
+ return;
+ }
+
+ res = cookieTagMap.deleteValue(sock_cookie);
+ if (!res.ok()) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Failed to untag the socket: %s",
+ strerror(res.error().code()));
+ return;
+ }
+
+ ALOGI("untag socket cookie %" PRIu64 "", sock_cookie);
+ return;
+}
+
/*
* JNI registration.
*/
@@ -517,6 +573,10 @@
{"native_stopClatd",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
(void*)com_android_server_connectivity_ClatCoordinator_stopClatd},
+ {"native_tagSocketAsClat", "(Ljava/io/FileDescriptor;)J",
+ (void*)com_android_server_connectivity_ClatCoordinator_tagSocketAsClat},
+ {"native_untagSocket", "(J)V",
+ (void*)com_android_server_connectivity_ClatCoordinator_untagSocket},
};
int register_com_android_server_connectivity_ClatCoordinator(JNIEnv* env) {
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index f2ca18b..c006bc6 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -54,6 +54,13 @@
sInitialized = true;
}
+ /** Constructor used after T that doesn't need to use netd anymore. */
+ public BpfNetMaps() {
+ this(null);
+
+ if (USE_NETD) throw new IllegalArgumentException("BpfNetMaps need to use netd before T");
+ }
+
public BpfNetMaps(INetd netd) {
ensureInitialized();
mNetd = netd;
@@ -69,15 +76,10 @@
* Add naughty app bandwidth rule for specific app
*
* @param uid uid of target app
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void addNaughtyApp(final int uid) throws RemoteException {
- if (USE_NETD) {
- mNetd.bandwidthAddNaughtyApp(uid);
- return;
- }
+ public void addNaughtyApp(final int uid) {
final int err = native_addNaughtyApp(uid);
maybeThrow(err, "Unable to add naughty app");
}
@@ -86,15 +88,10 @@
* Remove naughty app bandwidth rule for specific app
*
* @param uid uid of target app
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void removeNaughtyApp(final int uid) throws RemoteException {
- if (USE_NETD) {
- mNetd.bandwidthRemoveNaughtyApp(uid);
- return;
- }
+ public void removeNaughtyApp(final int uid) {
final int err = native_removeNaughtyApp(uid);
maybeThrow(err, "Unable to remove naughty app");
}
@@ -103,15 +100,10 @@
* Add nice app bandwidth rule for specific app
*
* @param uid uid of target app
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void addNiceApp(final int uid) throws RemoteException {
- if (USE_NETD) {
- mNetd.bandwidthAddNiceApp(uid);
- return;
- }
+ public void addNiceApp(final int uid) {
final int err = native_addNiceApp(uid);
maybeThrow(err, "Unable to add nice app");
}
@@ -120,15 +112,10 @@
* Remove nice app bandwidth rule for specific app
*
* @param uid uid of target app
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void removeNiceApp(final int uid) throws RemoteException {
- if (USE_NETD) {
- mNetd.bandwidthRemoveNiceApp(uid);
- return;
- }
+ public void removeNiceApp(final int uid) {
final int err = native_removeNiceApp(uid);
maybeThrow(err, "Unable to remove nice app");
}
@@ -138,15 +125,10 @@
*
* @param childChain target chain to enable
* @param enable whether to enable or disable child chain.
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void setChildChain(final int childChain, final boolean enable) throws RemoteException {
- if (USE_NETD) {
- mNetd.firewallEnableChildChain(childChain, enable);
- return;
- }
+ public void setChildChain(final int childChain, final boolean enable) {
final int err = native_setChildChain(childChain, enable);
maybeThrow(err, "Unable to set child chain");
}
@@ -163,14 +145,9 @@
* @param isAllowlist Whether this is an allowlist or denylist chain.
* @param uids The list of UIDs to allow/deny.
* @return 0 if the chain was successfully replaced, errno otherwise.
- * @throws RemoteException when netd has crashed.
*/
public int replaceUidChain(final String chainName, final boolean isAllowlist,
- final int[] uids) throws RemoteException {
- if (USE_NETD) {
- mNetd.firewallReplaceUidChain(chainName, isAllowlist, uids);
- return 0;
- }
+ final int[] uids) {
final int err = native_replaceUidChain(chainName, isAllowlist, uids);
if (err != 0) {
Log.e(TAG, "replaceUidChain failed: " + Os.strerror(-err));
@@ -184,16 +161,10 @@
* @param childChain target chain
* @param uid uid to allow/deny
* @param firewallRule either FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void setUidRule(final int childChain, final int uid, final int firewallRule)
- throws RemoteException {
- if (USE_NETD) {
- mNetd.firewallSetUidRule(childChain, uid, firewallRule);
- return;
- }
+ public void setUidRule(final int childChain, final int uid, final int firewallRule) {
final int err = native_setUidRule(childChain, uid, firewallRule);
maybeThrow(err, "Unable to set uid rule");
}
@@ -247,15 +218,10 @@
/**
* Request netd to change the current active network stats map.
*
- * @throws RemoteException when netd has crashed.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the failure.
*/
- public void swapActiveStatsMap() throws RemoteException {
- if (USE_NETD) {
- mNetd.trafficSwapActiveStatsMap();
- return;
- }
+ public void swapActiveStatsMap() {
final int err = native_swapActiveStatsMap();
maybeThrow(err, "Unable to swap active stats map");
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index eabcd10..da80e0a 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -198,7 +198,6 @@
import android.net.resolv.aidl.Nat64PrefixEventParcel;
import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.PrivateDnsConfig;
-import android.net.util.InterfaceParams;
import android.net.util.MultinetworkPolicyTracker;
import android.os.BatteryStatsManager;
import android.os.Binder;
@@ -245,6 +244,7 @@
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.DeviceConfigUtils;
+import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.net.module.util.LocationPermissionChecker;
@@ -936,7 +936,7 @@
}
// Ethernet is often not specified in the configs, although many devices can use it via
// USB host adapters. Add it as long as the ethernet service is here.
- if (ctx.getSystemService(Context.ETHERNET_SERVICE) != null) {
+ if (deviceSupportsEthernet(ctx)) {
addSupportedType(TYPE_ETHERNET);
}
@@ -1621,6 +1621,15 @@
mContext);
}
+ /**
+ * Check whether or not the device supports Ethernet transport.
+ */
+ public static boolean deviceSupportsEthernet(final Context context) {
+ final PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET)
+ || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST);
+ }
+
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton(
new UidRange(uid, uid)));
@@ -10699,6 +10708,9 @@
}
private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) {
+ // Rate-limiting cannot run correctly before T because the BPF program is not loaded.
+ if (!SdkLevel.isAtLeastT()) return false;
+
final NetworkCapabilities agentCaps = networkAgent.networkCapabilities;
// Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide
// internet connectivity can be rate limited.
@@ -11056,7 +11068,7 @@
} else {
mBpfNetMaps.removeNiceApp(uid);
}
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -11071,7 +11083,7 @@
} else {
mBpfNetMaps.removeNaughtyApp(uid);
}
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -11083,7 +11095,7 @@
try {
mBpfNetMaps.setUidRule(chain, uid,
allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -11094,7 +11106,7 @@
try {
mBpfNetMaps.setChildChain(chain, enable);
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
@@ -11125,17 +11137,7 @@
throw new IllegalArgumentException("replaceFirewallChain with invalid chain: "
+ chain);
}
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void swapActiveStatsMap() {
- enforceNetworkStackOrSettingsPermission();
- try {
- mBpfNetMaps.swapActiveStatsMap();
- } catch (RemoteException | ServiceSpecificException e) {
+ } catch (ServiceSpecificException e) {
throw new IllegalStateException(e);
}
}
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index c57983b..c1a8195 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -67,6 +67,7 @@
private static final int INVALID_IFINDEX = 0;
private static final int INVALID_PID = 0;
+ private static final long INVALID_COOKIE = 0;
@NonNull
private final INetd mNetd;
@@ -81,6 +82,7 @@
@Nullable
private String mXlatLocalAddress6 = null;
private int mPid = INVALID_PID;
+ private long mCookie = INVALID_COOKIE;
@VisibleForTesting
abstract static class Dependencies {
@@ -185,6 +187,20 @@
throws IOException {
native_stopClatd(iface, pfx96, v4, v6, pid);
}
+
+ /**
+ * Tag socket as clat.
+ */
+ public long tagSocketAsClat(@NonNull FileDescriptor sock) throws IOException {
+ return native_tagSocketAsClat(sock);
+ }
+
+ /**
+ * Untag socket.
+ */
+ public void untagSocket(long cookie) throws IOException {
+ native_untagSocket(cookie);
+ }
}
@VisibleForTesting
@@ -335,6 +351,17 @@
throw new IOException("add anycast sockopt failed: " + e);
}
+ // Tag socket as AID_CLAT to avoid duplicated CLAT data usage accounting.
+ long cookie;
+ try {
+ cookie = mDeps.tagSocketAsClat(writeSock6.getFileDescriptor());
+ } catch (IOException e) {
+ tunFd.close();
+ readSock6.close();
+ writeSock6.close();
+ throw new IOException("tag raw socket failed: " + e);
+ }
+
// Update our packet socket filter to reflect the new 464xlat IP address.
try {
mDeps.configurePacketSocket(readSock6.getFileDescriptor(), v6, ifaceIndex);
@@ -353,7 +380,9 @@
mNat64Prefix = pfx96;
mXlatLocalAddress4 = v4;
mXlatLocalAddress6 = v6;
+ mCookie = cookie;
} catch (IOException e) {
+ mDeps.untagSocket(cookie);
throw new IOException("Error start clatd on " + iface + ": " + e);
} finally {
tunFd.close();
@@ -374,7 +403,7 @@
Log.i(TAG, "Stopping clatd pid=" + mPid + " on " + mIface);
mDeps.stopClatd(mIface, mNat64Prefix, mXlatLocalAddress4, mXlatLocalAddress6, mPid);
- // TODO: remove setIptablesDropRule
+ mDeps.untagSocket(mCookie);
Log.i(TAG, "clatd on " + mIface + " stopped");
@@ -383,6 +412,7 @@
mXlatLocalAddress4 = null;
mXlatLocalAddress6 = null;
mPid = INVALID_PID;
+ mCookie = INVALID_COOKIE;
}
private static native String native_selectIpv4Address(String v4addr, int prefixlen)
@@ -403,4 +433,6 @@
throws IOException;
private static native void native_stopClatd(String iface, String pfx96, String v4, String v6,
int pid) throws IOException;
+ private static native long native_tagSocketAsClat(FileDescriptor sock) throws IOException;
+ private static native void native_untagSocket(long cookie) throws IOException;
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index f82e377..9894444 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -899,6 +899,11 @@
}
}
+ protected void startActivity() throws Exception {
+ final Intent launchIntent = getIntentForComponent(TYPE_COMPONENT_ACTIVTIY);
+ mContext.startActivity(launchIntent);
+ }
+
private void startForegroundService() throws Exception {
final Intent launchIntent = getIntentForComponent(TYPE_COMPONENT_FOREGROUND_SERVICE);
mContext.startForegroundService(launchIntent);
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index 604a0b6..2f30536 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -20,6 +20,7 @@
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
+import static com.android.compatibility.common.util.FeatureUtil.isTV;
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
import static com.android.cts.net.hostside.Property.METERED_NETWORK;
@@ -27,14 +28,14 @@
import static org.junit.Assert.fail;
+import androidx.test.filters.LargeTest;
+
import com.android.compatibility.common.util.CddTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import androidx.test.filters.LargeTest;
-
@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK})
@LargeTest
public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
@@ -113,6 +114,11 @@
turnScreenOff();
assertBackgroundNetworkAccess(false);
turnScreenOn();
+ // On some TVs, it is possible that the activity on top may change after the screen is
+ // turned off and on again, so relaunch the activity in the test app again.
+ if (isTV()) {
+ startActivity();
+ }
assertForegroundNetworkAccess();
// Goes back to background state.
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
index 0526a75..78ae7b8 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
@@ -62,6 +62,7 @@
"dumpsys network_management",
"dumpsys usagestats " + TEST_PKG + " " + TEST_APP2_PKG,
"dumpsys usagestats appstandby",
+ "dumpsys connectivity trafficcontroller",
"dumpsys netd trafficcontroller",
}) {
dumpCommandOutput(out, cmd);
diff --git a/tests/cts/net/AndroidTestTemplate.xml b/tests/cts/net/AndroidTestTemplate.xml
index d605799..48a1c79 100644
--- a/tests/cts/net/AndroidTestTemplate.xml
+++ b/tests/cts/net/AndroidTestTemplate.xml
@@ -30,6 +30,8 @@
</target_preparer>
<target_preparer class="com.android.testutils.ConnectivityCheckTargetPreparer">
</target_preparer>
+ <target_preparer class="com.android.testutils.DisableConfigSyncTargetPreparer">
+ </target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.net.cts" />
<option name="runtime-hint" value="9m4s" />
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 1967e53..988f21b 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -59,6 +59,7 @@
name: "non-connectivity-module-test",
srcs: [
"java/android/app/usage/*.java",
+ "java/android/net/EthernetNetworkUpdateRequestTest.java",
"java/android/net/Ikev2VpnProfileTest.java",
"java/android/net/IpMemoryStoreTest.java",
"java/android/net/IpSecAlgorithmTest.java",
diff --git a/tests/unit/java/android/net/EthernetNetworkUpdateRequestTest.java b/tests/unit/java/android/net/EthernetNetworkUpdateRequestTest.java
new file mode 100644
index 0000000..314fbcf
--- /dev/null
+++ b/tests/unit/java/android/net/EthernetNetworkUpdateRequestTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class EthernetNetworkUpdateRequestTest {
+ private IpConfiguration buildIpConfiguration() {
+ return new IpConfiguration.Builder().setHttpProxy(
+ new ProxyInfo("test.example.com", 1234, "")).build();
+ }
+
+ private NetworkCapabilities buildNetworkCapabilities() {
+ return new NetworkCapabilities.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_ETHERNET).build();
+ }
+
+ @Test
+ public void testParcelUnparcel() {
+ EthernetNetworkUpdateRequest reqWithNonNull =
+ new EthernetNetworkUpdateRequest.Builder().setIpConfiguration(
+ buildIpConfiguration()).setNetworkCapabilities(
+ buildNetworkCapabilities()).build();
+ EthernetNetworkUpdateRequest reqWithNullCaps =
+ new EthernetNetworkUpdateRequest.Builder().setIpConfiguration(
+ buildIpConfiguration()).build();
+
+ assertParcelSane(reqWithNonNull, 2);
+ assertParcelSane(reqWithNullCaps, 2);
+ }
+}
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index ac21e77..f07a10d 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -16,8 +16,6 @@
package com.android.server;
-import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
-import static android.net.INetd.FIREWALL_RULE_ALLOW;
import static android.net.INetd.PERMISSION_INTERNET;
import static org.junit.Assume.assumeFalse;
@@ -60,26 +58,10 @@
@Test
public void testBpfNetMapsBeforeT() throws Exception {
assumeFalse(SdkLevel.isAtLeastT());
- mBpfNetMaps.addNaughtyApp(TEST_UID);
- verify(mNetd).bandwidthAddNaughtyApp(TEST_UID);
- mBpfNetMaps.removeNaughtyApp(TEST_UID);
- verify(mNetd).bandwidthRemoveNaughtyApp(TEST_UID);
- mBpfNetMaps.addNiceApp(TEST_UID);
- verify(mNetd).bandwidthAddNiceApp(TEST_UID);
- mBpfNetMaps.removeNiceApp(TEST_UID);
- verify(mNetd).bandwidthRemoveNiceApp(TEST_UID);
- mBpfNetMaps.setChildChain(FIREWALL_CHAIN_DOZABLE, true);
- verify(mNetd).firewallEnableChildChain(FIREWALL_CHAIN_DOZABLE, true);
- mBpfNetMaps.replaceUidChain(CHAINNAME, true, TEST_UIDS);
- verify(mNetd).firewallReplaceUidChain(CHAINNAME, true, TEST_UIDS);
- mBpfNetMaps.setUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, FIREWALL_RULE_ALLOW);
- verify(mNetd).firewallSetUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, FIREWALL_RULE_ALLOW);
mBpfNetMaps.addUidInterfaceRules(IFNAME, TEST_UIDS);
verify(mNetd).firewallAddUidInterfaceRules(IFNAME, TEST_UIDS);
mBpfNetMaps.removeUidInterfaceRules(TEST_UIDS);
verify(mNetd).firewallRemoveUidInterfaceRules(TEST_UIDS);
- mBpfNetMaps.swapActiveStatsMap();
- verify(mNetd).trafficSwapActiveStatsMap();
mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
verify(mNetd).trafficSetNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 777da17..94272b8 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -36,6 +36,7 @@
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
+import static android.content.pm.PackageManager.FEATURE_ETHERNET;
import static android.content.pm.PackageManager.FEATURE_WIFI;
import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
@@ -137,6 +138,9 @@
import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
import static com.android.testutils.ConcurrentUtils.await;
import static com.android.testutils.ConcurrentUtils.durationOf;
+import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static com.android.testutils.ExceptionUtils.ignoreExceptions;
import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor;
import static com.android.testutils.MiscAsserts.assertContainsAll;
@@ -358,6 +362,7 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.AdditionalAnswers;
@@ -420,6 +425,9 @@
public class ConnectivityServiceTest {
private static final String TAG = "ConnectivityServiceTest";
+ @Rule
+ public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
private static final int TIMEOUT_MS = 2_000;
// Broadcasts can take a long time to be delivered. The test will not wait for that long unless
// there is a failure, so use a long timeout.
@@ -1732,6 +1740,7 @@
mockDefaultPackages();
mockHasSystemFeature(FEATURE_WIFI, true);
mockHasSystemFeature(FEATURE_WIFI_DIRECT, true);
+ mockHasSystemFeature(FEATURE_ETHERNET, true);
doReturn(true).when(mTelephonyManager).isDataCapable();
FakeSettingsProvider.clearSettingsProvider();
@@ -15397,7 +15406,7 @@
null /* callingAttributionTag */));
}
- @Test
+ @Test @IgnoreUpTo(SC_V2)
public void testUpdateRateLimit_EnableDisable() throws Exception {
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
@@ -15436,7 +15445,7 @@
it -> it.first == cellLp.getInterfaceName() && it.second == -1));
}
- @Test
+ @Test @IgnoreUpTo(SC_V2)
public void testUpdateRateLimit_WhenNewNetworkIsAdded() throws Exception {
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
@@ -15462,7 +15471,7 @@
&& it.second == rateLimitInBytesPerSec));
}
- @Test
+ @Test @IgnoreUpTo(SC_V2)
public void testUpdateRateLimit_OnlyAffectsInternetCapableNetworks() throws Exception {
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
@@ -15480,7 +15489,7 @@
assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName()));
}
- @Test
+ @Test @IgnoreUpTo(SC_V2)
public void testUpdateRateLimit_DisconnectingResetsRateLimit()
throws Exception {
// Steps:
@@ -15516,7 +15525,7 @@
assertNull(readHeadWifi.poll(TIMEOUT_MS, it -> it.first == wifiLp.getInterfaceName()));
}
- @Test
+ @Test @IgnoreUpTo(SC_V2)
public void testUpdateRateLimit_UpdateExistingRateLimit() throws Exception {
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
@@ -15545,4 +15554,21 @@
it -> it.first == wifiLp.getInterfaceName()
&& it.second == 2000));
}
+
+ @Test @IgnoreAfter(SC_V2)
+ public void testUpdateRateLimit_DoesNothingBeforeT() throws Exception {
+ final LinkProperties wifiLp = new LinkProperties();
+ wifiLp.setInterfaceName(WIFI_IFNAME);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
+ mWiFiNetworkAgent.connect(true);
+ waitForIdle();
+
+ final ArrayTrackRecord<Pair<String, Long>>.ReadHead readHead =
+ mDeps.mRateLimitHistory.newReadHead();
+
+ setIngressRateLimit(1000);
+ waitForIdle();
+
+ assertNull(readHead.poll(TEST_CALLBACK_TIMEOUT_MS, it -> true));
+ }
}
diff --git a/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt
index 64736f2..7ed55e5 100644
--- a/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt
+++ b/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -23,6 +23,8 @@
import android.content.Context
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.FEATURE_ETHERNET
+import android.content.pm.PackageManager.FEATURE_USB_HOST
import android.content.pm.PackageManager.FEATURE_WIFI
import android.content.pm.PackageManager.FEATURE_WIFI_DIRECT
import android.net.ConnectivityManager.TYPE_ETHERNET
@@ -40,7 +42,6 @@
import android.net.ConnectivityManager.TYPE_WIFI
import android.net.ConnectivityManager.TYPE_WIFI_P2P
import android.net.ConnectivityManager.TYPE_WIMAX
-import android.net.EthernetManager
import android.net.NetworkInfo.DetailedState.CONNECTED
import android.net.NetworkInfo.DetailedState.DISCONNECTED
import android.os.Build
@@ -82,9 +83,8 @@
private val mContext = mock(Context::class.java).apply {
doReturn(true).`when`(mPm).hasSystemFeature(FEATURE_WIFI)
doReturn(true).`when`(mPm).hasSystemFeature(FEATURE_WIFI_DIRECT)
+ doReturn(true).`when`(mPm).hasSystemFeature(FEATURE_ETHERNET)
doReturn(mPm).`when`(this).packageManager
- doReturn(mock(EthernetManager::class.java)).`when`(this).getSystemService(
- Context.ETHERNET_SERVICE)
}
private val mTm = mock(TelephonyManager::class.java).apply {
doReturn(true).`when`(this).isDataCapable
@@ -105,7 +105,8 @@
@Test
fun testSupportedTypes_NoEthernet() {
- doReturn(null).`when`(mContext).getSystemService(Context.ETHERNET_SERVICE)
+ doReturn(false).`when`(mPm).hasSystemFeature(FEATURE_ETHERNET)
+ doReturn(false).`when`(mPm).hasSystemFeature(FEATURE_USB_HOST)
assertFalse(makeTracker().isTypeSupported(TYPE_ETHERNET))
}
diff --git a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java b/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
index a3b0e7c..7688a6b 100644
--- a/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/unit/java/com/android/server/NetworkManagementServiceTest.java
@@ -250,7 +250,7 @@
mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, true);
assertTrue("Should be true since mobile data usage is restricted",
mNMService.isNetworkRestricted(TEST_UID));
- verify(mCm).updateMeteredNetworkDenyList(TEST_UID, true /* enabled */);
+ verify(mCm).addUidToMeteredNetworkDenyList(TEST_UID);
mNMService.setDataSaverModeEnabled(true);
verify(mNetdService).bandwidthEnableDataSaver(true);
@@ -258,16 +258,16 @@
mNMService.setUidOnMeteredNetworkDenylist(TEST_UID, false);
assertTrue("Should be true since data saver is on and the uid is not allowlisted",
mNMService.isNetworkRestricted(TEST_UID));
- verify(mCm).updateMeteredNetworkDenyList(TEST_UID, true /* false */);
+ verify(mCm).removeUidFromMeteredNetworkDenyList(TEST_UID);
mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, true);
assertFalse("Should be false since data saver is on and the uid is allowlisted",
mNMService.isNetworkRestricted(TEST_UID));
- verify(mCm).updateMeteredNetworkAllowList(TEST_UID, true /* enabled */);
+ verify(mCm).addUidToMeteredNetworkAllowList(TEST_UID);
// remove uid from allowlist and turn datasaver off again
mNMService.setUidOnMeteredNetworkAllowlist(TEST_UID, false);
- verify(mCm).updateMeteredNetworkAllowList(TEST_UID, false /* enabled */);
+ verify(mCm).removeUidFromMeteredNetworkAllowList(TEST_UID);
mNMService.setDataSaverModeEnabled(false);
verify(mNetdService).bandwidthEnableDataSaver(false);
assertFalse("Network should not be restricted when data saver is off",
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index 84e02ce..8a2cfc2 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -26,13 +26,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
import android.annotation.NonNull;
import android.net.INetd;
@@ -82,6 +79,7 @@
private static final int TUN_FD = 534;
private static final int RAW_SOCK_FD = 535;
private static final int PACKET_SOCK_FD = 536;
+ private static final long RAW_SOCK_COOKIE = 27149;
private static final ParcelFileDescriptor TUN_PFD = new ParcelFileDescriptor(
new FileDescriptor());
private static final ParcelFileDescriptor RAW_SOCK_PFD = new ParcelFileDescriptor(
@@ -258,12 +256,35 @@
/**
* Stop clatd.
*/
+ @Override
public void stopClatd(@NonNull String iface, @NonNull String pfx96, @NonNull String v4,
@NonNull String v6, int pid) throws IOException {
if (pid == -1) {
fail("unsupported arg: " + pid);
}
}
+
+ /**
+ * Tag socket as clat.
+ */
+ @Override
+ public long tagSocketAsClat(@NonNull FileDescriptor sock) throws IOException {
+ if (Objects.equals(RAW_SOCK_PFD.getFileDescriptor(), sock)) {
+ return RAW_SOCK_COOKIE;
+ }
+ fail("unsupported arg: " + sock);
+ return 0;
+ }
+
+ /**
+ * Untag socket.
+ */
+ @Override
+ public void untagSocket(long cookie) throws IOException {
+ if (cookie != RAW_SOCK_COOKIE) {
+ fail("unsupported arg: " + cookie);
+ }
+ }
};
@NonNull
@@ -326,6 +347,8 @@
inOrder.verify(mDeps).addAnycastSetsockopt(
argThat(fd -> Objects.equals(RAW_SOCK_PFD.getFileDescriptor(), fd)),
eq(XLAT_LOCAL_IPV6ADDR_STRING), eq(BASE_IFINDEX));
+ inOrder.verify(mDeps).tagSocketAsClat(
+ argThat(fd -> Objects.equals(RAW_SOCK_PFD.getFileDescriptor(), fd)));
inOrder.verify(mDeps).configurePacketSocket(
argThat(fd -> Objects.equals(PACKET_SOCK_PFD.getFileDescriptor(), fd)),
eq(XLAT_LOCAL_IPV6ADDR_STRING), eq(BASE_IFINDEX));
@@ -348,13 +371,12 @@
coordinator.clatStop();
inOrder.verify(mDeps).stopClatd(eq(BASE_IFACE), eq(NAT64_PREFIX_STRING),
eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(XLAT_LOCAL_IPV6ADDR_STRING), eq(CLATD_PID));
+ inOrder.verify(mDeps).untagSocket(eq(RAW_SOCK_COOKIE));
inOrder.verifyNoMoreInteractions();
// [4] Expect an IO exception while stopping a clatd that doesn't exist.
assertThrows("java.io.IOException: Clatd has not started", IOException.class,
() -> coordinator.clatStop());
- inOrder.verify(mDeps, never()).stopClatd(anyString(), anyString(), anyString(),
- anyString(), anyInt());
inOrder.verifyNoMoreInteractions();
}
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
index 6872f80..79744b1 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -32,12 +32,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
import android.content.Context;
import android.content.res.Resources;
-import android.net.ConnectivityManager;
import android.net.NetworkStats;
import android.net.TrafficStats;
import android.net.UnderlyingNetworkInfo;
@@ -77,7 +74,6 @@
private File mTestProc;
private NetworkStatsFactory mFactory;
@Mock private Context mContext;
- @Mock private ConnectivityManager mCm;
@Before
public void setUp() throws Exception {
@@ -88,9 +84,6 @@
// applications. So in order to have a test support native library, the native code
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni");
- doReturn(Context.CONNECTIVITY_SERVICE).when(mContext).getSystemServiceName(
- eq(ConnectivityManager.class));
- doReturn(mCm).when(mContext).getSystemService(eq(Context.CONNECTIVITY_SERVICE));
mFactory = new NetworkStatsFactory(mContext, mTestProc, false);
mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
}