From 1f8bd41e872827ec43e5b643d75bf399dc93d2a1 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Wed, 1 Jun 2022 21:06:42 -0700 Subject: [PATCH] ethernet: broadcast state change for server interfaces Also update the test to ensure mFactory.hasInterface is mocked to match mFactory.getInterfaceState: previously it would be called by the factory in the mocked getInterfaceState, but the new code calls it directly. Bug: 171872016 Test: atest EthernetManagerTest Change-Id: I9ac959f181c88a7992991923b98a836f2833fa88 (cherry picked from commit f33f276b291d8b24b680a02f64404fd1c94186ad) Merged-In: I9ac959f181c88a7992991923b98a836f2833fa88 --- .../server/ethernet/EthernetTracker.java | 31 +++++++++++++++---- .../server/ethernet/EthernetTrackerTest.java | 19 ++++++++++-- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java index 709b774e4f..1ab7515b8c 100644 --- a/service-t/src/com/android/server/ethernet/EthernetTracker.java +++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java @@ -229,7 +229,7 @@ public class EthernetTracker { */ protected void broadcastInterfaceStateChange(@NonNull String iface) { ensureRunningOnEthernetServiceThread(); - final int state = mFactory.getInterfaceState(iface); + final int state = getInterfaceState(iface); final int role = getInterfaceRole(iface); final IpConfiguration config = getIpConfigurationForCallback(iface, state); final int n = mListeners.beginBroadcast(); @@ -436,15 +436,34 @@ public class EthernetTracker { if (mDefaultInterface != null) { removeInterface(mDefaultInterface); addInterface(mDefaultInterface); + // when this broadcast is sent, any calls to notifyTetheredInterfaceAvailable or + // notifyTetheredInterfaceUnavailable have already happened + broadcastInterfaceStateChange(mDefaultInterface); } } + private int getInterfaceState(final String iface) { + if (mFactory.hasInterface(iface)) { + return mFactory.getInterfaceState(iface); + } + if (getInterfaceMode(iface) == INTERFACE_MODE_SERVER) { + // server mode interfaces are not tracked by the factory. + // TODO(b/234743836): interface state for server mode interfaces is not tracked + // properly; just return link up. + return EthernetManager.STATE_LINK_UP; + } + return EthernetManager.STATE_ABSENT; + } + private int getInterfaceRole(final String iface) { - if (!mFactory.hasInterface(iface)) return EthernetManager.ROLE_NONE; - final int mode = getInterfaceMode(iface); - return (mode == INTERFACE_MODE_CLIENT) - ? EthernetManager.ROLE_CLIENT - : EthernetManager.ROLE_SERVER; + if (mFactory.hasInterface(iface)) { + // only client mode interfaces are tracked by the factory. + return EthernetManager.ROLE_CLIENT; + } + if (getInterfaceMode(iface) == INTERFACE_MODE_SERVER) { + return EthernetManager.ROLE_SERVER; + } + return EthernetManager.ROLE_NONE; } private int getInterfaceMode(final String iface) { diff --git a/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java b/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java index 115f0e145b..e90d55dcf4 100644 --- a/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java +++ b/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java @@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -68,6 +69,7 @@ import org.mockito.MockitoAnnotations; import java.net.InetAddress; import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; @SmallTest @RunWith(AndroidJUnit4.class) @@ -445,7 +447,20 @@ public class EthernetTrackerTest { when(mNetd.interfaceGetList()).thenReturn(new String[] {testIface}); when(mNetd.interfaceGetCfg(eq(testIface))).thenReturn(ifaceParcel); doReturn(new String[] {testIface}).when(mFactory).getAvailableInterfaces(anyBoolean()); - doReturn(EthernetManager.STATE_LINK_UP).when(mFactory).getInterfaceState(eq(testIface)); + + final AtomicBoolean ifaceUp = new AtomicBoolean(true); + doAnswer(inv -> ifaceUp.get()).when(mFactory).hasInterface(testIface); + doAnswer(inv -> + ifaceUp.get() ? EthernetManager.STATE_LINK_UP : EthernetManager.STATE_ABSENT) + .when(mFactory).getInterfaceState(testIface); + doAnswer(inv -> { + ifaceUp.set(true); + return null; + }).when(mFactory).addInterface(eq(testIface), eq(testHwAddr), any(), any()); + doAnswer(inv -> { + ifaceUp.set(false); + return null; + }).when(mFactory).removeInterface(testIface); final EthernetStateListener listener = spy(new EthernetStateListener()); tracker.addListener(listener, true /* canUseRestrictedNetworks */); @@ -456,7 +471,6 @@ public class EthernetTrackerTest { verify(listener).onEthernetStateChanged(eq(EthernetManager.ETHERNET_STATE_ENABLED)); reset(listener); - doReturn(EthernetManager.STATE_ABSENT).when(mFactory).getInterfaceState(eq(testIface)); tracker.setEthernetEnabled(false); waitForIdle(); verify(mFactory).removeInterface(eq(testIface)); @@ -465,7 +479,6 @@ public class EthernetTrackerTest { anyInt(), any()); reset(listener); - doReturn(EthernetManager.STATE_LINK_UP).when(mFactory).getInterfaceState(eq(testIface)); tracker.setEthernetEnabled(true); waitForIdle(); verify(mFactory).addInterface(eq(testIface), eq(testHwAddr), any(), any());