blob: feb99e6b248d29594849dbf0de9c434aff9da5b4 [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;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +000051
markchien0f63ca62019-09-30 14:40:57 +080052import static org.junit.Assert.assertArrayEquals;
Erik Klineea9cc482017-03-10 19:35:34 +090053import static org.junit.Assert.assertEquals;
markchien0f63ca62019-09-30 14:40:57 +080054import static org.junit.Assert.assertFalse;
Christopher Wiley497c1472016-10-11 13:26:03 -070055import static org.junit.Assert.assertTrue;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090056import static org.junit.Assert.fail;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090057import static org.mockito.ArgumentMatchers.argThat;
58import static org.mockito.ArgumentMatchers.notNull;
Erik Klineea9cc482017-03-10 19:35:34 +090059import static org.mockito.Matchers.anyString;
Christopher Wiley497c1472016-10-11 13:26:03 -070060import static org.mockito.Matchers.eq;
Erik Kline1fdc2e22017-05-08 17:56:35 +090061import static org.mockito.Mockito.any;
Erik Kline1fdc2e22017-05-08 17:56:35 +090062import static org.mockito.Mockito.doThrow;
markchienb6eb2c22018-07-18 14:29:20 +080063import static org.mockito.Mockito.mock;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090064import static org.mockito.Mockito.never;
markchien3fe660b2019-12-05 12:04:59 +080065import static org.mockito.Mockito.reset;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +090066import static org.mockito.Mockito.spy;
67import static org.mockito.Mockito.timeout;
Erik Klineea9cc482017-03-10 19:35:34 +090068import static org.mockito.Mockito.times;
69import static org.mockito.Mockito.verify;
70import static org.mockito.Mockito.verifyNoMoreInteractions;
Christopher Wiley497c1472016-10-11 13:26:03 -070071import static org.mockito.Mockito.when;
72
junyulaicaa81002019-12-11 11:03:01 +080073import android.app.usage.NetworkStatsManager;
markchien3fe660b2019-12-05 12:04:59 +080074import android.bluetooth.BluetoothAdapter;
Erik Kline8351faa2017-04-17 16:47:23 +090075import android.content.BroadcastReceiver;
Erik Kline92c4db02017-05-31 10:21:32 +090076import android.content.ContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -070077import android.content.Context;
Erik Klineea9cc482017-03-10 19:35:34 +090078import android.content.Intent;
Erik Kline8351faa2017-04-17 16:47:23 +090079import android.content.IntentFilter;
Erik Klinef3a08b42017-06-07 16:33:19 +090080import android.content.pm.ApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -070081import android.content.res.Resources;
Erik Klineea9cc482017-03-10 19:35:34 +090082import android.hardware.usb.UsbManager;
markchien3fe660b2019-12-05 12:04:59 +080083import android.net.ConnectivityManager;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +000084import android.net.EthernetManager;
85import android.net.EthernetManager.TetheredInterfaceRequest;
Automerger Merge Worker37a22752020-03-17 16:59:57 +000086import android.net.IIntResultListener;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090087import android.net.INetd;
markchienae8aa642019-12-16 20:15:20 +080088import android.net.ITetheringEventCallback;
markchien986750b2019-12-06 15:24:53 +080089import android.net.InetAddresses;
markchiena9d9ef82020-01-07 14:43:17 +080090import android.net.InterfaceConfigurationParcel;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090091import android.net.IpPrefix;
92import android.net.LinkAddress;
93import android.net.LinkProperties;
94import android.net.MacAddress;
95import android.net.Network;
96import android.net.NetworkCapabilities;
markchienae8aa642019-12-16 20:15:20 +080097import android.net.NetworkRequest;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +090098import android.net.RouteInfo;
markchien0f63ca62019-09-30 14:40:57 +080099import android.net.TetherStatesParcel;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900100import android.net.TetheredClient;
markchien40898ca2020-01-21 13:11:06 +0800101import android.net.TetheringCallbackStartedParcel;
markchien0f63ca62019-09-30 14:40:57 +0800102import android.net.TetheringConfigurationParcel;
markchiene8b9d752020-01-20 19:31:56 +0800103import android.net.TetheringRequestParcel;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900104import android.net.dhcp.DhcpServerCallbacks;
105import android.net.dhcp.DhcpServingParamsParcel;
106import android.net.dhcp.IDhcpServer;
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900107import android.net.ip.IpNeighborMonitor;
Erik Kline7a4ccc62018-08-27 17:26:47 +0900108import android.net.ip.IpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900109import android.net.ip.RouterAdvertisementDaemon;
110import android.net.util.InterfaceParams;
111import android.net.util.NetworkConstants;
Erik Klinef4b6e342017-04-25 19:19:59 +0900112import android.net.util.SharedLog;
lesl6b7551a2019-12-13 10:56:35 +0800113import android.net.wifi.SoftApConfiguration;
Erik Klineea9cc482017-03-10 19:35:34 +0900114import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800115import android.net.wifi.p2p.WifiP2pGroup;
116import android.net.wifi.p2p.WifiP2pInfo;
117import android.net.wifi.p2p.WifiP2pManager;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100118import android.os.Bundle;
Erik Klineea9cc482017-03-10 19:35:34 +0900119import android.os.Handler;
markchien0f63ca62019-09-30 14:40:57 +0800120import android.os.Looper;
Christopher Wiley497c1472016-10-11 13:26:03 -0700121import android.os.PersistableBundle;
Erik Kline1fdc2e22017-05-08 17:56:35 +0900122import android.os.RemoteException;
Erik Klineea9cc482017-03-10 19:35:34 +0900123import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100124import android.os.UserManager;
markchienb6eb2c22018-07-18 14:29:20 +0800125import android.os.test.TestLooper;
Erik Kline92c4db02017-05-31 10:21:32 +0900126import android.provider.Settings;
Christopher Wiley497c1472016-10-11 13:26:03 -0700127import android.telephony.CarrierConfigManager;
markchien04bdf872019-06-17 21:05:34 +0800128import android.telephony.PhoneStateListener;
129import android.telephony.TelephonyManager;
Erik Kline92c4db02017-05-31 10:21:32 +0900130import android.test.mock.MockContentResolver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700131
markchien0f63ca62019-09-30 14:40:57 +0800132import androidx.annotation.NonNull;
Brett Chabot1ae2aa62019-03-04 14:14:56 -0800133import androidx.test.filters.SmallTest;
134import androidx.test.runner.AndroidJUnit4;
135
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900136import com.android.internal.util.ArrayUtils;
137import com.android.internal.util.StateMachine;
Erik Klineea9cc482017-03-10 19:35:34 +0900138import com.android.internal.util.test.BroadcastInterceptingContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900139import com.android.internal.util.test.FakeSettingsProvider;
markchienfaa37282020-02-06 14:34:08 +0800140import com.android.testutils.MiscAssertsKt;
Erik Klineea9cc482017-03-10 19:35:34 +0900141
Erik Kline8351faa2017-04-17 16:47:23 +0900142import org.junit.After;
Mark Chien09ad80f2020-04-07 16:17:49 +0000143import org.junit.AfterClass;
Christopher Wiley497c1472016-10-11 13:26:03 -0700144import org.junit.Before;
Mark Chien09ad80f2020-04-07 16:17:49 +0000145import org.junit.BeforeClass;
Christopher Wiley497c1472016-10-11 13:26:03 -0700146import org.junit.Test;
147import org.junit.runner.RunWith;
markchien04bdf872019-06-17 21:05:34 +0800148import org.mockito.ArgumentCaptor;
Christopher Wiley497c1472016-10-11 13:26:03 -0700149import org.mockito.Mock;
150import org.mockito.MockitoAnnotations;
151
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900152import java.net.Inet4Address;
153import java.net.Inet6Address;
Erik Kline8351faa2017-04-17 16:47:23 +0900154import java.util.ArrayList;
markchien26299ed2019-02-27 14:56:11 +0800155import java.util.Arrays;
markchien3fe660b2019-12-05 12:04:59 +0800156import java.util.Collection;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900157import java.util.List;
Erik Kline8351faa2017-04-17 16:47:23 +0900158import java.util.Vector;
159
Christopher Wiley497c1472016-10-11 13:26:03 -0700160@RunWith(AndroidJUnit4.class)
161@SmallTest
162public class TetheringTest {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900163 private static final int IFINDEX_OFFSET = 100;
164
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900165 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
166 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
167 private static final String TEST_USB_IFNAME = "test_rndis0";
168 private static final String TEST_WLAN_IFNAME = "test_wlan0";
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800169 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
Milim Lee31ef4c02019-10-17 05:02:33 +0900170 private static final String TEST_NCM_IFNAME = "test_ncm0";
markchiena9d9ef82020-01-07 14:43:17 +0800171 private static final String TETHERING_NAME = "Tethering";
Christopher Wiley497c1472016-10-11 13:26:03 -0700172
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900173 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
174
Erik Klinef3a08b42017-06-07 16:33:19 +0900175 @Mock private ApplicationInfo mApplicationInfo;
Christopher Wiley497c1472016-10-11 13:26:03 -0700176 @Mock private Context mContext;
junyulaicaa81002019-12-11 11:03:01 +0800177 @Mock private NetworkStatsManager mStatsManager;
Erik Kline5a7c8a02017-04-30 19:36:15 +0900178 @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000179 @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats;
Christopher Wiley497c1472016-10-11 13:26:03 -0700180 @Mock private Resources mResources;
markchien04bdf872019-06-17 21:05:34 +0800181 @Mock private TelephonyManager mTelephonyManager;
Erik Klineea9cc482017-03-10 19:35:34 +0900182 @Mock private UsbManager mUsbManager;
183 @Mock private WifiManager mWifiManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700184 @Mock private CarrierConfigManager mCarrierConfigManager;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900185 @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
186 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
187 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900188 @Mock private IpNeighborMonitor mIpNeighborMonitor;
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900189 @Mock private IDhcpServer mDhcpServer;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900190 @Mock private INetd mNetd;
markchien1ddfba42019-11-27 21:20:33 +0800191 @Mock private UserManager mUserManager;
markchienae8aa642019-12-16 20:15:20 +0800192 @Mock private NetworkRequest mNetworkRequest;
markchien3fe660b2019-12-05 12:04:59 +0800193 @Mock private ConnectivityManager mCm;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000194 @Mock private EthernetManager mEm;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000195 @Mock private TetheringNotificationUpdater mNotificationUpdater;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900196
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900197 private final MockIpServerDependencies mIpServerDependencies =
198 spy(new MockIpServerDependencies());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900199 private final MockTetheringDependencies mTetheringDependencies =
200 new MockTetheringDependencies();
Christopher Wiley497c1472016-10-11 13:26:03 -0700201
202 // Like so many Android system APIs, these cannot be mocked because it is marked final.
203 // We have to use the real versions.
204 private final PersistableBundle mCarrierConfig = new PersistableBundle();
205 private final TestLooper mLooper = new TestLooper();
206
Erik Kline8351faa2017-04-17 16:47:23 +0900207 private Vector<Intent> mIntents;
Erik Klineea9cc482017-03-10 19:35:34 +0900208 private BroadcastInterceptingContext mServiceContext;
Erik Kline92c4db02017-05-31 10:21:32 +0900209 private MockContentResolver mContentResolver;
Erik Kline8351faa2017-04-17 16:47:23 +0900210 private BroadcastReceiver mBroadcastReceiver;
Christopher Wiley497c1472016-10-11 13:26:03 -0700211 private Tethering mTethering;
markchien04bdf872019-06-17 21:05:34 +0800212 private PhoneStateListener mPhoneStateListener;
markchiena9d9ef82020-01-07 14:43:17 +0800213 private InterfaceConfigurationParcel mInterfaceConfiguration;
Christopher Wiley497c1472016-10-11 13:26:03 -0700214
markchien0f63ca62019-09-30 14:40:57 +0800215 private class TestContext extends BroadcastInterceptingContext {
216 TestContext(Context base) {
Erik Klineea9cc482017-03-10 19:35:34 +0900217 super(base);
218 }
219
220 @Override
markchien0f63ca62019-09-30 14:40:57 +0800221 public ApplicationInfo getApplicationInfo() {
222 return mApplicationInfo;
223 }
Erik Klinef3a08b42017-06-07 16:33:19 +0900224
225 @Override
markchien0f63ca62019-09-30 14:40:57 +0800226 public ContentResolver getContentResolver() {
227 return mContentResolver;
228 }
Erik Kline92c4db02017-05-31 10:21:32 +0900229
230 @Override
markchien0f63ca62019-09-30 14:40:57 +0800231 public String getPackageName() {
232 return "TetheringTest";
233 }
Erik Kline92c4db02017-05-31 10:21:32 +0900234
235 @Override
markchien0f63ca62019-09-30 14:40:57 +0800236 public Resources getResources() {
237 return mResources;
238 }
Erik Klineea9cc482017-03-10 19:35:34 +0900239
240 @Override
241 public Object getSystemService(String name) {
Erik Klineea9cc482017-03-10 19:35:34 +0900242 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
Erik Klinec438e302017-07-04 22:02:49 +0900243 if (Context.USB_SERVICE.equals(name)) return mUsbManager;
markchien04bdf872019-06-17 21:05:34 +0800244 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
markchien1ddfba42019-11-27 21:20:33 +0800245 if (Context.USER_SERVICE.equals(name)) return mUserManager;
junyulaicaa81002019-12-11 11:03:01 +0800246 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
markchien3fe660b2019-12-05 12:04:59 +0800247 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000248 if (Context.ETHERNET_SERVICE.equals(name)) return mEm;
Erik Klineea9cc482017-03-10 19:35:34 +0900249 return super.getSystemService(name);
250 }
Jayachandran C43fa1be2019-11-15 09:58:04 -0800251
252 @Override
253 public String getSystemServiceName(Class<?> serviceClass) {
254 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
255 return super.getSystemServiceName(serviceClass);
256 }
Erik Klineea9cc482017-03-10 19:35:34 +0900257 }
258
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900259 public class MockIpServerDependencies extends IpServer.Dependencies {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900260 @Override
261 public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
262 InterfaceParams ifParams) {
263 return mRouterAdvertisementDaemon;
264 }
265
266 @Override
267 public InterfaceParams getInterfaceParams(String ifName) {
268 assertTrue("Non-mocked interface " + ifName,
269 ifName.equals(TEST_USB_IFNAME)
270 || ifName.equals(TEST_WLAN_IFNAME)
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800271 || ifName.equals(TEST_MOBILE_IFNAME)
Milim Lee31ef4c02019-10-17 05:02:33 +0900272 || ifName.equals(TEST_P2P_IFNAME)
273 || ifName.equals(TEST_NCM_IFNAME));
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900274 final String[] ifaces = new String[] {
Milim Lee31ef4c02019-10-17 05:02:33 +0900275 TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME,
276 TEST_NCM_IFNAME};
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900277 return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
278 MacAddress.ALL_ZEROS_ADDRESS);
279 }
280
281 @Override
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900282 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
283 DhcpServerCallbacks cb) {
284 new Thread(() -> {
285 try {
286 cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
287 } catch (RemoteException e) {
288 fail(e.getMessage());
289 }
290 }).run();
291 }
Lorenzo Colittifb19f492020-02-14 01:06:35 +0900292
293 public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l,
294 IpNeighborMonitor.NeighborEventConsumer c) {
295 return mIpNeighborMonitor;
296 }
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900297 }
298
markchien04bdf872019-06-17 21:05:34 +0800299 private class MockTetheringConfiguration extends TetheringConfiguration {
300 MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
301 super(ctx, log, id);
302 }
303
304 @Override
markchien2dfee022020-01-13 16:09:42 +0800305 protected boolean getDeviceConfigBoolean(final String name) {
306 return false;
307 }
308
309 @Override
markchien04bdf872019-06-17 21:05:34 +0800310 protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
311 return mResources;
312 }
313 }
314
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900315 public class MockTetheringDependencies extends TetheringDependencies {
markchien0f63ca62019-09-30 14:40:57 +0800316 StateMachine mUpstreamNetworkMonitorMasterSM;
317 ArrayList<IpServer> mIpv6CoordinatorNotifyList;
Erik Kline465ff3a2018-03-09 14:18:02 +0900318
319 public void reset() {
markchien0f63ca62019-09-30 14:40:57 +0800320 mUpstreamNetworkMonitorMasterSM = null;
321 mIpv6CoordinatorNotifyList = null;
Erik Kline465ff3a2018-03-09 14:18:02 +0900322 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900323
324 @Override
325 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
326 return mOffloadHardwareInterface;
327 }
328
329 @Override
330 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
331 StateMachine target, SharedLog log, int what) {
markchien0f63ca62019-09-30 14:40:57 +0800332 mUpstreamNetworkMonitorMasterSM = target;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900333 return mUpstreamNetworkMonitor;
334 }
335
336 @Override
337 public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
Erik Kline7a4ccc62018-08-27 17:26:47 +0900338 ArrayList<IpServer> notifyList, SharedLog log) {
markchien0f63ca62019-09-30 14:40:57 +0800339 mIpv6CoordinatorNotifyList = notifyList;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900340 return mIPv6TetheringCoordinator;
341 }
342
343 @Override
Remi NGUYEN VAN5db454c2019-02-14 18:04:20 +0900344 public IpServer.Dependencies getIpServerDependencies() {
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900345 return mIpServerDependencies;
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900346 }
Erik Kline465ff3a2018-03-09 14:18:02 +0900347
348 @Override
markchienae8aa642019-12-16 20:15:20 +0800349 public NetworkRequest getDefaultNetworkRequest() {
350 return mNetworkRequest;
351 }
352
353 @Override
Erik Kline465ff3a2018-03-09 14:18:02 +0900354 public boolean isTetheringSupported() {
Erik Kline465ff3a2018-03-09 14:18:02 +0900355 return true;
356 }
markchien0b595072019-01-08 23:52:21 +0800357
358 @Override
markchien04bdf872019-06-17 21:05:34 +0800359 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
360 int subId) {
361 return new MockTetheringConfiguration(ctx, log, subId);
markchien0b595072019-01-08 23:52:21 +0800362 }
markchien0f63ca62019-09-30 14:40:57 +0800363
364 @Override
markchien0f63ca62019-09-30 14:40:57 +0800365 public INetd getINetd(Context context) {
366 return mNetd;
367 }
368
369 @Override
370 public Looper getTetheringLooper() {
371 return mLooper.getLooper();
372 }
373
374 @Override
375 public Context getContext() {
376 return mServiceContext;
377 }
markchien3fe660b2019-12-05 12:04:59 +0800378
379 @Override
380 public BluetoothAdapter getBluetoothAdapter() {
381 // TODO: add test for bluetooth tethering.
382 return null;
383 }
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000384
385 @Override
Paul Hu77fa8d62020-04-16 02:54:37 +0000386 public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000387 return mNotificationUpdater;
388 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900389 }
390
markchienb0aca962019-12-05 16:21:17 +0800391 private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
392 boolean withIPv6, boolean with464xlat) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900393 final LinkProperties prop = new LinkProperties();
394 prop.setInterfaceName(TEST_MOBILE_IFNAME);
395
396 if (withIPv4) {
397 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800398 InetAddresses.parseNumericAddress("10.0.0.1"),
399 TEST_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900400 }
401
402 if (withIPv6) {
markchien986750b2019-12-06 15:24:53 +0800403 prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900404 prop.addLinkAddress(
markchien986750b2019-12-06 15:24:53 +0800405 new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900406 NetworkConstants.RFC7421_PREFIX_LENGTH));
407 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800408 InetAddresses.parseNumericAddress("2001:db8::1"),
409 TEST_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900410 }
411
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900412 if (with464xlat) {
413 final LinkProperties stackedLink = new LinkProperties();
414 stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME);
415 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
markchien986750b2019-12-06 15:24:53 +0800416 InetAddresses.parseNumericAddress("192.0.0.1"),
417 TEST_XLAT_MOBILE_IFNAME, RTN_UNICAST));
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900418
419 prop.addStackedLink(stackedLink);
420 }
421
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900422
423 final NetworkCapabilities capabilities = new NetworkCapabilities()
markchien0f63ca62019-09-30 14:40:57 +0800424 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
markchienb0aca962019-12-05 16:21:17 +0800425 return new UpstreamNetworkState(prop, capabilities, new Network(100));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900426 }
427
markchienb0aca962019-12-05 16:21:17 +0800428 private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900429 return buildMobileUpstreamState(true, false, false);
430 }
431
markchienb0aca962019-12-05 16:21:17 +0800432 private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900433 return buildMobileUpstreamState(false, true, false);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900434 }
435
markchienb0aca962019-12-05 16:21:17 +0800436 private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900437 return buildMobileUpstreamState(true, true, false);
438 }
439
markchienb0aca962019-12-05 16:21:17 +0800440 private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900441 return buildMobileUpstreamState(false, true, true);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900442 }
443
Mark Chien09ad80f2020-04-07 16:17:49 +0000444 // See FakeSettingsProvider#clearSettingsProvider() that this needs to be called before and
445 // after use.
446 @BeforeClass
447 public static void setupOnce() {
448 FakeSettingsProvider.clearSettingsProvider();
449 }
450
451 @AfterClass
452 public static void tearDownOnce() {
453 FakeSettingsProvider.clearSettingsProvider();
454 }
455
Erik Kline8351faa2017-04-17 16:47:23 +0900456 @Before
457 public void setUp() throws Exception {
Christopher Wiley497c1472016-10-11 13:26:03 -0700458 MockitoAnnotations.initMocks(this);
markchienda4519a2020-01-14 12:46:53 +0800459 when(mResources.getStringArray(R.array.config_tether_dhcp_range))
Christopher Wiley497c1472016-10-11 13:26:03 -0700460 .thenReturn(new String[0]);
markchienda4519a2020-01-14 12:46:53 +0800461 when(mResources.getStringArray(R.array.config_tether_usb_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900462 .thenReturn(new String[] { "test_rndis\\d" });
markchienda4519a2020-01-14 12:46:53 +0800463 when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900464 .thenReturn(new String[]{ "test_wlan\\d" });
markchienda4519a2020-01-14 12:46:53 +0800465 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800466 .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
markchienda4519a2020-01-14 12:46:53 +0800467 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
Christopher Wiley497c1472016-10-11 13:26:03 -0700468 .thenReturn(new String[0]);
Milim Lee31ef4c02019-10-17 05:02:33 +0900469 when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
470 .thenReturn(new String[] { "test_ncm\\d" });
markchienda4519a2020-01-14 12:46:53 +0800471 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
472 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false);
473 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
474 false);
markchiena9d9ef82020-01-07 14:43:17 +0800475 when(mNetd.interfaceGetList())
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900476 .thenReturn(new String[] {
Milim Lee31ef4c02019-10-17 05:02:33 +0900477 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME,
478 TEST_NCM_IFNAME});
markchienda4519a2020-01-14 12:46:53 +0800479 when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
markchiena9d9ef82020-01-07 14:43:17 +0800480 mInterfaceConfiguration = new InterfaceConfigurationParcel();
481 mInterfaceConfiguration.flags = new String[0];
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900482 when(mRouterAdvertisementDaemon.start())
483 .thenReturn(true);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000484 initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
485 0 /* defaultDisabled */);
486 when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
Erik Klineea9cc482017-03-10 19:35:34 +0900487
markchien0f63ca62019-09-30 14:40:57 +0800488 mServiceContext = new TestContext(mContext);
Erik Kline92c4db02017-05-31 10:21:32 +0900489 mContentResolver = new MockContentResolver(mServiceContext);
490 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Erik Kline8351faa2017-04-17 16:47:23 +0900491 mIntents = new Vector<>();
492 mBroadcastReceiver = new BroadcastReceiver() {
493 @Override
494 public void onReceive(Context context, Intent intent) {
495 mIntents.addElement(intent);
496 }
497 };
498 mServiceContext.registerReceiver(mBroadcastReceiver,
Erik Kline465ff3a2018-03-09 14:18:02 +0900499 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900500 mTethering = makeTethering();
Mark Chien674a0122020-03-27 09:37:01 +0000501 mTethering.startStateMachineUpdaters();
junyulaicaa81002019-12-11 11:03:01 +0800502 verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
markchien0f63ca62019-09-30 14:40:57 +0800503 verify(mNetd).registerUnsolicitedEventListener(any());
markchien04bdf872019-06-17 21:05:34 +0800504 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
505 ArgumentCaptor.forClass(PhoneStateListener.class);
506 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
507 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900508 verify(mWifiManager).registerSoftApCallback(any(), any());
markchien04bdf872019-06-17 21:05:34 +0800509 mPhoneStateListener = phoneListenerCaptor.getValue();
Christopher Wiley497c1472016-10-11 13:26:03 -0700510 }
511
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900512 private Tethering makeTethering() {
markchien0f63ca62019-09-30 14:40:57 +0800513 mTetheringDependencies.reset();
514 return new Tethering(mTetheringDependencies);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900515 }
516
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000517 private TetheringRequestParcel createTetheringRequestParcel(final int type) {
518 return createTetheringRequestParcel(type, null, null);
519 }
520
521 private TetheringRequestParcel createTetheringRequestParcel(final int type,
522 final LinkAddress serverAddr, final LinkAddress clientAddr) {
markchiene8b9d752020-01-20 19:31:56 +0800523 final TetheringRequestParcel request = new TetheringRequestParcel();
524 request.tetheringType = type;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000525 request.localIPv4Address = serverAddr;
526 request.staticClientAddress = clientAddr;
markchiene8b9d752020-01-20 19:31:56 +0800527 request.exemptFromEntitlementCheck = false;
528 request.showProvisioningUi = false;
529
530 return request;
531 }
532
Erik Kline8351faa2017-04-17 16:47:23 +0900533 @After
534 public void tearDown() {
535 mServiceContext.unregisterReceiver(mBroadcastReceiver);
536 }
537
Erik Klineea9cc482017-03-10 19:35:34 +0900538 private void sendWifiApStateChanged(int state) {
539 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Erik Kline2efb8272017-05-31 15:53:53 +0900540 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
Erik Klineea9cc482017-03-10 19:35:34 +0900541 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
542 }
543
Erik Kline2efb8272017-05-31 15:53:53 +0900544 private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
545 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
546 intent.putExtra(EXTRA_WIFI_AP_STATE, state);
547 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
548 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
549 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
550 }
551
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800552 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
553 android.Manifest.permission.ACCESS_FINE_LOCATION,
554 android.Manifest.permission.ACCESS_WIFI_STATE
555 };
556
557 private void sendWifiP2pConnectionChanged(
558 boolean isGroupFormed, boolean isGroupOwner, String ifname) {
Jimmy Chen151384d2019-12-03 11:37:09 +0800559 WifiP2pGroup group = null;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800560 WifiP2pInfo p2pInfo = new WifiP2pInfo();
561 p2pInfo.groupFormed = isGroupFormed;
Jimmy Chen151384d2019-12-03 11:37:09 +0800562 if (isGroupFormed) {
563 p2pInfo.isGroupOwner = isGroupOwner;
564 group = mock(WifiP2pGroup.class);
565 when(group.isGroupOwner()).thenReturn(isGroupOwner);
566 when(group.getInterface()).thenReturn(ifname);
567 }
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800568
David Su798a92b2020-01-13 12:49:21 -0800569 final Intent intent = mock(Intent.class);
570 when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
571 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo);
572 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group);
573
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800574 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
575 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
576 }
577
Milim Lee31ef4c02019-10-17 05:02:33 +0900578 private void sendUsbBroadcast(boolean connected, boolean configured, boolean function,
579 int type) {
Erik Klinec438e302017-07-04 22:02:49 +0900580 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
581 intent.putExtra(USB_CONNECTED, connected);
582 intent.putExtra(USB_CONFIGURED, configured);
Milim Lee31ef4c02019-10-17 05:02:33 +0900583 if (type == TETHERING_USB) {
584 intent.putExtra(USB_FUNCTION_RNDIS, function);
585 } else {
586 intent.putExtra(USB_FUNCTION_NCM, function);
587 }
Erik Klinec438e302017-07-04 22:02:49 +0900588 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
589 }
590
Erik Kline80b7a9f2018-02-28 15:01:35 +0900591 private void sendConfigurationChanged() {
592 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
593 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
594 }
595
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800596 private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
markchiena9d9ef82020-01-07 14:43:17 +0800597 verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
598 verify(mNetd, times(1)).tetherInterfaceAdd(ifname);
599 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
600 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
601 anyString(), anyString());
Erik Kline8351faa2017-04-17 16:47:23 +0900602 }
603
604 private void verifyTetheringBroadcast(String ifname, String whichExtra) {
605 // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
606 final Intent bcast = mIntents.get(0);
Erik Kline465ff3a2018-03-09 14:18:02 +0900607 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
Erik Kline8351faa2017-04-17 16:47:23 +0900608 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
609 assertTrue(ifnames.contains(ifname));
610 mIntents.remove(bcast);
611 }
612
Erik Klinea9cde8b2017-06-20 21:18:31 +0900613 public void failingLocalOnlyHotspotLegacyApBroadcast(
614 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Klineea9cc482017-03-10 19:35:34 +0900615 // Emulate externally-visible WifiManager effects, causing the
616 // per-interface state machine to start up, and telling us that
617 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900618 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900619 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900620 }
Erik Kline9e225542017-06-08 17:48:48 +0900621 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900622 mLooper.dispatchAll();
623
Erik Kline7a4ccc62018-08-27 17:26:47 +0900624 // If, and only if, Tethering received an interface status changed then
625 // it creates a IpServer and sends out a broadcast indicating that the
626 // interface is "available".
Erik Klinea9cde8b2017-06-20 21:18:31 +0900627 if (emulateInterfaceStatusChanged) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000628 // There is 1 IpServer state change event: STATE_AVAILABLE
629 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Kline465ff3a2018-03-09 14:18:02 +0900630 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900631 verify(mWifiManager).updateInterfaceIpState(
632 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900633 }
markchiena9d9ef82020-01-07 14:43:17 +0800634 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900635 verifyNoMoreInteractions(mWifiManager);
636 }
637
Milim Lee31ef4c02019-10-17 05:02:33 +0900638 private void prepareNcmTethering() {
639 // Emulate startTethering(TETHERING_NCM) called
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000640 mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
Milim Lee31ef4c02019-10-17 05:02:33 +0900641 mLooper.dispatchAll();
642 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
643
644 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
645 }
646
markchienb0aca962019-12-05 16:21:17 +0800647 private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
Erik Kline72302902018-06-14 17:36:40 +0900648 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900649 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
650 .thenReturn(upstreamState);
Erik Klinec438e302017-07-04 22:02:49 +0900651
652 // Emulate pressing the USB tethering button in Settings UI.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000653 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
Erik Klinec438e302017-07-04 22:02:49 +0900654 mLooper.dispatchAll();
Jerry Zhang327b8092018-01-09 17:53:04 -0800655 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
Erik Klinec438e302017-07-04 22:02:49 +0900656
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900657 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
658 }
659
660 @Test
661 public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800662 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900663 prepareUsbTethering(upstreamState);
664
Erik Klinec438e302017-07-04 22:02:49 +0900665 // This should produce no activity of any kind.
markchiena9d9ef82020-01-07 14:43:17 +0800666 verifyNoMoreInteractions(mNetd);
Erik Klinec438e302017-07-04 22:02:49 +0900667
668 // Pretend we then receive USB configured broadcast.
Milim Lee31ef4c02019-10-17 05:02:33 +0900669 sendUsbBroadcast(true, true, true, TETHERING_USB);
Erik Klinec438e302017-07-04 22:02:49 +0900670 mLooper.dispatchAll();
671 // Now we should see the start of tethering mechanics (in this case:
672 // tetherMatchingInterfaces() which starts by fetching all interfaces).
markchiena9d9ef82020-01-07 14:43:17 +0800673 verify(mNetd, times(1)).interfaceGetList();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900674
675 // UpstreamNetworkMonitor should receive selected upstream
676 verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
677 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
Erik Klinec438e302017-07-04 22:02:49 +0900678 }
679
680 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900681 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
682 failingLocalOnlyHotspotLegacyApBroadcast(true);
683 }
684
685 @Test
686 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
687 failingLocalOnlyHotspotLegacyApBroadcast(false);
688 }
689
690 public void workingLocalOnlyHotspotEnrichedApBroadcast(
691 boolean emulateInterfaceStatusChanged) throws Exception {
Erik Kline9e225542017-06-08 17:48:48 +0900692 // Emulate externally-visible WifiManager effects, causing the
693 // per-interface state machine to start up, and telling us that
694 // hotspot mode is to be started.
Erik Klinea9cde8b2017-06-20 21:18:31 +0900695 if (emulateInterfaceStatusChanged) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900696 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Klinea9cde8b2017-06-20 21:18:31 +0900697 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900698 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline9e225542017-06-08 17:48:48 +0900699 mLooper.dispatchAll();
700
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800701 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900702 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +0800703 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
704 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
705 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +0900706 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900707 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
708 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900709 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +0900710 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900711 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
markchiena6c72872018-11-13 18:34:56 +0900712 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000713 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
714 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Klineea9cc482017-03-10 19:35:34 +0900715
716 // Emulate externally-visible WifiManager effects, when hotspot mode
717 // is being torn down.
718 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900719 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +0900720 mLooper.dispatchAll();
721
markchiena9d9ef82020-01-07 14:43:17 +0800722 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
723 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
724 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
725 // interfaceSetCfg() called once for enabling and twice disabling IPv4.
726 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
727 verify(mNetd, times(1)).tetherStop();
728 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900729 verify(mWifiManager, times(3)).updateInterfaceIpState(
730 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +0800731 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +0900732 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +0900733 // Asking for the last error after the per-interface state machine
734 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +0900735 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +0900736 }
737
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900738 /**
Erik Kline7a4ccc62018-08-27 17:26:47 +0900739 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900740 */
markchienb0aca962019-12-05 16:21:17 +0800741 private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900742 // IPv6TetheringCoordinator must have been notified of downstream
743 verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream(
744 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)),
Erik Kline7a4ccc62018-08-27 17:26:47 +0900745 eq(IpServer.STATE_TETHERED));
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900746
markchien0f63ca62019-09-30 14:40:57 +0800747 for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
markchienb0aca962019-12-05 16:21:17 +0800748 UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900749 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
paulhud9736de2019-03-08 16:35:20 +0800750 upstreamState.linkProperties.isIpv6Provisioned()
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900751 ? ipv6OnlyState.linkProperties
752 : null);
753 }
754 mLooper.dispatchAll();
755 }
756
markchienb0aca962019-12-05 16:21:17 +0800757 private void runUsbTethering(UpstreamNetworkState upstreamState) {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900758 prepareUsbTethering(upstreamState);
Milim Lee31ef4c02019-10-17 05:02:33 +0900759 sendUsbBroadcast(true, true, true, TETHERING_USB);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900760 mLooper.dispatchAll();
761 }
762
763 @Test
764 public void workingMobileUsbTethering_IPv4() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800765 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900766 runUsbTethering(upstreamState);
767
markchiena9d9ef82020-01-07 14:43:17 +0800768 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
769 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900770
771 sendIPv6TetherUpdates(upstreamState);
772 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900773 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
774 any(), any());
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900775 }
776
777 @Test
778 public void workingMobileUsbTethering_IPv4LegacyDhcp() {
markchienda4519a2020-01-14 12:46:53 +0800779 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
780 true);
markchien0f63ca62019-09-30 14:40:57 +0800781 sendConfigurationChanged();
markchienb0aca962019-12-05 16:21:17 +0800782 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900783 runUsbTethering(upstreamState);
784 sendIPv6TetherUpdates(upstreamState);
785
Remi NGUYEN VAN0e3d09232018-12-04 12:13:09 +0900786 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900787 }
788
789 @Test
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900790 public void workingMobileUsbTethering_IPv6() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800791 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900792 runUsbTethering(upstreamState);
793
markchiena9d9ef82020-01-07 14:43:17 +0800794 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
795 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900796
797 sendIPv6TetherUpdates(upstreamState);
798 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
799 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
800 }
801
802 @Test
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900803 public void workingMobileUsbTethering_DualStack() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800804 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900805 runUsbTethering(upstreamState);
806
markchiena9d9ef82020-01-07 14:43:17 +0800807 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
808 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900809 verify(mRouterAdvertisementDaemon, times(1)).start();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900810 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
811 any(), any());
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900812
813 sendIPv6TetherUpdates(upstreamState);
814 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
815 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
816 }
817
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900818 @Test
819 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
markchienb0aca962019-12-05 16:21:17 +0800820 UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900821 runUsbTethering(upstreamState);
822
markchiena9d9ef82020-01-07 14:43:17 +0800823 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
824 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900825 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
826 any(), any());
markchiena9d9ef82020-01-07 14:43:17 +0800827 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
828 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900829
830 sendIPv6TetherUpdates(upstreamState);
831 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
832 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
833 }
834
835 @Test
836 public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
837 // Setup IPv6
markchienb0aca962019-12-05 16:21:17 +0800838 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900839 runUsbTethering(upstreamState);
840
markchiena9d9ef82020-01-07 14:43:17 +0800841 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900842 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
843 any(), any());
markchiena9d9ef82020-01-07 14:43:17 +0800844 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900845
846 // Then 464xlat comes up
847 upstreamState = buildMobile464xlatUpstreamState();
848 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
849 .thenReturn(upstreamState);
850
851 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
markchien0f63ca62019-09-30 14:40:57 +0800852 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900853 Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
854 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
855 0,
856 upstreamState);
857 mLooper.dispatchAll();
858
859 // Forwarding is added for 464xlat
markchiena9d9ef82020-01-07 14:43:17 +0800860 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
861 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900862 // Forwarding was not re-added for v6 (still times(1))
markchiena9d9ef82020-01-07 14:43:17 +0800863 verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
864 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
Remi NGUYEN VANf5581f82018-09-28 11:34:15 +0900865 // DHCP not restarted on downstream (still times(1))
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900866 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
867 any(), any());
Remi NGUYEN VAN25a7e4f2018-03-09 14:07:18 +0900868 }
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900869
Erik Klineea9cc482017-03-10 19:35:34 +0900870 @Test
Erik Kline72302902018-06-14 17:36:40 +0900871 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
markchienda4519a2020-01-14 12:46:53 +0800872 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
Erik Kline72302902018-06-14 17:36:40 +0900873 sendConfigurationChanged();
874
875 // Setup IPv6
markchienb0aca962019-12-05 16:21:17 +0800876 final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
Erik Kline72302902018-06-14 17:36:40 +0900877 runUsbTethering(upstreamState);
878
879 // UpstreamNetworkMonitor should choose upstream automatically
880 // (in this specific case: choose the default network).
881 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
882 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
883
884 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
885 }
886
Milim Lee31ef4c02019-10-17 05:02:33 +0900887 private void runNcmTethering() {
888 prepareNcmTethering();
889 sendUsbBroadcast(true, true, true, TETHERING_NCM);
890 mLooper.dispatchAll();
891 }
892
893 @Test
894 public void workingNcmTethering() throws Exception {
895 runNcmTethering();
896
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900897 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
898 any(), any());
Milim Lee31ef4c02019-10-17 05:02:33 +0900899 }
900
901 @Test
902 public void workingNcmTethering_LegacyDhcp() {
903 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
904 true);
905 sendConfigurationChanged();
906 runNcmTethering();
907
908 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
909 }
910
Erik Kline72302902018-06-14 17:36:40 +0900911 @Test
Erik Klinea9cde8b2017-06-20 21:18:31 +0900912 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
913 workingLocalOnlyHotspotEnrichedApBroadcast(true);
914 }
915
916 @Test
917 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
918 workingLocalOnlyHotspotEnrichedApBroadcast(false);
919 }
920
921 // TODO: Test with and without interfaceStatusChanged().
922 @Test
Erik Kline9e225542017-06-08 17:48:48 +0900923 public void failingWifiTetheringLegacyApBroadcast() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +0800924 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
Erik Klineea9cc482017-03-10 19:35:34 +0900925
926 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000927 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Klineea9cc482017-03-10 19:35:34 +0900928 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +0800929 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Klineea9cc482017-03-10 19:35:34 +0900930 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +0800931 verifyNoMoreInteractions(mNetd);
Erik Klineea9cc482017-03-10 19:35:34 +0900932
933 // Emulate externally-visible WifiManager effects, causing the
934 // per-interface state machine to start up, and telling us that
935 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900936 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
Erik Kline9e225542017-06-08 17:48:48 +0900937 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
Erik Klineea9cc482017-03-10 19:35:34 +0900938 mLooper.dispatchAll();
939
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000940 // There is 1 IpServer state change event: STATE_AVAILABLE
941 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
Erik Kline465ff3a2018-03-09 14:18:02 +0900942 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Jianpeng Lia70feec2019-05-24 17:40:15 +0900943 verify(mWifiManager).updateInterfaceIpState(
944 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +0800945 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900946 verifyNoMoreInteractions(mWifiManager);
947 }
948
Erik Klinea9cde8b2017-06-20 21:18:31 +0900949 // TODO: Test with and without interfaceStatusChanged().
Erik Kline9e225542017-06-08 17:48:48 +0900950 @Test
951 public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +0800952 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
Erik Kline9e225542017-06-08 17:48:48 +0900953
954 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000955 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Kline9e225542017-06-08 17:48:48 +0900956 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +0800957 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Kline9e225542017-06-08 17:48:48 +0900958 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +0800959 verifyNoMoreInteractions(mNetd);
Erik Kline9e225542017-06-08 17:48:48 +0900960
961 // Emulate externally-visible WifiManager effects, causing the
962 // per-interface state machine to start up, and telling us that
963 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900964 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
965 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline9e225542017-06-08 17:48:48 +0900966 mLooper.dispatchAll();
967
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800968 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
Erik Kline465ff3a2018-03-09 14:18:02 +0900969 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +0800970 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
971 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
972 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
973 anyString(), anyString());
974 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +0900975 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +0900976 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
977 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900978 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +0900979 verifyNoMoreInteractions(mWifiManager);
Erik Kline465ff3a2018-03-09 14:18:02 +0900980 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
markchiena6c72872018-11-13 18:34:56 +0900981 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Erik Klineea9cc482017-03-10 19:35:34 +0900982 // In tethering mode, in the default configuration, an explicit request
983 // for a mobile network is also made.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +0900984 verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000985 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED
986 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
987 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
Erik Klineea9cc482017-03-10 19:35:34 +0900988
989 /////
990 // We do not currently emulate any upstream being found.
991 //
markchiena9d9ef82020-01-07 14:43:17 +0800992 // This is why there are no calls to verify mNetd.tetherAddForward() or
993 // mNetd.ipfwdAddInterfaceForward().
Erik Klineea9cc482017-03-10 19:35:34 +0900994 /////
995
996 // Emulate pressing the WiFi tethering button.
Erik Klinec438e302017-07-04 22:02:49 +0900997 mTethering.stopTethering(TETHERING_WIFI);
Erik Klineea9cc482017-03-10 19:35:34 +0900998 mLooper.dispatchAll();
Erik Klineceb54c62017-04-18 14:22:25 +0900999 verify(mWifiManager, times(1)).stopSoftAp();
Erik Klineea9cc482017-03-10 19:35:34 +09001000 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001001 verifyNoMoreInteractions(mNetd);
Erik Klineea9cc482017-03-10 19:35:34 +09001002
1003 // Emulate externally-visible WifiManager effects, when tethering mode
1004 // is being torn down.
1005 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001006 mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
Erik Klineea9cc482017-03-10 19:35:34 +09001007 mLooper.dispatchAll();
1008
markchiena9d9ef82020-01-07 14:43:17 +08001009 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1010 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1011 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1012 // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
1013 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1014 verify(mNetd, times(1)).tetherStop();
1015 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jianpeng Lia70feec2019-05-24 17:40:15 +09001016 verify(mWifiManager, times(3)).updateInterfaceIpState(
1017 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
markchiena9d9ef82020-01-07 14:43:17 +08001018 verifyNoMoreInteractions(mNetd);
Erik Kline216af6d2017-04-27 20:57:23 +09001019 verifyNoMoreInteractions(mWifiManager);
Erik Klineea9cc482017-03-10 19:35:34 +09001020 // Asking for the last error after the per-interface state machine
1021 // has been reaped yields an unknown interface error.
Erik Kline465ff3a2018-03-09 14:18:02 +09001022 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME));
Erik Klineea9cc482017-03-10 19:35:34 +09001023 }
1024
Erik Klinea9cde8b2017-06-20 21:18:31 +09001025 // TODO: Test with and without interfaceStatusChanged().
Erik Kline1fdc2e22017-05-08 17:56:35 +09001026 @Test
1027 public void failureEnablingIpForwarding() throws Exception {
lesl6b7551a2019-12-13 10:56:35 +08001028 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
markchiena9d9ef82020-01-07 14:43:17 +08001029 doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001030
1031 // Emulate pressing the WiFi tethering button.
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001032 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001033 mLooper.dispatchAll();
lesl6b7551a2019-12-13 10:56:35 +08001034 verify(mWifiManager, times(1)).startTetheredHotspot(null);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001035 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001036 verifyNoMoreInteractions(mNetd);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001037
1038 // Emulate externally-visible WifiManager effects, causing the
1039 // per-interface state machine to start up, and telling us that
1040 // tethering mode is to be started.
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001041 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1042 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001043 mLooper.dispatchAll();
1044
markchiena9d9ef82020-01-07 14:43:17 +08001045 // We verify get/set called three times here: twice for setup and once during
1046 // teardown because all events happen over the course of the single
Erik Kline7a4ccc62018-08-27 17:26:47 +09001047 // dispatchAll() above. Note that once the IpServer IPv4 address config
Erik Kline472276a2018-05-18 16:09:24 +09001048 // code is refactored the two calls during shutdown will revert to one.
markchiena9d9ef82020-01-07 14:43:17 +08001049 verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
1050 verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
1051 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1052 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
1053 anyString(), anyString());
Erik Kline1fdc2e22017-05-08 17:56:35 +09001054 verify(mWifiManager).updateInterfaceIpState(
Jianpeng Lia70feec2019-05-24 17:40:15 +09001055 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1056 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001057 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +00001058 // There are 3 IpServer state change event:
1059 // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
1060 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
1061 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
Erik Kline465ff3a2018-03-09 14:18:02 +09001062 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001063 // This is called, but will throw.
markchiena9d9ef82020-01-07 14:43:17 +08001064 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001065 // This never gets called because of the exception thrown above.
markchiena9d9ef82020-01-07 14:43:17 +08001066 verify(mNetd, times(0)).tetherStartWithConfiguration(any());
Erik Kline1fdc2e22017-05-08 17:56:35 +09001067 // When the master state machine transitions to an error state it tells
1068 // downstream interfaces, which causes us to tell Wi-Fi about the error
1069 // so it can take down AP mode.
markchiena9d9ef82020-01-07 14:43:17 +08001070 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1071 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1072 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001073 verify(mWifiManager).updateInterfaceIpState(
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001074 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001075
1076 verifyNoMoreInteractions(mWifiManager);
markchiena9d9ef82020-01-07 14:43:17 +08001077 verifyNoMoreInteractions(mNetd);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001078 }
1079
markchien1ddfba42019-11-27 21:20:33 +08001080 private void runUserRestrictionsChange(
markchien0f63ca62019-09-30 14:40:57 +08001081 boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
1082 int expectedInteractionsWithShowNotification) throws Exception {
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001083 final Bundle newRestrictions = new Bundle();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001084 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
markchien1ddfba42019-11-27 21:20:33 +08001085 final Tethering mockTethering = mock(Tethering.class);
1086 when(mockTethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
1087 when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001088
markchien1ddfba42019-11-27 21:20:33 +08001089 final Tethering.UserRestrictionActionListener ural =
Paul Huf950dc92020-03-25 12:39:13 +00001090 new Tethering.UserRestrictionActionListener(
1091 mUserManager, mockTethering, mNotificationUpdater);
markchien1ddfba42019-11-27 21:20:33 +08001092 ural.mDisallowTethering = currentDisallow;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001093
markchien1ddfba42019-11-27 21:20:33 +08001094 ural.onUserRestrictionsChanged();
1095
Paul Huf950dc92020-03-25 12:39:13 +00001096 verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
1097 .notifyTetheringDisabledByRestriction();
1098 verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001099 }
1100
1101 @Test
1102 public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
1103 final String[] emptyActiveIfacesList = new String[]{};
1104 final boolean currDisallow = false;
1105 final boolean nextDisallow = true;
Paul Huf950dc92020-03-25 12:39:13 +00001106 final int expectedInteractionsWithShowNotification = 1;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001107
markchien1ddfba42019-11-27 21:20:33 +08001108 runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001109 expectedInteractionsWithShowNotification);
1110 }
1111
1112 @Test
1113 public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001114 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001115 final boolean currDisallow = false;
1116 final boolean nextDisallow = true;
1117 final int expectedInteractionsWithShowNotification = 1;
1118
markchien1ddfba42019-11-27 21:20:33 +08001119 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001120 expectedInteractionsWithShowNotification);
1121 }
1122
1123 @Test
1124 public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
1125 final String[] nonEmptyActiveIfacesList = new String[]{};
1126 final boolean currDisallow = true;
1127 final boolean nextDisallow = false;
1128 final int expectedInteractionsWithShowNotification = 0;
1129
markchien1ddfba42019-11-27 21:20:33 +08001130 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001131 expectedInteractionsWithShowNotification);
1132 }
1133
1134 @Test
1135 public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001136 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001137 final boolean currDisallow = true;
1138 final boolean nextDisallow = false;
1139 final int expectedInteractionsWithShowNotification = 0;
1140
markchien1ddfba42019-11-27 21:20:33 +08001141 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001142 expectedInteractionsWithShowNotification);
1143 }
1144
1145 @Test
1146 public void testDisallowTetheringUnchanged() throws Exception {
Remi NGUYEN VANa911e842018-03-15 11:57:14 +09001147 final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001148 final int expectedInteractionsWithShowNotification = 0;
1149 boolean currDisallow = true;
1150 boolean nextDisallow = true;
1151
markchien1ddfba42019-11-27 21:20:33 +08001152 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001153 expectedInteractionsWithShowNotification);
1154
1155 currDisallow = false;
1156 nextDisallow = false;
1157
markchien1ddfba42019-11-27 21:20:33 +08001158 runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001159 expectedInteractionsWithShowNotification);
1160 }
1161
markchienae8aa642019-12-16 20:15:20 +08001162 private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
markchien26299ed2019-02-27 14:56:11 +08001163 private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
markchien0f63ca62019-09-30 14:40:57 +08001164 private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
1165 new ArrayList<>();
1166 private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001167 private final ArrayList<Integer> mOffloadStatus = new ArrayList<>();
markchien26299ed2019-02-27 14:56:11 +08001168
markchien0f63ca62019-09-30 14:40:57 +08001169 // This function will remove the recorded callbacks, so it must be called once for
1170 // each callback. If this is called after multiple callback, the order matters.
1171 // onCallbackCreated counts as the first call to expectUpstreamChanged with
1172 // @see onCallbackCreated.
markchien26299ed2019-02-27 14:56:11 +08001173 public void expectUpstreamChanged(Network... networks) {
markchien0f63ca62019-09-30 14:40:57 +08001174 if (networks == null) {
1175 assertNoUpstreamChangeCallback();
1176 return;
1177 }
1178
markchien26299ed2019-02-27 14:56:11 +08001179 final ArrayList<Network> expectedUpstreams =
1180 new ArrayList<Network>(Arrays.asList(networks));
1181 for (Network upstream : expectedUpstreams) {
1182 // throws OOB if no expectations
1183 assertEquals(mActualUpstreams.remove(0), upstream);
1184 }
markchien0f63ca62019-09-30 14:40:57 +08001185 assertNoUpstreamChangeCallback();
1186 }
1187
1188 // This function will remove the recorded callbacks, so it must be called once
1189 // for each callback. If this is called after multiple callback, the order matters.
1190 // onCallbackCreated counts as the first call to onConfigurationChanged with
1191 // @see onCallbackCreated.
1192 public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
1193 final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
1194 new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
1195 for (TetheringConfigurationParcel config : expectedTetherConfig) {
1196 // throws OOB if no expectations
1197 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
1198 assertTetherConfigParcelEqual(actualConfig, config);
1199 }
1200 assertNoConfigChangeCallback();
1201 }
1202
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001203 public void expectOffloadStatusChanged(final int expectedStatus) {
1204 assertOffloadStatusChangedCallback();
1205 assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus));
1206 }
1207
markchien0f63ca62019-09-30 14:40:57 +08001208 public TetherStatesParcel pollTetherStatesChanged() {
1209 assertStateChangeCallback();
1210 return mTetherStates.remove(0);
markchien26299ed2019-02-27 14:56:11 +08001211 }
1212
1213 @Override
1214 public void onUpstreamChanged(Network network) {
1215 mActualUpstreams.add(network);
1216 }
1217
markchien0f63ca62019-09-30 14:40:57 +08001218 @Override
1219 public void onConfigurationChanged(TetheringConfigurationParcel config) {
1220 mTetheringConfigs.add(config);
1221 }
1222
1223 @Override
1224 public void onTetherStatesChanged(TetherStatesParcel states) {
1225 mTetherStates.add(states);
1226 }
1227
1228 @Override
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09001229 public void onTetherClientsChanged(List<TetheredClient> clients) {
1230 // TODO: check this
1231 }
1232
1233 @Override
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001234 public void onOffloadStatusChanged(final int status) {
1235 mOffloadStatus.add(status);
1236 }
1237
1238 @Override
markchien40898ca2020-01-21 13:11:06 +08001239 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
1240 mActualUpstreams.add(parcel.upstreamNetwork);
1241 mTetheringConfigs.add(parcel.config);
1242 mTetherStates.add(parcel.states);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001243 mOffloadStatus.add(parcel.offloadStatus);
markchien0f63ca62019-09-30 14:40:57 +08001244 }
1245
markchienae8aa642019-12-16 20:15:20 +08001246 @Override
1247 public void onCallbackStopped(int errorCode) { }
1248
markchien0f63ca62019-09-30 14:40:57 +08001249 public void assertNoUpstreamChangeCallback() {
markchien26299ed2019-02-27 14:56:11 +08001250 assertTrue(mActualUpstreams.isEmpty());
1251 }
markchien0f63ca62019-09-30 14:40:57 +08001252
1253 public void assertNoConfigChangeCallback() {
1254 assertTrue(mTetheringConfigs.isEmpty());
1255 }
1256
markchienae8aa642019-12-16 20:15:20 +08001257 public void assertNoStateChangeCallback() {
1258 assertTrue(mTetherStates.isEmpty());
1259 }
1260
markchien0f63ca62019-09-30 14:40:57 +08001261 public void assertStateChangeCallback() {
1262 assertFalse(mTetherStates.isEmpty());
1263 }
1264
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001265 public void assertOffloadStatusChangedCallback() {
1266 assertFalse(mOffloadStatus.isEmpty());
1267 }
1268
markchienae8aa642019-12-16 20:15:20 +08001269 public void assertNoCallback() {
1270 assertNoUpstreamChangeCallback();
1271 assertNoConfigChangeCallback();
1272 assertNoStateChangeCallback();
1273 }
1274
markchien0f63ca62019-09-30 14:40:57 +08001275 private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
1276 @NonNull TetheringConfigurationParcel expect) {
1277 assertEquals(actual.subId, expect.subId);
1278 assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
1279 assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
1280 assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
1281 assertEquals(actual.isDunRequired, expect.isDunRequired);
1282 assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
1283 assertArrayEquals(actual.preferredUpstreamIfaceTypes,
1284 expect.preferredUpstreamIfaceTypes);
1285 assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
1286 assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
1287 assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
1288 assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
1289 assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
1290 assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
1291 }
markchien26299ed2019-02-27 14:56:11 +08001292 }
1293
markchienfaa37282020-02-06 14:34:08 +08001294 private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) {
1295 assertFalse(parcel == null);
1296 assertEquals(0, parcel.availableList.length);
1297 assertEquals(0, parcel.tetheredList.length);
1298 assertEquals(0, parcel.localOnlyList.length);
1299 assertEquals(0, parcel.erroredIfaceList.length);
1300 assertEquals(0, parcel.lastErrorList.length);
1301 MiscAssertsKt.assertFieldCountEquals(5, TetherStatesParcel.class);
1302 }
1303
markchien26299ed2019-02-27 14:56:11 +08001304 @Test
markchienae8aa642019-12-16 20:15:20 +08001305 public void testRegisterTetheringEventCallback() throws Exception {
1306 TestTetheringEventCallback callback = new TestTetheringEventCallback();
1307 TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
markchien26299ed2019-02-27 14:56:11 +08001308
markchien0f63ca62019-09-30 14:40:57 +08001309 // 1. Register one callback before running any tethering.
markchienae8aa642019-12-16 20:15:20 +08001310 mTethering.registerTetheringEventCallback(callback);
markchien26299ed2019-02-27 14:56:11 +08001311 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001312 callback.expectUpstreamChanged(new Network[] {null});
1313 callback.expectConfigurationChanged(
1314 mTethering.getTetheringConfiguration().toStableParcelable());
1315 TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
markchienfaa37282020-02-06 14:34:08 +08001316 assertTetherStatesNotNullButEmpty(tetherState);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001317 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
markchienae8aa642019-12-16 20:15:20 +08001318 // 2. Enable wifi tethering.
markchienb0aca962019-12-05 16:21:17 +08001319 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
markchien26299ed2019-02-27 14:56:11 +08001320 when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
1321 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
1322 .thenReturn(upstreamState);
lesl6b7551a2019-12-13 10:56:35 +08001323 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
markchien26299ed2019-02-27 14:56:11 +08001324 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
markchien0f63ca62019-09-30 14:40:57 +08001325 mLooper.dispatchAll();
1326 tetherState = callback.pollTetherStatesChanged();
1327 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1328
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001329 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
markchien26299ed2019-02-27 14:56:11 +08001330 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1331 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001332 tetherState = callback.pollTetherStatesChanged();
1333 assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
1334 callback.expectUpstreamChanged(upstreamState.network);
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001335 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
markchien0f63ca62019-09-30 14:40:57 +08001336
markchienae8aa642019-12-16 20:15:20 +08001337 // 3. Register second callback.
1338 mTethering.registerTetheringEventCallback(callback2);
1339 mLooper.dispatchAll();
1340 callback2.expectUpstreamChanged(upstreamState.network);
1341 callback2.expectConfigurationChanged(
1342 mTethering.getTetheringConfiguration().toStableParcelable());
1343 tetherState = callback2.pollTetherStatesChanged();
1344 assertEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME});
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001345 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
markchienae8aa642019-12-16 20:15:20 +08001346
1347 // 4. Unregister first callback and disable wifi tethering
1348 mTethering.unregisterTetheringEventCallback(callback);
1349 mLooper.dispatchAll();
markchien0f63ca62019-09-30 14:40:57 +08001350 mTethering.stopTethering(TETHERING_WIFI);
1351 sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED);
1352 mLooper.dispatchAll();
markchienae8aa642019-12-16 20:15:20 +08001353 tetherState = callback2.pollTetherStatesChanged();
markchien0f63ca62019-09-30 14:40:57 +08001354 assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
1355 mLooper.dispatchAll();
markchienae8aa642019-12-16 20:15:20 +08001356 callback2.expectUpstreamChanged(new Network[] {null});
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001357 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
markchienae8aa642019-12-16 20:15:20 +08001358 callback.assertNoCallback();
markchien26299ed2019-02-27 14:56:11 +08001359 }
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001360
markchien04bdf872019-06-17 21:05:34 +08001361 @Test
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001362 public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
1363 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1364 TestTetheringEventCallback callback = new TestTetheringEventCallback();
1365 mTethering.registerTetheringEventCallback(callback);
1366 mLooper.dispatchAll();
1367 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1368
1369 // 1. Offload fail if no OffloadConfig.
1370 initOffloadConfiguration(false /* offloadConfig */, true /* offloadControl */,
1371 0 /* defaultDisabled */);
1372 runUsbTethering(upstreamState);
1373 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1374 runStopUSBTethering();
1375 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1376 reset(mUsbManager);
1377 // 2. Offload fail if no OffloadControl.
1378 initOffloadConfiguration(true /* offloadConfig */, false /* offloadControl */,
1379 0 /* defaultDisabled */);
1380 runUsbTethering(upstreamState);
1381 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1382 runStopUSBTethering();
1383 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1384 reset(mUsbManager);
1385 // 3. Offload fail if disabled by settings.
1386 initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
1387 1 /* defaultDisabled */);
1388 runUsbTethering(upstreamState);
1389 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1390 runStopUSBTethering();
1391 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1392 }
1393
1394 private void runStopUSBTethering() {
1395 mTethering.stopTethering(TETHERING_USB);
1396 mLooper.dispatchAll();
1397 mTethering.interfaceRemoved(TEST_USB_IFNAME);
1398 mLooper.dispatchAll();
1399 }
1400
1401 private void initOffloadConfiguration(final boolean offloadConfig,
1402 final boolean offloadControl, final int defaultDisabled) {
1403 when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
1404 when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControl);
1405 when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
1406 defaultDisabled);
1407 }
1408
1409 @Test
markchien04bdf872019-06-17 21:05:34 +08001410 public void testMultiSimAware() throws Exception {
1411 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
markchien986750b2019-12-06 15:24:53 +08001412 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
markchien04bdf872019-06-17 21:05:34 +08001413
1414 final int fakeSubId = 1234;
1415 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1416 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
markchien986750b2019-12-06 15:24:53 +08001417 assertEquals(fakeSubId, newConfig.activeDataSubId);
Paul Hu274cc1c2020-03-25 06:22:43 +00001418 verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
markchien04bdf872019-06-17 21:05:34 +08001419 }
1420
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001421 @Test
1422 public void testNoDuplicatedEthernetRequest() throws Exception {
1423 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
1424 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001425 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001426 mLooper.dispatchAll();
1427 verify(mEm, times(1)).requestTetheredInterface(any(), any());
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001428 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +00001429 mLooper.dispatchAll();
1430 verifyNoMoreInteractions(mEm);
1431 mTethering.stopTethering(TETHERING_ETHERNET);
1432 mLooper.dispatchAll();
1433 verify(mockRequest, times(1)).release();
1434 mTethering.stopTethering(TETHERING_ETHERNET);
1435 mLooper.dispatchAll();
1436 verifyNoMoreInteractions(mEm);
1437 }
1438
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001439 private void workingWifiP2pGroupOwner(
1440 boolean emulateInterfaceStatusChanged) throws Exception {
1441 if (emulateInterfaceStatusChanged) {
1442 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1443 }
1444 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1445 mLooper.dispatchAll();
1446
1447 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
1448 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
markchiena9d9ef82020-01-07 14:43:17 +08001449 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
1450 verify(mNetd, times(1)).tetherStartWithConfiguration(any());
1451 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001452 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
1453 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +00001454 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
1455 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001456
1457 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1458
1459 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1460 // is being removed.
1461 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
1462 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1463 mLooper.dispatchAll();
1464
markchiena9d9ef82020-01-07 14:43:17 +08001465 verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1466 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
1467 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1468 // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
1469 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1470 verify(mNetd, times(1)).tetherStop();
1471 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001472 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
1473 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
markchiena9d9ef82020-01-07 14:43:17 +08001474 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001475 // Asking for the last error after the per-interface state machine
1476 // has been reaped yields an unknown interface error.
1477 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1478 }
1479
1480 private void workingWifiP2pGroupClient(
1481 boolean emulateInterfaceStatusChanged) throws Exception {
1482 if (emulateInterfaceStatusChanged) {
1483 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1484 }
1485 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
1486 mLooper.dispatchAll();
1487
markchiena9d9ef82020-01-07 14:43:17 +08001488 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1489 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
1490 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1491 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
1492 verify(mNetd, never()).tetherStartWithConfiguration(any());
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001493
1494 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
1495 // is being removed.
1496 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
1497 mTethering.interfaceRemoved(TEST_P2P_IFNAME);
1498 mLooper.dispatchAll();
1499
markchiena9d9ef82020-01-07 14:43:17 +08001500 verify(mNetd, never()).tetherApplyDnsInterfaces();
1501 verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
1502 verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1503 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1504 verify(mNetd, never()).tetherStop();
1505 verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
1506 verifyNoMoreInteractions(mNetd);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001507 // Asking for the last error after the per-interface state machine
1508 // has been reaped yields an unknown interface error.
1509 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1510 }
1511
1512 @Test
1513 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
1514 workingWifiP2pGroupOwner(true);
1515 }
1516
1517 @Test
1518 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
1519 workingWifiP2pGroupOwner(false);
1520 }
1521
1522 private void workingWifiP2pGroupOwnerLegacyMode(
1523 boolean emulateInterfaceStatusChanged) throws Exception {
1524 // change to legacy mode and update tethering information by chaning SIM
markchienda4519a2020-01-14 12:46:53 +08001525 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001526 .thenReturn(new String[]{});
1527 final int fakeSubId = 1234;
1528 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1529
1530 if (emulateInterfaceStatusChanged) {
1531 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
1532 }
1533 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
1534 mLooper.dispatchAll();
1535
markchiena9d9ef82020-01-07 14:43:17 +08001536 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1537 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
1538 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
1539 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
1540 verify(mNetd, never()).tetherStartWithConfiguration(any());
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001541 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME));
1542 }
1543 @Test
1544 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
1545 workingWifiP2pGroupOwnerLegacyMode(true);
1546 }
1547
1548 @Test
1549 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
1550 workingWifiP2pGroupOwnerLegacyMode(false);
1551 }
1552
1553 @Test
1554 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
1555 workingWifiP2pGroupClient(true);
1556 }
1557
1558 @Test
1559 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
1560 workingWifiP2pGroupClient(false);
1561 }
1562
markchien3fe660b2019-12-05 12:04:59 +08001563 private void setDataSaverEnabled(boolean enabled) {
1564 final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED);
1565 mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
1566
1567 final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED
1568 : RESTRICT_BACKGROUND_STATUS_DISABLED;
1569 when(mCm.getRestrictBackgroundStatus()).thenReturn(status);
1570 mLooper.dispatchAll();
1571 }
1572
1573 @Test
1574 public void testDataSaverChanged() {
1575 // Start Tethering.
1576 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1577 runUsbTethering(upstreamState);
1578 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1579 // Data saver is ON.
1580 setDataSaverEnabled(true);
1581 // Verify that tethering should be disabled.
1582 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1583 mTethering.interfaceRemoved(TEST_USB_IFNAME);
1584 mLooper.dispatchAll();
1585 assertEquals(mTethering.getTetheredIfaces(), new String[0]);
1586 reset(mUsbManager);
1587
1588 runUsbTethering(upstreamState);
1589 // Verify that user can start tethering again without turning OFF data saver.
1590 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1591
1592 // If data saver is keep ON with change event, tethering should not be OFF this time.
1593 setDataSaverEnabled(true);
1594 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1595 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1596
1597 // If data saver is turned OFF, it should not change tethering.
1598 setDataSaverEnabled(false);
1599 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1600 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME);
1601 }
1602
1603 private static <T> void assertContains(Collection<T> collection, T element) {
1604 assertTrue(element + " not found in " + collection, collection.contains(element));
1605 }
1606
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001607 private class ResultListener extends IIntResultListener.Stub {
1608 private final int mExpectedResult;
1609 private boolean mHasResult = false;
1610 ResultListener(final int expectedResult) {
1611 mExpectedResult = expectedResult;
1612 }
1613
1614 @Override
1615 public void onResult(final int resultCode) {
1616 mHasResult = true;
1617 if (resultCode != mExpectedResult) {
1618 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
1619 }
1620 }
1621
1622 public void assertHasResult() {
1623 if (!mHasResult) fail("No callback result");
1624 }
1625 }
1626
1627 @Test
1628 public void testMultipleStartTethering() throws Exception {
1629 final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
1630 final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
1631 final String serverAddr = "192.168.20.1";
1632 final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1633 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1634 final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
1635
1636 // Enable USB tethering and check that Tethering starts USB.
1637 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
1638 null, null), firstResult);
1639 mLooper.dispatchAll();
1640 firstResult.assertHasResult();
1641 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1642 verifyNoMoreInteractions(mUsbManager);
1643
1644 // Enable USB tethering again with the same request and expect no change to USB.
1645 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
1646 null, null), secondResult);
1647 mLooper.dispatchAll();
1648 secondResult.assertHasResult();
1649 verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1650 reset(mUsbManager);
1651
1652 // Enable USB tethering with a different request and expect that USB is stopped and
1653 // started.
1654 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
1655 serverLinkAddr, clientLinkAddr), thirdResult);
1656 mLooper.dispatchAll();
1657 thirdResult.assertHasResult();
1658 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1659 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1660
1661 // Expect that when USB comes up, the DHCP server is configured with the requested address.
1662 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
1663 sendUsbBroadcast(true, true, true, TETHERING_USB);
1664 mLooper.dispatchAll();
1665 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1666 any(), any());
1667 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
1668 }
1669
1670 @Test
Treehugger Robot86d212b2020-03-30 04:23:55 +00001671 public void testRequestStaticIp() throws Exception {
1672 final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
1673 final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
1674 final String serverAddr = "192.168.0.123";
1675 final int clientAddrParceled = 0xc0a8002a;
1676 final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
1677 ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001678 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
1679 serverLinkAddr, clientLinkAddr), null);
1680 mLooper.dispatchAll();
1681 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1682 mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
1683 sendUsbBroadcast(true, true, true, TETHERING_USB);
1684 mLooper.dispatchAll();
1685 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
Treehugger Robot86d212b2020-03-30 04:23:55 +00001686 verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
1687 any());
1688 final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
1689 assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
1690 assertEquals(24, params.serverAddrPrefixLength);
1691 assertEquals(clientAddrParceled, params.clientAddr);
Automerger Merge Worker37a22752020-03-17 16:59:57 +00001692 }
1693
Paul Hu77fa8d62020-04-16 02:54:37 +00001694 @Test
1695 public void testUpstreamNetworkChanged() {
1696 final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
1697 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
1698 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1699 when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
1700 stateMachine.chooseUpstreamType(true);
1701
1702 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
1703 verify(mNotificationUpdater, times(1)).onUpstreamNetworkChanged(eq(upstreamState.network));
1704 }
1705
Erik Kline1fdc2e22017-05-08 17:56:35 +09001706 // TODO: Test that a request for hotspot mode doesn't interfere with an
Erik Klineea9cc482017-03-10 19:35:34 +09001707 // already operating tethering mode interface.
Christopher Wiley497c1472016-10-11 13:26:03 -07001708}