blob: 2bd8ae028814186a78ec43ecd5bc8038c6df8801 [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
markchien503be612020-04-12 21:41:29 +080017package com.android.networkstack.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;
Milim Lee31ef4c02019-10-17 05:02:33 +090021import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
Erik Klinec438e302017-07-04 22:02:49 +090022import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
markchien3fe660b2019-12-05 12:04:59 +080023import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
24import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
25import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
markchien986750b2019-12-06 15:24:53 +080026import static android.net.RouteInfo.RTN_UNICAST;
markchien9e44cde2019-12-25 19:40:32 +080027import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
28import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
29import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
30import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +000031import static android.net.TetheringManager.TETHERING_ETHERNET;
Milim Lee31ef4c02019-10-17 05:02:33 +090032import static android.net.TetheringManager.TETHERING_NCM;
markchien9e44cde2019-12-25 19:40:32 +080033import static android.net.TetheringManager.TETHERING_USB;
34import static android.net.TetheringManager.TETHERING_WIFI;
35import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
36import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +000037import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
38import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
39import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090040import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
Treehugger Robot86d212b2020-03-30 04:23:55 +000041import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
Erik Kline2efb8272017-05-31 15:53:53 +090042import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
43import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
44import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
markchienb6eb2c22018-07-18 14:29:20 +080045import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
46import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
Erik Kline2efb8272017-05-31 15:53:53 +090047import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
markchien0b595072019-01-08 23:52:21 +080048import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090049
markchien503be612020-04-12 21:41:29 +080050import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
Chalard Jeanc0fc2762020-04-17 17:12:44 +000051import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +000052
markchien0f63ca62019-09-30 14:40:57 +080053import static org.junit.Assert.assertArrayEquals;
Erik Klineea9cc482017-03-10 19:35:34 +090054import static org.junit.Assert.assertEquals;
markchien0f63ca62019-09-30 14:40:57 +080055import static org.junit.Assert.assertFalse;
Christopher Wiley497c1472016-10-11 13:26:03 -070056import static org.junit.Assert.assertTrue;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090057import static org.junit.Assert.fail;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090058import static org.mockito.ArgumentMatchers.argThat;
59import static org.mockito.ArgumentMatchers.notNull;
markchien5788f2a2020-05-08 18:55:26 +080060import static org.mockito.Matchers.anyInt;
Erik Klineea9cc482017-03-10 19:35:34 +090061import static org.mockito.Matchers.anyString;
Christopher Wiley497c1472016-10-11 13:26:03 -070062import static org.mockito.Matchers.eq;
Erik Kline1fdc2e22017-05-08 17:56:35 +090063import static org.mockito.Mockito.any;
Erik Kline1fdc2e22017-05-08 17:56:35 +090064import static org.mockito.Mockito.doThrow;
markchienb6eb2c22018-07-18 14:29:20 +080065import static org.mockito.Mockito.mock;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090066import static org.mockito.Mockito.never;
markchien3fe660b2019-12-05 12:04:59 +080067import static org.mockito.Mockito.reset;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090068import static org.mockito.Mockito.spy;
69import static org.mockito.Mockito.timeout;
Erik Klineea9cc482017-03-10 19:35:34 +090070import static org.mockito.Mockito.times;
71import static org.mockito.Mockito.verify;
72import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley497c1472016-10-11 13:26:03 -070073import static org.mockito.Mockito.when;
74
junyulaicaa81002019-12-11 11:03:01 +080075import android.app.usage.NetworkStatsManager;
markchien3fe660b2019-12-05 12:04:59 +080076import android.bluetooth.BluetoothAdapter;
Erik Kline8351faa2017-04-17 16:47:23 +090077import android.content.BroadcastReceiver;
Erik Kline92c4db02017-05-31 10:21:32 +090078import android.content.ContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070079import android.content.Context;
Erik Klineea9cc482017-03-10 19:35:34 +090080import android.content.Intent;
Erik Kline8351faa2017-04-17 16:47:23 +090081import android.content.IntentFilter;
Erik Klinef3a08b42017-06-07 16:33:19 +090082import android.content.pm.ApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -070083import android.content.res.Resources;
Erik Klineea9cc482017-03-10 19:35:34 +090084import android.hardware.usb.UsbManager;
markchien3fe660b2019-12-05 12:04:59 +080085import android.net.ConnectivityManager;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +000086import android.net.EthernetManager;
87import android.net.EthernetManager.TetheredInterfaceRequest;
Automerger Merge Worker37a22752020-03-17 16:59:57 +000088import android.net.IIntResultListener;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090089import android.net.INetd;
markchienae8aa642019-12-16 20:15:20 +080090import android.net.ITetheringEventCallback;
markchien986750b2019-12-06 15:24:53 +080091import android.net.InetAddresses;
markchiena9d9ef82020-01-07 14:43:17 +080092import android.net.InterfaceConfigurationParcel;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090093import android.net.IpPrefix;
94import android.net.LinkAddress;
95import android.net.LinkProperties;
96import android.net.MacAddress;
97import android.net.Network;
98import android.net.NetworkCapabilities;
markchienae8aa642019-12-16 20:15:20 +080099import android.net.NetworkRequest;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900100import android.net.RouteInfo;
markchien0f63ca62019-09-30 14:40:57 +0800101import android.net.TetherStatesParcel;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900102import android.net.TetheredClient;
markchien40898ca2020-01-21 13:11:06 +0800103import android.net.TetheringCallbackStartedParcel;
markchien0f63ca62019-09-30 14:40:57 +0800104import android.net.TetheringConfigurationParcel;
markchiene8b9d752020-01-20 19:31:56 +0800105import android.net.TetheringRequestParcel;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900106import android.net.dhcp.DhcpServerCallbacks;
107import android.net.dhcp.DhcpServingParamsParcel;
108import android.net.dhcp.IDhcpServer;
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900109import android.net.ip.IpNeighborMonitor;
Erik Kline7a4ccc62018-08-27 17:26:47 +0900110import android.net.ip.IpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900111import android.net.ip.RouterAdvertisementDaemon;
112import android.net.util.InterfaceParams;
113import android.net.util.NetworkConstants;
Erik Klinef4b6e342017-04-25 19:19:59 +0900114import android.net.util.SharedLog;
lesl6b7551a2019-12-13 10:56:35 +0800115import android.net.wifi.SoftApConfiguration;
Erik Klineea9cc482017-03-10 19:35:34 +0900116import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800117import android.net.wifi.p2p.WifiP2pGroup;
118import android.net.wifi.p2p.WifiP2pInfo;
119import android.net.wifi.p2p.WifiP2pManager;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100120import android.os.Bundle;
Erik Klineea9cc482017-03-10 19:35:34 +0900121import android.os.Handler;
markchien0f63ca62019-09-30 14:40:57 +0800122import android.os.Looper;
Christopher Wiley497c1472016-10-11 13:26:03 -0700123import android.os.PersistableBundle;
Erik Kline1fdc2e22017-05-08 17:56:35 +0900124import android.os.RemoteException;
Erik Klineea9cc482017-03-10 19:35:34 +0900125import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100126import android.os.UserManager;
markchienb6eb2c22018-07-18 14:29:20 +0800127import android.os.test.TestLooper;
Erik Kline92c4db02017-05-31 10:21:32 +0900128import android.provider.Settings;
Christopher Wiley497c1472016-10-11 13:26:03 -0700129import android.telephony.CarrierConfigManager;
markchien04bdf872019-06-17 21:05:34 +0800130import android.telephony.PhoneStateListener;
131import android.telephony.TelephonyManager;
Erik Kline92c4db02017-05-31 10:21:32 +0900132import android.test.mock.MockContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700133
markchien0f63ca62019-09-30 14:40:57 +0800134import androidx.annotation.NonNull;
Brett Chabot1ae2aa62019-03-04 14:14:56 -0800135import androidx.test.filters.SmallTest;
136import androidx.test.runner.AndroidJUnit4;
137
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900138import com.android.internal.util.ArrayUtils;
139import com.android.internal.util.StateMachine;
Erik Klineea9cc482017-03-10 19:35:34 +0900140import com.android.internal.util.test.BroadcastInterceptingContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900141import com.android.internal.util.test.FakeSettingsProvider;
markchienfaa37282020-02-06 14:34:08 +0800142import com.android.testutils.MiscAssertsKt;
Erik Klineea9cc482017-03-10 19:35:34 +0900143
Erik Kline8351faa2017-04-17 16:47:23 +0900144import org.junit.After;
Mark Chien09ad80f2020-04-07 16:17:49 +0000145import org.junit.AfterClass;
Christopher Wiley497c1472016-10-11 13:26:03 -0700146import org.junit.Before;
Mark Chien09ad80f2020-04-07 16:17:49 +0000147import org.junit.BeforeClass;
Christopher Wiley497c1472016-10-11 13:26:03 -0700148import org.junit.Test;
149import org.junit.runner.RunWith;
markchien04bdf872019-06-17 21:05:34 +0800150import org.mockito.ArgumentCaptor;
Christopher Wiley497c1472016-10-11 13:26:03 -0700151import org.mockito.Mock;
152import org.mockito.MockitoAnnotations;
153
Mark Chien66b9a4a2020-05-07 03:49:42 +0000154import java.io.FileDescriptor;
155import java.io.PrintWriter;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900156import java.net.Inet4Address;
157import java.net.Inet6Address;
Erik Kline8351faa2017-04-17 16:47:23 +0900158import java.util.ArrayList;
markchien26299ed2019-02-27 14:56:11 +0800159import java.util.Arrays;
markchien3fe660b2019-12-05 12:04:59 +0800160import java.util.Collection;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900161import java.util.List;
Erik Kline8351faa2017-04-17 16:47:23 +0900162import java.util.Vector;
163
Christopher Wiley497c1472016-10-11 13:26:03 -0700164@RunWith(AndroidJUnit4.class)
165@SmallTest
166public class TetheringTest {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900167 private static final int IFINDEX_OFFSET = 100;
168
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900169 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
170 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
171 private static final String TEST_USB_IFNAME = "test_rndis0";
172 private static final String TEST_WLAN_IFNAME = "test_wlan0";
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800173 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
Milim Lee31ef4c02019-10-17 05:02:33 +0900174 private static final String TEST_NCM_IFNAME = "test_ncm0";
markchiena9d9ef82020-01-07 14:43:17 +0800175 private static final String TETHERING_NAME = "Tethering";
markchien5788f2a2020-05-08 18:55:26 +0800176 private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
177 private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
Christopher Wiley497c1472016-10-11 13:26:03 -0700178
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900179 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
180
Erik Klinef3a08b42017-06-07 16:33:19 +0900181 @Mock private ApplicationInfo mApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -0700182 @Mock private Context mContext;
junyulaicaa81002019-12-11 11:03:01 +0800183 @Mock private NetworkStatsManager mStatsManager;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900184 @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000185 @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats;
Christopher Wiley497c1472016-10-11 13:26:03 -0700186 @Mock private Resources mResources;
markchien04bdf872019-06-17 21:05:34 +0800187 @Mock private TelephonyManager mTelephonyManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900188 @Mock private UsbManager mUsbManager;
189 @Mock private WifiManager mWifiManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700190 @Mock private CarrierConfigManager mCarrierConfigManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900191 @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
192 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
193 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900194 @Mock private IpNeighborMonitor mIpNeighborMonitor;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900195 @Mock private IDhcpServer mDhcpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900196 @Mock private INetd mNetd;
markchien1ddfba42019-11-27 21:20:33 +0800197 @Mock private UserManager mUserManager;
markchienae8aa642019-12-16 20:15:20 +0800198 @Mock private NetworkRequest mNetworkRequest;
markchien3fe660b2019-12-05 12:04:59 +0800199 @Mock private ConnectivityManager mCm;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000200 @Mock private EthernetManager mEm;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000201 @Mock private TetheringNotificationUpdater mNotificationUpdater;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900202
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900203 private final MockIpServerDependencies mIpServerDependencies =
204 spy(new MockIpServerDependencies());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900205 private final MockTetheringDependencies mTetheringDependencies =
206 new MockTetheringDependencies();
Christopher Wiley497c1472016-10-11 13:26:03 -0700207
208 // Like so many Android system APIs, these cannot be mocked because it is marked final.
209 // We have to use the real versions.
210 private final PersistableBundle mCarrierConfig = new PersistableBundle();
211 private final TestLooper mLooper = new TestLooper();
212
Erik Kline8351faa2017-04-17 16:47:23 +0900213 private Vector<Intent> mIntents;
Erik Klineea9cc482017-03-10 19:35:34 +0900214 private BroadcastInterceptingContext mServiceContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900215 private MockContentResolver mContentResolver;
Erik Kline8351faa2017-04-17 16:47:23 +0900216 private BroadcastReceiver mBroadcastReceiver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700217 private Tethering mTethering;
markchien04bdf872019-06-17 21:05:34 +0800218 private PhoneStateListener mPhoneStateListener;
markchiena9d9ef82020-01-07 14:43:17 +0800219 private InterfaceConfigurationParcel mInterfaceConfiguration;
Mark Chien66b9a4a2020-05-07 03:49:42 +0000220 private TetheringConfiguration mConfig;
221 private EntitlementManager mEntitleMgr;
222 private OffloadController mOffloadCtrl;
Christopher Wiley497c1472016-10-11 13:26:03 -0700223
markchien0f63ca62019-09-30 14:40:57 +0800224 private class TestContext extends BroadcastInterceptingContext {
225 TestContext(Context base) {
Erik Klineea9cc482017-03-10 19:35:34 +0900226 super(base);
227 }
228
229 @Override
markchien0f63ca62019-09-30 14:40:57 +0800230 public ApplicationInfo getApplicationInfo() {
231 return mApplicationInfo;
232 }
Erik Klinef3a08b42017-06-07 16:33:19 +0900233
234 @Override
markchien0f63ca62019-09-30 14:40:57 +0800235 public ContentResolver getContentResolver() {
236 return mContentResolver;
237 }
Erik Kline92c4db02017-05-31 10:21:32 +0900238
239 @Override
markchien0f63ca62019-09-30 14:40:57 +0800240 public String getPackageName() {
241 return "TetheringTest";
242 }
Erik Kline92c4db02017-05-31 10:21:32 +0900243
244 @Override
markchien0f63ca62019-09-30 14:40:57 +0800245 public Resources getResources() {
246 return mResources;
247 }
Erik Klineea9cc482017-03-10 19:35:34 +0900248
249 @Override
250 public Object getSystemService(String name) {
Erik Klineea9cc482017-03-10 19:35:34 +0900251 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
Erik Klinec438e302017-07-04 22:02:49 +0900252 if (Context.USB_SERVICE.equals(name)) return mUsbManager;
markchien04bdf872019-06-17 21:05:34 +0800253 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
markchien1ddfba42019-11-27 21:20:33 +0800254 if (Context.USER_SERVICE.equals(name)) return mUserManager;
junyulaicaa81002019-12-11 11:03:01 +0800255 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
markchien3fe660b2019-12-05 12:04:59 +0800256 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000257 if (Context.ETHERNET_SERVICE.equals(name)) return mEm;
Erik Klineea9cc482017-03-10 19:35:34 +0900258 return super.getSystemService(name);
259 }
Jayachandran C43fa1be2019-11-15 09:58:04 -0800260
261 @Override
262 public String getSystemServiceName(Class<?> serviceClass) {
263 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
264 return super.getSystemServiceName(serviceClass);
265 }
Erik Klineea9cc482017-03-10 19:35:34 +0900266 }
267
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900268 public class MockIpServerDependencies extends IpServer.Dependencies {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900269 @Override
270 public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
271 InterfaceParams ifParams) {
272 return mRouterAdvertisementDaemon;
273 }
274
275 @Override
276 public InterfaceParams getInterfaceParams(String ifName) {
277 assertTrue("Non-mocked interface " + ifName,
278 ifName.equals(TEST_USB_IFNAME)
279 || ifName.equals(TEST_WLAN_IFNAME)
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800280 || ifName.equals(TEST_MOBILE_IFNAME)
Milim Lee31ef4c02019-10-17 05:02:33 +0900281 || ifName.equals(TEST_P2P_IFNAME)
282 || ifName.equals(TEST_NCM_IFNAME));
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900283 final String[] ifaces = new String[] {
Milim Lee31ef4c02019-10-17 05:02:33 +0900284 TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME,
285 TEST_NCM_IFNAME};
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900286 return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
287 MacAddress.ALL_ZEROS_ADDRESS);
288 }
289
290 @Override
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900291 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
292 DhcpServerCallbacks cb) {
293 new Thread(() -> {
294 try {
295 cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
296 } catch (RemoteException e) {
297 fail(e.getMessage());
298 }
299 }).run();
300 }
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900301
302 public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l,
303 IpNeighborMonitor.NeighborEventConsumer c) {
304 return mIpNeighborMonitor;
305 }
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900306 }
307
Mark Chien66b9a4a2020-05-07 03:49:42 +0000308 // MyTetheringConfiguration is used to override static method for testing.
309 private class MyTetheringConfiguration extends TetheringConfiguration {
310 MyTetheringConfiguration(Context ctx, SharedLog log, int id) {
markchien04bdf872019-06-17 21:05:34 +0800311 super(ctx, log, id);
312 }
313
314 @Override
markchien2dfee022020-01-13 16:09:42 +0800315 protected boolean getDeviceConfigBoolean(final String name) {
316 return false;
317 }
318
319 @Override
markchien04bdf872019-06-17 21:05:34 +0800320 protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
321 return mResources;
322 }
323 }
324
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900325 public class MockTetheringDependencies extends TetheringDependencies {
markchien0f63ca62019-09-30 14:40:57 +0800326 StateMachine mUpstreamNetworkMonitorMasterSM;
327 ArrayList<IpServer> mIpv6CoordinatorNotifyList;
Erik Kline465ff3a2018-03-09 14:18:02 +0900328
329 public void reset() {
markchien0f63ca62019-09-30 14:40:57 +0800330 mUpstreamNetworkMonitorMasterSM = null;
331 mIpv6CoordinatorNotifyList = null;
Erik Kline465ff3a2018-03-09 14:18:02 +0900332 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900333
334 @Override
335 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
336 return mOffloadHardwareInterface;
337 }
338
339 @Override
Mark Chien66b9a4a2020-05-07 03:49:42 +0000340 public OffloadController getOffloadController(Handler h, SharedLog log,
341 OffloadController.Dependencies deps) {
342 mOffloadCtrl = spy(super.getOffloadController(h, log, deps));
343 // Return real object here instead of mock because
344 // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
345 return mOffloadCtrl;
346 }
347
348 @Override
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900349 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
350 StateMachine target, SharedLog log, int what) {
markchien0f63ca62019-09-30 14:40:57 +0800351 mUpstreamNetworkMonitorMasterSM = target;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900352 return mUpstreamNetworkMonitor;
353 }
354
355 @Override
356 public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
Erik Kline7a4ccc62018-08-27 17:26:47 +0900357 ArrayList<IpServer> notifyList, SharedLog log) {
markchien0f63ca62019-09-30 14:40:57 +0800358 mIpv6CoordinatorNotifyList = notifyList;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900359 return mIPv6TetheringCoordinator;
360 }
361
362 @Override
Remi NGUYEN VAN5db454c2019-02-14 18:04:20 +0900363 public IpServer.Dependencies getIpServerDependencies() {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900364 return mIpServerDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900365 }
Erik Kline465ff3a2018-03-09 14:18:02 +0900366
367 @Override
markchienae8aa642019-12-16 20:15:20 +0800368 public NetworkRequest getDefaultNetworkRequest() {
369 return mNetworkRequest;
370 }
371
372 @Override
Mark Chien47430c02020-05-08 11:00:42 +0000373 public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
374 Runnable callback) {
375 mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback));
Mark Chien66b9a4a2020-05-07 03:49:42 +0000376 return mEntitleMgr;
377 }
378
379 @Override
Erik Kline465ff3a2018-03-09 14:18:02 +0900380 public boolean isTetheringSupported() {
Erik Kline465ff3a2018-03-09 14:18:02 +0900381 return true;
382 }
markchien0b595072019-01-08 23:52:21 +0800383
384 @Override
markchien04bdf872019-06-17 21:05:34 +0800385 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
386 int subId) {
Mark Chien66b9a4a2020-05-07 03:49:42 +0000387 mConfig = spy(new MyTetheringConfiguration(ctx, log, subId));
388 return mConfig;
markchien0b595072019-01-08 23:52:21 +0800389 }
markchien0f63ca62019-09-30 14:40:57 +0800390
391 @Override
markchien0f63ca62019-09-30 14:40:57 +0800392 public INetd getINetd(Context context) {
393 return mNetd;
394 }
395
396 @Override
397 public Looper getTetheringLooper() {
398 return mLooper.getLooper();
399 }
400
401 @Override
402 public Context getContext() {
403 return mServiceContext;
404 }
markchien3fe660b2019-12-05 12:04:59 +0800405
406 @Override
407 public BluetoothAdapter getBluetoothAdapter() {
408 // TODO: add test for bluetooth tethering.
409 return null;
410 }
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000411
412 @Override
Paul Hu77fa8d62020-04-16 02:54:37 +0000413 public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000414 return mNotificationUpdater;
415 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900416 }
417
markchienb0aca962019-12-05 16:21:17 +0800418 private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
419 boolean withIPv6, boolean with464xlat) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900420 final LinkProperties prop = new LinkProperties();
421 prop.setInterfaceName(TEST_MOBILE_IFNAME);
422
423 if (withIPv4) {
424 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800425 InetAddresses.parseNumericAddress("10.0.0.1"),
426 TEST_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900427 }
428
429 if (withIPv6) {
markchien986750b2019-12-06 15:24:53 +0800430 prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900431 prop.addLinkAddress(
markchien986750b2019-12-06 15:24:53 +0800432 new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900433 NetworkConstants.RFC7421_PREFIX_LENGTH));
434 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800435 InetAddresses.parseNumericAddress("2001:db8::1"),
436 TEST_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900437 }
438
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900439 if (with464xlat) {
440 final LinkProperties stackedLink = new LinkProperties();
441 stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
442 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800443 InetAddresses.parseNumericAddress("192.0.0.1"),
444 TEST_XLAT_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900445
446 prop.addStackedLink(stackedLink);
447 }
448
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900449
450 final NetworkCapabilities capabilities = new NetworkCapabilities()
markchien0f63ca62019-09-30 14:40:57 +0800451 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
markchienb0aca962019-12-05 16:21:17 +0800452 return new UpstreamNetworkState(prop, capabilities, new Network(100));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900453 }
454
markchienb0aca962019-12-05 16:21:17 +0800455 private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900456 return buildMobileUpstreamState(true, false, false);
457 }
458
markchienb0aca962019-12-05 16:21:17 +0800459 private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900460 return buildMobileUpstreamState(false, true, false);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900461 }
462
markchienb0aca962019-12-05 16:21:17 +0800463 private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900464 return buildMobileUpstreamState(true, true, false);
465 }
466
markchienb0aca962019-12-05 16:21:17 +0800467 private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900468 return buildMobileUpstreamState(false, true, true);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900469 }
470
Mark Chien09ad80f2020-04-07 16:17:49 +0000471 // See FakeSettingsProvider#clearSettingsProvider() that this needs to be called before and
472 // after use.
473 @BeforeClass
474 public static void setupOnce() {
475 FakeSettingsProvider.clearSettingsProvider();
476 }
477
478 @AfterClass
479 public static void tearDownOnce() {
480 FakeSettingsProvider.clearSettingsProvider();
481 }
482
Erik Kline8351faa2017-04-17 16:47:23 +0900483 @Before
484 public void setUp() throws Exception {
Christopher Wiley497c1472016-10-11 13:26:03 -0700485 MockitoAnnotations.initMocks(this);
markchienda4519a2020-01-14 12:46:53 +0800486 when(mResources.getStringArray(R.array.config_tether_dhcp_range))
Christopher Wiley497c1472016-10-11 13:26:03 -0700487 .thenReturn(new String[0]);
markchienda4519a2020-01-14 12:46:53 +0800488 when(mResources.getStringArray(R.array.config_tether_usb_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900489 .thenReturn(new String[] { "test_rndis\\d" });
markchienda4519a2020-01-14 12:46:53 +0800490 when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900491 .thenReturn(new String[]{ "test_wlan\\d" });
markchienda4519a2020-01-14 12:46:53 +0800492 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800493 .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
markchienda4519a2020-01-14 12:46:53 +0800494 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
Christopher Wiley497c1472016-10-11 13:26:03 -0700495 .thenReturn(new String[0]);
Milim Lee31ef4c02019-10-17 05:02:33 +0900496 when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
497 .thenReturn(new String[] { "test_ncm\\d" });
markchienda4519a2020-01-14 12:46:53 +0800498 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
499 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false);
500 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
501 false);
markchiena9d9ef82020-01-07 14:43:17 +0800502 when(mNetd.interfaceGetList())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900503 .thenReturn(new String[] {
Milim Lee31ef4c02019-10-17 05:02:33 +0900504 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME,
505 TEST_NCM_IFNAME});
markchienda4519a2020-01-14 12:46:53 +0800506 when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
markchiena9d9ef82020-01-07 14:43:17 +0800507 mInterfaceConfiguration = new InterfaceConfigurationParcel();
508 mInterfaceConfiguration.flags = new String[0];
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900509 when(mRouterAdvertisementDaemon.start())
510 .thenReturn(true);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000511 initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
512 0 /* defaultDisabled */);
513 when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
Erik Klineea9cc482017-03-10 19:35:34 +0900514
markchien0f63ca62019-09-30 14:40:57 +0800515 mServiceContext = new TestContext(mContext);
Erik Kline92c4db02017-05-31 10:21:32 +0900516 mContentResolver = new MockContentResolver(mServiceContext);
517 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Erik Kline8351faa2017-04-17 16:47:23 +0900518 mIntents = new Vector<>();
519 mBroadcastReceiver = new BroadcastReceiver() {
520 @Override
521 public void onReceive(Context context, Intent intent) {
522 mIntents.addElement(intent);
523 }
524 };
525 mServiceContext.registerReceiver(mBroadcastReceiver,
Erik Kline465ff3a2018-03-09 14:18:02 +0900526 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900527 mTethering = makeTethering();
Mark Chien674a0122020-03-27 09:37:01 +0000528 mTethering.startStateMachineUpdaters();
junyulaicaa81002019-12-11 11:03:01 +0800529 verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
markchien0f63ca62019-09-30 14:40:57 +0800530 verify(mNetd).registerUnsolicitedEventListener(any());
markchien04bdf872019-06-17 21:05:34 +0800531 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
532 ArgumentCaptor.forClass(PhoneStateListener.class);
533 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
534 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900535 verify(mWifiManager).registerSoftApCallback(any(), any());
markchien04bdf872019-06-17 21:05:34 +0800536 mPhoneStateListener = phoneListenerCaptor.getValue();
Christopher Wiley497c1472016-10-11 13:26:03 -0700537 }
538
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900539 private Tethering makeTethering() {
markchien0f63ca62019-09-30 14:40:57 +0800540 mTetheringDependencies.reset();
541 return new Tethering(mTetheringDependencies);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900542 }
543
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000544 private TetheringRequestParcel createTetheringRequestParcel(final int type) {
markchien5788f2a2020-05-08 18:55:26 +0800545 return createTetheringRequestParcel(type, null, null, false);
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000546 }
547
548 private TetheringRequestParcel createTetheringRequestParcel(final int type,
markchien5788f2a2020-05-08 18:55:26 +0800549 final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt) {
markchiene8b9d752020-01-20 19:31:56 +0800550 final TetheringRequestParcel request = new TetheringRequestParcel();
551 request.tetheringType = type;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000552 request.localIPv4Address = serverAddr;
553 request.staticClientAddress = clientAddr;
markchien5788f2a2020-05-08 18:55:26 +0800554 request.exemptFromEntitlementCheck = exempt;
markchiene8b9d752020-01-20 19:31:56 +0800555 request.showProvisioningUi = false;
556
557 return request;
558 }
559
Erik Kline8351faa2017-04-17 16:47:23 +0900560 @After
561 public void tearDown() {
562 mServiceContext.unregisterReceiver(mBroadcastReceiver);
563 }
564
Erik Klineea9cc482017-03-10 19:35:34 +0900565 private void sendWifiApStateChanged(int state) {
566 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Erik Kline2efb8272017-05-31 15:53:53 +0900567 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
Erik Klineea9cc482017-03-10 19:35:34 +0900568 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
569 }
570
Erik Kline2efb8272017-05-31 15:53:53 +0900571 private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
572 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
573 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
574 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
575 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
576 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
577 }
578
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800579 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
580 android.Manifest.permission.ACCESS_FINE_LOCATION,
581 android.Manifest.permission.ACCESS_WIFI_STATE
582 };
583
584 private void sendWifiP2pConnectionChanged(
585 boolean isGroupFormed, boolean isGroupOwner, String ifname) {
Jimmy Chen151384d2019-12-03 11:37:09 +0800586 WifiP2pGroup group = null;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800587 WifiP2pInfo p2pInfo = new WifiP2pInfo();
588 p2pInfo.groupFormed = isGroupFormed;
Jimmy Chen151384d2019-12-03 11:37:09 +0800589 if (isGroupFormed) {
590 p2pInfo.isGroupOwner = isGroupOwner;
591 group = mock(WifiP2pGroup.class);
592 when(group.isGroupOwner()).thenReturn(isGroupOwner);
593 when(group.getInterface()).thenReturn(ifname);
594 }
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800595
David Su798a92b2020-01-13 12:49:21 -0800596 final Intent intent = mock(Intent.class);
597 when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
598 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo);
599 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group);
600
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800601 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
602 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
603 }
604
Milim Lee31ef4c02019-10-17 05:02:33 +0900605 private void sendUsbBroadcast(boolean connected, boolean configured, boolean function,
606 int type) {
Erik Klinec438e302017-07-04 22:02:49 +0900607 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
608 intent.putExtra(USB_CONNECTED, connected);
609 intent.putExtra(USB_CONFIGURED, configured);
Milim Lee31ef4c02019-10-17 05:02:33 +0900610 if (type == TETHERING_USB) {
611 intent.putExtra(USB_FUNCTION_RNDIS, function);
612 } else {
613 intent.putExtra(USB_FUNCTION_NCM, function);
614 }
Erik Klinec438e302017-07-04 22:02:49 +0900615 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
616 }
617
Erik Kline80b7a9f2018-02-28 15:01:35 +0900618 private void sendConfigurationChanged() {
619 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
620 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
621 }
622
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800623 private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
markchiena9d9ef82020-01-07 14:43:17 +0800624 verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
625 verify(mNetd, times(1)).tetherInterfaceAdd(ifname);
626 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
627 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
628 anyString(), anyString());
Erik Kline8351faa2017-04-17 16:47:23 +0900629 }
630
631 private void verifyTetheringBroadcast(String ifname, String whichExtra) {
632 // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
633 final Intent bcast = mIntents.get(0);
Erik Kline465ff3a2018-03-09 14:18:02 +0900634 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
Erik Kline8351faa2017-04-17 16:47:23 +0900635 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
636 assertTrue(ifnames.contains(ifname));
637 mIntents.remove(bcast);
638 }
639
Erik Klinea9cde8b2017-06-20 21:18:31 +0900640 public void failingLocalOnlyHotspotLegacyApBroadcast(
641 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Klineea9cc482017-03-10 19:35:34 +0900642 // Emulate externally-visible WifiManager effects, causing the
643 // per-interface state machine to start up, and telling us that
644 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900645 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900646 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900647 }
Erik Kline9e225542017-06-08 17:48:48 +0900648 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900649 mLooper.dispatchAll();
650
Erik Kline7a4ccc62018-08-27 17:26:47 +0900651 // If, and only if, Tethering received an interface status changed then
652 // it creates a IpServer and sends out a broadcast indicating that the
653 // interface is "available".
Erik Klinea9cde8b2017-06-20 21:18:31 +0900654 if (emulateInterfaceStatusChanged) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000655 // There is 1 IpServer state change event: STATE_AVAILABLE
656 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Kline465ff3a2018-03-09 14:18:02 +0900657 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900658 verify(mWifiManager).updateInterfaceIpState(
659 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900660 }
markchiena9d9ef82020-01-07 14:43:17 +0800661 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900662 verifyNoMoreInteractions(mWifiManager);
663 }
664
Milim Lee31ef4c02019-10-17 05:02:33 +0900665 private void prepareNcmTethering() {
666 // Emulate startTethering(TETHERING_NCM) called
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000667 mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
Milim Lee31ef4c02019-10-17 05:02:33 +0900668 mLooper.dispatchAll();
669 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
670
671 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
672 }
673
markchienb0aca962019-12-05 16:21:17 +0800674 private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
Erik Kline72302902018-06-14 17:36:40 +0900675 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900676 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
677 .thenReturn(upstreamState);
Erik Klinec438e302017-07-04 22:02:49 +0900678
679 // Emulate pressing the USB tethering button in Settings UI.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000680 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
Erik Klinec438e302017-07-04 22:02:49 +0900681 mLooper.dispatchAll();
Jerry Zhang327b8092018-01-09 17:53:04 -0800682 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
Erik Klinec438e302017-07-04 22:02:49 +0900683
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900684 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
685 }
686
687 @Test
688 public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800689 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900690 prepareUsbTethering(upstreamState);
691
Erik Klinec438e302017-07-04 22:02:49 +0900692 // This should produce no activity of any kind.
markchiena9d9ef82020-01-07 14:43:17 +0800693 verifyNoMoreInteractions(mNetd);
Erik Klinec438e302017-07-04 22:02:49 +0900694
695 // Pretend we then receive USB configured broadcast.
Milim Lee31ef4c02019-10-17 05:02:33 +0900696 sendUsbBroadcast(true, true, true, TETHERING_USB);
Erik Klinec438e302017-07-04 22:02:49 +0900697 mLooper.dispatchAll();
698 // Now we should see the start of tethering mechanics (in this case:
699 // tetherMatchingInterfaces() which starts by fetching all interfaces).
markchiena9d9ef82020-01-07 14:43:17 +0800700 verify(mNetd, times(1)).interfaceGetList();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900701
702 // UpstreamNetworkMonitor should receive selected upstream
703 verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
704 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
Erik Klinec438e302017-07-04 22:02:49 +0900705 }
706
707 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900708 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
709 failingLocalOnlyHotspotLegacyApBroadcast(true);
710 }
711
712 @Test
713 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
714 failingLocalOnlyHotspotLegacyApBroadcast(false);
715 }
716
717 public void workingLocalOnlyHotspotEnrichedApBroadcast(
718 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900719 // Emulate externally-visible WifiManager effects, causing the
720 // per-interface state machine to start up, and telling us that
721 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900722 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900723 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900724 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900725 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline9e225542017-06-08 17:48:48 +0900726 mLooper.dispatchAll();
727
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800728 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900729 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +0800730 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
731 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
732 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +0900733 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900734 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
735 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900736 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +0900737 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900738 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
markchiena6c72872018-11-13 18:34:56 +0900739 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000740 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
741 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Klineea9cc482017-03-10 19:35:34 +0900742
743 // Emulate externally-visible WifiManager effects, when hotspot mode
744 // is being torn down.
745 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900746 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900747 mLooper.dispatchAll();
748
markchiena9d9ef82020-01-07 14:43:17 +0800749 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
750 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
751 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
752 // interfaceSetCfg() called once for enabling and twice disabling IPv4.
753 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
754 verify(mNetd, times(1)).tetherStop();
755 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900756 verify(mWifiManager, times(3)).updateInterfaceIpState(
757 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +0800758 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +0900759 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900760 // Asking for the last error after the per-interface state machine
761 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900762 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900763 }
764
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900765 /**
Erik Kline7a4ccc62018-08-27 17:26:47 +0900766 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900767 */
markchienb0aca962019-12-05 16:21:17 +0800768 private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900769 // IPv6TetheringCoordinator must have been notified of downstream
770 verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
771 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
Erik Kline7a4ccc62018-08-27 17:26:47 +0900772 eq(IpServer.STATE_TETHERED));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900773
markchien0f63ca62019-09-30 14:40:57 +0800774 for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
markchienb0aca962019-12-05 16:21:17 +0800775 UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900776 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
paulhud9736de2019-03-08 16:35:20 +0800777 upstreamState.linkProperties.isIpv6Provisioned()
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900778 ? ipv6OnlyState.linkProperties
779 : null);
780 }
781 mLooper.dispatchAll();
782 }
783
markchienb0aca962019-12-05 16:21:17 +0800784 private void runUsbTethering(UpstreamNetworkState upstreamState) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900785 prepareUsbTethering(upstreamState);
Milim Lee31ef4c02019-10-17 05:02:33 +0900786 sendUsbBroadcast(true, true, true, TETHERING_USB);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900787 mLooper.dispatchAll();
788 }
789
790 @Test
791 public void workingMobileUsbTethering_IPv4() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800792 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900793 runUsbTethering(upstreamState);
794
markchiena9d9ef82020-01-07 14:43:17 +0800795 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
796 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900797
798 sendIPv6TetherUpdates(upstreamState);
799 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900800 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
801 any(), any());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900802 }
803
804 @Test
805 public void workingMobileUsbTethering_IPv4LegacyDhcp() {
markchienda4519a2020-01-14 12:46:53 +0800806 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
807 true);
markchien0f63ca62019-09-30 14:40:57 +0800808 sendConfigurationChanged();
markchienb0aca962019-12-05 16:21:17 +0800809 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900810 runUsbTethering(upstreamState);
811 sendIPv6TetherUpdates(upstreamState);
812
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900813 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900814 }
815
816 @Test
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900817 public void workingMobileUsbTethering_IPv6() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800818 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900819 runUsbTethering(upstreamState);
820
markchiena9d9ef82020-01-07 14:43:17 +0800821 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
822 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900823
824 sendIPv6TetherUpdates(upstreamState);
825 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
826 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
827 }
828
829 @Test
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900830 public void workingMobileUsbTethering_DualStack() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800831 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900832 runUsbTethering(upstreamState);
833
markchiena9d9ef82020-01-07 14:43:17 +0800834 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
835 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900836 verify(mRouterAdvertisementDaemon, times(1)).start();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900837 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
838 any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900839
840 sendIPv6TetherUpdates(upstreamState);
841 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
842 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
843 }
844
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900845 @Test
846 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800847 UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900848 runUsbTethering(upstreamState);
849
markchiena9d9ef82020-01-07 14:43:17 +0800850 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
851 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900852 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
853 any(), any());
markchiena9d9ef82020-01-07 14:43:17 +0800854 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
855 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900856
857 sendIPv6TetherUpdates(upstreamState);
858 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
859 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
860 }
861
862 @Test
863 public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
864 // Setup IPv6
markchienb0aca962019-12-05 16:21:17 +0800865 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900866 runUsbTethering(upstreamState);
867
markchiena9d9ef82020-01-07 14:43:17 +0800868 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900869 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
870 any(), any());
markchiena9d9ef82020-01-07 14:43:17 +0800871 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900872
873 // Then 464xlat comes up
874 upstreamState = buildMobile464xlatUpstreamState();
875 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
876 .thenReturn(upstreamState);
877
878 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
markchien0f63ca62019-09-30 14:40:57 +0800879 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900880 Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
881 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
882 0,
883 upstreamState);
884 mLooper.dispatchAll();
885
886 // Forwarding is added for 464xlat
markchiena9d9ef82020-01-07 14:43:17 +0800887 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
888 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900889 // Forwarding was not re-added for v6 (still times(1))
markchiena9d9ef82020-01-07 14:43:17 +0800890 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
891 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900892 // DHCP not restarted on downstream (still times(1))
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900893 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
894 any(), any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900895 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900896
Erik Klineea9cc482017-03-10 19:35:34 +0900897 @Test
Erik Kline72302902018-06-14 17:36:40 +0900898 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
markchienda4519a2020-01-14 12:46:53 +0800899 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
Erik Kline72302902018-06-14 17:36:40 +0900900 sendConfigurationChanged();
901
902 // Setup IPv6
markchienb0aca962019-12-05 16:21:17 +0800903 final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Erik Kline72302902018-06-14 17:36:40 +0900904 runUsbTethering(upstreamState);
905
906 // UpstreamNetworkMonitor should choose upstream automatically
907 // (in this specific case: choose the default network).
908 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
909 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
910
911 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
912 }
913
Milim Lee31ef4c02019-10-17 05:02:33 +0900914 private void runNcmTethering() {
915 prepareNcmTethering();
916 sendUsbBroadcast(true, true, true, TETHERING_NCM);
917 mLooper.dispatchAll();
918 }
919
920 @Test
921 public void workingNcmTethering() throws Exception {
922 runNcmTethering();
923
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900924 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
925 any(), any());
Milim Lee31ef4c02019-10-17 05:02:33 +0900926 }
927
928 @Test
929 public void workingNcmTethering_LegacyDhcp() {
930 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
931 true);
932 sendConfigurationChanged();
933 runNcmTethering();
934
935 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
936 }
937
Erik Kline72302902018-06-14 17:36:40 +0900938 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900939 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
940 workingLocalOnlyHotspotEnrichedApBroadcast(true);
941 }
942
943 @Test
944 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
945 workingLocalOnlyHotspotEnrichedApBroadcast(false);
946 }
947
948 // TODO: Test with and without interfaceStatusChanged().
949 @Test
Erik Kline9e225542017-06-08 17:48:48 +0900950 public void failingWifiTetheringLegacyApBroadcast() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +0800951 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900952
953 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000954 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Klineea9cc482017-03-10 19:35:34 +0900955 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +0800956 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Klineea9cc482017-03-10 19:35:34 +0900957 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +0800958 verifyNoMoreInteractions(mNetd);
Erik Klineea9cc482017-03-10 19:35:34 +0900959
960 // Emulate externally-visible WifiManager effects, causing the
961 // per-interface state machine to start up, and telling us that
962 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900963 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Kline9e225542017-06-08 17:48:48 +0900964 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900965 mLooper.dispatchAll();
966
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000967 // There is 1 IpServer state change event: STATE_AVAILABLE
968 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Kline465ff3a2018-03-09 14:18:02 +0900969 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900970 verify(mWifiManager).updateInterfaceIpState(
971 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +0800972 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900973 verifyNoMoreInteractions(mWifiManager);
974 }
975
Erik Klinea9cde8b2017-06-20 21:18:31 +0900976 // TODO: Test with and without interfaceStatusChanged().
Erik Kline9e225542017-06-08 17:48:48 +0900977 @Test
978 public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +0800979 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
Erik Kline9e225542017-06-08 17:48:48 +0900980
981 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000982 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Kline9e225542017-06-08 17:48:48 +0900983 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +0800984 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Kline9e225542017-06-08 17:48:48 +0900985 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +0800986 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900987
988 // Emulate externally-visible WifiManager effects, causing the
989 // per-interface state machine to start up, and telling us that
990 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900991 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
992 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline9e225542017-06-08 17:48:48 +0900993 mLooper.dispatchAll();
994
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800995 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900996 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +0800997 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
998 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
999 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
1000 anyString(), anyString());
1001 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +09001002 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +09001003 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1004 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001005 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +09001006 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +09001007 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
markchiena6c72872018-11-13 18:34:56 +09001008 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Erik Klineea9cc482017-03-10 19:35:34 +09001009 // In tethering mode, in the default configuration, an explicit request
1010 // for a mobile network is also made.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001011 verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +00001012 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED
1013 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
1014 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
Erik Klineea9cc482017-03-10 19:35:34 +09001015
1016 /////
1017 // We do not currently emulate any upstream being found.
1018 //
markchiena9d9ef82020-01-07 14:43:17 +08001019 // This is why there are no calls to verify mNetd.tetherAddForward() or
1020 // mNetd.ipfwdAddInterfaceForward().
Erik Klineea9cc482017-03-10 19:35:34 +09001021 /////
1022
1023 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +09001024 mTethering.stopTethering(TETHERING_WIFI);
Erik Klineea9cc482017-03-10 19:35:34 +09001025 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +09001026 verify(mWifiManager, times(1)).stopSoftAp();
Erik Klineea9cc482017-03-10 19:35:34 +09001027 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001028 verifyNoMoreInteractions(mNetd);
Erik Klineea9cc482017-03-10 19:35:34 +09001029
1030 // Emulate externally-visible WifiManager effects, when tethering mode
1031 // is being torn down.
1032 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001033 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +09001034 mLooper.dispatchAll();
1035
markchiena9d9ef82020-01-07 14:43:17 +08001036 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1037 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1038 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1039 // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
1040 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1041 verify(mNetd, times(1)).tetherStop();
1042 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jianpeng Lia70feec2019-05-24 17:40:15 +09001043 verify(mWifiManager, times(3)).updateInterfaceIpState(
1044 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +08001045 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +09001046 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +09001047 // Asking for the last error after the per-interface state machine
1048 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +09001049 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +09001050 }
1051
Erik Klinea9cde8b2017-06-20 21:18:31 +09001052 // TODO: Test with and without interfaceStatusChanged().
Erik Kline1fdc2e22017-05-08 17:56:35 +09001053 @Test
1054 public void failureEnablingIpForwarding() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +08001055 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
markchiena9d9ef82020-01-07 14:43:17 +08001056 doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001057
1058 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001059 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001060 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +08001061 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001062 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001063 verifyNoMoreInteractions(mNetd);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001064
1065 // Emulate externally-visible WifiManager effects, causing the
1066 // per-interface state machine to start up, and telling us that
1067 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001068 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1069 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001070 mLooper.dispatchAll();
1071
markchiena9d9ef82020-01-07 14:43:17 +08001072 // We verify get/set called three times here: twice for setup and once during
1073 // teardown because all events happen over the course of the single
Erik Kline7a4ccc62018-08-27 17:26:47 +09001074 // dispatchAll() above. Note that once the IpServer IPv4 address config
Erik Kline472276a2018-05-18 16:09:24 +09001075 // code is refactored the two calls during shutdown will revert to one.
markchiena9d9ef82020-01-07 14:43:17 +08001076 verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
1077 verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
1078 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1079 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
1080 anyString(), anyString());
Erik Kline1fdc2e22017-05-08 17:56:35 +09001081 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +09001082 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1083 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001084 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +00001085 // There are 3 IpServer state change event:
1086 // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
1087 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
1088 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
Erik Kline465ff3a2018-03-09 14:18:02 +09001089 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001090 // This is called, but will throw.
markchiena9d9ef82020-01-07 14:43:17 +08001091 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001092 // This never gets called because of the exception thrown above.
markchiena9d9ef82020-01-07 14:43:17 +08001093 verify(mNetd, times(0)).tetherStartWithConfiguration(any());
Erik Kline1fdc2e22017-05-08 17:56:35 +09001094 // When the master state machine transitions to an error state it tells
1095 // downstream interfaces, which causes us to tell Wi-Fi about the error
1096 // so it can take down AP mode.
markchiena9d9ef82020-01-07 14:43:17 +08001097 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1098 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1099 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001100 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001101 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001102
1103 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001104 verifyNoMoreInteractions(mNetd);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001105 }
1106
markchien1ddfba42019-11-27 21:20:33 +08001107 private void runUserRestrictionsChange(
Paul Hu4089bb12020-04-23 09:07:00 +00001108 boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
markchien0f63ca62019-09-30 14:40:57 +08001109 int expectedInteractionsWithShowNotification) throws Exception {
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001110 final Bundle newRestrictions = new Bundle();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001111 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
markchien1ddfba42019-11-27 21:20:33 +08001112 final Tethering mockTethering = mock(Tethering.class);
Paul Hu4089bb12020-04-23 09:07:00 +00001113 when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
markchien1ddfba42019-11-27 21:20:33 +08001114 when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001115
markchien1ddfba42019-11-27 21:20:33 +08001116 final Tethering.UserRestrictionActionListener ural =
Paul Huf950dc92020-03-25 12:39:13 +00001117 new Tethering.UserRestrictionActionListener(
1118 mUserManager, mockTethering, mNotificationUpdater);
markchien1ddfba42019-11-27 21:20:33 +08001119 ural.mDisallowTethering = currentDisallow;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001120
markchien1ddfba42019-11-27 21:20:33 +08001121 ural.onUserRestrictionsChanged();
1122
Paul Huf950dc92020-03-25 12:39:13 +00001123 verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
1124 .notifyTetheringDisabledByRestriction();
1125 verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001126 }
1127
1128 @Test
Paul Hu4089bb12020-04-23 09:07:00 +00001129 public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception {
1130 final boolean isTetheringActive = false;
1131 final boolean currDisallow = false;
1132 final boolean nextDisallow = true;
1133 final int expectedInteractionsWithShowNotification = 0;
1134
1135 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1136 expectedInteractionsWithShowNotification);
1137 }
1138
1139 @Test
1140 public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
1141 final boolean isTetheringActive = true;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001142 final boolean currDisallow = false;
1143 final boolean nextDisallow = true;
Paul Huf950dc92020-03-25 12:39:13 +00001144 final int expectedInteractionsWithShowNotification = 1;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001145
Paul Hu4089bb12020-04-23 09:07:00 +00001146 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001147 expectedInteractionsWithShowNotification);
1148 }
1149
1150 @Test
Paul Hu4089bb12020-04-23 09:07:00 +00001151 public void testAllowTetheringWhenTetheringIsNotActive() throws Exception {
1152 final boolean isTetheringActive = false;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001153 final boolean currDisallow = true;
1154 final boolean nextDisallow = false;
1155 final int expectedInteractionsWithShowNotification = 0;
1156
Paul Hu4089bb12020-04-23 09:07:00 +00001157 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001158 expectedInteractionsWithShowNotification);
1159 }
1160
1161 @Test
Paul Hu4089bb12020-04-23 09:07:00 +00001162 public void testAllowTetheringWhenTetheringIsActive() throws Exception {
1163 final boolean isTetheringActive = true;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001164 final boolean currDisallow = true;
1165 final boolean nextDisallow = false;
1166 final int expectedInteractionsWithShowNotification = 0;
1167
Paul Hu4089bb12020-04-23 09:07:00 +00001168 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001169 expectedInteractionsWithShowNotification);
1170 }
1171
1172 @Test
1173 public void testDisallowTetheringUnchanged() throws Exception {
Paul Hu4089bb12020-04-23 09:07:00 +00001174 final boolean isTetheringActive = true;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001175 final int expectedInteractionsWithShowNotification = 0;
1176 boolean currDisallow = true;
1177 boolean nextDisallow = true;
1178
Paul Hu4089bb12020-04-23 09:07:00 +00001179 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001180 expectedInteractionsWithShowNotification);
1181
1182 currDisallow = false;
1183 nextDisallow = false;
1184
Paul Hu4089bb12020-04-23 09:07:00 +00001185 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001186 expectedInteractionsWithShowNotification);
1187 }
1188
markchienae8aa642019-12-16 20:15:20 +08001189 private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
markchien26299ed2019-02-27 14:56:11 +08001190 private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
markchien0f63ca62019-09-30 14:40:57 +08001191 private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
1192 new ArrayList<>();
1193 private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001194 private final ArrayList<Integer> mOffloadStatus = new ArrayList<>();
markchien26299ed2019-02-27 14:56:11 +08001195
markchien0f63ca62019-09-30 14:40:57 +08001196 // This function will remove the recorded callbacks, so it must be called once for
1197 // each callback. If this is called after multiple callback, the order matters.
1198 // onCallbackCreated counts as the first call to expectUpstreamChanged with
1199 // @see onCallbackCreated.
markchien26299ed2019-02-27 14:56:11 +08001200 public void expectUpstreamChanged(Network... networks) {
markchien0f63ca62019-09-30 14:40:57 +08001201 if (networks == null) {
1202 assertNoUpstreamChangeCallback();
1203 return;
1204 }
1205
markchien26299ed2019-02-27 14:56:11 +08001206 final ArrayList<Network> expectedUpstreams =
1207 new ArrayList<Network>(Arrays.asList(networks));
1208 for (Network upstream : expectedUpstreams) {
1209 // throws OOB if no expectations
1210 assertEquals(mActualUpstreams.remove(0), upstream);
1211 }
markchien0f63ca62019-09-30 14:40:57 +08001212 assertNoUpstreamChangeCallback();
1213 }
1214
1215 // This function will remove the recorded callbacks, so it must be called once
1216 // for each callback. If this is called after multiple callback, the order matters.
1217 // onCallbackCreated counts as the first call to onConfigurationChanged with
1218 // @see onCallbackCreated.
1219 public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
1220 final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
1221 new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
1222 for (TetheringConfigurationParcel config : expectedTetherConfig) {
1223 // throws OOB if no expectations
1224 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
1225 assertTetherConfigParcelEqual(actualConfig, config);
1226 }
1227 assertNoConfigChangeCallback();
1228 }
1229
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001230 public void expectOffloadStatusChanged(final int expectedStatus) {
1231 assertOffloadStatusChangedCallback();
1232 assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus));
1233 }
1234
markchien0f63ca62019-09-30 14:40:57 +08001235 public TetherStatesParcel pollTetherStatesChanged() {
1236 assertStateChangeCallback();
1237 return mTetherStates.remove(0);
markchien26299ed2019-02-27 14:56:11 +08001238 }
1239
1240 @Override
1241 public void onUpstreamChanged(Network network) {
1242 mActualUpstreams.add(network);
1243 }
1244
markchien0f63ca62019-09-30 14:40:57 +08001245 @Override
1246 public void onConfigurationChanged(TetheringConfigurationParcel config) {
1247 mTetheringConfigs.add(config);
1248 }
1249
1250 @Override
1251 public void onTetherStatesChanged(TetherStatesParcel states) {
1252 mTetherStates.add(states);
1253 }
1254
1255 @Override
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09001256 public void onTetherClientsChanged(List<TetheredClient> clients) {
1257 // TODO: check this
1258 }
1259
1260 @Override
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001261 public void onOffloadStatusChanged(final int status) {
1262 mOffloadStatus.add(status);
1263 }
1264
1265 @Override
markchien40898ca2020-01-21 13:11:06 +08001266 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
1267 mActualUpstreams.add(parcel.upstreamNetwork);
1268 mTetheringConfigs.add(parcel.config);
1269 mTetherStates.add(parcel.states);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001270 mOffloadStatus.add(parcel.offloadStatus);
markchien0f63ca62019-09-30 14:40:57 +08001271 }
1272
markchienae8aa642019-12-16 20:15:20 +08001273 @Override
1274 public void onCallbackStopped(int errorCode) { }
1275
markchien0f63ca62019-09-30 14:40:57 +08001276 public void assertNoUpstreamChangeCallback() {
markchien26299ed2019-02-27 14:56:11 +08001277 assertTrue(mActualUpstreams.isEmpty());
1278 }
markchien0f63ca62019-09-30 14:40:57 +08001279
1280 public void assertNoConfigChangeCallback() {
1281 assertTrue(mTetheringConfigs.isEmpty());
1282 }
1283
markchienae8aa642019-12-16 20:15:20 +08001284 public void assertNoStateChangeCallback() {
1285 assertTrue(mTetherStates.isEmpty());
1286 }
1287
markchien0f63ca62019-09-30 14:40:57 +08001288 public void assertStateChangeCallback() {
1289 assertFalse(mTetherStates.isEmpty());
1290 }
1291
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001292 public void assertOffloadStatusChangedCallback() {
1293 assertFalse(mOffloadStatus.isEmpty());
1294 }
1295
markchienae8aa642019-12-16 20:15:20 +08001296 public void assertNoCallback() {
1297 assertNoUpstreamChangeCallback();
1298 assertNoConfigChangeCallback();
1299 assertNoStateChangeCallback();
1300 }
1301
markchien0f63ca62019-09-30 14:40:57 +08001302 private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
1303 @NonNull TetheringConfigurationParcel expect) {
1304 assertEquals(actual.subId, expect.subId);
1305 assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
1306 assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
1307 assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
1308 assertEquals(actual.isDunRequired, expect.isDunRequired);
1309 assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
1310 assertArrayEquals(actual.preferredUpstreamIfaceTypes,
1311 expect.preferredUpstreamIfaceTypes);
1312 assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
1313 assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
1314 assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
1315 assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
1316 assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
1317 assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
1318 }
markchien26299ed2019-02-27 14:56:11 +08001319 }
1320
markchienfaa37282020-02-06 14:34:08 +08001321 private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) {
1322 assertFalse(parcel == null);
1323 assertEquals(0, parcel.availableList.length);
1324 assertEquals(0, parcel.tetheredList.length);
1325 assertEquals(0, parcel.localOnlyList.length);
1326 assertEquals(0, parcel.erroredIfaceList.length);
1327 assertEquals(0, parcel.lastErrorList.length);
1328 MiscAssertsKt.assertFieldCountEquals(5, TetherStatesParcel.class);
1329 }
1330
markchien26299ed2019-02-27 14:56:11 +08001331 @Test
markchienae8aa642019-12-16 20:15:20 +08001332 public void testRegisterTetheringEventCallback() throws Exception {
1333 TestTetheringEventCallback callback = new TestTetheringEventCallback();
1334 TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
markchien26299ed2019-02-27 14:56:11 +08001335
markchien0f63ca62019-09-30 14:40:57 +08001336 // 1. Register one callback before running any tethering.
markchienae8aa642019-12-16 20:15:20 +08001337 mTethering.registerTetheringEventCallback(callback);
markchien26299ed2019-02-27 14:56:11 +08001338 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001339 callback.expectUpstreamChanged(new Network[] {null});
1340 callback.expectConfigurationChanged(
1341 mTethering.getTetheringConfiguration().toStableParcelable());
1342 TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
markchienfaa37282020-02-06 14:34:08 +08001343 assertTetherStatesNotNullButEmpty(tetherState);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001344 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
markchienae8aa642019-12-16 20:15:20 +08001345 // 2. Enable wifi tethering.
markchienb0aca962019-12-05 16:21:17 +08001346 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
markchien26299ed2019-02-27 14:56:11 +08001347 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
1348 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
1349 .thenReturn(upstreamState);
lesl6b7551a2019-12-13 10:56:35 +08001350 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
markchien26299ed2019-02-27 14:56:11 +08001351 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
markchien0f63ca62019-09-30 14:40:57 +08001352 mLooper.dispatchAll();
1353 tetherState = callback.pollTetherStatesChanged();
1354 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1355
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001356 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
markchien26299ed2019-02-27 14:56:11 +08001357 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1358 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001359 tetherState = callback.pollTetherStatesChanged();
1360 assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
1361 callback.expectUpstreamChanged(upstreamState.network);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001362 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
markchien0f63ca62019-09-30 14:40:57 +08001363
markchienae8aa642019-12-16 20:15:20 +08001364 // 3. Register second callback.
1365 mTethering.registerTetheringEventCallback(callback2);
1366 mLooper.dispatchAll();
1367 callback2.expectUpstreamChanged(upstreamState.network);
1368 callback2.expectConfigurationChanged(
1369 mTethering.getTetheringConfiguration().toStableParcelable());
1370 tetherState = callback2.pollTetherStatesChanged();
1371 assertEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001372 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
markchienae8aa642019-12-16 20:15:20 +08001373
1374 // 4. Unregister first callback and disable wifi tethering
1375 mTethering.unregisterTetheringEventCallback(callback);
1376 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001377 mTethering.stopTethering(TETHERING_WIFI);
1378 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
1379 mLooper.dispatchAll();
markchienae8aa642019-12-16 20:15:20 +08001380 tetherState = callback2.pollTetherStatesChanged();
markchien0f63ca62019-09-30 14:40:57 +08001381 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1382 mLooper.dispatchAll();
markchienae8aa642019-12-16 20:15:20 +08001383 callback2.expectUpstreamChanged(new Network[] {null});
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001384 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
markchienae8aa642019-12-16 20:15:20 +08001385 callback.assertNoCallback();
markchien26299ed2019-02-27 14:56:11 +08001386 }
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001387
markchien04bdf872019-06-17 21:05:34 +08001388 @Test
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001389 public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
1390 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1391 TestTetheringEventCallback callback = new TestTetheringEventCallback();
1392 mTethering.registerTetheringEventCallback(callback);
1393 mLooper.dispatchAll();
1394 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1395
1396 // 1. Offload fail if no OffloadConfig.
1397 initOffloadConfiguration(false /* offloadConfig */, true /* offloadControl */,
1398 0 /* defaultDisabled */);
1399 runUsbTethering(upstreamState);
1400 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1401 runStopUSBTethering();
1402 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1403 reset(mUsbManager);
1404 // 2. Offload fail if no OffloadControl.
1405 initOffloadConfiguration(true /* offloadConfig */, false /* offloadControl */,
1406 0 /* defaultDisabled */);
1407 runUsbTethering(upstreamState);
1408 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1409 runStopUSBTethering();
1410 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1411 reset(mUsbManager);
1412 // 3. Offload fail if disabled by settings.
1413 initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
1414 1 /* defaultDisabled */);
1415 runUsbTethering(upstreamState);
1416 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1417 runStopUSBTethering();
1418 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1419 }
1420
1421 private void runStopUSBTethering() {
1422 mTethering.stopTethering(TETHERING_USB);
1423 mLooper.dispatchAll();
1424 mTethering.interfaceRemoved(TEST_USB_IFNAME);
1425 mLooper.dispatchAll();
1426 }
1427
1428 private void initOffloadConfiguration(final boolean offloadConfig,
1429 final boolean offloadControl, final int defaultDisabled) {
1430 when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
1431 when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControl);
1432 when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
1433 defaultDisabled);
1434 }
1435
1436 @Test
markchien04bdf872019-06-17 21:05:34 +08001437 public void testMultiSimAware() throws Exception {
1438 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
markchien986750b2019-12-06 15:24:53 +08001439 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
markchien04bdf872019-06-17 21:05:34 +08001440
1441 final int fakeSubId = 1234;
1442 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1443 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
markchien986750b2019-12-06 15:24:53 +08001444 assertEquals(fakeSubId, newConfig.activeDataSubId);
Paul Hu274cc1c2020-03-25 06:22:43 +00001445 verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
markchien04bdf872019-06-17 21:05:34 +08001446 }
1447
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001448 @Test
1449 public void testNoDuplicatedEthernetRequest() throws Exception {
1450 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
1451 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001452 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001453 mLooper.dispatchAll();
1454 verify(mEm, times(1)).requestTetheredInterface(any(), any());
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001455 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001456 mLooper.dispatchAll();
1457 verifyNoMoreInteractions(mEm);
1458 mTethering.stopTethering(TETHERING_ETHERNET);
1459 mLooper.dispatchAll();
1460 verify(mockRequest, times(1)).release();
1461 mTethering.stopTethering(TETHERING_ETHERNET);
1462 mLooper.dispatchAll();
1463 verifyNoMoreInteractions(mEm);
1464 }
1465
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001466 private void workingWifiP2pGroupOwner(
1467 boolean emulateInterfaceStatusChanged) throws Exception {
1468 if (emulateInterfaceStatusChanged) {
1469 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1470 }
1471 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1472 mLooper.dispatchAll();
1473
1474 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
1475 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +08001476 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
1477 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
1478 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001479 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
1480 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +00001481 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
1482 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001483
1484 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1485
1486 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1487 // is being removed.
1488 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
1489 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1490 mLooper.dispatchAll();
1491
markchiena9d9ef82020-01-07 14:43:17 +08001492 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1493 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
1494 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1495 // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
1496 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1497 verify(mNetd, times(1)).tetherStop();
1498 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001499 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
1500 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
markchiena9d9ef82020-01-07 14:43:17 +08001501 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001502 // Asking for the last error after the per-interface state machine
1503 // has been reaped yields an unknown interface error.
1504 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1505 }
1506
1507 private void workingWifiP2pGroupClient(
1508 boolean emulateInterfaceStatusChanged) throws Exception {
1509 if (emulateInterfaceStatusChanged) {
1510 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1511 }
1512 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
1513 mLooper.dispatchAll();
1514
markchiena9d9ef82020-01-07 14:43:17 +08001515 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1516 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
1517 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1518 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
1519 verify(mNetd, never()).tetherStartWithConfiguration(any());
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001520
1521 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1522 // is being removed.
1523 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
1524 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1525 mLooper.dispatchAll();
1526
markchiena9d9ef82020-01-07 14:43:17 +08001527 verify(mNetd, never()).tetherApplyDnsInterfaces();
1528 verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
1529 verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1530 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1531 verify(mNetd, never()).tetherStop();
1532 verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
1533 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001534 // Asking for the last error after the per-interface state machine
1535 // has been reaped yields an unknown interface error.
1536 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1537 }
1538
1539 @Test
1540 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
1541 workingWifiP2pGroupOwner(true);
1542 }
1543
1544 @Test
1545 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
1546 workingWifiP2pGroupOwner(false);
1547 }
1548
1549 private void workingWifiP2pGroupOwnerLegacyMode(
1550 boolean emulateInterfaceStatusChanged) throws Exception {
1551 // change to legacy mode and update tethering information by chaning SIM
markchienda4519a2020-01-14 12:46:53 +08001552 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001553 .thenReturn(new String[]{});
1554 final int fakeSubId = 1234;
1555 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1556
1557 if (emulateInterfaceStatusChanged) {
1558 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1559 }
1560 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1561 mLooper.dispatchAll();
1562
markchiena9d9ef82020-01-07 14:43:17 +08001563 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1564 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
1565 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1566 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
1567 verify(mNetd, never()).tetherStartWithConfiguration(any());
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001568 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1569 }
1570 @Test
1571 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
1572 workingWifiP2pGroupOwnerLegacyMode(true);
1573 }
1574
1575 @Test
1576 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
1577 workingWifiP2pGroupOwnerLegacyMode(false);
1578 }
1579
1580 @Test
1581 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
1582 workingWifiP2pGroupClient(true);
1583 }
1584
1585 @Test
1586 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
1587 workingWifiP2pGroupClient(false);
1588 }
1589
markchien3fe660b2019-12-05 12:04:59 +08001590 private void setDataSaverEnabled(boolean enabled) {
1591 final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED);
1592 mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
1593
1594 final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED
1595 : RESTRICT_BACKGROUND_STATUS_DISABLED;
1596 when(mCm.getRestrictBackgroundStatus()).thenReturn(status);
1597 mLooper.dispatchAll();
1598 }
1599
1600 @Test
1601 public void testDataSaverChanged() {
1602 // Start Tethering.
1603 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1604 runUsbTethering(upstreamState);
1605 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1606 // Data saver is ON.
1607 setDataSaverEnabled(true);
1608 // Verify that tethering should be disabled.
1609 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1610 mTethering.interfaceRemoved(TEST_USB_IFNAME);
1611 mLooper.dispatchAll();
1612 assertEquals(mTethering.getTetheredIfaces(), new String[0]);
1613 reset(mUsbManager);
1614
1615 runUsbTethering(upstreamState);
1616 // Verify that user can start tethering again without turning OFF data saver.
1617 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1618
1619 // If data saver is keep ON with change event, tethering should not be OFF this time.
1620 setDataSaverEnabled(true);
1621 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1622 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1623
1624 // If data saver is turned OFF, it should not change tethering.
1625 setDataSaverEnabled(false);
1626 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1627 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1628 }
1629
1630 private static <T> void assertContains(Collection<T> collection, T element) {
1631 assertTrue(element + " not found in " + collection, collection.contains(element));
1632 }
1633
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001634 private class ResultListener extends IIntResultListener.Stub {
1635 private final int mExpectedResult;
1636 private boolean mHasResult = false;
1637 ResultListener(final int expectedResult) {
1638 mExpectedResult = expectedResult;
1639 }
1640
1641 @Override
1642 public void onResult(final int resultCode) {
1643 mHasResult = true;
1644 if (resultCode != mExpectedResult) {
1645 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
1646 }
1647 }
1648
1649 public void assertHasResult() {
1650 if (!mHasResult) fail("No callback result");
1651 }
1652 }
1653
1654 @Test
1655 public void testMultipleStartTethering() throws Exception {
1656 final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
1657 final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
1658 final String serverAddr = "192.168.20.1";
1659 final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1660 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1661 final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1662
1663 // Enable USB tethering and check that Tethering starts USB.
1664 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
markchien5788f2a2020-05-08 18:55:26 +08001665 null, null, false), firstResult);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001666 mLooper.dispatchAll();
1667 firstResult.assertHasResult();
1668 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1669 verifyNoMoreInteractions(mUsbManager);
1670
1671 // Enable USB tethering again with the same request and expect no change to USB.
1672 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
markchien5788f2a2020-05-08 18:55:26 +08001673 null, null, false), secondResult);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001674 mLooper.dispatchAll();
1675 secondResult.assertHasResult();
1676 verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1677 reset(mUsbManager);
1678
1679 // Enable USB tethering with a different request and expect that USB is stopped and
1680 // started.
1681 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
markchien5788f2a2020-05-08 18:55:26 +08001682 serverLinkAddr, clientLinkAddr, false), thirdResult);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001683 mLooper.dispatchAll();
1684 thirdResult.assertHasResult();
1685 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1686 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1687
1688 // Expect that when USB comes up, the DHCP server is configured with the requested address.
1689 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
1690 sendUsbBroadcast(true, true, true, TETHERING_USB);
1691 mLooper.dispatchAll();
1692 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1693 any(), any());
1694 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
1695 }
1696
1697 @Test
Treehugger Robot86d212b2020-03-30 04:23:55 +00001698 public void testRequestStaticIp() throws Exception {
1699 final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
1700 final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
1701 final String serverAddr = "192.168.0.123";
1702 final int clientAddrParceled = 0xc0a8002a;
1703 final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
1704 ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001705 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
markchien5788f2a2020-05-08 18:55:26 +08001706 serverLinkAddr, clientLinkAddr, false), null);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001707 mLooper.dispatchAll();
1708 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1709 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
1710 sendUsbBroadcast(true, true, true, TETHERING_USB);
1711 mLooper.dispatchAll();
1712 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
Treehugger Robot86d212b2020-03-30 04:23:55 +00001713 verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
1714 any());
1715 final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
1716 assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
1717 assertEquals(24, params.serverAddrPrefixLength);
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00001718 assertEquals(clientAddrParceled, params.singleClientAddr);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001719 }
1720
Paul Hu77fa8d62020-04-16 02:54:37 +00001721 @Test
1722 public void testUpstreamNetworkChanged() {
1723 final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
1724 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
1725 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1726 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
1727 stateMachine.chooseUpstreamType(true);
1728
1729 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001730 verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any());
1731 }
1732
1733 @Test
1734 public void testUpstreamCapabilitiesChanged() {
1735 final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
1736 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
1737 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1738 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
1739 stateMachine.chooseUpstreamType(true);
1740
1741 stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
1742 // Should have two onUpstreamCapabilitiesChanged().
1743 // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES.
1744 verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any());
1745 reset(mNotificationUpdater);
1746
1747 // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network
1748 // capabilities changed.
1749 final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState(
1750 upstreamState.linkProperties, upstreamState.networkCapabilities, new Network(101));
1751 stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2);
1752 verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
Paul Hu77fa8d62020-04-16 02:54:37 +00001753 }
1754
Mark Chien66b9a4a2020-05-07 03:49:42 +00001755 @Test
1756 public void testDumpTetheringLog() throws Exception {
1757 final FileDescriptor mockFd = mock(FileDescriptor.class);
1758 final PrintWriter mockPw = mock(PrintWriter.class);
1759 runUsbTethering(null);
Mark Chien47430c02020-05-08 11:00:42 +00001760 mLooper.startAutoDispatch();
Mark Chien66b9a4a2020-05-07 03:49:42 +00001761 mTethering.dump(mockFd, mockPw, new String[0]);
1762 verify(mConfig).dump(any());
1763 verify(mEntitleMgr).dump(any());
1764 verify(mOffloadCtrl).dump(any());
Mark Chien47430c02020-05-08 11:00:42 +00001765 mLooper.stopAutoDispatch();
Mark Chien66b9a4a2020-05-07 03:49:42 +00001766 }
1767
markchien5788f2a2020-05-08 18:55:26 +08001768 @Test
1769 public void testExemptFromEntitlementCheck() throws Exception {
1770 setupForRequiredProvisioning();
1771 final TetheringRequestParcel wifiNotExemptRequest =
1772 createTetheringRequestParcel(TETHERING_WIFI, null, null, false);
1773 mTethering.startTethering(wifiNotExemptRequest, null);
1774 mLooper.dispatchAll();
1775 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
1776 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
1777 assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
1778 mTethering.stopTethering(TETHERING_WIFI);
1779 mLooper.dispatchAll();
1780 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
1781 reset(mEntitleMgr);
1782
1783 setupForRequiredProvisioning();
1784 final TetheringRequestParcel wifiExemptRequest =
1785 createTetheringRequestParcel(TETHERING_WIFI, null, null, true);
1786 mTethering.startTethering(wifiExemptRequest, null);
1787 mLooper.dispatchAll();
1788 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
1789 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
1790 assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
1791 mTethering.stopTethering(TETHERING_WIFI);
1792 mLooper.dispatchAll();
1793 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
1794 reset(mEntitleMgr);
1795
1796 // If one app enables tethering without provisioning check first, then another app enables
1797 // tethering of the same type but does not disable the provisioning check.
1798 setupForRequiredProvisioning();
1799 mTethering.startTethering(wifiExemptRequest, null);
1800 mLooper.dispatchAll();
1801 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
1802 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
1803 assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
1804 reset(mEntitleMgr);
1805 setupForRequiredProvisioning();
1806 mTethering.startTethering(wifiNotExemptRequest, null);
1807 mLooper.dispatchAll();
1808 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
1809 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
1810 assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
1811 mTethering.stopTethering(TETHERING_WIFI);
1812 mLooper.dispatchAll();
1813 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
1814 reset(mEntitleMgr);
1815 }
1816
1817 private void setupForRequiredProvisioning() {
1818 // Produce some acceptable looking provision app setting if requested.
1819 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
1820 .thenReturn(PROVISIONING_APP_NAME);
1821 when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
1822 .thenReturn(PROVISIONING_NO_UI_APP_NAME);
1823 // Act like the CarrierConfigManager is present and ready unless told otherwise.
1824 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
1825 .thenReturn(mCarrierConfigManager);
1826 when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
1827 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
1828 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
1829 sendConfigurationChanged();
1830 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09001831 // TODO: Test that a request for hotspot mode doesn't interfere with an
Erik Klineea9cc482017-03-10 19:35:34 +09001832 // already operating tethering mode interface.
Christopher Wiley497c1472016-10-11 13:26:03 -07001833}