blob: 0273ed3586737fd5f1337e42d012778a7a5b8af2 [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
markchien0df2ebc42019-09-30 14:40:57 +080017package com.android.server.connectivity.tethering;
Christopher Wiley497c1472016-10-11 13:26:03 -070018
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
markchien0df2ebc42019-09-30 14:40:57 +080042import static org.junit.Assert.assertArrayEquals;
Erik Klineea9cc482017-03-10 19:35:34 +090043import static org.junit.Assert.assertEquals;
markchien0df2ebc42019-09-30 14:40:57 +080044import static org.junit.Assert.assertFalse;
Christopher Wiley497c1472016-10-11 13:26:03 -070045import static org.junit.Assert.assertTrue;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090046import static org.junit.Assert.fail;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090047import static org.mockito.ArgumentMatchers.argThat;
48import static org.mockito.ArgumentMatchers.notNull;
Erik Klineea9cc482017-03-10 19:35:34 +090049import static org.mockito.Matchers.anyInt;
50import static org.mockito.Matchers.anyString;
Christopher Wiley497c1472016-10-11 13:26:03 -070051import static org.mockito.Matchers.eq;
Erik Kline1fdc2e22017-05-08 17:56:35 +090052import static org.mockito.Mockito.any;
Erik Klineea9cc482017-03-10 19:35:34 +090053import static org.mockito.Mockito.atLeastOnce;
Erik Kline1fdc2e22017-05-08 17:56:35 +090054import static org.mockito.Mockito.doThrow;
markchienb6eb2c22018-07-18 14:29:20 +080055import static org.mockito.Mockito.mock;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090056import static org.mockito.Mockito.never;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090057import static org.mockito.Mockito.spy;
58import static org.mockito.Mockito.timeout;
Erik Klineea9cc482017-03-10 19:35:34 +090059import static org.mockito.Mockito.times;
60import static org.mockito.Mockito.verify;
61import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley497c1472016-10-11 13:26:03 -070062import static org.mockito.Mockito.when;
63
Erik Kline8351faa2017-04-17 16:47:23 +090064import android.content.BroadcastReceiver;
Erik Kline92c4db02017-05-31 10:21:32 +090065import android.content.ContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070066import android.content.Context;
Erik Klineea9cc482017-03-10 19:35:34 +090067import android.content.Intent;
Erik Kline8351faa2017-04-17 16:47:23 +090068import android.content.IntentFilter;
Erik Klinef3a08b42017-06-07 16:33:19 +090069import android.content.pm.ApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -070070import android.content.res.Resources;
Erik Klineea9cc482017-03-10 19:35:34 +090071import android.hardware.usb.UsbManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090072import android.net.INetd;
Christopher Wiley497c1472016-10-11 13:26:03 -070073import android.net.INetworkPolicyManager;
74import android.net.INetworkStatsService;
markchien0df2ebc42019-09-30 14:40:57 +080075import android.net.ITetherInternalCallback;
Erik Klineea9cc482017-03-10 19:35:34 +090076import android.net.InterfaceConfiguration;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090077import android.net.IpPrefix;
78import android.net.LinkAddress;
79import android.net.LinkProperties;
80import android.net.MacAddress;
81import android.net.Network;
82import android.net.NetworkCapabilities;
83import android.net.NetworkInfo;
84import android.net.NetworkState;
85import android.net.NetworkUtils;
86import android.net.RouteInfo;
markchien0df2ebc42019-09-30 14:40:57 +080087import android.net.TetherStatesParcel;
88import android.net.TetheringConfigurationParcel;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090089import android.net.dhcp.DhcpServerCallbacks;
90import android.net.dhcp.DhcpServingParamsParcel;
91import android.net.dhcp.IDhcpServer;
Erik Kline7a4ccc62018-08-27 17:26:47 +090092import android.net.ip.IpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090093import android.net.ip.RouterAdvertisementDaemon;
94import android.net.util.InterfaceParams;
95import android.net.util.NetworkConstants;
Erik Klinef4b6e342017-04-25 19:19:59 +090096import android.net.util.SharedLog;
Erik Klineea9cc482017-03-10 19:35:34 +090097import android.net.wifi.WifiConfiguration;
98import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +080099import android.net.wifi.p2p.WifiP2pGroup;
100import android.net.wifi.p2p.WifiP2pInfo;
101import android.net.wifi.p2p.WifiP2pManager;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100102import android.os.Bundle;
Erik Klineea9cc482017-03-10 19:35:34 +0900103import android.os.Handler;
Christopher Wiley497c1472016-10-11 13:26:03 -0700104import android.os.INetworkManagementService;
markchien0df2ebc42019-09-30 14:40:57 +0800105import android.os.Looper;
Christopher Wiley497c1472016-10-11 13:26:03 -0700106import android.os.PersistableBundle;
Erik Kline1fdc2e22017-05-08 17:56:35 +0900107import android.os.RemoteException;
Erik Klineea9cc482017-03-10 19:35:34 +0900108import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100109import android.os.UserManager;
markchienb6eb2c22018-07-18 14:29:20 +0800110import android.os.test.TestLooper;
Erik Kline92c4db02017-05-31 10:21:32 +0900111import android.provider.Settings;
Christopher Wiley497c1472016-10-11 13:26:03 -0700112import android.telephony.CarrierConfigManager;
markchien04bdf872019-06-17 21:05:34 +0800113import android.telephony.PhoneStateListener;
114import android.telephony.TelephonyManager;
Erik Kline92c4db02017-05-31 10:21:32 +0900115import android.test.mock.MockContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700116
markchien0df2ebc42019-09-30 14:40:57 +0800117import androidx.annotation.NonNull;
Brett Chabot1ae2aa62019-03-04 14:14:56 -0800118import androidx.test.filters.SmallTest;
119import androidx.test.runner.AndroidJUnit4;
120
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900121import com.android.internal.util.ArrayUtils;
122import com.android.internal.util.StateMachine;
Erik Klineea9cc482017-03-10 19:35:34 +0900123import com.android.internal.util.test.BroadcastInterceptingContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900124import com.android.internal.util.test.FakeSettingsProvider;
Erik Klineea9cc482017-03-10 19:35:34 +0900125
Erik Kline8351faa2017-04-17 16:47:23 +0900126import org.junit.After;
Christopher Wiley497c1472016-10-11 13:26:03 -0700127import org.junit.Before;
128import org.junit.Test;
129import org.junit.runner.RunWith;
markchien04bdf872019-06-17 21:05:34 +0800130import org.mockito.ArgumentCaptor;
Christopher Wiley497c1472016-10-11 13:26:03 -0700131import org.mockito.Mock;
132import org.mockito.MockitoAnnotations;
133
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900134import java.net.Inet4Address;
135import java.net.Inet6Address;
Erik Kline8351faa2017-04-17 16:47:23 +0900136import java.util.ArrayList;
markchien26299ed2019-02-27 14:56:11 +0800137import java.util.Arrays;
Erik Kline8351faa2017-04-17 16:47:23 +0900138import java.util.Vector;
139
Christopher Wiley497c1472016-10-11 13:26:03 -0700140@RunWith(AndroidJUnit4.class)
141@SmallTest
142public class TetheringTest {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900143 private static final int IFINDEX_OFFSET = 100;
144
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900145 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
146 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
147 private static final String TEST_USB_IFNAME = "test_rndis0";
148 private static final String TEST_WLAN_IFNAME = "test_wlan0";
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800149 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
Christopher Wiley497c1472016-10-11 13:26:03 -0700150
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900151 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
152
Erik Klinef3a08b42017-06-07 16:33:19 +0900153 @Mock private ApplicationInfo mApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -0700154 @Mock private Context mContext;
155 @Mock private INetworkManagementService mNMService;
156 @Mock private INetworkStatsService mStatsService;
157 @Mock private INetworkPolicyManager mPolicyManager;
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;
markchienb741c642019-11-27 21:20:33 +0800169 @Mock private UserManager mUserManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900170
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900171 private final MockIpServerDependencies mIpServerDependencies =
172 spy(new MockIpServerDependencies());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900173 private final MockTetheringDependencies mTetheringDependencies =
174 new MockTetheringDependencies();
Christopher Wiley497c1472016-10-11 13:26:03 -0700175
176 // Like so many Android system APIs, these cannot be mocked because it is marked final.
177 // We have to use the real versions.
178 private final PersistableBundle mCarrierConfig = new PersistableBundle();
179 private final TestLooper mLooper = new TestLooper();
180
Erik Kline8351faa2017-04-17 16:47:23 +0900181 private Vector<Intent> mIntents;
Erik Klineea9cc482017-03-10 19:35:34 +0900182 private BroadcastInterceptingContext mServiceContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900183 private MockContentResolver mContentResolver;
Erik Kline8351faa2017-04-17 16:47:23 +0900184 private BroadcastReceiver mBroadcastReceiver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700185 private Tethering mTethering;
markchien04bdf872019-06-17 21:05:34 +0800186 private PhoneStateListener mPhoneStateListener;
Christopher Wiley497c1472016-10-11 13:26:03 -0700187
markchien0df2ebc42019-09-30 14:40:57 +0800188 private class TestContext extends BroadcastInterceptingContext {
189 TestContext(Context base) {
Erik Klineea9cc482017-03-10 19:35:34 +0900190 super(base);
191 }
192
193 @Override
markchien0df2ebc42019-09-30 14:40:57 +0800194 public ApplicationInfo getApplicationInfo() {
195 return mApplicationInfo;
196 }
Erik Klinef3a08b42017-06-07 16:33:19 +0900197
198 @Override
markchien0df2ebc42019-09-30 14:40:57 +0800199 public ContentResolver getContentResolver() {
200 return mContentResolver;
201 }
Erik Kline92c4db02017-05-31 10:21:32 +0900202
203 @Override
markchien0df2ebc42019-09-30 14:40:57 +0800204 public String getPackageName() {
205 return "TetheringTest";
206 }
Erik Kline92c4db02017-05-31 10:21:32 +0900207
208 @Override
markchien0df2ebc42019-09-30 14:40:57 +0800209 public Resources getResources() {
210 return mResources;
211 }
Erik Klineea9cc482017-03-10 19:35:34 +0900212
213 @Override
214 public Object getSystemService(String name) {
Erik Klineea9cc482017-03-10 19:35:34 +0900215 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
Erik Klinec438e302017-07-04 22:02:49 +0900216 if (Context.USB_SERVICE.equals(name)) return mUsbManager;
markchien04bdf872019-06-17 21:05:34 +0800217 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
markchienb741c642019-11-27 21:20:33 +0800218 if (Context.USER_SERVICE.equals(name)) return mUserManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900219 return super.getSystemService(name);
220 }
Jayachandran C43fa1be2019-11-15 09:58:04 -0800221
222 @Override
223 public String getSystemServiceName(Class<?> serviceClass) {
224 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
225 return super.getSystemServiceName(serviceClass);
226 }
Erik Klineea9cc482017-03-10 19:35:34 +0900227 }
228
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900229 public class MockIpServerDependencies extends IpServer.Dependencies {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900230 @Override
231 public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
232 InterfaceParams ifParams) {
233 return mRouterAdvertisementDaemon;
234 }
235
236 @Override
237 public InterfaceParams getInterfaceParams(String ifName) {
238 assertTrue("Non-mocked interface " + ifName,
239 ifName.equals(TEST_USB_IFNAME)
240 || ifName.equals(TEST_WLAN_IFNAME)
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800241 || ifName.equals(TEST_MOBILE_IFNAME)
242 || ifName.equals(TEST_P2P_IFNAME));
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900243 final String[] ifaces = new String[] {
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800244 TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME};
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900245 return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
246 MacAddress.ALL_ZEROS_ADDRESS);
247 }
248
249 @Override
250 public INetd getNetdService() {
251 return mNetd;
252 }
253
254 @Override
255 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
256 DhcpServerCallbacks cb) {
257 new Thread(() -> {
258 try {
259 cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
260 } catch (RemoteException e) {
261 fail(e.getMessage());
262 }
263 }).run();
264 }
265 }
266
markchien04bdf872019-06-17 21:05:34 +0800267 private class MockTetheringConfiguration extends TetheringConfiguration {
268 MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
269 super(ctx, log, id);
270 }
271
272 @Override
273 protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
274 return mResources;
275 }
276 }
277
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900278 public class MockTetheringDependencies extends TetheringDependencies {
markchien0df2ebc42019-09-30 14:40:57 +0800279 StateMachine mUpstreamNetworkMonitorMasterSM;
280 ArrayList<IpServer> mIpv6CoordinatorNotifyList;
281 int mIsTetheringSupportedCalls;
Erik Kline465ff3a2018-03-09 14:18:02 +0900282
283 public void reset() {
markchien0df2ebc42019-09-30 14:40:57 +0800284 mUpstreamNetworkMonitorMasterSM = null;
285 mIpv6CoordinatorNotifyList = null;
286 mIsTetheringSupportedCalls = 0;
Erik Kline465ff3a2018-03-09 14:18:02 +0900287 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900288
289 @Override
290 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
291 return mOffloadHardwareInterface;
292 }
293
294 @Override
295 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
296 StateMachine target, SharedLog log, int what) {
markchien0df2ebc42019-09-30 14:40:57 +0800297 mUpstreamNetworkMonitorMasterSM = target;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900298 return mUpstreamNetworkMonitor;
299 }
300
301 @Override
302 public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
Erik Kline7a4ccc62018-08-27 17:26:47 +0900303 ArrayList<IpServer> notifyList, SharedLog log) {
markchien0df2ebc42019-09-30 14:40:57 +0800304 mIpv6CoordinatorNotifyList = notifyList;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900305 return mIPv6TetheringCoordinator;
306 }
307
308 @Override
Remi NGUYEN VAN5db454c2019-02-14 18:04:20 +0900309 public IpServer.Dependencies getIpServerDependencies() {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900310 return mIpServerDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900311 }
Erik Kline465ff3a2018-03-09 14:18:02 +0900312
313 @Override
314 public boolean isTetheringSupported() {
markchien0df2ebc42019-09-30 14:40:57 +0800315 mIsTetheringSupportedCalls++;
Erik Kline465ff3a2018-03-09 14:18:02 +0900316 return true;
317 }
markchien0b595072019-01-08 23:52:21 +0800318
319 @Override
markchien04bdf872019-06-17 21:05:34 +0800320 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
321 int subId) {
322 return new MockTetheringConfiguration(ctx, log, subId);
markchien0b595072019-01-08 23:52:21 +0800323 }
markchien0df2ebc42019-09-30 14:40:57 +0800324
325 @Override
326 public INetworkManagementService getINetworkManagementService() {
327 return mNMService;
328 }
329
330 @Override
331 public INetworkStatsService getINetworkStatsService() {
332 return mStatsService;
333 }
334
335 @Override
336 public INetworkPolicyManager getINetworkPolicyManager() {
337 return mPolicyManager;
338 }
339
340 @Override
341 public INetd getINetd(Context context) {
342 return mNetd;
343 }
344
345 @Override
346 public Looper getTetheringLooper() {
347 return mLooper.getLooper();
348 }
349
350 @Override
351 public Context getContext() {
352 return mServiceContext;
353 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900354 }
355
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900356 private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
357 boolean with464xlat) {
Erik Kline465ff3a2018-03-09 14:18:02 +0900358 final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, 0, null, null);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900359 info.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
360 final LinkProperties prop = new LinkProperties();
361 prop.setInterfaceName(TEST_MOBILE_IFNAME);
362
363 if (withIPv4) {
364 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
365 NetworkUtils.numericToInetAddress("10.0.0.1"), TEST_MOBILE_IFNAME));
366 }
367
368 if (withIPv6) {
369 prop.addDnsServer(NetworkUtils.numericToInetAddress("2001:db8::2"));
370 prop.addLinkAddress(
371 new LinkAddress(NetworkUtils.numericToInetAddress("2001:db8::"),
372 NetworkConstants.RFC7421_PREFIX_LENGTH));
373 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
374 NetworkUtils.numericToInetAddress("2001:db8::1"), TEST_MOBILE_IFNAME));
375 }
376
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900377 if (with464xlat) {
378 final LinkProperties stackedLink = new LinkProperties();
379 stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
380 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
381 NetworkUtils.numericToInetAddress("192.0.0.1"), TEST_XLAT_MOBILE_IFNAME));
382
383 prop.addStackedLink(stackedLink);
384 }
385
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900386
387 final NetworkCapabilities capabilities = new NetworkCapabilities()
markchien0df2ebc42019-09-30 14:40:57 +0800388 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900389 return new NetworkState(info, prop, capabilities, new Network(100), null, "netid");
390 }
391
392 private static NetworkState buildMobileIPv4UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900393 return buildMobileUpstreamState(true, false, false);
394 }
395
396 private static NetworkState buildMobileIPv6UpstreamState() {
397 return buildMobileUpstreamState(false, true, false);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900398 }
399
400 private static NetworkState buildMobileDualStackUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900401 return buildMobileUpstreamState(true, true, false);
402 }
403
404 private static NetworkState buildMobile464xlatUpstreamState() {
405 return buildMobileUpstreamState(false, true, true);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900406 }
407
Erik Kline8351faa2017-04-17 16:47:23 +0900408 @Before
409 public void setUp() throws Exception {
Christopher Wiley497c1472016-10-11 13:26:03 -0700410 MockitoAnnotations.initMocks(this);
Christopher Wiley497c1472016-10-11 13:26:03 -0700411 when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range))
412 .thenReturn(new String[0]);
413 when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900414 .thenReturn(new String[] { "test_rndis\\d" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700415 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900416 .thenReturn(new String[]{ "test_wlan\\d" });
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800417 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs))
418 .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
Christopher Wiley497c1472016-10-11 13:26:03 -0700419 when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
420 .thenReturn(new String[0]);
421 when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
422 .thenReturn(new int[0]);
Erik Kline72302902018-06-14 17:36:40 +0900423 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
424 .thenReturn(false);
Erik Klineea9cc482017-03-10 19:35:34 +0900425 when(mNMService.listInterfaces())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900426 .thenReturn(new String[] {
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800427 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME});
Erik Klineea9cc482017-03-10 19:35:34 +0900428 when(mNMService.getInterfaceConfig(anyString()))
429 .thenReturn(new InterfaceConfiguration());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900430 when(mRouterAdvertisementDaemon.start())
431 .thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900432
markchien0df2ebc42019-09-30 14:40:57 +0800433 mServiceContext = new TestContext(mContext);
Erik Kline92c4db02017-05-31 10:21:32 +0900434 mContentResolver = new MockContentResolver(mServiceContext);
435 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900436 Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
Erik Kline8351faa2017-04-17 16:47:23 +0900437 mIntents = new Vector<>();
438 mBroadcastReceiver = new BroadcastReceiver() {
439 @Override
440 public void onReceive(Context context, Intent intent) {
441 mIntents.addElement(intent);
442 }
443 };
444 mServiceContext.registerReceiver(mBroadcastReceiver,
Erik Kline465ff3a2018-03-09 14:18:02 +0900445 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900446 mTethering = makeTethering();
Lorenzo Colitti5a7dea12017-07-12 15:48:07 +0900447 verify(mNMService).registerTetheringStatsProvider(any(), anyString());
markchien0df2ebc42019-09-30 14:40:57 +0800448 verify(mNetd).registerUnsolicitedEventListener(any());
markchien04bdf872019-06-17 21:05:34 +0800449 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
450 ArgumentCaptor.forClass(PhoneStateListener.class);
451 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
452 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
453 mPhoneStateListener = phoneListenerCaptor.getValue();
Christopher Wiley497c1472016-10-11 13:26:03 -0700454 }
455
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900456 private Tethering makeTethering() {
markchien0df2ebc42019-09-30 14:40:57 +0800457 mTetheringDependencies.reset();
458 return new Tethering(mTetheringDependencies);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900459 }
460
Erik Kline8351faa2017-04-17 16:47:23 +0900461 @After
462 public void tearDown() {
463 mServiceContext.unregisterReceiver(mBroadcastReceiver);
464 }
465
Erik Klineea9cc482017-03-10 19:35:34 +0900466 private void sendWifiApStateChanged(int state) {
467 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Erik Kline2efb8272017-05-31 15:53:53 +0900468 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
Erik Klineea9cc482017-03-10 19:35:34 +0900469 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
470 }
471
Erik Kline2efb8272017-05-31 15:53:53 +0900472 private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
473 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
474 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
475 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
476 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
477 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
478 }
479
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800480 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
481 android.Manifest.permission.ACCESS_FINE_LOCATION,
482 android.Manifest.permission.ACCESS_WIFI_STATE
483 };
484
485 private void sendWifiP2pConnectionChanged(
486 boolean isGroupFormed, boolean isGroupOwner, String ifname) {
487 WifiP2pInfo p2pInfo = new WifiP2pInfo();
488 p2pInfo.groupFormed = isGroupFormed;
489 p2pInfo.isGroupOwner = isGroupOwner;
490
491 NetworkInfo networkInfo = new NetworkInfo(TYPE_WIFI_P2P, 0, null, null);
492
493 WifiP2pGroup group = new WifiP2pGroup();
494 group.setIsGroupOwner(isGroupOwner);
495 group.setInterface(ifname);
496
497 final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
498 intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, p2pInfo);
499 intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, networkInfo);
500 intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, group);
501 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
502 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
503 }
504
Erik Klinec438e302017-07-04 22:02:49 +0900505 private void sendUsbBroadcast(boolean connected, boolean configured, boolean rndisFunction) {
506 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
507 intent.putExtra(USB_CONNECTED, connected);
508 intent.putExtra(USB_CONFIGURED, configured);
509 intent.putExtra(USB_FUNCTION_RNDIS, rndisFunction);
510 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
511 }
512
Erik Kline80b7a9f2018-02-28 15:01:35 +0900513 private void sendConfigurationChanged() {
514 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
515 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
516 }
517
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800518 private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
519 verify(mNMService, times(1)).getInterfaceConfig(ifname);
Erik Kline8351faa2017-04-17 16:47:23 +0900520 verify(mNMService, times(1))
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800521 .setInterfaceConfig(eq(ifname), any(InterfaceConfiguration.class));
522 verify(mNMService, times(1)).tetherInterface(ifname);
Erik Kline8351faa2017-04-17 16:47:23 +0900523 }
524
525 private void verifyTetheringBroadcast(String ifname, String whichExtra) {
526 // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
527 final Intent bcast = mIntents.get(0);
Erik Kline465ff3a2018-03-09 14:18:02 +0900528 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
Erik Kline8351faa2017-04-17 16:47:23 +0900529 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
530 assertTrue(ifnames.contains(ifname));
531 mIntents.remove(bcast);
532 }
533
Erik Klinea9cde8b2017-06-20 21:18:31 +0900534 public void failingLocalOnlyHotspotLegacyApBroadcast(
535 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Klineea9cc482017-03-10 19:35:34 +0900536 // Emulate externally-visible WifiManager effects, causing the
537 // per-interface state machine to start up, and telling us that
538 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900539 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900540 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900541 }
Erik Kline9e225542017-06-08 17:48:48 +0900542 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900543 mLooper.dispatchAll();
544
Erik Kline7a4ccc62018-08-27 17:26:47 +0900545 // If, and only if, Tethering received an interface status changed then
546 // it creates a IpServer and sends out a broadcast indicating that the
547 // interface is "available".
Erik Klinea9cde8b2017-06-20 21:18:31 +0900548 if (emulateInterfaceStatusChanged) {
markchien0df2ebc42019-09-30 14:40:57 +0800549 assertEquals(1, mTetheringDependencies.mIsTetheringSupportedCalls);
Erik Kline465ff3a2018-03-09 14:18:02 +0900550 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900551 verify(mWifiManager).updateInterfaceIpState(
552 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900553 }
Erik Kline9e225542017-06-08 17:48:48 +0900554 verifyNoMoreInteractions(mNMService);
555 verifyNoMoreInteractions(mWifiManager);
556 }
557
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900558 private void prepareUsbTethering(NetworkState upstreamState) {
Erik Kline72302902018-06-14 17:36:40 +0900559 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900560 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
561 .thenReturn(upstreamState);
Erik Klinec438e302017-07-04 22:02:49 +0900562
563 // Emulate pressing the USB tethering button in Settings UI.
564 mTethering.startTethering(TETHERING_USB, null, false);
565 mLooper.dispatchAll();
Jerry Zhang327b8092018-01-09 17:53:04 -0800566 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
Erik Klinec438e302017-07-04 22:02:49 +0900567
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900568 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
569 }
570
571 @Test
572 public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
573 NetworkState upstreamState = buildMobileIPv4UpstreamState();
574 prepareUsbTethering(upstreamState);
575
Erik Klinec438e302017-07-04 22:02:49 +0900576 // This should produce no activity of any kind.
Erik Klinec438e302017-07-04 22:02:49 +0900577 verifyNoMoreInteractions(mNMService);
578
579 // Pretend we then receive USB configured broadcast.
580 sendUsbBroadcast(true, true, true);
581 mLooper.dispatchAll();
582 // Now we should see the start of tethering mechanics (in this case:
583 // tetherMatchingInterfaces() which starts by fetching all interfaces).
584 verify(mNMService, times(1)).listInterfaces();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900585
586 // UpstreamNetworkMonitor should receive selected upstream
587 verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
588 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
Erik Klinec438e302017-07-04 22:02:49 +0900589 }
590
591 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900592 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
593 failingLocalOnlyHotspotLegacyApBroadcast(true);
594 }
595
596 @Test
597 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
598 failingLocalOnlyHotspotLegacyApBroadcast(false);
599 }
600
601 public void workingLocalOnlyHotspotEnrichedApBroadcast(
602 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900603 // Emulate externally-visible WifiManager effects, causing the
604 // per-interface state machine to start up, and telling us that
605 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900606 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900607 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900608 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900609 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline9e225542017-06-08 17:48:48 +0900610 mLooper.dispatchAll();
611
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800612 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900613 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900614 verify(mNMService, times(1)).setIpForwardingEnabled(true);
615 verify(mNMService, times(1)).startTethering(any(String[].class));
616 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900617 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900618 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
619 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900620 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +0900621 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900622 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
markchiena6c72872018-11-13 18:34:56 +0900623 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800624 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
625 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
markchien0df2ebc42019-09-30 14:40:57 +0800626 assertEquals(2, mTetheringDependencies.mIsTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900627
628 // Emulate externally-visible WifiManager effects, when hotspot mode
629 // is being torn down.
630 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900631 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900632 mLooper.dispatchAll();
633
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900634 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800635 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
636 verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
637 verify(mNMService, times(2))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900638 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900639 verify(mNMService, times(1)).stopTethering();
640 verify(mNMService, times(1)).setIpForwardingEnabled(false);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900641 verify(mWifiManager, times(3)).updateInterfaceIpState(
642 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klineea9cc482017-03-10 19:35:34 +0900643 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900644 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900645 // Asking for the last error after the per-interface state machine
646 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900647 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900648 }
649
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900650 /**
Erik Kline7a4ccc62018-08-27 17:26:47 +0900651 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900652 */
653 private void sendIPv6TetherUpdates(NetworkState upstreamState) {
654 // IPv6TetheringCoordinator must have been notified of downstream
655 verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
656 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
Erik Kline7a4ccc62018-08-27 17:26:47 +0900657 eq(IpServer.STATE_TETHERED));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900658
markchien0df2ebc42019-09-30 14:40:57 +0800659 for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900660 NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900661 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
paulhud9736de2019-03-08 16:35:20 +0800662 upstreamState.linkProperties.isIpv6Provisioned()
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900663 ? ipv6OnlyState.linkProperties
664 : null);
665 }
666 mLooper.dispatchAll();
667 }
668
669 private void runUsbTethering(NetworkState upstreamState) {
670 prepareUsbTethering(upstreamState);
671 sendUsbBroadcast(true, true, true);
672 mLooper.dispatchAll();
673 }
674
675 @Test
676 public void workingMobileUsbTethering_IPv4() throws Exception {
677 NetworkState upstreamState = buildMobileIPv4UpstreamState();
678 runUsbTethering(upstreamState);
679
680 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
681 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
682
683 sendIPv6TetherUpdates(upstreamState);
684 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900685 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900686 }
687
688 @Test
689 public void workingMobileUsbTethering_IPv4LegacyDhcp() {
690 Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
markchien0df2ebc42019-09-30 14:40:57 +0800691 sendConfigurationChanged();
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900692 final NetworkState upstreamState = buildMobileIPv4UpstreamState();
693 runUsbTethering(upstreamState);
694 sendIPv6TetherUpdates(upstreamState);
695
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900696 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900697 }
698
699 @Test
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900700 public void workingMobileUsbTethering_IPv6() throws Exception {
701 NetworkState upstreamState = buildMobileIPv6UpstreamState();
702 runUsbTethering(upstreamState);
703
704 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
705 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
706
707 sendIPv6TetherUpdates(upstreamState);
708 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
709 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
710 }
711
712 @Test
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900713 public void workingMobileUsbTethering_DualStack() throws Exception {
714 NetworkState upstreamState = buildMobileDualStackUpstreamState();
715 runUsbTethering(upstreamState);
716
717 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
718 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
719 verify(mRouterAdvertisementDaemon, times(1)).start();
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900720 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900721
722 sendIPv6TetherUpdates(upstreamState);
723 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
724 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
725 }
726
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900727 @Test
728 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
729 NetworkState upstreamState = buildMobile464xlatUpstreamState();
730 runUsbTethering(upstreamState);
731
732 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
733 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900734 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900735 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
736 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
737 TEST_XLAT_MOBILE_IFNAME);
738
739 sendIPv6TetherUpdates(upstreamState);
740 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
741 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
742 }
743
744 @Test
745 public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
746 // Setup IPv6
747 NetworkState upstreamState = buildMobileIPv6UpstreamState();
748 runUsbTethering(upstreamState);
749
750 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900751 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900752 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
753
754 // Then 464xlat comes up
755 upstreamState = buildMobile464xlatUpstreamState();
756 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
757 .thenReturn(upstreamState);
758
759 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
markchien0df2ebc42019-09-30 14:40:57 +0800760 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900761 Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
762 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
763 0,
764 upstreamState);
765 mLooper.dispatchAll();
766
767 // Forwarding is added for 464xlat
768 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
769 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
770 TEST_XLAT_MOBILE_IFNAME);
771 // Forwarding was not re-added for v6 (still times(1))
772 verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
773 verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900774 // DHCP not restarted on downstream (still times(1))
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900775 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).start(any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900776 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900777
Erik Klineea9cc482017-03-10 19:35:34 +0900778 @Test
Erik Kline72302902018-06-14 17:36:40 +0900779 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
780 when(mResources.getBoolean(com.android.internal.R.bool.config_tether_upstream_automatic))
781 .thenReturn(true);
782 sendConfigurationChanged();
783
784 // Setup IPv6
785 final NetworkState upstreamState = buildMobileIPv6UpstreamState();
786 runUsbTethering(upstreamState);
787
788 // UpstreamNetworkMonitor should choose upstream automatically
789 // (in this specific case: choose the default network).
790 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
791 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
792
793 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
794 }
795
796 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900797 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
798 workingLocalOnlyHotspotEnrichedApBroadcast(true);
799 }
800
801 @Test
802 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
803 workingLocalOnlyHotspotEnrichedApBroadcast(false);
804 }
805
806 // TODO: Test with and without interfaceStatusChanged().
807 @Test
Erik Kline9e225542017-06-08 17:48:48 +0900808 public void failingWifiTetheringLegacyApBroadcast() throws Exception {
Erik Klineceb54c62017-04-18 14:22:25 +0900809 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900810
811 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900812 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Klineea9cc482017-03-10 19:35:34 +0900813 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900814 verify(mWifiManager, times(1)).startSoftAp(null);
Erik Klineea9cc482017-03-10 19:35:34 +0900815 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900816 verifyNoMoreInteractions(mNMService);
817
818 // Emulate externally-visible WifiManager effects, causing the
819 // per-interface state machine to start up, and telling us that
820 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900821 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Kline9e225542017-06-08 17:48:48 +0900822 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900823 mLooper.dispatchAll();
824
markchien0df2ebc42019-09-30 14:40:57 +0800825 assertEquals(1, mTetheringDependencies.mIsTetheringSupportedCalls);
Erik Kline465ff3a2018-03-09 14:18:02 +0900826 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900827 verify(mWifiManager).updateInterfaceIpState(
828 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Kline9e225542017-06-08 17:48:48 +0900829 verifyNoMoreInteractions(mNMService);
830 verifyNoMoreInteractions(mWifiManager);
831 }
832
Erik Klinea9cde8b2017-06-20 21:18:31 +0900833 // TODO: Test with and without interfaceStatusChanged().
Erik Kline9e225542017-06-08 17:48:48 +0900834 @Test
835 public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900836 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
837
838 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900839 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline9e225542017-06-08 17:48:48 +0900840 mLooper.dispatchAll();
841 verify(mWifiManager, times(1)).startSoftAp(null);
842 verifyNoMoreInteractions(mWifiManager);
Erik Kline9e225542017-06-08 17:48:48 +0900843 verifyNoMoreInteractions(mNMService);
844
845 // Emulate externally-visible WifiManager effects, causing the
846 // per-interface state machine to start up, and telling us that
847 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900848 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
849 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline9e225542017-06-08 17:48:48 +0900850 mLooper.dispatchAll();
851
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800852 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900853 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Klineea9cc482017-03-10 19:35:34 +0900854 verify(mNMService, times(1)).setIpForwardingEnabled(true);
855 verify(mNMService, times(1)).startTethering(any(String[].class));
856 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900857 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900858 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
859 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900860 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +0900861 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900862 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
markchiena6c72872018-11-13 18:34:56 +0900863 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Erik Klineea9cc482017-03-10 19:35:34 +0900864 // In tethering mode, in the default configuration, an explicit request
865 // for a mobile network is also made.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900866 verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800867 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
868 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
markchien0df2ebc42019-09-30 14:40:57 +0800869 assertEquals(2, mTetheringDependencies.mIsTetheringSupportedCalls);
Erik Klineea9cc482017-03-10 19:35:34 +0900870
871 /////
872 // We do not currently emulate any upstream being found.
873 //
874 // This is why there are no calls to verify mNMService.enableNat() or
875 // mNMService.startInterfaceForwarding().
876 /////
877
878 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900879 mTethering.stopTethering(TETHERING_WIFI);
Erik Klineea9cc482017-03-10 19:35:34 +0900880 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900881 verify(mWifiManager, times(1)).stopSoftAp();
Erik Klineea9cc482017-03-10 19:35:34 +0900882 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900883 verifyNoMoreInteractions(mNMService);
884
885 // Emulate externally-visible WifiManager effects, when tethering mode
886 // is being torn down.
887 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900888 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900889 mLooper.dispatchAll();
890
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900891 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800892 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900893 verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900894 verify(mNMService, atLeastOnce())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900895 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Erik Klineea9cc482017-03-10 19:35:34 +0900896 verify(mNMService, times(1)).stopTethering();
897 verify(mNMService, times(1)).setIpForwardingEnabled(false);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900898 verify(mWifiManager, times(3)).updateInterfaceIpState(
899 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klineea9cc482017-03-10 19:35:34 +0900900 verifyNoMoreInteractions(mNMService);
Erik Kline216af6d2017-04-27 20:57:23 +0900901 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900902 // Asking for the last error after the per-interface state machine
903 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900904 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900905 }
906
Erik Klinea9cde8b2017-06-20 21:18:31 +0900907 // TODO: Test with and without interfaceStatusChanged().
Erik Kline1fdc2e22017-05-08 17:56:35 +0900908 @Test
909 public void failureEnablingIpForwarding() throws Exception {
Erik Kline1fdc2e22017-05-08 17:56:35 +0900910 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
911 doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);
912
913 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900914 mTethering.startTethering(TETHERING_WIFI, null, false);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900915 mLooper.dispatchAll();
916 verify(mWifiManager, times(1)).startSoftAp(null);
917 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900918 verifyNoMoreInteractions(mNMService);
919
920 // Emulate externally-visible WifiManager effects, causing the
921 // per-interface state machine to start up, and telling us that
922 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900923 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
924 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900925 mLooper.dispatchAll();
926
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900927 // We verify get/set called thrice here: twice for setup (on NMService) and once during
928 // teardown (on Netd) because all events happen over the course of the single
Erik Kline7a4ccc62018-08-27 17:26:47 +0900929 // dispatchAll() above. Note that once the IpServer IPv4 address config
Erik Kline472276a2018-05-18 16:09:24 +0900930 // code is refactored the two calls during shutdown will revert to one.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900931 verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900932 verify(mNMService, times(2))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900933 .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
Remi NGUYEN VANd1b51a32019-01-22 16:13:57 +0900934 verify(mNetd, times(1)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900935 verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900936 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900937 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
938 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900939 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800940 // There are 3 state change event:
941 // AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
markchien0df2ebc42019-09-30 14:40:57 +0800942 assertEquals(3, mTetheringDependencies.mIsTetheringSupportedCalls);
Erik Kline465ff3a2018-03-09 14:18:02 +0900943 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900944 // This is called, but will throw.
945 verify(mNMService, times(1)).setIpForwardingEnabled(true);
946 // This never gets called because of the exception thrown above.
947 verify(mNMService, times(0)).startTethering(any(String[].class));
948 // When the master state machine transitions to an error state it tells
949 // downstream interfaces, which causes us to tell Wi-Fi about the error
950 // so it can take down AP mode.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900951 verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900952 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900953 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900954
955 verifyNoMoreInteractions(mWifiManager);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900956 verifyNoMoreInteractions(mNMService);
957 }
958
markchienb741c642019-11-27 21:20:33 +0800959 private void runUserRestrictionsChange(
markchien0df2ebc42019-09-30 14:40:57 +0800960 boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
961 int expectedInteractionsWithShowNotification) throws Exception {
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100962 final Bundle newRestrictions = new Bundle();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100963 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
markchienb741c642019-11-27 21:20:33 +0800964 final Tethering mockTethering = mock(Tethering.class);
965 when(mockTethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
966 when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100967
markchienb741c642019-11-27 21:20:33 +0800968 final Tethering.UserRestrictionActionListener ural =
969 new Tethering.UserRestrictionActionListener(mUserManager, mockTethering);
970 ural.mDisallowTethering = currentDisallow;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100971
markchienb741c642019-11-27 21:20:33 +0800972 ural.onUserRestrictionsChanged();
973
974 verify(mockTethering, times(expectedInteractionsWithShowNotification))
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100975 .showTetheredNotification(anyInt(), eq(false));
976
markchienb741c642019-11-27 21:20:33 +0800977 verify(mockTethering, times(expectedInteractionsWithShowNotification))
978 .untetherAll();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100979 }
980
981 @Test
982 public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
983 final String[] emptyActiveIfacesList = new String[]{};
984 final boolean currDisallow = false;
985 final boolean nextDisallow = true;
986 final int expectedInteractionsWithShowNotification = 0;
987
markchienb741c642019-11-27 21:20:33 +0800988 runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100989 expectedInteractionsWithShowNotification);
990 }
991
992 @Test
993 public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900994 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100995 final boolean currDisallow = false;
996 final boolean nextDisallow = true;
997 final int expectedInteractionsWithShowNotification = 1;
998
markchienb741c642019-11-27 21:20:33 +0800999 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001000 expectedInteractionsWithShowNotification);
1001 }
1002
1003 @Test
1004 public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
1005 final String[] nonEmptyActiveIfacesList = new String[]{};
1006 final boolean currDisallow = true;
1007 final boolean nextDisallow = false;
1008 final int expectedInteractionsWithShowNotification = 0;
1009
markchienb741c642019-11-27 21:20:33 +08001010 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001011 expectedInteractionsWithShowNotification);
1012 }
1013
1014 @Test
1015 public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001016 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001017 final boolean currDisallow = true;
1018 final boolean nextDisallow = false;
1019 final int expectedInteractionsWithShowNotification = 0;
1020
markchienb741c642019-11-27 21:20:33 +08001021 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001022 expectedInteractionsWithShowNotification);
1023 }
1024
1025 @Test
1026 public void testDisallowTetheringUnchanged() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001027 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001028 final int expectedInteractionsWithShowNotification = 0;
1029 boolean currDisallow = true;
1030 boolean nextDisallow = true;
1031
markchienb741c642019-11-27 21:20:33 +08001032 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001033 expectedInteractionsWithShowNotification);
1034
1035 currDisallow = false;
1036 nextDisallow = false;
1037
markchienb741c642019-11-27 21:20:33 +08001038 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001039 expectedInteractionsWithShowNotification);
1040 }
1041
markchien0df2ebc42019-09-30 14:40:57 +08001042 private class TestTetherInternalCallback extends ITetherInternalCallback.Stub {
markchien26299ed2019-02-27 14:56:11 +08001043 private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
markchien0df2ebc42019-09-30 14:40:57 +08001044 private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
1045 new ArrayList<>();
1046 private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
markchien26299ed2019-02-27 14:56:11 +08001047
markchien0df2ebc42019-09-30 14:40:57 +08001048 // This function will remove the recorded callbacks, so it must be called once for
1049 // each callback. If this is called after multiple callback, the order matters.
1050 // onCallbackCreated counts as the first call to expectUpstreamChanged with
1051 // @see onCallbackCreated.
markchien26299ed2019-02-27 14:56:11 +08001052 public void expectUpstreamChanged(Network... networks) {
markchien0df2ebc42019-09-30 14:40:57 +08001053 if (networks == null) {
1054 assertNoUpstreamChangeCallback();
1055 return;
1056 }
1057
markchien26299ed2019-02-27 14:56:11 +08001058 final ArrayList<Network> expectedUpstreams =
1059 new ArrayList<Network>(Arrays.asList(networks));
1060 for (Network upstream : expectedUpstreams) {
1061 // throws OOB if no expectations
1062 assertEquals(mActualUpstreams.remove(0), upstream);
1063 }
markchien0df2ebc42019-09-30 14:40:57 +08001064 assertNoUpstreamChangeCallback();
1065 }
1066
1067 // This function will remove the recorded callbacks, so it must be called once
1068 // for each callback. If this is called after multiple callback, the order matters.
1069 // onCallbackCreated counts as the first call to onConfigurationChanged with
1070 // @see onCallbackCreated.
1071 public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
1072 final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
1073 new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
1074 for (TetheringConfigurationParcel config : expectedTetherConfig) {
1075 // throws OOB if no expectations
1076 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
1077 assertTetherConfigParcelEqual(actualConfig, config);
1078 }
1079 assertNoConfigChangeCallback();
1080 }
1081
1082 public TetherStatesParcel pollTetherStatesChanged() {
1083 assertStateChangeCallback();
1084 return mTetherStates.remove(0);
markchien26299ed2019-02-27 14:56:11 +08001085 }
1086
1087 @Override
1088 public void onUpstreamChanged(Network network) {
1089 mActualUpstreams.add(network);
1090 }
1091
markchien0df2ebc42019-09-30 14:40:57 +08001092 @Override
1093 public void onConfigurationChanged(TetheringConfigurationParcel config) {
1094 mTetheringConfigs.add(config);
1095 }
1096
1097 @Override
1098 public void onTetherStatesChanged(TetherStatesParcel states) {
1099 mTetherStates.add(states);
1100 }
1101
1102 @Override
1103 public void onCallbackCreated(Network network, TetheringConfigurationParcel config,
1104 TetherStatesParcel states) {
1105 mActualUpstreams.add(network);
1106 mTetheringConfigs.add(config);
1107 mTetherStates.add(states);
1108 }
1109
1110 public void assertNoUpstreamChangeCallback() {
markchien26299ed2019-02-27 14:56:11 +08001111 assertTrue(mActualUpstreams.isEmpty());
1112 }
markchien0df2ebc42019-09-30 14:40:57 +08001113
1114 public void assertNoConfigChangeCallback() {
1115 assertTrue(mTetheringConfigs.isEmpty());
1116 }
1117
1118 public void assertStateChangeCallback() {
1119 assertFalse(mTetherStates.isEmpty());
1120 }
1121
1122 private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
1123 @NonNull TetheringConfigurationParcel expect) {
1124 assertEquals(actual.subId, expect.subId);
1125 assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
1126 assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
1127 assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
1128 assertEquals(actual.isDunRequired, expect.isDunRequired);
1129 assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
1130 assertArrayEquals(actual.preferredUpstreamIfaceTypes,
1131 expect.preferredUpstreamIfaceTypes);
1132 assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
1133 assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
1134 assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
1135 assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
1136 assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
1137 assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
1138 }
markchien26299ed2019-02-27 14:56:11 +08001139 }
1140
1141 @Test
markchien0df2ebc42019-09-30 14:40:57 +08001142 public void testRegisterTetherInternalCallback() throws Exception {
1143 TestTetherInternalCallback callback = new TestTetherInternalCallback();
markchien26299ed2019-02-27 14:56:11 +08001144
markchien0df2ebc42019-09-30 14:40:57 +08001145 // 1. Register one callback before running any tethering.
1146 mTethering.registerTetherInternalCallback(callback);
markchien26299ed2019-02-27 14:56:11 +08001147 mLooper.dispatchAll();
markchien0df2ebc42019-09-30 14:40:57 +08001148 callback.expectUpstreamChanged(new Network[] {null});
1149 callback.expectConfigurationChanged(
1150 mTethering.getTetheringConfiguration().toStableParcelable());
1151 TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
1152 assertEquals(tetherState, null);
1153 // 2. Enable wifi tethering
markchien26299ed2019-02-27 14:56:11 +08001154 NetworkState upstreamState = buildMobileDualStackUpstreamState();
markchien26299ed2019-02-27 14:56:11 +08001155 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
1156 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
1157 .thenReturn(upstreamState);
1158 when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
markchien26299ed2019-02-27 14:56:11 +08001159 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
markchien0df2ebc42019-09-30 14:40:57 +08001160 mLooper.dispatchAll();
1161 tetherState = callback.pollTetherStatesChanged();
1162 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1163
1164 mTethering.startTethering(TETHERING_WIFI, null, false);
markchien26299ed2019-02-27 14:56:11 +08001165 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1166 mLooper.dispatchAll();
markchien0df2ebc42019-09-30 14:40:57 +08001167 tetherState = callback.pollTetherStatesChanged();
1168 assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
1169 callback.expectUpstreamChanged(upstreamState.network);
1170
1171 // 3. Disable wifi tethering.
1172 mTethering.stopTethering(TETHERING_WIFI);
1173 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
1174 mLooper.dispatchAll();
1175 tetherState = callback.pollTetherStatesChanged();
1176 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1177 mLooper.dispatchAll();
1178 callback.expectUpstreamChanged(new Network[] {null});
markchien26299ed2019-02-27 14:56:11 +08001179 }
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001180
markchien04bdf872019-06-17 21:05:34 +08001181 @Test
1182 public void testMultiSimAware() throws Exception {
1183 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
1184 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId);
1185
1186 final int fakeSubId = 1234;
1187 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1188 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
1189 assertEquals(fakeSubId, newConfig.subId);
1190 }
1191
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001192 private void workingWifiP2pGroupOwner(
1193 boolean emulateInterfaceStatusChanged) throws Exception {
1194 if (emulateInterfaceStatusChanged) {
1195 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1196 }
1197 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1198 mLooper.dispatchAll();
1199
1200 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
1201 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
1202 verify(mNMService, times(1)).setIpForwardingEnabled(true);
1203 verify(mNMService, times(1)).startTethering(any(String[].class));
1204 verifyNoMoreInteractions(mNMService);
1205 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
1206 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
1207 // This will be called twice, one is on entering IpServer.STATE_AVAILABLE,
1208 // and another one is on IpServer.STATE_TETHERED/IpServer.STATE_LOCAL_ONLY.
markchien0df2ebc42019-09-30 14:40:57 +08001209 assertEquals(2, mTetheringDependencies.mIsTetheringSupportedCalls);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001210
1211 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1212
1213 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1214 // is being removed.
1215 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
1216 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1217 mLooper.dispatchAll();
1218
1219 verify(mNMService, times(1)).untetherInterface(TEST_P2P_IFNAME);
1220 // {g,s}etInterfaceConfig() called twice for enabling and disabling IPv4.
1221 verify(mNMService, times(2)).getInterfaceConfig(TEST_P2P_IFNAME);
1222 verify(mNMService, times(2))
1223 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1224 verify(mNMService, times(1)).stopTethering();
1225 verify(mNMService, times(1)).setIpForwardingEnabled(false);
1226 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
1227 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
1228 verifyNoMoreInteractions(mNMService);
1229 // Asking for the last error after the per-interface state machine
1230 // has been reaped yields an unknown interface error.
1231 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1232 }
1233
1234 private void workingWifiP2pGroupClient(
1235 boolean emulateInterfaceStatusChanged) throws Exception {
1236 if (emulateInterfaceStatusChanged) {
1237 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1238 }
1239 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
1240 mLooper.dispatchAll();
1241
1242 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1243 verify(mNMService, never())
1244 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1245 verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
1246 verify(mNMService, never()).setIpForwardingEnabled(true);
1247 verify(mNMService, never()).startTethering(any(String[].class));
1248
1249 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1250 // is being removed.
1251 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
1252 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1253 mLooper.dispatchAll();
1254
1255 verify(mNMService, never()).untetherInterface(TEST_P2P_IFNAME);
1256 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1257 verify(mNMService, never())
1258 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1259 verify(mNMService, never()).stopTethering();
1260 verify(mNMService, never()).setIpForwardingEnabled(false);
1261 verifyNoMoreInteractions(mNMService);
1262 // Asking for the last error after the per-interface state machine
1263 // has been reaped yields an unknown interface error.
1264 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1265 }
1266
1267 @Test
1268 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
1269 workingWifiP2pGroupOwner(true);
1270 }
1271
1272 @Test
1273 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
1274 workingWifiP2pGroupOwner(false);
1275 }
1276
1277 private void workingWifiP2pGroupOwnerLegacyMode(
1278 boolean emulateInterfaceStatusChanged) throws Exception {
1279 // change to legacy mode and update tethering information by chaning SIM
1280 when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_p2p_regexs))
1281 .thenReturn(new String[]{});
1282 final int fakeSubId = 1234;
1283 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1284
1285 if (emulateInterfaceStatusChanged) {
1286 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1287 }
1288 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1289 mLooper.dispatchAll();
1290
1291 verify(mNMService, never()).getInterfaceConfig(TEST_P2P_IFNAME);
1292 verify(mNMService, never())
1293 .setInterfaceConfig(eq(TEST_P2P_IFNAME), any(InterfaceConfiguration.class));
1294 verify(mNMService, never()).tetherInterface(TEST_P2P_IFNAME);
1295 verify(mNMService, never()).setIpForwardingEnabled(true);
1296 verify(mNMService, never()).startTethering(any(String[].class));
1297 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1298 }
1299 @Test
1300 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
1301 workingWifiP2pGroupOwnerLegacyMode(true);
1302 }
1303
1304 @Test
1305 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
1306 workingWifiP2pGroupOwnerLegacyMode(false);
1307 }
1308
1309 @Test
1310 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
1311 workingWifiP2pGroupClient(true);
1312 }
1313
1314 @Test
1315 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
1316 workingWifiP2pGroupClient(false);
1317 }
1318
Erik Kline1fdc2e22017-05-08 17:56:35 +09001319 // TODO: Test that a request for hotspot mode doesn't interfere with an
Erik Klineea9cc482017-03-10 19:35:34 +09001320 // already operating tethering mode interface.
Christopher Wiley497c1472016-10-11 13:26:03 -07001321}