From a2d1cb97fa2e8397ba4116bb983e5d0801dfb349 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Thu, 12 Jun 2025 15:30:57 -0700 Subject: [PATCH] Pass TrackingReason to NetworkInterfaceState Because changing the tethering mode invokes addInterface(), the tracking mode for the tethering interface needs to be persisted separately. Test: TH Flag: EXEMPT mainline Bug: 1000001 Change-Id: Ifb8371a55a582bf2133a59bdbedcce95c94626cc --- .../ethernet/EthernetNetworkFactory.java | 15 ++++++--- .../server/ethernet/EthernetTracker.java | 33 +++++++++++-------- .../ethernet/EthernetNetworkFactoryTest.java | 5 +-- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java index 531b60fe7e..9e2d5721b8 100644 --- a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java +++ b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java @@ -50,9 +50,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; import com.android.net.module.util.InterfaceParams; import com.android.server.connectivity.ConnectivityResources; +import com.android.server.ethernet.EthernetTracker.TrackingReason; import java.io.FileDescriptor; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -159,7 +161,7 @@ public class EthernetNetworkFactory { /** Add an interface to the factory. */ public void addInterface(EthernetPort port, IpConfiguration ipConfig, - NetworkCapabilities capabilities) { + NetworkCapabilities capabilities, EnumSet trackingReason) { final String ifaceName = port.getInterfaceName(); final String hwAddress = port.getMacAddress().toString(); @@ -177,7 +179,7 @@ public class EthernetNetworkFactory { } final NetworkInterfaceState iface = new NetworkInterfaceState( - port, mHandler, mContext, ipConfig, nc, mProvider, mDeps); + port, trackingReason, mHandler, mContext, ipConfig, nc, mProvider, mDeps); mTrackingInterfaces.put(ifaceName, iface); } @@ -259,6 +261,7 @@ public class EthernetNetworkFactory { @VisibleForTesting static class NetworkInterfaceState { private final EthernetPort mPort; + private final EnumSet mTrackingReason; private final Handler mHandler; private final Context mContext; private final NetworkProvider mNetworkProvider; @@ -401,10 +404,12 @@ public class EthernetNetworkFactory { } } - NetworkInterfaceState(EthernetPort port, Handler handler, Context context, - @NonNull IpConfiguration ipConfig, @NonNull NetworkCapabilities capabilities, - NetworkProvider networkProvider, Dependencies deps) { + NetworkInterfaceState(EthernetPort port, EnumSet trackingReason, + Handler handler, Context context, IpConfiguration ipConfig, + NetworkCapabilities capabilities, NetworkProvider networkProvider, + Dependencies deps) { mPort = port; + mTrackingReason = trackingReason; mIpConfig = Objects.requireNonNull(ipConfig); mCapabilities = Objects.requireNonNull(capabilities); mLegacyType = getLegacyType(mCapabilities); diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java index 990b358e32..cc4be5bdbd 100644 --- a/service-t/src/com/android/server/ethernet/EthernetTracker.java +++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java @@ -171,7 +171,8 @@ public class EthernetTracker { // The first interface discovered is set as the mTetheringInterface. It is the interface that is // returned when a tethered interface is requested; until then, it remains in client mode. Its // current mode is reflected in mTetheringInterfaceMode. - private EthernetPort mTetheringInterface; + @Nullable private EthernetPort mTetheringInterface; + @Nullable private EnumSet mTetheringTrackingReason; private int mTetheringInterfaceMode = INTERFACE_MODE_CLIENT; // Tracks whether clients were notified that the tethered interface is available private boolean mTetheredInterfaceWasAvailable = false; @@ -205,7 +206,7 @@ public class EthernetTracker { } /** Enum used to convey the reason an interface is tracked. */ - private enum TrackingReason { + public enum TrackingReason { /** The interface is tracked because it is part of the regex. */ REGEX, /** The interface is tracked because it is an NCM interface. */ @@ -241,11 +242,12 @@ public class EthernetTracker { sendNetlinkMessage(buf); } - private void onNewLink(EthernetPort port, boolean linkUp) { + private void onNewLink(EthernetPort port, EnumSet trackingReason, + boolean linkUp) { final String ifname = port.getInterfaceName(); if (!mFactory.hasInterface(ifname) && !ifname.equals(mTetheringInterface)) { Log.i(TAG, "onInterfaceAdded: " + port); - maybeTrackInterface(port); + maybeTrackInterface(port, trackingReason); } Log.i(TAG, "interfaceLinkStateChanged: " + port + ", up: " + linkUp); updateInterfaceState(port, linkUp); @@ -273,12 +275,13 @@ public class EthernetTracker { final EthernetPort port = new EthernetPort(ifname, mac, ifinfomsg.index); // check if the received message applies to an ethernet interface. // TODO: start tracking USB NCM interfaces. - if (!getTrackingReason(port.getInterfaceName()).contains(TrackingReason.REGEX)) return; + final EnumSet trackingReason = getTrackingReason(ifname); + if (!trackingReason.contains(TrackingReason.REGEX)) return; switch (msg.getHeader().nlmsg_type) { case NetlinkConstants.RTM_NEWLINK: final boolean linkUp = (ifinfomsg.flags & NetlinkConstants.IFF_LOWER_UP) != 0; - onNewLink(port, linkUp); + onNewLink(port, trackingReason, linkUp); break; case NetlinkConstants.RTM_DELLINK: @@ -628,7 +631,7 @@ public class EthernetTracker { mTetheringInterfaceMode = mode; if (mTetheringInterface != null) { removeInterface(mTetheringInterface); - addInterface(mTetheringInterface); + addInterface(mTetheringInterface, mTetheringTrackingReason); // when this broadcast is sent, any calls to notifyTetheredInterfaceAvailable or // notifyTetheredInterfaceUnavailable have already happened broadcastInterfaceStateChange(mTetheringInterface.getInterfaceName()); @@ -676,11 +679,12 @@ public class EthernetTracker { final String iface = port.getInterfaceName(); if (mTetheringInterface != null && iface.equals(mTetheringInterface.getInterfaceName())) { mTetheringInterface = null; + mTetheringTrackingReason = null; } broadcastInterfaceStateChange(iface); } - private void addInterface(EthernetPort port) { + private void addInterface(EthernetPort port, EnumSet trackingReason) { final String iface = port.getInterfaceName(); final InterfaceConfigurationParcel config; // Bring up the interface so we get link status indications. @@ -717,7 +721,7 @@ public class EthernetTracker { IpConfiguration ipConfiguration = getOrCreateIpConfiguration(iface); Log.d(TAG, "Tracking interface in client mode: " + iface); - mFactory.addInterface(port, ipConfiguration, nc); + mFactory.addInterface(port, ipConfiguration, nc, trackingReason); // Note: if the interface already has link (e.g., if we crashed and got // restarted while it was running), we need to fake a link up notification so we @@ -784,7 +788,7 @@ public class EthernetTracker { mTetheredInterfaceWasAvailable = available; } - private void maybeTrackInterface(EthernetPort port) { + private void maybeTrackInterface(EthernetPort port, EnumSet trackingReason) { final String iface = port.getInterfaceName(); // If we don't already track this interface, and if this interface matches // our regex, start tracking it. @@ -794,12 +798,15 @@ public class EthernetTracker { } if (DBG) Log.i(TAG, "maybeTrackInterface: " + port); - // Do not use an interface for tethering if it has configured NetworkCapabilities. - if (mTetheringInterface == null && !mNetworkCapabilities.containsKey(iface)) { + // Do not use an interface for tethering if it has configured NetworkCapabilities, or if it + // was not included in the regex. + if (mTetheringInterface == null && !mNetworkCapabilities.containsKey(iface) + && trackingReason.contains(TrackingReason.REGEX)) { mTetheringInterface = port; + mTetheringTrackingReason = trackingReason; } - addInterface(port); + addInterface(port, trackingReason); broadcastInterfaceStateChange(iface); } diff --git a/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java b/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java index 74b02367c0..e62b2fcfea 100644 --- a/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java +++ b/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java @@ -69,6 +69,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.EnumSet; import java.util.Objects; @SmallTest @@ -232,8 +233,8 @@ public class EthernetNetworkFactoryTest { private void createInterfaceUndergoingProvisioning( EthernetPort port, final int transportType) { final IpConfiguration ipConfig = createDefaultIpConfig(); - mNetFactory.addInterface(port, ipConfig, - createInterfaceCapsBuilder(transportType).build()); + mNetFactory.addInterface(port, ipConfig, createInterfaceCapsBuilder(transportType).build(), + EnumSet.of(EthernetTracker.TrackingReason.REGEX)); assertTrue(mNetFactory.updateInterfaceLinkState(port, true)); ArgumentCaptor captor = ArgumentCaptor.forClass(