blob: 9e5717b4bd64277825ac591c535eb4a218921535 [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;
Erik Klinec438e302017-07-04 22:02:49 +090026import static android.net.ConnectivityManager.TETHERING_USB;
markchienb6eb2c22018-07-18 14:29:20 +080027import static android.net.ConnectivityManager.TETHERING_WIFI;
Jimmy Chenbcd86d02019-07-15 18:03:23 +080028import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
markchienb6eb2c22018-07-18 14:29:20 +080029import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
Erik Kline465ff3a2018-03-09 14:18:02 +090030import static android.net.ConnectivityManager.TYPE_MOBILE;
Jimmy Chenbcd86d02019-07-15 18:03:23 +080031import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090032import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
Erik Kline2efb8272017-05-31 15:53:53 +090033import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
34import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
35import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
markchienb6eb2c22018-07-18 14:29:20 +080036import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
37import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
Erik Kline2efb8272017-05-31 15:53:53 +090038import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +090039import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
markchien0b595072019-01-08 23:52:21 +080040import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090041
Erik Klineea9cc482017-03-10 19:35:34 +090042import static org.junit.Assert.assertEquals;
Christopher Wiley497c1472016-10-11 13:26:03 -070043import static org.junit.Assert.assertTrue;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090044import static org.junit.Assert.fail;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090045import static org.mockito.ArgumentMatchers.argThat;
46import static org.mockito.ArgumentMatchers.notNull;
Erik Klineea9cc482017-03-10 19:35:34 +090047import static org.mockito.Matchers.anyInt;
48import static org.mockito.Matchers.anyString;
Christopher Wiley497c1472016-10-11 13:26:03 -070049import static org.mockito.Matchers.eq;
Erik Kline1fdc2e22017-05-08 17:56:35 +090050import static org.mockito.Mockito.any;
Erik Klineea9cc482017-03-10 19:35:34 +090051import static org.mockito.Mockito.atLeastOnce;
Erik Kline1fdc2e22017-05-08 17:56:35 +090052import static org.mockito.Mockito.doThrow;
markchienb6eb2c22018-07-18 14:29:20 +080053import static org.mockito.Mockito.mock;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090054import static org.mockito.Mockito.never;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090055import static org.mockito.Mockito.spy;
56import static org.mockito.Mockito.timeout;
Erik Klineea9cc482017-03-10 19:35:34 +090057import static org.mockito.Mockito.times;
58import static org.mockito.Mockito.verify;
59import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley497c1472016-10-11 13:26:03 -070060import static org.mockito.Mockito.when;
61
Erik Kline8351faa2017-04-17 16:47:23 +090062import android.content.BroadcastReceiver;
Erik Kline92c4db02017-05-31 10:21:32 +090063import android.content.ContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070064import android.content.Context;
Erik Klineea9cc482017-03-10 19:35:34 +090065import android.content.Intent;
Erik Kline8351faa2017-04-17 16:47:23 +090066import android.content.IntentFilter;
Erik Klinef3a08b42017-06-07 16:33:19 +090067import android.content.pm.ApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -070068import android.content.res.Resources;
Erik Klineea9cc482017-03-10 19:35:34 +090069import android.hardware.usb.UsbManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090070import android.net.INetd;
Christopher Wiley497c1472016-10-11 13:26:03 -070071import android.net.INetworkPolicyManager;
72import android.net.INetworkStatsService;
markchien26299ed2019-02-27 14:56:11 +080073import android.net.ITetheringEventCallback;
Erik Klineea9cc482017-03-10 19:35:34 +090074import android.net.InterfaceConfiguration;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090075import android.net.IpPrefix;
76import android.net.LinkAddress;
77import android.net.LinkProperties;
78import android.net.MacAddress;
79import android.net.Network;
80import android.net.NetworkCapabilities;
81import android.net.NetworkInfo;
82import android.net.NetworkState;
83import android.net.NetworkUtils;
84import android.net.RouteInfo;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090085import android.net.dhcp.DhcpServerCallbacks;
86import android.net.dhcp.DhcpServingParamsParcel;
87import android.net.dhcp.IDhcpServer;
Erik Kline7a4ccc62018-08-27 17:26:47 +090088import android.net.ip.IpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090089import android.net.ip.RouterAdvertisementDaemon;
90import android.net.util.InterfaceParams;
91import android.net.util.NetworkConstants;
Erik Klinef4b6e342017-04-25 19:19:59 +090092import android.net.util.SharedLog;
Erik Klineea9cc482017-03-10 19:35:34 +090093import android.net.wifi.WifiConfiguration;
94import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +080095import android.net.wifi.p2p.WifiP2pGroup;
96import android.net.wifi.p2p.WifiP2pInfo;
97import android.net.wifi.p2p.WifiP2pManager;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010098import android.os.Bundle;
Erik Klineea9cc482017-03-10 19:35:34 +090099import android.os.Handler;
Christopher Wiley497c1472016-10-11 13:26:03 -0700100import android.os.INetworkManagementService;
101import android.os.PersistableBundle;
Erik Kline1fdc2e22017-05-08 17:56:35 +0900102import android.os.RemoteException;
Erik Klineea9cc482017-03-10 19:35:34 +0900103import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100104import android.os.UserManager;
markchienb6eb2c22018-07-18 14:29:20 +0800105import android.os.test.TestLooper;
Erik Kline92c4db02017-05-31 10:21:32 +0900106import android.provider.Settings;
Christopher Wiley497c1472016-10-11 13:26:03 -0700107import android.telephony.CarrierConfigManager;
markchien04bdf872019-06-17 21:05:34 +0800108import android.telephony.PhoneStateListener;
109import android.telephony.TelephonyManager;
Erik Kline92c4db02017-05-31 10:21:32 +0900110import android.test.mock.MockContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700111
Brett Chabot1ae2aa62019-03-04 14:14:56 -0800112import androidx.test.filters.SmallTest;
113import androidx.test.runner.AndroidJUnit4;
114
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900115import com.android.internal.util.ArrayUtils;
116import com.android.internal.util.StateMachine;
Erik Klineea9cc482017-03-10 19:35:34 +0900117import com.android.internal.util.test.BroadcastInterceptingContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900118import com.android.internal.util.test.FakeSettingsProvider;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900119import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900120import com.android.server.connectivity.tethering.OffloadHardwareInterface;
markchien04bdf872019-06-17 21:05:34 +0800121import com.android.server.connectivity.tethering.TetheringConfiguration;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900122import com.android.server.connectivity.tethering.TetheringDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900123import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
Erik Klineea9cc482017-03-10 19:35:34 +0900124
Erik Kline8351faa2017-04-17 16:47:23 +0900125import org.junit.After;
Christopher Wiley497c1472016-10-11 13:26:03 -0700126import org.junit.Before;
127import org.junit.Test;
128import org.junit.runner.RunWith;
markchien04bdf872019-06-17 21:05:34 +0800129import org.mockito.ArgumentCaptor;
Christopher Wiley497c1472016-10-11 13:26:03 -0700130import org.mockito.Mock;
131import org.mockito.MockitoAnnotations;
132
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900133import java.net.Inet4Address;
134import java.net.Inet6Address;
Erik Kline8351faa2017-04-17 16:47:23 +0900135import java.util.ArrayList;
markchien26299ed2019-02-27 14:56:11 +0800136import java.util.Arrays;
Erik Kline8351faa2017-04-17 16:47:23 +0900137import java.util.Vector;
138
Christopher Wiley497c1472016-10-11 13:26:03 -0700139@RunWith(AndroidJUnit4.class)
140@SmallTest
141public class TetheringTest {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900142 private static final int IFINDEX_OFFSET = 100;
143
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900144 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
145 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
146 private static final String TEST_USB_IFNAME = "test_rndis0";
147 private static final String TEST_WLAN_IFNAME = "test_wlan0";
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800148 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
Christopher Wiley497c1472016-10-11 13:26:03 -0700149
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900150 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
151
Erik Klinef3a08b42017-06-07 16:33:19 +0900152 @Mock private ApplicationInfo mApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -0700153 @Mock private Context mContext;
154 @Mock private INetworkManagementService mNMService;
155 @Mock private INetworkStatsService mStatsService;
156 @Mock private INetworkPolicyManager mPolicyManager;
157 @Mock private MockableSystemProperties mSystemProperties;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900158 @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
Christopher Wiley497c1472016-10-11 13:26:03 -0700159 @Mock private Resources mResources;
markchien04bdf872019-06-17 21:05:34 +0800160 @Mock private TelephonyManager mTelephonyManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900161 @Mock private UsbManager mUsbManager;
162 @Mock private WifiManager mWifiManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700163 @Mock private CarrierConfigManager mCarrierConfigManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900164 @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
165 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
166 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900167 @Mock private IDhcpServer mDhcpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900168 @Mock private INetd mNetd;
169
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900170 private final MockIpServerDependencies mIpServerDependencies =
171 spy(new MockIpServerDependencies());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900172 private final MockTetheringDependencies mTetheringDependencies =
173 new MockTetheringDependencies();
Christopher Wiley497c1472016-10-11 13:26:03 -0700174
175 // Like so many Android system APIs, these cannot be mocked because it is marked final.
176 // We have to use the real versions.
177 private final PersistableBundle mCarrierConfig = new PersistableBundle();
178 private final TestLooper mLooper = new TestLooper();
179
Erik Kline8351faa2017-04-17 16:47:23 +0900180 private Vector<Intent> mIntents;
Erik Klineea9cc482017-03-10 19:35:34 +0900181 private BroadcastInterceptingContext mServiceContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900182 private MockContentResolver mContentResolver;
Erik Kline8351faa2017-04-17 16:47:23 +0900183 private BroadcastReceiver mBroadcastReceiver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700184 private Tethering mTethering;
markchien04bdf872019-06-17 21:05:34 +0800185 private PhoneStateListener mPhoneStateListener;
Christopher Wiley497c1472016-10-11 13:26:03 -0700186
Erik Klineea9cc482017-03-10 19:35:34 +0900187 private class MockContext extends BroadcastInterceptingContext {
188 MockContext(Context base) {
189 super(base);
190 }
191
192 @Override
Erik Klinef3a08b42017-06-07 16:33:19 +0900193 public ApplicationInfo getApplicationInfo() { return mApplicationInfo; }
194
195 @Override
Erik Kline92c4db02017-05-31 10:21:32 +0900196 public ContentResolver getContentResolver() { return mContentResolver; }
197
198 @Override
199 public String getPackageName() { return "TetheringTest"; }
200
201 @Override
Erik Klineea9cc482017-03-10 19:35:34 +0900202 public Resources getResources() { return mResources; }
203
204 @Override
205 public Object getSystemService(String name) {
Erik Klineea9cc482017-03-10 19:35:34 +0900206 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
Erik Klinec438e302017-07-04 22:02:49 +0900207 if (Context.USB_SERVICE.equals(name)) return mUsbManager;
markchien04bdf872019-06-17 21:05:34 +0800208 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900209 return super.getSystemService(name);
210 }
Jayachandran C43fa1be2019-11-15 09:58:04 -0800211
212 @Override
213 public String getSystemServiceName(Class<?> serviceClass) {
214 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
215 return super.getSystemServiceName(serviceClass);
216 }
Erik Klineea9cc482017-03-10 19:35:34 +0900217 }
218
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900219 public class MockIpServerDependencies extends IpServer.Dependencies {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900220 @Override
221 public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
222 InterfaceParams ifParams) {
223 return mRouterAdvertisementDaemon;
224 }
225
226 @Override
227 public InterfaceParams getInterfaceParams(String ifName) {
228 assertTrue("Non-mocked interface " + ifName,
229 ifName.equals(TEST_USB_IFNAME)
230 || ifName.equals(TEST_WLAN_IFNAME)
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800231 || ifName.equals(TEST_MOBILE_IFNAME)
232 || ifName.equals(TEST_P2P_IFNAME));
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900233 final String[] ifaces = new String[] {
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800234 TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME};
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900235 return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
236 MacAddress.ALL_ZEROS_ADDRESS);
237 }
238
239 @Override
240 public INetd getNetdService() {
241 return mNetd;
242 }
243
244 @Override
245 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
246 DhcpServerCallbacks cb) {
247 new Thread(() -> {
248 try {
249 cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
250 } catch (RemoteException e) {
251 fail(e.getMessage());
252 }
253 }).run();
254 }
255 }
256
markchien04bdf872019-06-17 21:05:34 +0800257 private class MockTetheringConfiguration extends TetheringConfiguration {
258 MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
259 super(ctx, log, id);
260 }
261
262 @Override
263 protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
264 return mResources;
265 }
266 }
267
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900268 public class MockTetheringDependencies extends TetheringDependencies {
Erik Kline465ff3a2018-03-09 14:18:02 +0900269 StateMachine upstreamNetworkMonitorMasterSM;
Erik Kline7a4ccc62018-08-27 17:26:47 +0900270 ArrayList<IpServer> ipv6CoordinatorNotifyList;
Erik Kline465ff3a2018-03-09 14:18:02 +0900271 int isTetheringSupportedCalls;
272
273 public void reset() {
274 upstreamNetworkMonitorMasterSM = null;
275 ipv6CoordinatorNotifyList = null;
276 isTetheringSupportedCalls = 0;
277 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900278
279 @Override
280 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
281 return mOffloadHardwareInterface;
282 }
283
284 @Override
285 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
286 StateMachine target, SharedLog log, int what) {
287 upstreamNetworkMonitorMasterSM = target;
288 return mUpstreamNetworkMonitor;
289 }
290
291 @Override
292 public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
Erik Kline7a4ccc62018-08-27 17:26:47 +0900293 ArrayList<IpServer> notifyList, SharedLog log) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900294 ipv6CoordinatorNotifyList = notifyList;
295 return mIPv6TetheringCoordinator;
296 }
297
298 @Override
Remi NGUYEN VAN5db454c2019-02-14 18:04:20 +0900299 public IpServer.Dependencies getIpServerDependencies() {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900300 return mIpServerDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900301 }
Erik Kline465ff3a2018-03-09 14:18:02 +0900302
303 @Override
304 public boolean isTetheringSupported() {
305 isTetheringSupportedCalls++;
306 return true;
307 }
markchien0b595072019-01-08 23:52:21 +0800308
309 @Override
markchien04bdf872019-06-17 21:05:34 +0800310 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
311 int subId) {
312 return new MockTetheringConfiguration(ctx, log, subId);
markchien0b595072019-01-08 23:52:21 +0800313 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900314 }
315
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900316 private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
317 boolean with464xlat) {
Erik Kline465ff3a2018-03-09 14:18:02 +0900318 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, 0, null, null);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900319 info.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
320 final LinkProperties prop = new LinkProperties();
321 prop.setInterfaceName(TEST_MOBILE_IFNAME);
322
323 if (withIPv4) {
324 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
325 NetworkUtils.numericToInetAddress("10.0.0.1"), TEST_MOBILE_IFNAME));
326 }
327
328 if (withIPv6) {
329 prop.addDnsServer(NetworkUtils.numericToInetAddress("2001:db8::2"));
330 prop.addLinkAddress(
331 new LinkAddress(NetworkUtils.numericToInetAddress("2001:db8::"),
332 NetworkConstants.RFC7421_PREFIX_LENGTH));
333 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
334 NetworkUtils.numericToInetAddress("2001:db8::1"), TEST_MOBILE_IFNAME));
335 }
336
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900337 if (with464xlat) {
338 final LinkProperties stackedLink = new LinkProperties();
339 stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
340 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
341 NetworkUtils.numericToInetAddress("192.0.0.1"), TEST_XLAT_MOBILE_IFNAME));
342
343 prop.addStackedLink(stackedLink);
344 }
345
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900346
347 final NetworkCapabilities capabilities = new NetworkCapabilities()
348 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);;
349 return new NetworkState(info, prop, capabilities, new Network(100), null, "netid");
350 }
351
352 private static NetworkState buildMobileIPv4UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900353 return buildMobileUpstreamState(true, false, false);
354 }
355
356 private static NetworkState buildMobileIPv6UpstreamState() {
357 return buildMobileUpstreamState(false, true, false);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900358 }
359
360 private static NetworkState buildMobileDualStackUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900361 return buildMobileUpstreamState(true, true, false);
362 }
363
364 private static NetworkState buildMobile464xlatUpstreamState() {
365 return buildMobileUpstreamState(false, true, true);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900366 }
367
Erik Kline8351faa2017-04-17 16:47:23 +0900368 @Before
369 public void setUp() throws Exception {
Christopher Wiley497c1472016-10-11 13:26:03 -0700370 MockitoAnnotations.initMocks(this);
Christopher Wiley497c1472016-10-11 13:26:03 -0700371 when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range))
372 .thenReturn(new String[0]);
373 when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900374 .thenReturn(new String[] { "test_rndis\\d" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700375 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900376 .thenReturn(new String[]{ "test_wlan\\d" });
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800377 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs))
378 .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700379 when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
380 .thenReturn(new String[0]);
381 when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
382 .thenReturn(new int[0]);
Erik Kline72302902018-06-14 17:36:40 +0900383 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
384 .thenReturn(false);
Erik Klineea9cc482017-03-10 19:35:34 +0900385 when(mNMService.listInterfaces())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900386 .thenReturn(new String[] {
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800387 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME});
Erik Klineea9cc482017-03-10 19:35:34 +0900388 when(mNMService.getInterfaceConfig(anyString()))
389 .thenReturn(new InterfaceConfiguration());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900390 when(mRouterAdvertisementDaemon.start())
391 .thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900392
393 mServiceContext = new MockContext(mContext);
Erik Kline92c4db02017-05-31 10:21:32 +0900394 mContentResolver = new MockContentResolver(mServiceContext);
395 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900396 Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
Erik Kline8351faa2017-04-17 16:47:23 +0900397 mIntents = new Vector<>();
398 mBroadcastReceiver = new BroadcastReceiver() {
399 @Override
400 public void onReceive(Context context, Intent intent) {
401 mIntents.addElement(intent);
402 }
403 };
404 mServiceContext.registerReceiver(mBroadcastReceiver,
Erik Kline465ff3a2018-03-09 14:18:02 +0900405 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
406 mTetheringDependencies.reset();
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900407 mTethering = makeTethering();
Lorenzo Colitti5a7dea12017-07-12 15:48:07 +0900408 verify(mNMService).registerTetheringStatsProvider(any(), anyString());
markchien04bdf872019-06-17 21:05:34 +0800409 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
410 ArgumentCaptor.forClass(PhoneStateListener.class);
411 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
412 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
413 mPhoneStateListener = phoneListenerCaptor.getValue();
Christopher Wiley497c1472016-10-11 13:26:03 -0700414 }
415
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900416 private Tethering makeTethering() {
417 return new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
418 mLooper.getLooper(), mSystemProperties,
419 mTetheringDependencies);
420 }
421
Erik Kline8351faa2017-04-17 16:47:23 +0900422 @After
423 public void tearDown() {
424 mServiceContext.unregisterReceiver(mBroadcastReceiver);
425 }
426
Erik Klineea9cc482017-03-10 19:35:34 +0900427 private void sendWifiApStateChanged(int state) {
428 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Erik Kline2efb8272017-05-31 15:53:53 +0900429 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
Erik Klineea9cc482017-03-10 19:35:34 +0900430 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
431 }
432
Erik Kline2efb8272017-05-31 15:53:53 +0900433 private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
434 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
435 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
436 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
437 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
438 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
439 }
440
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800441 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
442 android.Manifest.permission.ACCESS_FINE_LOCATION,
443 android.Manifest.permission.ACCESS_WIFI_STATE
444 };
445
446 private void sendWifiP2pConnectionChanged(
447 boolean isGroupFormed, boolean isGroupOwner, String ifname) {
448 WifiP2pInfo p2pInfo = new WifiP2pInfo();
449 p2pInfo.groupFormed = isGroupFormed;
450 p2pInfo.isGroupOwner = isGroupOwner;
451
452 NetworkInfo networkInfo = new NetworkInfo(TYPE_WIFI_P2P, 0, null, null);
453
454 WifiP2pGroup group = new WifiP2pGroup();
455 group.setIsGroupOwner(isGroupOwner);
456 group.setInterface(ifname);
457
458 final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
459 intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, p2pInfo);
460 intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, networkInfo);
461 intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, group);
462 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
463 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
464 }
465
Erik Klinec438e302017-07-04 22:02:49 +0900466 private void sendUsbBroadcast(boolean connected, boolean configured, boolean rndisFunction) {
467 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
468 intent.putExtra(USB_CONNECTED, connected);
469 intent.putExtra(USB_CONFIGURED, configured);
470 intent.putExtra(USB_FUNCTION_RNDIS, rndisFunction);
471 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
472 }
473
Erik Kline80b7a9f2018-02-28 15:01:35 +0900474 private void sendConfigurationChanged() {
475 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
476 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
477 }
478
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800479 private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
480 verify(mNMService, times(1)).getInterfaceConfig(ifname);
Erik Kline8351faa2017-04-17 16:47:23 +0900481 verify(mNMService, times(1))
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800482 .setInterfaceConfig(eq(ifname), any(InterfaceConfiguration.class));
483 verify(mNMService, times(1)).tetherInterface(ifname);
Erik Kline8351faa2017-04-17 16:47:23 +0900484 }
485
486 private void verifyTetheringBroadcast(String ifname, String whichExtra) {
487 // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
488 final Intent bcast = mIntents.get(0);
Erik Kline465ff3a2018-03-09 14:18:02 +0900489 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
Erik Kline8351faa2017-04-17 16:47:23 +0900490 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
491 assertTrue(ifnames.contains(ifname));
492 mIntents.remove(bcast);
493 }
494
Erik Klinea9cde8b2017-06-20 21:18:31 +0900495 public void failingLocalOnlyHotspotLegacyApBroadcast(
496 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Klineea9cc482017-03-10 19:35:34 +0900497 // Emulate externally-visible WifiManager effects, causing the
498 // per-interface state machine to start up, and telling us that
499 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900500 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900501 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900502 }
Erik Kline9e225542017-06-08 17:48:48 +0900503 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900504 mLooper.dispatchAll();
505
Erik Kline7a4ccc62018-08-27 17:26:47 +0900506 // If, and only if, Tethering received an interface status changed then
507 // it creates a IpServer and sends out a broadcast indicating that the
508 // interface is "available".
Erik Klinea9cde8b2017-06-20 21:18:31 +0900509 if (emulateInterfaceStatusChanged) {
Erik Kline465ff3a2018-03-09 14:18:02 +0900510 assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls);
511 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900512 verify(mWifiManager).updateInterfaceIpState(
513 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900514 }
Erik Kline9e225542017-06-08 17:48:48 +0900515 verifyNoMoreInteractions(mNMService);
516 verifyNoMoreInteractions(mWifiManager);
517 }
518
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900519 private void prepareUsbTethering(NetworkState upstreamState) {
Erik Kline72302902018-06-14 17:36:40 +0900520 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900521 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
522 .thenReturn(upstreamState);
Erik Klinec438e302017-07-04 22:02:49 +0900523
524 // Emulate pressing the USB tethering button in Settings UI.
525 mTethering.startTethering(TETHERING_USB, null, false);
526 mLooper.dispatchAll();
Jerry Zhang327b8092018-01-09 17:53:04 -0800527 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
Erik Klinec438e302017-07-04 22:02:49 +0900528
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900529 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
530 }
531
532 @Test
533 public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
534 NetworkState upstreamState = buildMobileIPv4UpstreamState();
535 prepareUsbTethering(upstreamState);
536
Erik Klinec438e302017-07-04 22:02:49 +0900537 // This should produce no activity of any kind.
Erik Klinec438e302017-07-04 22:02:49 +0900538 verifyNoMoreInteractions(mNMService);
539
540 // Pretend we then receive USB configured broadcast.
541 sendUsbBroadcast(true, true, true);
542 mLooper.dispatchAll();
543 // Now we should see the start of tethering mechanics (in this case:
544 // tetherMatchingInterfaces() which starts by fetching all interfaces).
545 verify(mNMService, times(1)).listInterfaces();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900546
547 // UpstreamNetworkMonitor should receive selected upstream
548 verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
549 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
Erik Klinec438e302017-07-04 22:02:49 +0900550 }
551
552 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900553 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
554 failingLocalOnlyHotspotLegacyApBroadcast(true);
555 }
556
557 @Test
558 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
559 failingLocalOnlyHotspotLegacyApBroadcast(false);
560 }
561
562 public void workingLocalOnlyHotspotEnrichedApBroadcast(
563 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900564 // Emulate externally-visible WifiManager effects, causing the
565 // per-interface state machine to start up, and telling us that
566 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900567 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900568 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900569 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900570 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline9e225542017-06-08 17:48:48 +0900571 mLooper.dispatchAll();
572
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800573 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900574 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900575 verify(mNMService, times(1)).setIpForwardingEnabled(true);
576 verify(mNMService, times(1)).startTethering(any(String[].class));
577 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900578 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900579 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
580 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900581 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +0900582 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900583 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
markchiena6c72872018-11-13 18:34:56 +0900584 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800585 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
586 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
587 assertEquals(2, mTetheringDependencies.isTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900588
589 // Emulate externally-visible WifiManager effects, when hotspot mode
590 // is being torn down.
591 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900592 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900593 mLooper.dispatchAll();
594
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900595 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800596 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
597 verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
598 verify(mNMService, times(2))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900599 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900600 verify(mNMService, times(1)).stopTethering();
601 verify(mNMService, times(1)).setIpForwardingEnabled(false);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900602 verify(mWifiManager, times(3)).updateInterfaceIpState(
603 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klineea9cc482017-03-10 19:35:34 +0900604 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900605 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900606 // Asking for the last error after the per-interface state machine
607 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900608 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900609 }
610
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900611 /**
Erik Kline7a4ccc62018-08-27 17:26:47 +0900612 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900613 */
614 private void sendIPv6TetherUpdates(NetworkState upstreamState) {
615 // IPv6TetheringCoordinator must have been notified of downstream
616 verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
617 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
Erik Kline7a4ccc62018-08-27 17:26:47 +0900618 eq(IpServer.STATE_TETHERED));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900619
Erik Kline7a4ccc62018-08-27 17:26:47 +0900620 for (IpServer ipSrv :
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900621 mTetheringDependencies.ipv6CoordinatorNotifyList) {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900622 NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900623 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
paulhud9736de2019-03-08 16:35:20 +0800624 upstreamState.linkProperties.isIpv6Provisioned()
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900625 ? ipv6OnlyState.linkProperties
626 : null);
627 }
628 mLooper.dispatchAll();
629 }
630
631 private void runUsbTethering(NetworkState upstreamState) {
632 prepareUsbTethering(upstreamState);
633 sendUsbBroadcast(true, true, true);
634 mLooper.dispatchAll();
635 }
636
637 @Test
638 public void workingMobileUsbTethering_IPv4() throws Exception {
639 NetworkState upstreamState = buildMobileIPv4UpstreamState();
640 runUsbTethering(upstreamState);
641
642 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
643 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
644
645 sendIPv6TetherUpdates(upstreamState);
646 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900647 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900648 }
649
650 @Test
651 public void workingMobileUsbTethering_IPv4LegacyDhcp() {
652 Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
653 mTethering = makeTethering();
654 final NetworkState upstreamState = buildMobileIPv4UpstreamState();
655 runUsbTethering(upstreamState);
656 sendIPv6TetherUpdates(upstreamState);
657
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900658 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900659 }
660
661 @Test
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900662 public void workingMobileUsbTethering_IPv6() throws Exception {
663 NetworkState upstreamState = buildMobileIPv6UpstreamState();
664 runUsbTethering(upstreamState);
665
666 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
667 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
668
669 sendIPv6TetherUpdates(upstreamState);
670 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
671 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
672 }
673
674 @Test
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900675 public void workingMobileUsbTethering_DualStack() throws Exception {
676 NetworkState upstreamState = buildMobileDualStackUpstreamState();
677 runUsbTethering(upstreamState);
678
679 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
680 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
681 verify(mRouterAdvertisementDaemon, times(1)).start();
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900682 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900683
684 sendIPv6TetherUpdates(upstreamState);
685 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
686 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
687 }
688
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900689 @Test
690 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
691 NetworkState upstreamState = buildMobile464xlatUpstreamState();
692 runUsbTethering(upstreamState);
693
694 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
695 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900696 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900697 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
698 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
699 TEST_XLAT_MOBILE_IFNAME);
700
701 sendIPv6TetherUpdates(upstreamState);
702 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
703 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
704 }
705
706 @Test
707 public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
708 // Setup IPv6
709 NetworkState upstreamState = buildMobileIPv6UpstreamState();
710 runUsbTethering(upstreamState);
711
712 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900713 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900714 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
715
716 // Then 464xlat comes up
717 upstreamState = buildMobile464xlatUpstreamState();
718 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
719 .thenReturn(upstreamState);
720
721 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
722 mTetheringDependencies.upstreamNetworkMonitorMasterSM.sendMessage(
723 Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
724 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
725 0,
726 upstreamState);
727 mLooper.dispatchAll();
728
729 // Forwarding is added for 464xlat
730 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
731 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
732 TEST_XLAT_MOBILE_IFNAME);
733 // Forwarding was not re-added for v6 (still times(1))
734 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
735 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900736 // DHCP not restarted on downstream (still times(1))
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900737 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900738 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900739
Erik Klineea9cc482017-03-10 19:35:34 +0900740 @Test
Erik Kline72302902018-06-14 17:36:40 +0900741 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
742 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
743 .thenReturn(true);
744 sendConfigurationChanged();
745
746 // Setup IPv6
747 final NetworkState upstreamState = buildMobileIPv6UpstreamState();
748 runUsbTethering(upstreamState);
749
750 // UpstreamNetworkMonitor should choose upstream automatically
751 // (in this specific case: choose the default network).
752 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
753 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
754
755 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
756 }
757
758 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900759 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
760 workingLocalOnlyHotspotEnrichedApBroadcast(true);
761 }
762
763 @Test
764 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
765 workingLocalOnlyHotspotEnrichedApBroadcast(false);
766 }
767
768 // TODO: Test with and without interfaceStatusChanged().
769 @Test
Erik Kline9e225542017-06-08 17:48:48 +0900770 public void failingWifiTetheringLegacyApBroadcast() throws Exception {
Erik Klineceb54c62017-04-18 14:22:25 +0900771 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900772
773 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900774 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Klineea9cc482017-03-10 19:35:34 +0900775 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900776 verify(mWifiManager, times(1)).startSoftAp(null);
Erik Klineea9cc482017-03-10 19:35:34 +0900777 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900778 verifyNoMoreInteractions(mNMService);
779
780 // Emulate externally-visible WifiManager effects, causing the
781 // per-interface state machine to start up, and telling us that
782 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900783 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Kline9e225542017-06-08 17:48:48 +0900784 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900785 mLooper.dispatchAll();
786
Erik Kline465ff3a2018-03-09 14:18:02 +0900787 assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls);
788 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900789 verify(mWifiManager).updateInterfaceIpState(
790 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Kline9e225542017-06-08 17:48:48 +0900791 verifyNoMoreInteractions(mNMService);
792 verifyNoMoreInteractions(mWifiManager);
793 }
794
Erik Klinea9cde8b2017-06-20 21:18:31 +0900795 // TODO: Test with and without interfaceStatusChanged().
Erik Kline9e225542017-06-08 17:48:48 +0900796 @Test
797 public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900798 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
799
800 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900801 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline9e225542017-06-08 17:48:48 +0900802 mLooper.dispatchAll();
803 verify(mWifiManager, times(1)).startSoftAp(null);
804 verifyNoMoreInteractions(mWifiManager);
Erik Kline9e225542017-06-08 17:48:48 +0900805 verifyNoMoreInteractions(mNMService);
806
807 // Emulate externally-visible WifiManager effects, causing the
808 // per-interface state machine to start up, and telling us that
809 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900810 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
811 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline9e225542017-06-08 17:48:48 +0900812 mLooper.dispatchAll();
813
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800814 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900815 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900816 verify(mNMService, times(1)).setIpForwardingEnabled(true);
817 verify(mNMService, times(1)).startTethering(any(String[].class));
818 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900819 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900820 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
821 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900822 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +0900823 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900824 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
markchiena6c72872018-11-13 18:34:56 +0900825 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Erik Klineea9cc482017-03-10 19:35:34 +0900826 // In tethering mode, in the default configuration, an explicit request
827 // for a mobile network is also made.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900828 verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800829 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
830 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
831 assertEquals(2, mTetheringDependencies.isTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900832
833 /////
834 // We do not currently emulate any upstream being found.
835 //
836 // This is why there are no calls to verify mNMService.enableNat() or
837 // mNMService.startInterfaceForwarding().
838 /////
839
840 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900841 mTethering.stopTethering(TETHERING_WIFI);
Erik Klineea9cc482017-03-10 19:35:34 +0900842 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900843 verify(mWifiManager, times(1)).stopSoftAp();
Erik Klineea9cc482017-03-10 19:35:34 +0900844 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900845 verifyNoMoreInteractions(mNMService);
846
847 // Emulate externally-visible WifiManager effects, when tethering mode
848 // is being torn down.
849 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900850 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900851 mLooper.dispatchAll();
852
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900853 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800854 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900855 verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900856 verify(mNMService, atLeastOnce())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900857 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900858 verify(mNMService, times(1)).stopTethering();
859 verify(mNMService, times(1)).setIpForwardingEnabled(false);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900860 verify(mWifiManager, times(3)).updateInterfaceIpState(
861 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klineea9cc482017-03-10 19:35:34 +0900862 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900863 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900864 // Asking for the last error after the per-interface state machine
865 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900866 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900867 }
868
Erik Klinea9cde8b2017-06-20 21:18:31 +0900869 // TODO: Test with and without interfaceStatusChanged().
Erik Kline1fdc2e22017-05-08 17:56:35 +0900870 @Test
871 public void failureEnablingIpForwarding() throws Exception {
Erik Kline1fdc2e22017-05-08 17:56:35 +0900872 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
873 doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);
874
875 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900876 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900877 mLooper.dispatchAll();
878 verify(mWifiManager, times(1)).startSoftAp(null);
879 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900880 verifyNoMoreInteractions(mNMService);
881
882 // Emulate externally-visible WifiManager effects, causing the
883 // per-interface state machine to start up, and telling us that
884 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900885 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
886 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900887 mLooper.dispatchAll();
888
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900889 // We verify get/set called thrice here: twice for setup (on NMService) and once during
890 // teardown (on Netd) because all events happen over the course of the single
Erik Kline7a4ccc62018-08-27 17:26:47 +0900891 // dispatchAll() above. Note that once the IpServer IPv4 address config
Erik Kline472276a2018-05-18 16:09:24 +0900892 // code is refactored the two calls during shutdown will revert to one.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900893 verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900894 verify(mNMService, times(2))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900895 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900896 verify(mNetd, times(1)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900897 verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900898 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900899 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
900 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900901 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800902 // There are 3 state change event:
903 // AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
904 assertEquals(3, mTetheringDependencies.isTetheringSupportedCalls);
Erik Kline465ff3a2018-03-09 14:18:02 +0900905 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900906 // This is called, but will throw.
907 verify(mNMService, times(1)).setIpForwardingEnabled(true);
908 // This never gets called because of the exception thrown above.
909 verify(mNMService, times(0)).startTethering(any(String[].class));
910 // When the master state machine transitions to an error state it tells
911 // downstream interfaces, which causes us to tell Wi-Fi about the error
912 // so it can take down AP mode.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900913 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900914 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900915 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900916
917 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900918 verifyNoMoreInteractions(mNMService);
919 }
920
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100921 private void userRestrictionsListenerBehaviour(
922 boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
923 int expectedInteractionsWithShowNotification) throws Exception {
924 final int userId = 0;
925 final Bundle currRestrictions = new Bundle();
926 final Bundle newRestrictions = new Bundle();
927 Tethering tethering = mock(Tethering.class);
928 Tethering.TetheringUserRestrictionListener turl =
929 new Tethering.TetheringUserRestrictionListener(tethering);
930
931 currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow);
932 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
933 when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
934
935 turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions);
936
937 verify(tethering, times(expectedInteractionsWithShowNotification))
938 .showTetheredNotification(anyInt(), eq(false));
939
940 verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll();
941 }
942
943 @Test
944 public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
945 final String[] emptyActiveIfacesList = new String[]{};
946 final boolean currDisallow = false;
947 final boolean nextDisallow = true;
948 final int expectedInteractionsWithShowNotification = 0;
949
950 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList,
951 expectedInteractionsWithShowNotification);
952 }
953
954 @Test
955 public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900956 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100957 final boolean currDisallow = false;
958 final boolean nextDisallow = true;
959 final int expectedInteractionsWithShowNotification = 1;
960
961 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
962 expectedInteractionsWithShowNotification);
963 }
964
965 @Test
966 public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
967 final String[] nonEmptyActiveIfacesList = new String[]{};
968 final boolean currDisallow = true;
969 final boolean nextDisallow = false;
970 final int expectedInteractionsWithShowNotification = 0;
971
972 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
973 expectedInteractionsWithShowNotification);
974 }
975
976 @Test
977 public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900978 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100979 final boolean currDisallow = true;
980 final boolean nextDisallow = false;
981 final int expectedInteractionsWithShowNotification = 0;
982
983 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
984 expectedInteractionsWithShowNotification);
985 }
986
987 @Test
988 public void testDisallowTetheringUnchanged() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900989 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100990 final int expectedInteractionsWithShowNotification = 0;
991 boolean currDisallow = true;
992 boolean nextDisallow = true;
993
994 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
995 expectedInteractionsWithShowNotification);
996
997 currDisallow = false;
998 nextDisallow = false;
999
1000 userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
1001 expectedInteractionsWithShowNotification);
1002 }
1003
markchien26299ed2019-02-27 14:56:11 +08001004 private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
1005 private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
1006
1007 public void expectUpstreamChanged(Network... networks) {
1008 final ArrayList<Network> expectedUpstreams =
1009 new ArrayList<Network>(Arrays.asList(networks));
1010 for (Network upstream : expectedUpstreams) {
1011 // throws OOB if no expectations
1012 assertEquals(mActualUpstreams.remove(0), upstream);
1013 }
1014 assertNoCallback();
1015 }
1016
1017 @Override
1018 public void onUpstreamChanged(Network network) {
1019 mActualUpstreams.add(network);
1020 }
1021
1022 public void assertNoCallback() {
1023 assertTrue(mActualUpstreams.isEmpty());
1024 }
1025 }
1026
1027 @Test
1028 public void testRegisterTetheringEventCallback() throws Exception {
1029 TestTetheringEventCallback callback1 = new TestTetheringEventCallback();
1030 TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
1031
1032 // 1. Register one callback and run usb tethering.
1033 mTethering.registerTetheringEventCallback(callback1);
1034 mLooper.dispatchAll();
1035 callback1.expectUpstreamChanged(new Network[] {null});
1036 NetworkState upstreamState = buildMobileDualStackUpstreamState();
1037 runUsbTethering(upstreamState);
1038 callback1.expectUpstreamChanged(upstreamState.network);
1039 // 2. Register second callback.
1040 mTethering.registerTetheringEventCallback(callback2);
1041 mLooper.dispatchAll();
1042 callback2.expectUpstreamChanged(upstreamState.network);
1043 // 3. Disable usb tethering.
1044 mTethering.stopTethering(TETHERING_USB);
1045 mLooper.dispatchAll();
1046 sendUsbBroadcast(false, false, false);
1047 mLooper.dispatchAll();
1048 callback1.expectUpstreamChanged(new Network[] {null});
1049 callback2.expectUpstreamChanged(new Network[] {null});
1050 // 4. Unregister first callback and run hotspot.
1051 mTethering.unregisterTetheringEventCallback(callback1);
1052 mLooper.dispatchAll();
1053 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
1054 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
1055 .thenReturn(upstreamState);
1056 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
1057 mTethering.startTethering(TETHERING_WIFI, null, false);
1058 mLooper.dispatchAll();
1059 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1060 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1061 mLooper.dispatchAll();
1062 callback1.assertNoCallback();
1063 callback2.expectUpstreamChanged(upstreamState.network);
1064 }
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001065
markchien04bdf872019-06-17 21:05:34 +08001066 @Test
1067 public void testMultiSimAware() throws Exception {
1068 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
1069 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId);
1070
1071 final int fakeSubId = 1234;
1072 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1073 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
1074 assertEquals(fakeSubId, newConfig.subId);
1075 }
1076
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001077 private void workingWifiP2pGroupOwner(
1078 boolean emulateInterfaceStatusChanged) throws Exception {
1079 if (emulateInterfaceStatusChanged) {
1080 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1081 }
1082 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1083 mLooper.dispatchAll();
1084
1085 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
1086 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
1087 verify(mNMService, times(1)).setIpForwardingEnabled(true);
1088 verify(mNMService, times(1)).startTethering(any(String[].class));
1089 verifyNoMoreInteractions(mNMService);
1090 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
1091 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
1092 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
1093 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
1094 assertEquals(2, mTetheringDependencies.isTetheringSupportedCalls);
1095
1096 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1097
1098 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1099 // is being removed.
1100 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
1101 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1102 mLooper.dispatchAll();
1103
1104 verify(mNMService, times(1)).untetherInterface(TEST_P2P_IFNAME);
1105 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
1106 verify(mNMService, times(2)).getInterfaceConfig(TEST_P2P_IFNAME);
1107 verify(mNMService, times(2))
1108 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1109 verify(mNMService, times(1)).stopTethering();
1110 verify(mNMService, times(1)).setIpForwardingEnabled(false);
1111 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
1112 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
1113 verifyNoMoreInteractions(mNMService);
1114 // Asking for the last error after the per-interface state machine
1115 // has been reaped yields an unknown interface error.
1116 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1117 }
1118
1119 private void workingWifiP2pGroupClient(
1120 boolean emulateInterfaceStatusChanged) throws Exception {
1121 if (emulateInterfaceStatusChanged) {
1122 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1123 }
1124 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
1125 mLooper.dispatchAll();
1126
1127 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1128 verify(mNMService, never())
1129 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1130 verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
1131 verify(mNMService, never()).setIpForwardingEnabled(true);
1132 verify(mNMService, never()).startTethering(any(String[].class));
1133
1134 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1135 // is being removed.
1136 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
1137 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1138 mLooper.dispatchAll();
1139
1140 verify(mNMService, never()).untetherInterface(TEST_P2P_IFNAME);
1141 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1142 verify(mNMService, never())
1143 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1144 verify(mNMService, never()).stopTethering();
1145 verify(mNMService, never()).setIpForwardingEnabled(false);
1146 verifyNoMoreInteractions(mNMService);
1147 // Asking for the last error after the per-interface state machine
1148 // has been reaped yields an unknown interface error.
1149 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1150 }
1151
1152 @Test
1153 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
1154 workingWifiP2pGroupOwner(true);
1155 }
1156
1157 @Test
1158 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
1159 workingWifiP2pGroupOwner(false);
1160 }
1161
1162 private void workingWifiP2pGroupOwnerLegacyMode(
1163 boolean emulateInterfaceStatusChanged) throws Exception {
1164 // change to legacy mode and update tethering information by chaning SIM
1165 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs))
1166 .thenReturn(new String[]{});
1167 final int fakeSubId = 1234;
1168 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1169
1170 if (emulateInterfaceStatusChanged) {
1171 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1172 }
1173 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1174 mLooper.dispatchAll();
1175
1176 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1177 verify(mNMService, never())
1178 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1179 verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
1180 verify(mNMService, never()).setIpForwardingEnabled(true);
1181 verify(mNMService, never()).startTethering(any(String[].class));
1182 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1183 }
1184 @Test
1185 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
1186 workingWifiP2pGroupOwnerLegacyMode(true);
1187 }
1188
1189 @Test
1190 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
1191 workingWifiP2pGroupOwnerLegacyMode(false);
1192 }
1193
1194 @Test
1195 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
1196 workingWifiP2pGroupClient(true);
1197 }
1198
1199 @Test
1200 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
1201 workingWifiP2pGroupClient(false);
1202 }
1203
Erik Kline1fdc2e22017-05-08 17:56:35 +09001204 // TODO: Test that a request for hotspot mode doesn't interfere with an
Erik Klineea9cc482017-03-10 19:35:34 +09001205 // already operating tethering mode interface.
Christopher Wiley497c1472016-10-11 13:26:03 -07001206}