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
diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java
index 709b774..1ab7515 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 @@
*/
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 @@
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 115f0e1..e90d55d 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.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 java.net.InetAddress;
import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -445,7 +447,20 @@
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 @@
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 @@
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());