blob: 40d5544dccd83f4b6a07231665b01f43a47be3bf [file] [log] [blame]
Christopher Wiley497c1472016-10-11 13:26:03 -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;
18
Erik Klinec438e302017-07-04 22:02:49 +090019import static android.hardware.usb.UsbManager.USB_CONFIGURED;
20import static android.hardware.usb.UsbManager.USB_CONNECTED;
21import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
Erik Kline465ff3a2018-03-09 14:18:02 +090022import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
23import static android.net.ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY;
24import static android.net.ConnectivityManager.EXTRA_ACTIVE_TETHER;
25import static android.net.ConnectivityManager.EXTRA_AVAILABLE_TETHER;
26import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
Erik Klinec438e302017-07-04 22:02:49 +090027import static android.net.ConnectivityManager.TETHERING_WIFI;
28import static android.net.ConnectivityManager.TETHERING_USB;
Erik Kline465ff3a2018-03-09 14:18:02 +090029import static android.net.ConnectivityManager.TYPE_MOBILE;
Erik Kline2efb8272017-05-31 15:53:53 +090030import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
31import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
32import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
33import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
34import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
35import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090036
Erik Klineea9cc482017-03-10 19:35:34 +090037import static org.junit.Assert.assertEquals;
Christopher Wiley497c1472016-10-11 13:26:03 -070038import static org.junit.Assert.assertTrue;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090039import static org.mockito.ArgumentMatchers.argThat;
40import static org.mockito.ArgumentMatchers.notNull;
Christopher Wiley497c1472016-10-11 13:26:03 -070041import static org.mockito.Matchers.anyBoolean;
Erik Klineea9cc482017-03-10 19:35:34 +090042import static org.mockito.Matchers.anyInt;
43import static org.mockito.Matchers.anyString;
Christopher Wiley497c1472016-10-11 13:26:03 -070044import static org.mockito.Matchers.eq;
Erik Kline1fdc2e22017-05-08 17:56:35 +090045import static org.mockito.Mockito.any;
Erik Klineea9cc482017-03-10 19:35:34 +090046import static org.mockito.Mockito.atLeastOnce;
Erik Kline1fdc2e22017-05-08 17:56:35 +090047import static org.mockito.Mockito.doThrow;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090048import static org.mockito.Mockito.never;
Erik Klineea9cc482017-03-10 19:35:34 +090049import static org.mockito.Mockito.times;
50import static org.mockito.Mockito.verify;
51import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley497c1472016-10-11 13:26:03 -070052import static org.mockito.Mockito.when;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010053import static org.mockito.Mockito.mock;
Christopher Wiley497c1472016-10-11 13:26:03 -070054
Erik Kline8351faa2017-04-17 16:47:23 +090055import android.content.BroadcastReceiver;
Erik Kline92c4db02017-05-31 10:21:32 +090056import android.content.ContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070057import android.content.Context;
Erik Klineea9cc482017-03-10 19:35:34 +090058import android.content.Intent;
Erik Kline8351faa2017-04-17 16:47:23 +090059import android.content.IntentFilter;
Erik Klinef3a08b42017-06-07 16:33:19 +090060import android.content.pm.ApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -070061import android.content.res.Resources;
Erik Klineea9cc482017-03-10 19:35:34 +090062import android.hardware.usb.UsbManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090063import android.net.INetd;
Christopher Wiley497c1472016-10-11 13:26:03 -070064import android.net.INetworkPolicyManager;
65import android.net.INetworkStatsService;
Erik Klineea9cc482017-03-10 19:35:34 +090066import android.net.InterfaceConfiguration;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090067import android.net.IpPrefix;
68import android.net.LinkAddress;
69import android.net.LinkProperties;
70import android.net.MacAddress;
71import android.net.Network;
72import android.net.NetworkCapabilities;
73import android.net.NetworkInfo;
Erik Kline72302902018-06-14 17:36:40 +090074import android.net.NetworkRequest;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090075import android.net.NetworkState;
76import android.net.NetworkUtils;
77import android.net.RouteInfo;
Erik Kline7a4ccc62018-08-27 17:26:47 +090078import android.net.ip.IpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090079import android.net.ip.RouterAdvertisementDaemon;
80import android.net.util.InterfaceParams;
81import android.net.util.NetworkConstants;
Erik Klinef4b6e342017-04-25 19:19:59 +090082import android.net.util.SharedLog;
Erik Klineea9cc482017-03-10 19:35:34 +090083import android.net.wifi.WifiConfiguration;
84import android.net.wifi.WifiManager;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010085import android.os.Bundle;
Erik Klineea9cc482017-03-10 19:35:34 +090086import android.os.Handler;
Christopher Wiley497c1472016-10-11 13:26:03 -070087import android.os.INetworkManagementService;
88import android.os.PersistableBundle;
Erik Kline1fdc2e22017-05-08 17:56:35 +090089import android.os.RemoteException;
Christopher Wiley497c1472016-10-11 13:26:03 -070090import android.os.test.TestLooper;
Erik Klineea9cc482017-03-10 19:35:34 +090091import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010092import android.os.UserManager;
Erik Kline92c4db02017-05-31 10:21:32 +090093import android.provider.Settings;
Christopher Wiley497c1472016-10-11 13:26:03 -070094import android.support.test.filters.SmallTest;
95import android.support.test.runner.AndroidJUnit4;
96import android.telephony.CarrierConfigManager;
Erik Kline92c4db02017-05-31 10:21:32 +090097import android.test.mock.MockContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070098
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090099import com.android.internal.util.ArrayUtils;
100import com.android.internal.util.StateMachine;
Erik Klineea9cc482017-03-10 19:35:34 +0900101import com.android.internal.util.test.BroadcastInterceptingContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900102import com.android.internal.util.test.FakeSettingsProvider;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900103import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900104import com.android.server.connectivity.tethering.OffloadHardwareInterface;
105import com.android.server.connectivity.tethering.TetheringDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900106import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
Erik Klineea9cc482017-03-10 19:35:34 +0900107
Erik Kline8351faa2017-04-17 16:47:23 +0900108import org.junit.After;
Christopher Wiley497c1472016-10-11 13:26:03 -0700109import org.junit.Before;
110import org.junit.Test;
111import org.junit.runner.RunWith;
112import org.mockito.Mock;
113import org.mockito.MockitoAnnotations;
114
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900115import java.net.Inet4Address;
116import java.net.Inet6Address;
Erik Kline8351faa2017-04-17 16:47:23 +0900117import java.util.ArrayList;
118import java.util.Vector;
119
Christopher Wiley497c1472016-10-11 13:26:03 -0700120@RunWith(AndroidJUnit4.class)
121@SmallTest
122public class TetheringTest {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900123 private static final int IFINDEX_OFFSET = 100;
124
Christopher Wiley497c1472016-10-11 13:26:03 -0700125 private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900126 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
127 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
128 private static final String TEST_USB_IFNAME = "test_rndis0";
129 private static final String TEST_WLAN_IFNAME = "test_wlan0";
Christopher Wiley497c1472016-10-11 13:26:03 -0700130
Erik Kline72302902018-06-14 17:36:40 +0900131 // Actual contents of the request don't matter for this test. The lack of
132 // any specific TRANSPORT_* is sufficient to identify this request.
133 private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
134
Erik Klinef3a08b42017-06-07 16:33:19 +0900135 @Mock private ApplicationInfo mApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -0700136 @Mock private Context mContext;
137 @Mock private INetworkManagementService mNMService;
138 @Mock private INetworkStatsService mStatsService;
139 @Mock private INetworkPolicyManager mPolicyManager;
140 @Mock private MockableSystemProperties mSystemProperties;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900141 @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
Christopher Wiley497c1472016-10-11 13:26:03 -0700142 @Mock private Resources mResources;
Erik Klineea9cc482017-03-10 19:35:34 +0900143 @Mock private UsbManager mUsbManager;
144 @Mock private WifiManager mWifiManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700145 @Mock private CarrierConfigManager mCarrierConfigManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900146 @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
147 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
148 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
149 @Mock private INetd mNetd;
150
151 private final MockTetheringDependencies mTetheringDependencies =
152 new MockTetheringDependencies();
Christopher Wiley497c1472016-10-11 13:26:03 -0700153
154 // Like so many Android system APIs, these cannot be mocked because it is marked final.
155 // We have to use the real versions.
156 private final PersistableBundle mCarrierConfig = new PersistableBundle();
157 private final TestLooper mLooper = new TestLooper();
158
Erik Kline8351faa2017-04-17 16:47:23 +0900159 private Vector<Intent> mIntents;
Erik Klineea9cc482017-03-10 19:35:34 +0900160 private BroadcastInterceptingContext mServiceContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900161 private MockContentResolver mContentResolver;
Erik Kline8351faa2017-04-17 16:47:23 +0900162 private BroadcastReceiver mBroadcastReceiver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700163 private Tethering mTethering;
164
Erik Klineea9cc482017-03-10 19:35:34 +0900165 private class MockContext extends BroadcastInterceptingContext {
166 MockContext(Context base) {
167 super(base);
168 }
169
170 @Override
Erik Klinef3a08b42017-06-07 16:33:19 +0900171 public ApplicationInfo getApplicationInfo() { return mApplicationInfo; }
172
173 @Override
Erik Kline92c4db02017-05-31 10:21:32 +0900174 public ContentResolver getContentResolver() { return mContentResolver; }
175
176 @Override
177 public String getPackageName() { return "TetheringTest"; }
178
179 @Override
Erik Klineea9cc482017-03-10 19:35:34 +0900180 public Resources getResources() { return mResources; }
181
182 @Override
183 public Object getSystemService(String name) {
Erik Klineea9cc482017-03-10 19:35:34 +0900184 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
Erik Klinec438e302017-07-04 22:02:49 +0900185 if (Context.USB_SERVICE.equals(name)) return mUsbManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900186 return super.getSystemService(name);
187 }
188 }
189
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900190 public class MockTetheringDependencies extends TetheringDependencies {
Erik Kline465ff3a2018-03-09 14:18:02 +0900191 StateMachine upstreamNetworkMonitorMasterSM;
Erik Kline7a4ccc62018-08-27 17:26:47 +0900192 ArrayList<IpServer> ipv6CoordinatorNotifyList;
Erik Kline465ff3a2018-03-09 14:18:02 +0900193 int isTetheringSupportedCalls;
194
195 public void reset() {
196 upstreamNetworkMonitorMasterSM = null;
197 ipv6CoordinatorNotifyList = null;
198 isTetheringSupportedCalls = 0;
199 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900200
201 @Override
202 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
203 return mOffloadHardwareInterface;
204 }
205
206 @Override
207 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
208 StateMachine target, SharedLog log, int what) {
209 upstreamNetworkMonitorMasterSM = target;
210 return mUpstreamNetworkMonitor;
211 }
212
213 @Override
214 public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
Erik Kline7a4ccc62018-08-27 17:26:47 +0900215 ArrayList<IpServer> notifyList, SharedLog log) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900216 ipv6CoordinatorNotifyList = notifyList;
217 return mIPv6TetheringCoordinator;
218 }
219
220 @Override
Erik Kline7a4ccc62018-08-27 17:26:47 +0900221 public IpServer.Dependencies getIpServerDependencies() {
222 return new IpServer.Dependencies() {
223 @Override
224 public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
225 InterfaceParams ifParams) {
226 return mRouterAdvertisementDaemon;
227 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900228
Erik Kline7a4ccc62018-08-27 17:26:47 +0900229 @Override
230 public InterfaceParams getInterfaceParams(String ifName) {
231 final String[] ifaces = new String[] {
232 TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME };
233 final int index = ArrayUtils.indexOf(ifaces, ifName);
234 assertTrue("Non-mocked interface: " + ifName, index >= 0);
235 return new InterfaceParams(ifName, index + IFINDEX_OFFSET,
236 MacAddress.ALL_ZEROS_ADDRESS);
237 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900238
Erik Kline7a4ccc62018-08-27 17:26:47 +0900239 @Override
240 public INetd getNetdService() {
241 return mNetd;
242 }
243 };
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900244 }
Erik Kline465ff3a2018-03-09 14:18:02 +0900245
246 @Override
247 public boolean isTetheringSupported() {
248 isTetheringSupportedCalls++;
249 return true;
250 }
Erik Kline72302902018-06-14 17:36:40 +0900251
252 @Override
253 public NetworkRequest getDefaultNetworkRequest() {
254 return mDefaultRequest;
255 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900256 }
257
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900258 private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
259 boolean with464xlat) {
Erik Kline465ff3a2018-03-09 14:18:02 +0900260 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, 0, null, null);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900261 info.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
262 final LinkProperties prop = new LinkProperties();
263 prop.setInterfaceName(TEST_MOBILE_IFNAME);
264
265 if (withIPv4) {
266 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
267 NetworkUtils.numericToInetAddress("10.0.0.1"), TEST_MOBILE_IFNAME));
268 }
269
270 if (withIPv6) {
271 prop.addDnsServer(NetworkUtils.numericToInetAddress("2001:db8::2"));
272 prop.addLinkAddress(
273 new LinkAddress(NetworkUtils.numericToInetAddress("2001:db8::"),
274 NetworkConstants.RFC7421_PREFIX_LENGTH));
275 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
276 NetworkUtils.numericToInetAddress("2001:db8::1"), TEST_MOBILE_IFNAME));
277 }
278
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900279 if (with464xlat) {
280 final LinkProperties stackedLink = new LinkProperties();
281 stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
282 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
283 NetworkUtils.numericToInetAddress("192.0.0.1"), TEST_XLAT_MOBILE_IFNAME));
284
285 prop.addStackedLink(stackedLink);
286 }
287
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900288
289 final NetworkCapabilities capabilities = new NetworkCapabilities()
290 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);;
291 return new NetworkState(info, prop, capabilities, new Network(100), null, "netid");
292 }
293
294 private static NetworkState buildMobileIPv4UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900295 return buildMobileUpstreamState(true, false, false);
296 }
297
298 private static NetworkState buildMobileIPv6UpstreamState() {
299 return buildMobileUpstreamState(false, true, false);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900300 }
301
302 private static NetworkState buildMobileDualStackUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900303 return buildMobileUpstreamState(true, true, false);
304 }
305
306 private static NetworkState buildMobile464xlatUpstreamState() {
307 return buildMobileUpstreamState(false, true, true);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900308 }
309
Erik Kline8351faa2017-04-17 16:47:23 +0900310 @Before
311 public void setUp() throws Exception {
Christopher Wiley497c1472016-10-11 13:26:03 -0700312 MockitoAnnotations.initMocks(this);
Christopher Wiley497c1472016-10-11 13:26:03 -0700313 when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range))
314 .thenReturn(new String[0]);
315 when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900316 .thenReturn(new String[] { "test_rndis\\d" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700317 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900318 .thenReturn(new String[]{ "test_wlan\\d" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700319 when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
320 .thenReturn(new String[0]);
321 when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
322 .thenReturn(new int[0]);
Erik Kline72302902018-06-14 17:36:40 +0900323 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
324 .thenReturn(false);
Erik Klineea9cc482017-03-10 19:35:34 +0900325 when(mNMService.listInterfaces())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900326 .thenReturn(new String[] {
327 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME});
Erik Klineea9cc482017-03-10 19:35:34 +0900328 when(mNMService.getInterfaceConfig(anyString()))
329 .thenReturn(new InterfaceConfiguration());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900330 when(mRouterAdvertisementDaemon.start())
331 .thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900332
333 mServiceContext = new MockContext(mContext);
Erik Kline92c4db02017-05-31 10:21:32 +0900334 mContentResolver = new MockContentResolver(mServiceContext);
335 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Erik Kline8351faa2017-04-17 16:47:23 +0900336 mIntents = new Vector<>();
337 mBroadcastReceiver = new BroadcastReceiver() {
338 @Override
339 public void onReceive(Context context, Intent intent) {
340 mIntents.addElement(intent);
341 }
342 };
343 mServiceContext.registerReceiver(mBroadcastReceiver,
Erik Kline465ff3a2018-03-09 14:18:02 +0900344 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
345 mTetheringDependencies.reset();
Erik Klineea9cc482017-03-10 19:35:34 +0900346 mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
Erik Kline5a7c8a02017-04-30 19:36:15 +0900347 mLooper.getLooper(), mSystemProperties,
348 mTetheringDependencies);
Lorenzo Colitti5a7dea12017-07-12 15:48:07 +0900349 verify(mNMService).registerTetheringStatsProvider(any(), anyString());
Christopher Wiley497c1472016-10-11 13:26:03 -0700350 }
351
Erik Kline8351faa2017-04-17 16:47:23 +0900352 @After
353 public void tearDown() {
354 mServiceContext.unregisterReceiver(mBroadcastReceiver);
355 }
356
Christopher Wiley497c1472016-10-11 13:26:03 -0700357 private void setupForRequiredProvisioning() {
358 // Produce some acceptable looking provision app setting if requested.
359 when(mResources.getStringArray(
360 com.android.internal.R.array.config_mobile_hotspot_provision_app))
361 .thenReturn(PROVISIONING_APP_NAME);
362 // Don't disable tethering provisioning unless requested.
363 when(mSystemProperties.getBoolean(eq(Tethering.DISABLE_PROVISIONING_SYSPROP_KEY),
364 anyBoolean())).thenReturn(false);
365 // Act like the CarrierConfigManager is present and ready unless told otherwise.
366 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
367 .thenReturn(mCarrierConfigManager);
368 when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig);
369 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
370 }
371
372 @Test
373 public void canRequireProvisioning() {
374 setupForRequiredProvisioning();
Erik Kline80b7a9f2018-02-28 15:01:35 +0900375 sendConfigurationChanged();
Christopher Wiley497c1472016-10-11 13:26:03 -0700376 assertTrue(mTethering.isTetherProvisioningRequired());
377 }
378
379 @Test
380 public void toleratesCarrierConfigManagerMissing() {
381 setupForRequiredProvisioning();
382 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
383 .thenReturn(null);
Erik Kline80b7a9f2018-02-28 15:01:35 +0900384 sendConfigurationChanged();
Christopher Wiley497c1472016-10-11 13:26:03 -0700385 // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
386 // We therefore still require provisioning.
387 assertTrue(mTethering.isTetherProvisioningRequired());
388 }
389
390 @Test
391 public void toleratesCarrierConfigMissing() {
392 setupForRequiredProvisioning();
393 when(mCarrierConfigManager.getConfig()).thenReturn(null);
Erik Kline80b7a9f2018-02-28 15:01:35 +0900394 sendConfigurationChanged();
Christopher Wiley497c1472016-10-11 13:26:03 -0700395 // We still have a provisioning app configured, so still require provisioning.
396 assertTrue(mTethering.isTetherProvisioningRequired());
397 }
398
399 @Test
400 public void provisioningNotRequiredWhenAppNotFound() {
401 setupForRequiredProvisioning();
402 when(mResources.getStringArray(
403 com.android.internal.R.array.config_mobile_hotspot_provision_app))
404 .thenReturn(null);
405 assertTrue(!mTethering.isTetherProvisioningRequired());
406 when(mResources.getStringArray(
407 com.android.internal.R.array.config_mobile_hotspot_provision_app))
408 .thenReturn(new String[] {"malformedApp"});
409 assertTrue(!mTethering.isTetherProvisioningRequired());
410 }
Erik Klineea9cc482017-03-10 19:35:34 +0900411
412 private void sendWifiApStateChanged(int state) {
413 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Erik Kline2efb8272017-05-31 15:53:53 +0900414 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
Erik Klineea9cc482017-03-10 19:35:34 +0900415 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
416 }
417
Erik Kline2efb8272017-05-31 15:53:53 +0900418 private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
419 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
420 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
421 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
422 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
423 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
424 }
425
Erik Klinec438e302017-07-04 22:02:49 +0900426 private void sendUsbBroadcast(boolean connected, boolean configured, boolean rndisFunction) {
427 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
428 intent.putExtra(USB_CONNECTED, connected);
429 intent.putExtra(USB_CONFIGURED, configured);
430 intent.putExtra(USB_FUNCTION_RNDIS, rndisFunction);
431 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
432 }
433
Erik Kline80b7a9f2018-02-28 15:01:35 +0900434 private void sendConfigurationChanged() {
435 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
436 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
437 }
438
Erik Kline9e225542017-06-08 17:48:48 +0900439 private void verifyInterfaceServingModeStarted() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900440 verify(mNMService, times(1)).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Kline8351faa2017-04-17 16:47:23 +0900441 verify(mNMService, times(1))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900442 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
443 verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
Erik Kline8351faa2017-04-17 16:47:23 +0900444 }
445
446 private void verifyTetheringBroadcast(String ifname, String whichExtra) {
447 // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
448 final Intent bcast = mIntents.get(0);
Erik Kline465ff3a2018-03-09 14:18:02 +0900449 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
Erik Kline8351faa2017-04-17 16:47:23 +0900450 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
451 assertTrue(ifnames.contains(ifname));
452 mIntents.remove(bcast);
453 }
454
Erik Klinea9cde8b2017-06-20 21:18:31 +0900455 public void failingLocalOnlyHotspotLegacyApBroadcast(
456 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Klineea9cc482017-03-10 19:35:34 +0900457 // Emulate externally-visible WifiManager effects, causing the
458 // per-interface state machine to start up, and telling us that
459 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900460 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900461 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900462 }
Erik Kline9e225542017-06-08 17:48:48 +0900463 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900464 mLooper.dispatchAll();
465
Erik Kline7a4ccc62018-08-27 17:26:47 +0900466 // If, and only if, Tethering received an interface status changed then
467 // it creates a IpServer and sends out a broadcast indicating that the
468 // interface is "available".
Erik Klinea9cde8b2017-06-20 21:18:31 +0900469 if (emulateInterfaceStatusChanged) {
Erik Kline465ff3a2018-03-09 14:18:02 +0900470 assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls);
471 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900472 }
Erik Kline9e225542017-06-08 17:48:48 +0900473 verifyNoMoreInteractions(mNMService);
474 verifyNoMoreInteractions(mWifiManager);
475 }
476
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900477 private void prepareUsbTethering(NetworkState upstreamState) {
Erik Kline72302902018-06-14 17:36:40 +0900478 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900479 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
480 .thenReturn(upstreamState);
Erik Klinec438e302017-07-04 22:02:49 +0900481
482 // Emulate pressing the USB tethering button in Settings UI.
483 mTethering.startTethering(TETHERING_USB, null, false);
484 mLooper.dispatchAll();
Jerry Zhang327b8092018-01-09 17:53:04 -0800485 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
Erik Klinec438e302017-07-04 22:02:49 +0900486
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900487 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
488 }
489
490 @Test
491 public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
492 NetworkState upstreamState = buildMobileIPv4UpstreamState();
493 prepareUsbTethering(upstreamState);
494
Erik Klinec438e302017-07-04 22:02:49 +0900495 // This should produce no activity of any kind.
Erik Klinec438e302017-07-04 22:02:49 +0900496 verifyNoMoreInteractions(mNMService);
497
498 // Pretend we then receive USB configured broadcast.
499 sendUsbBroadcast(true, true, true);
500 mLooper.dispatchAll();
501 // Now we should see the start of tethering mechanics (in this case:
502 // tetherMatchingInterfaces() which starts by fetching all interfaces).
503 verify(mNMService, times(1)).listInterfaces();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900504
505 // UpstreamNetworkMonitor should receive selected upstream
506 verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
507 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
Erik Klinec438e302017-07-04 22:02:49 +0900508 }
509
510 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900511 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
512 failingLocalOnlyHotspotLegacyApBroadcast(true);
513 }
514
515 @Test
516 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
517 failingLocalOnlyHotspotLegacyApBroadcast(false);
518 }
519
520 public void workingLocalOnlyHotspotEnrichedApBroadcast(
521 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900522 // Emulate externally-visible WifiManager effects, causing the
523 // per-interface state machine to start up, and telling us that
524 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900525 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900526 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900527 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900528 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline9e225542017-06-08 17:48:48 +0900529 mLooper.dispatchAll();
530
531 verifyInterfaceServingModeStarted();
Erik Kline465ff3a2018-03-09 14:18:02 +0900532 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900533 verify(mNMService, times(1)).setIpForwardingEnabled(true);
534 verify(mNMService, times(1)).startTethering(any(String[].class));
535 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900536 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900537 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +0900538 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900539 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
Erik Kline72302902018-06-14 17:36:40 +0900540 verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900541 // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast().
Erik Kline465ff3a2018-03-09 14:18:02 +0900542 assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900543
544 // Emulate externally-visible WifiManager effects, when hotspot mode
545 // is being torn down.
546 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900547 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900548 mLooper.dispatchAll();
549
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900550 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900551 // TODO: Why is {g,s}etInterfaceConfig() called more than once?
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900552 verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900553 verify(mNMService, atLeastOnce())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900554 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900555 verify(mNMService, times(1)).stopTethering();
556 verify(mNMService, times(1)).setIpForwardingEnabled(false);
557 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900558 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900559 // Asking for the last error after the per-interface state machine
560 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900561 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900562 }
563
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900564 /**
Erik Kline7a4ccc62018-08-27 17:26:47 +0900565 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900566 */
567 private void sendIPv6TetherUpdates(NetworkState upstreamState) {
568 // IPv6TetheringCoordinator must have been notified of downstream
569 verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
570 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
Erik Kline7a4ccc62018-08-27 17:26:47 +0900571 eq(IpServer.STATE_TETHERED));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900572
Erik Kline7a4ccc62018-08-27 17:26:47 +0900573 for (IpServer ipSrv :
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900574 mTetheringDependencies.ipv6CoordinatorNotifyList) {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900575 NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900576 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900577 upstreamState.linkProperties.isIPv6Provisioned()
578 ? ipv6OnlyState.linkProperties
579 : null);
580 }
581 mLooper.dispatchAll();
582 }
583
584 private void runUsbTethering(NetworkState upstreamState) {
585 prepareUsbTethering(upstreamState);
586 sendUsbBroadcast(true, true, true);
587 mLooper.dispatchAll();
588 }
589
590 @Test
591 public void workingMobileUsbTethering_IPv4() throws Exception {
592 NetworkState upstreamState = buildMobileIPv4UpstreamState();
593 runUsbTethering(upstreamState);
594
595 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
596 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
597
598 sendIPv6TetherUpdates(upstreamState);
599 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
600 }
601
602 @Test
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900603 public void workingMobileUsbTethering_IPv6() throws Exception {
604 NetworkState upstreamState = buildMobileIPv6UpstreamState();
605 runUsbTethering(upstreamState);
606
607 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
608 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
609
610 sendIPv6TetherUpdates(upstreamState);
611 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
612 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
613 }
614
615 @Test
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900616 public void workingMobileUsbTethering_DualStack() throws Exception {
617 NetworkState upstreamState = buildMobileDualStackUpstreamState();
618 runUsbTethering(upstreamState);
619
620 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
621 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
622 verify(mRouterAdvertisementDaemon, times(1)).start();
623
624 sendIPv6TetherUpdates(upstreamState);
625 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
626 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
627 }
628
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900629 @Test
630 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
631 NetworkState upstreamState = buildMobile464xlatUpstreamState();
632 runUsbTethering(upstreamState);
633
634 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
635 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
636 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
637 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
638 TEST_XLAT_MOBILE_IFNAME);
639
640 sendIPv6TetherUpdates(upstreamState);
641 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
642 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
643 }
644
645 @Test
646 public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
647 // Setup IPv6
648 NetworkState upstreamState = buildMobileIPv6UpstreamState();
649 runUsbTethering(upstreamState);
650
651 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
652 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
653
654 // Then 464xlat comes up
655 upstreamState = buildMobile464xlatUpstreamState();
656 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
657 .thenReturn(upstreamState);
658
659 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
660 mTetheringDependencies.upstreamNetworkMonitorMasterSM.sendMessage(
661 Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
662 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
663 0,
664 upstreamState);
665 mLooper.dispatchAll();
666
667 // Forwarding is added for 464xlat
668 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
669 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
670 TEST_XLAT_MOBILE_IFNAME);
671 // Forwarding was not re-added for v6 (still times(1))
672 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
673 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
674 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900675
Erik Klineea9cc482017-03-10 19:35:34 +0900676 @Test
Erik Kline72302902018-06-14 17:36:40 +0900677 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
678 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
679 .thenReturn(true);
680 sendConfigurationChanged();
681
682 // Setup IPv6
683 final NetworkState upstreamState = buildMobileIPv6UpstreamState();
684 runUsbTethering(upstreamState);
685
686 // UpstreamNetworkMonitor should choose upstream automatically
687 // (in this specific case: choose the default network).
688 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
689 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
690
691 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
692 }
693
694 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900695 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
696 workingLocalOnlyHotspotEnrichedApBroadcast(true);
697 }
698
699 @Test
700 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
701 workingLocalOnlyHotspotEnrichedApBroadcast(false);
702 }
703
704 // TODO: Test with and without interfaceStatusChanged().
705 @Test
Erik Kline9e225542017-06-08 17:48:48 +0900706 public void failingWifiTetheringLegacyApBroadcast() throws Exception {
Erik Klineceb54c62017-04-18 14:22:25 +0900707 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900708
709 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900710 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Klineea9cc482017-03-10 19:35:34 +0900711 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900712 verify(mWifiManager, times(1)).startSoftAp(null);
Erik Klineea9cc482017-03-10 19:35:34 +0900713 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900714 verifyNoMoreInteractions(mNMService);
715
716 // Emulate externally-visible WifiManager effects, causing the
717 // per-interface state machine to start up, and telling us that
718 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900719 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Kline9e225542017-06-08 17:48:48 +0900720 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900721 mLooper.dispatchAll();
722
Erik Kline465ff3a2018-03-09 14:18:02 +0900723 assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls);
724 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline9e225542017-06-08 17:48:48 +0900725 verifyNoMoreInteractions(mNMService);
726 verifyNoMoreInteractions(mWifiManager);
727 }
728
Erik Klinea9cde8b2017-06-20 21:18:31 +0900729 // TODO: Test with and without interfaceStatusChanged().
Erik Kline9e225542017-06-08 17:48:48 +0900730 @Test
731 public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900732 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
733
734 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900735 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline9e225542017-06-08 17:48:48 +0900736 mLooper.dispatchAll();
737 verify(mWifiManager, times(1)).startSoftAp(null);
738 verifyNoMoreInteractions(mWifiManager);
Erik Kline9e225542017-06-08 17:48:48 +0900739 verifyNoMoreInteractions(mNMService);
740
741 // Emulate externally-visible WifiManager effects, causing the
742 // per-interface state machine to start up, and telling us that
743 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900744 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
745 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline9e225542017-06-08 17:48:48 +0900746 mLooper.dispatchAll();
747
748 verifyInterfaceServingModeStarted();
Erik Kline465ff3a2018-03-09 14:18:02 +0900749 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900750 verify(mNMService, times(1)).setIpForwardingEnabled(true);
751 verify(mNMService, times(1)).startTethering(any(String[].class));
752 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900753 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900754 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +0900755 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900756 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
Erik Kline72302902018-06-14 17:36:40 +0900757 verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900758 // In tethering mode, in the default configuration, an explicit request
759 // for a mobile network is also made.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900760 verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
Erik Klineea9cc482017-03-10 19:35:34 +0900761 // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast().
Erik Kline465ff3a2018-03-09 14:18:02 +0900762 assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900763
764 /////
765 // We do not currently emulate any upstream being found.
766 //
767 // This is why there are no calls to verify mNMService.enableNat() or
768 // mNMService.startInterfaceForwarding().
769 /////
770
771 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900772 mTethering.stopTethering(TETHERING_WIFI);
Erik Klineea9cc482017-03-10 19:35:34 +0900773 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900774 verify(mWifiManager, times(1)).stopSoftAp();
Erik Klineea9cc482017-03-10 19:35:34 +0900775 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900776 verifyNoMoreInteractions(mNMService);
777
778 // Emulate externally-visible WifiManager effects, when tethering mode
779 // is being torn down.
780 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900781 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900782 mLooper.dispatchAll();
783
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900784 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900785 // TODO: Why is {g,s}etInterfaceConfig() called more than once?
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900786 verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900787 verify(mNMService, atLeastOnce())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900788 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900789 verify(mNMService, times(1)).stopTethering();
790 verify(mNMService, times(1)).setIpForwardingEnabled(false);
791 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900792 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900793 // Asking for the last error after the per-interface state machine
794 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900795 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900796 }
797
Erik Klinea9cde8b2017-06-20 21:18:31 +0900798 // TODO: Test with and without interfaceStatusChanged().
Erik Kline1fdc2e22017-05-08 17:56:35 +0900799 @Test
800 public void failureEnablingIpForwarding() throws Exception {
Erik Kline1fdc2e22017-05-08 17:56:35 +0900801 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
802 doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);
803
804 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900805 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900806 mLooper.dispatchAll();
807 verify(mWifiManager, times(1)).startSoftAp(null);
808 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900809 verifyNoMoreInteractions(mNMService);
810
811 // Emulate externally-visible WifiManager effects, causing the
812 // per-interface state machine to start up, and telling us that
813 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900814 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
815 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900816 mLooper.dispatchAll();
817
Erik Kline472276a2018-05-18 16:09:24 +0900818 // We verify get/set called thrice here: once for setup and twice during
Erik Kline1fdc2e22017-05-08 17:56:35 +0900819 // teardown because all events happen over the course of the single
Erik Kline7a4ccc62018-08-27 17:26:47 +0900820 // dispatchAll() above. Note that once the IpServer IPv4 address config
Erik Kline472276a2018-05-18 16:09:24 +0900821 // code is refactored the two calls during shutdown will revert to one.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900822 verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Kline472276a2018-05-18 16:09:24 +0900823 verify(mNMService, times(3))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900824 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
825 verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900826 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900827 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline465ff3a2018-03-09 14:18:02 +0900828 // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast().
829 assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls);
830 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900831 // This is called, but will throw.
832 verify(mNMService, times(1)).setIpForwardingEnabled(true);
833 // This never gets called because of the exception thrown above.
834 verify(mNMService, times(0)).startTethering(any(String[].class));
835 // When the master state machine transitions to an error state it tells
836 // downstream interfaces, which causes us to tell Wi-Fi about the error
837 // so it can take down AP mode.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900838 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900839 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900840 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900841
842 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900843 verifyNoMoreInteractions(mNMService);
844 }
845
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100846 private void userRestrictionsListenerBehaviour(
847 boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
848 int expectedInteractionsWithShowNotification) throws Exception {
849 final int userId = 0;
850 final Bundle currRestrictions = new Bundle();
851 final Bundle newRestrictions = new Bundle();
852 Tethering tethering = mock(Tethering.class);
853 Tethering.TetheringUserRestrictionListener turl =
854 new Tethering.TetheringUserRestrictionListener(tethering);
855
856 currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow);
857 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
858 when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
859
860 turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions);
861
862 verify(tethering, times(expectedInteractionsWithShowNotification))
863 .showTetheredNotification(anyInt(), eq(false));
864
865 verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll();
866 }
867
868 @Test
869 public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
870 final String[] emptyActiveIfacesList = new String[]{};
871 final boolean currDisallow = false;
872 final boolean nextDisallow = true;
873 final int expectedInteractionsWithShowNotification = 0;
874
875 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList,
876 expectedInteractionsWithShowNotification);
877 }
878
879 @Test
880 public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900881 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100882 final boolean currDisallow = false;
883 final boolean nextDisallow = true;
884 final int expectedInteractionsWithShowNotification = 1;
885
886 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
887 expectedInteractionsWithShowNotification);
888 }
889
890 @Test
891 public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
892 final String[] nonEmptyActiveIfacesList = new String[]{};
893 final boolean currDisallow = true;
894 final boolean nextDisallow = false;
895 final int expectedInteractionsWithShowNotification = 0;
896
897 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
898 expectedInteractionsWithShowNotification);
899 }
900
901 @Test
902 public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900903 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100904 final boolean currDisallow = true;
905 final boolean nextDisallow = false;
906 final int expectedInteractionsWithShowNotification = 0;
907
908 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
909 expectedInteractionsWithShowNotification);
910 }
911
912 @Test
913 public void testDisallowTetheringUnchanged() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900914 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100915 final int expectedInteractionsWithShowNotification = 0;
916 boolean currDisallow = true;
917 boolean nextDisallow = true;
918
919 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
920 expectedInteractionsWithShowNotification);
921
922 currDisallow = false;
923 nextDisallow = false;
924
925 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
926 expectedInteractionsWithShowNotification);
927 }
928
929
Erik Kline1fdc2e22017-05-08 17:56:35 +0900930 // TODO: Test that a request for hotspot mode doesn't interfere with an
Erik Klineea9cc482017-03-10 19:35:34 +0900931 // already operating tethering mode interface.
Christopher Wiley497c1472016-10-11 13:26:03 -0700932}