blob: 2b31eb6bf8250a0cc040be8cb18303bc9e0b028e [file] [log] [blame]
Christopher Wiley08725a82016-05-18 16:32:44 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.connectivity.tethering;
18
Christopher Wileyf972edc2016-05-23 16:17:30 -070019import static org.mockito.Matchers.anyString;
20import static org.mockito.Mockito.doThrow;
Christopher Wiley279eca32016-05-20 13:23:10 -070021import static org.mockito.Mockito.inOrder;
22import static org.mockito.Mockito.reset;
23import static org.mockito.Mockito.verify;
Christopher Wiley08725a82016-05-18 16:32:44 -070024import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley279eca32016-05-20 13:23:10 -070025import static org.mockito.Mockito.when;
Christopher Wiley08725a82016-05-18 16:32:44 -070026
Christopher Wileye90e0a72016-05-31 10:44:35 -070027import static android.net.ConnectivityManager.TETHER_ERROR_ENABLE_NAT_ERROR;
28import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
29import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
30import static android.net.ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
Erik Klinea954be92017-02-13 17:12:02 +090031import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
32import static android.net.ConnectivityManager.TETHERING_USB;
33import static android.net.ConnectivityManager.TETHERING_WIFI;
Christopher Wileye90e0a72016-05-31 10:44:35 -070034import static com.android.server.connectivity.tethering.IControlsTethering.STATE_AVAILABLE;
35import static com.android.server.connectivity.tethering.IControlsTethering.STATE_TETHERED;
36import static com.android.server.connectivity.tethering.IControlsTethering.STATE_UNAVAILABLE;
37
Christopher Wileycd0cfbb2016-05-31 14:43:08 -070038import android.net.ConnectivityManager;
Christopher Wiley08725a82016-05-18 16:32:44 -070039import android.net.INetworkStatsService;
Christopher Wiley279eca32016-05-20 13:23:10 -070040import android.net.InterfaceConfiguration;
Christopher Wiley08725a82016-05-18 16:32:44 -070041import android.os.INetworkManagementService;
Christopher Wiley279eca32016-05-20 13:23:10 -070042import android.os.RemoteException;
Christopher Wiley08725a82016-05-18 16:32:44 -070043import android.os.test.TestLooper;
Christopher Wiley9bc0df22016-05-25 13:57:27 -070044import android.support.test.filters.SmallTest;
45import android.support.test.runner.AndroidJUnit4;
Christopher Wiley08725a82016-05-18 16:32:44 -070046
47import org.junit.Before;
48import org.junit.Test;
Christopher Wiley9bc0df22016-05-25 13:57:27 -070049import org.junit.runner.RunWith;
Christopher Wiley279eca32016-05-20 13:23:10 -070050import org.mockito.InOrder;
Christopher Wiley08725a82016-05-18 16:32:44 -070051import org.mockito.Mock;
52import org.mockito.MockitoAnnotations;
53
Christopher Wiley9bc0df22016-05-25 13:57:27 -070054@RunWith(AndroidJUnit4.class)
55@SmallTest
Mitchell Wills4622c2d2016-05-23 16:40:10 -070056public class TetherInterfaceStateMachineTest {
Christopher Wiley08725a82016-05-18 16:32:44 -070057 private static final String IFACE_NAME = "testnet1";
Christopher Wiley279eca32016-05-20 13:23:10 -070058 private static final String UPSTREAM_IFACE = "upstream0";
59 private static final String UPSTREAM_IFACE2 = "upstream1";
Christopher Wiley08725a82016-05-18 16:32:44 -070060
61 @Mock private INetworkManagementService mNMService;
62 @Mock private INetworkStatsService mStatsService;
63 @Mock private IControlsTethering mTetherHelper;
Christopher Wiley279eca32016-05-20 13:23:10 -070064 @Mock private InterfaceConfiguration mInterfaceConfiguration;
Lorenzo Colitti5bce5a12016-10-28 17:45:55 +090065 @Mock private IPv6TetheringInterfaceServices mIPv6TetheringInterfaceServices;
Christopher Wiley08725a82016-05-18 16:32:44 -070066
67 private final TestLooper mLooper = new TestLooper();
Mitchell Wills4622c2d2016-05-23 16:40:10 -070068 private TetherInterfaceStateMachine mTestedSm;
Christopher Wiley08725a82016-05-18 16:32:44 -070069
Christopher Wileycd0cfbb2016-05-31 14:43:08 -070070 private void initStateMachine(int interfaceType) throws Exception {
71 mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), interfaceType,
Lorenzo Colitti5bce5a12016-10-28 17:45:55 +090072 mNMService, mStatsService, mTetherHelper, mIPv6TetheringInterfaceServices);
Christopher Wiley279eca32016-05-20 13:23:10 -070073 mTestedSm.start();
74 // Starting the state machine always puts us in a consistent state and notifies
75 // the test of the world that we've changed from an unknown to available state.
76 mLooper.dispatchAll();
77 reset(mNMService, mStatsService, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -070078 when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
Christopher Wiley279eca32016-05-20 13:23:10 -070079 }
80
Christopher Wileycd0cfbb2016-05-31 14:43:08 -070081 private void initTetheredStateMachine(int interfaceType, String upstreamIface) throws Exception {
82 initStateMachine(interfaceType);
Mitchell Wills4622c2d2016-05-23 16:40:10 -070083 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
Christopher Wiley279eca32016-05-20 13:23:10 -070084 if (upstreamIface != null) {
85 dispatchTetherConnectionChanged(upstreamIface);
86 }
87 reset(mNMService, mStatsService, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -070088 when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration);
Christopher Wiley279eca32016-05-20 13:23:10 -070089 }
90
Christopher Wileye90e0a72016-05-31 10:44:35 -070091 @Before public void setUp() throws Exception {
Christopher Wiley08725a82016-05-18 16:32:44 -070092 MockitoAnnotations.initMocks(this);
Christopher Wiley279eca32016-05-20 13:23:10 -070093 }
94
95 @Test
96 public void startsOutAvailable() {
Christopher Wileycd0cfbb2016-05-31 14:43:08 -070097 mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
Erik Klinea954be92017-02-13 17:12:02 +090098 TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper,
Lorenzo Colitti5bce5a12016-10-28 17:45:55 +090099 mIPv6TetheringInterfaceServices);
Christopher Wiley08725a82016-05-18 16:32:44 -0700100 mTestedSm.start();
Christopher Wiley279eca32016-05-20 13:23:10 -0700101 mLooper.dispatchAll();
Christopher Wileye90e0a72016-05-31 10:44:35 -0700102 verify(mTetherHelper).notifyInterfaceStateChange(
103 IFACE_NAME, mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700104 verifyNoMoreInteractions(mTetherHelper, mNMService, mStatsService);
Christopher Wiley08725a82016-05-18 16:32:44 -0700105 }
106
107 @Test
Christopher Wileyf972edc2016-05-23 16:17:30 -0700108 public void shouldDoNothingUntilRequested() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900109 initStateMachine(TETHERING_BLUETOOTH);
Christopher Wiley08725a82016-05-18 16:32:44 -0700110 final int [] NOOP_COMMANDS = {
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700111 TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED,
112 TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR,
113 TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR,
114 TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR,
115 TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR,
116 TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR,
117 TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED
Christopher Wiley08725a82016-05-18 16:32:44 -0700118 };
119 for (int command : NOOP_COMMANDS) {
Christopher Wiley279eca32016-05-20 13:23:10 -0700120 // None of these commands should trigger us to request action from
Christopher Wiley08725a82016-05-18 16:32:44 -0700121 // the rest of the system.
Christopher Wiley279eca32016-05-20 13:23:10 -0700122 dispatchCommand(command);
123 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley08725a82016-05-18 16:32:44 -0700124 }
125 }
126
Christopher Wiley279eca32016-05-20 13:23:10 -0700127 @Test
Christopher Wileyf972edc2016-05-23 16:17:30 -0700128 public void handlesImmediateInterfaceDown() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900129 initStateMachine(TETHERING_BLUETOOTH);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700130
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700131 dispatchCommand(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700132 verify(mTetherHelper).notifyInterfaceStateChange(
133 IFACE_NAME, mTestedSm, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700134 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700135 }
136
137 @Test
Christopher Wileyf972edc2016-05-23 16:17:30 -0700138 public void canBeTethered() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900139 initStateMachine(TETHERING_BLUETOOTH);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700140
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700141 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
Christopher Wiley279eca32016-05-20 13:23:10 -0700142 InOrder inOrder = inOrder(mTetherHelper, mNMService);
Christopher Wiley279eca32016-05-20 13:23:10 -0700143 inOrder.verify(mNMService).tetherInterface(IFACE_NAME);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700144 inOrder.verify(mTetherHelper).notifyInterfaceStateChange(
145 IFACE_NAME, mTestedSm, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700146 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700147 }
148
149 @Test
150 public void canUnrequestTethering() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900151 initTetheredStateMachine(TETHERING_BLUETOOTH, null);
Christopher Wiley279eca32016-05-20 13:23:10 -0700152
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700153 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
Christopher Wiley279eca32016-05-20 13:23:10 -0700154 InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700155 inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700156 inOrder.verify(mTetherHelper).notifyInterfaceStateChange(
157 IFACE_NAME, mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700158 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700159 }
160
161 @Test
Christopher Wileyf972edc2016-05-23 16:17:30 -0700162 public void canBeTetheredAsUsb() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900163 initStateMachine(TETHERING_USB);
Christopher Wiley279eca32016-05-20 13:23:10 -0700164
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700165 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
Christopher Wiley279eca32016-05-20 13:23:10 -0700166 InOrder inOrder = inOrder(mTetherHelper, mNMService);
Christopher Wiley279eca32016-05-20 13:23:10 -0700167 inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME);
168 inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration);
Christopher Wiley279eca32016-05-20 13:23:10 -0700169 inOrder.verify(mNMService).tetherInterface(IFACE_NAME);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700170 inOrder.verify(mTetherHelper).notifyInterfaceStateChange(
171 IFACE_NAME, mTestedSm, STATE_TETHERED, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700172 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700173 }
174
175 @Test
176 public void handlesFirstUpstreamChange() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900177 initTetheredStateMachine(TETHERING_BLUETOOTH, null);
Christopher Wiley279eca32016-05-20 13:23:10 -0700178
179 // Telling the state machine about its upstream interface triggers a little more configuration.
180 dispatchTetherConnectionChanged(UPSTREAM_IFACE);
181 InOrder inOrder = inOrder(mNMService);
182 inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE);
183 inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
184 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700185 }
186
187 @Test
188 public void handlesChangingUpstream() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900189 initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
Christopher Wiley279eca32016-05-20 13:23:10 -0700190
191 dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
192 InOrder inOrder = inOrder(mNMService, mStatsService);
193 inOrder.verify(mStatsService).forceUpdate();
194 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
195 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
196 inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
197 inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
198 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700199 }
200
201 @Test
Erik Klinea954be92017-02-13 17:12:02 +0900202 public void handlesChangingUpstreamNatFailure() throws Exception {
203 initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
204
205 doThrow(RemoteException.class).when(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
206
207 dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
208 InOrder inOrder = inOrder(mNMService, mStatsService);
209 inOrder.verify(mStatsService).forceUpdate();
210 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
211 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
212 inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
Erik Kline8ea45482017-02-13 17:28:53 +0900213 inOrder.verify(mStatsService).forceUpdate();
214 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
215 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE2);
Erik Klinea954be92017-02-13 17:12:02 +0900216 }
217
218 @Test
219 public void handlesChangingUpstreamInterfaceForwardingFailure() throws Exception {
220 initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE);
221
222 doThrow(RemoteException.class).when(mNMService).startInterfaceForwarding(
223 IFACE_NAME, UPSTREAM_IFACE2);
224
225 dispatchTetherConnectionChanged(UPSTREAM_IFACE2);
226 InOrder inOrder = inOrder(mNMService, mStatsService);
227 inOrder.verify(mStatsService).forceUpdate();
228 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
229 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
230 inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2);
231 inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
Erik Kline8ea45482017-02-13 17:28:53 +0900232 inOrder.verify(mStatsService).forceUpdate();
233 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2);
234 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE2);
Erik Klinea954be92017-02-13 17:12:02 +0900235 }
236
237 @Test
Christopher Wiley279eca32016-05-20 13:23:10 -0700238 public void canUnrequestTetheringWithUpstream() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900239 initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE);
Christopher Wiley279eca32016-05-20 13:23:10 -0700240
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700241 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
Christopher Wiley279eca32016-05-20 13:23:10 -0700242 InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper);
243 inOrder.verify(mStatsService).forceUpdate();
244 inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
245 inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
246 inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700247 inOrder.verify(mTetherHelper).notifyInterfaceStateChange(
248 IFACE_NAME, mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
Christopher Wiley279eca32016-05-20 13:23:10 -0700249 verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper);
Christopher Wiley279eca32016-05-20 13:23:10 -0700250 }
251
Christopher Wileyf972edc2016-05-23 16:17:30 -0700252 @Test
253 public void interfaceDownLeadsToUnavailable() throws Exception {
254 for (boolean shouldThrow : new boolean[]{true, false}) {
Erik Klinea954be92017-02-13 17:12:02 +0900255 initTetheredStateMachine(TETHERING_USB, null);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700256
257 if (shouldThrow) {
258 doThrow(RemoteException.class).when(mNMService).untetherInterface(IFACE_NAME);
259 }
260 dispatchCommand(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700261 InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700262 usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
263 usbTeardownOrder.verify(mNMService).setInterfaceConfig(
264 IFACE_NAME, mInterfaceConfiguration);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700265 usbTeardownOrder.verify(mTetherHelper).notifyInterfaceStateChange(
266 IFACE_NAME, mTestedSm, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700267 }
268 }
269
270 @Test
271 public void usbShouldBeTornDownOnTetherError() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900272 initStateMachine(TETHERING_USB);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700273
274 doThrow(RemoteException.class).when(mNMService).tetherInterface(IFACE_NAME);
275 dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700276 InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700277 usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
278 usbTeardownOrder.verify(mNMService).setInterfaceConfig(
279 IFACE_NAME, mInterfaceConfiguration);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700280 usbTeardownOrder.verify(mTetherHelper).notifyInterfaceStateChange(
281 IFACE_NAME, mTestedSm, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700282 }
283
284 @Test
285 public void shouldTearDownUsbOnUpstreamError() throws Exception {
Erik Klinea954be92017-02-13 17:12:02 +0900286 initTetheredStateMachine(TETHERING_USB, null);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700287
288 doThrow(RemoteException.class).when(mNMService).enableNat(anyString(), anyString());
289 dispatchTetherConnectionChanged(UPSTREAM_IFACE);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700290 InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700291 usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown();
292 usbTeardownOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration);
Christopher Wileye90e0a72016-05-31 10:44:35 -0700293 usbTeardownOrder.verify(mTetherHelper).notifyInterfaceStateChange(
294 IFACE_NAME, mTestedSm, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR);
Christopher Wileyf972edc2016-05-23 16:17:30 -0700295 }
Christopher Wiley279eca32016-05-20 13:23:10 -0700296
297 /**
298 * Send a command to the state machine under test, and run the event loop to idle.
299 *
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700300 * @param command One of the TetherInterfaceStateMachine.CMD_* constants.
Christopher Wiley279eca32016-05-20 13:23:10 -0700301 */
302 private void dispatchCommand(int command) {
303 mTestedSm.sendMessage(command);
304 mLooper.dispatchAll();
305 }
306
307 /**
308 * Special override to tell the state machine that the upstream interface has changed.
309 *
310 * @see #dispatchCommand(int)
311 * @param upstreamIface String name of upstream interface (or null)
312 */
313 private void dispatchTetherConnectionChanged(String upstreamIface) {
Mitchell Wills4622c2d2016-05-23 16:40:10 -0700314 mTestedSm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
315 upstreamIface);
Christopher Wiley279eca32016-05-20 13:23:10 -0700316 mLooper.dispatchAll();
Christopher Wiley08725a82016-05-18 16:32:44 -0700317 }
Lorenzo Colitti5bce5a12016-10-28 17:45:55 +0900318}