Merge "Always stop dhcp server even it is obsolete" am: 0ae446b50d am: 4f671f3834 am: 17cfe5d843 am: 9125d2ed58

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1370217

Change-Id: I434a17c5f41aed0b7f40cc5d23f6c6c0999d3fa5
This commit is contained in:
Mark Chien
2020-07-29 05:36:59 +00:00
committed by Automerger Merge Worker
2 changed files with 50 additions and 14 deletions

View File

@@ -423,9 +423,13 @@ public class IpServer extends StateMachine {
getHandler().post(() -> { getHandler().post(() -> {
// We are on the handler thread: mDhcpServerStartIndex can be read safely. // We are on the handler thread: mDhcpServerStartIndex can be read safely.
if (mStartIndex != mDhcpServerStartIndex) { if (mStartIndex != mDhcpServerStartIndex) {
// This start request is obsolete. When the |server| binder token goes out of // This start request is obsolete. Explicitly stop the DHCP server to shut
// scope, the garbage collector will finalize it, which causes the network stack // down its thread. When the |server| binder token goes out of scope, the
// process garbage collector to collect the server itself. // garbage collector will finalize it, which causes the network stack process
// garbage collector to collect the server itself.
try {
server.stop(null);
} catch (RemoteException e) { }
return; return;
} }

View File

@@ -50,6 +50,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.inOrder;
@@ -73,6 +74,7 @@ import android.net.MacAddress;
import android.net.RouteInfo; import android.net.RouteInfo;
import android.net.TetherOffloadRuleParcel; import android.net.TetherOffloadRuleParcel;
import android.net.TetherStatsParcel; import android.net.TetherStatsParcel;
import android.net.dhcp.DhcpServerCallbacks;
import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.DhcpServingParamsParcel;
import android.net.dhcp.IDhcpEventCallbacks; import android.net.dhcp.IDhcpEventCallbacks;
import android.net.dhcp.IDhcpServer; import android.net.dhcp.IDhcpServer;
@@ -163,17 +165,6 @@ public class IpServerTest {
private void initStateMachine(int interfaceType, boolean usingLegacyDhcp, private void initStateMachine(int interfaceType, boolean usingLegacyDhcp,
boolean usingBpfOffload) throws Exception { boolean usingBpfOffload) throws Exception {
doAnswer(inv -> {
final IDhcpServerCallbacks cb = inv.getArgument(2);
new Thread(() -> {
try {
cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
} catch (RemoteException e) {
fail(e.getMessage());
}
}).run();
return null;
}).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon); when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon);
when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS); when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS);
@@ -225,6 +216,20 @@ public class IpServerTest {
when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress); when(mAddressCoordinator.requestDownstreamAddress(any())).thenReturn(mTestAddress);
} }
private void setUpDhcpServer() throws Exception {
doAnswer(inv -> {
final IDhcpServerCallbacks cb = inv.getArgument(2);
new Thread(() -> {
try {
cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
} catch (RemoteException e) {
fail(e.getMessage());
}
}).run();
return null;
}).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any());
}
@Before public void setUp() throws Exception { @Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog); when(mSharedLog.forSubComponent(anyString())).thenReturn(mSharedLog);
@@ -258,6 +263,8 @@ public class IpServerTest {
return mTetherConfig; return mTetherConfig;
} }
})); }));
setUpDhcpServer();
} }
@Test @Test
@@ -965,6 +972,31 @@ public class IpServerTest {
reset(mRaDaemon); reset(mRaDaemon);
} }
@Test
public void testStopObsoleteDhcpServer() throws Exception {
final ArgumentCaptor<DhcpServerCallbacks> cbCaptor =
ArgumentCaptor.forClass(DhcpServerCallbacks.class);
doNothing().when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(),
cbCaptor.capture());
initStateMachine(TETHERING_WIFI);
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
verify(mDhcpServer, never()).startWithCallbacks(any(), any());
// No stop dhcp server because dhcp server is not created yet.
dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED);
verify(mDhcpServer, never()).stop(any());
// Stop obsolete dhcp server.
try {
final DhcpServerCallbacks cb = cbCaptor.getValue();
cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
mLooper.dispatchAll();
} catch (RemoteException e) {
fail(e.getMessage());
}
verify(mDhcpServer).stop(any());
}
private void assertDhcpServingParams(final DhcpServingParamsParcel params, private void assertDhcpServingParams(final DhcpServingParamsParcel params,
final IpPrefix prefix) { final IpPrefix prefix) {
// Last address byte is random // Last address byte is random