1497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley/* 2497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * Copyright (C) 2016 The Android Open Source Project 3497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * 4497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * Licensed under the Apache License, Version 2.0 (the "License"); 5497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * you may not use this file except in compliance with the License. 6497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * You may obtain a copy of the License at 7497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * 8497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * http://www.apache.org/licenses/LICENSE-2.0 9497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * 10497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * Unless required by applicable law or agreed to in writing, software 11497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * distributed under the License is distributed on an "AS IS" BASIS, 12497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * See the License for the specific language governing permissions and 14497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley * limitations under the License. 15497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley */ 16497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 17497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileypackage com.android.server.connectivity; 18497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 19c438e306cc69b9d4d62512030267e93011b29978Erik Klineimport static android.hardware.usb.UsbManager.USB_CONFIGURED; 20c438e306cc69b9d4d62512030267e93011b29978Erik Klineimport static android.hardware.usb.UsbManager.USB_CONNECTED; 21c438e306cc69b9d4d62512030267e93011b29978Erik Klineimport static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; 227a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; 237a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY; 247a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.EXTRA_ACTIVE_TETHER; 257a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.EXTRA_AVAILABLE_TETHER; 267a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 27c438e306cc69b9d4d62512030267e93011b29978Erik Klineimport static android.net.ConnectivityManager.TETHERING_WIFI; 28c438e306cc69b9d4d62512030267e93011b29978Erik Klineimport static android.net.ConnectivityManager.TETHERING_USB; 297a26ba37f6a1205c8914c62c4756f24329317f6bErik Klineimport static android.net.ConnectivityManager.TYPE_MOBILE; 302efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 312efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 322efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; 332efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; 342efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; 352efb827f61db989ab55792052c99713ef5f5eefaErik Klineimport static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 365d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 37ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.junit.Assert.assertEquals; 38497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport static org.junit.Assert.assertTrue; 395d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport static org.mockito.ArgumentMatchers.argThat; 405d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport static org.mockito.ArgumentMatchers.notNull; 41497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport static org.mockito.Matchers.anyBoolean; 42ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Matchers.anyInt; 43ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Matchers.anyString; 44497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport static org.mockito.Matchers.eq; 451fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Klineimport static org.mockito.Mockito.any; 46ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Mockito.atLeastOnce; 471fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Klineimport static org.mockito.Mockito.doThrow; 485d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport static org.mockito.Mockito.never; 49ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Mockito.times; 50ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Mockito.verify; 51ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport static org.mockito.Mockito.verifyNoMoreInteractions; 52497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport static org.mockito.Mockito.when; 53fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaruimport static org.mockito.Mockito.mock; 54497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 558351faa900acdba1022f03bb3f18e26f539eadaeErik Klineimport android.content.BroadcastReceiver; 5692c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Klineimport android.content.ContentResolver; 57497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.content.Context; 58ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.content.Intent; 598351faa900acdba1022f03bb3f18e26f539eadaeErik Klineimport android.content.IntentFilter; 60f3a08b44ed5f3695720e92f7f51218f95018c12aErik Klineimport android.content.pm.ApplicationInfo; 61497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.content.res.Resources; 62ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.hardware.usb.UsbManager; 635d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.INetd; 64497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.net.INetworkPolicyManager; 65497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.net.INetworkStatsService; 66ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.net.InterfaceConfiguration; 675d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.IpPrefix; 685d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.LinkAddress; 695d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.LinkProperties; 705d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.MacAddress; 715d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.Network; 725d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.NetworkCapabilities; 735d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.NetworkInfo; 745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.NetworkState; 755d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.NetworkUtils; 765d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.RouteInfo; 775d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.ip.RouterAdvertisementDaemon; 785d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.util.InterfaceParams; 795d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport android.net.util.NetworkConstants; 80f4b6e34fc093d0e493bc97e91b71d753720f7114Erik Klineimport android.net.util.SharedLog; 81ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.net.wifi.WifiConfiguration; 82ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.net.wifi.WifiManager; 83fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaruimport android.os.Bundle; 84ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.os.Handler; 85497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.os.INetworkManagementService; 86497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.os.PersistableBundle; 871fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Klineimport android.os.RemoteException; 88497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.os.test.TestLooper; 89ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport android.os.UserHandle; 90fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaruimport android.os.UserManager; 9192c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Klineimport android.provider.Settings; 92497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.support.test.filters.SmallTest; 93497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.support.test.runner.AndroidJUnit4; 94497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport android.telephony.CarrierConfigManager; 9592c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Klineimport android.test.mock.MockContentResolver; 96497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 975d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.internal.util.ArrayUtils; 985d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.internal.util.StateMachine; 99ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Klineimport com.android.internal.util.test.BroadcastInterceptingContext; 10092c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Klineimport com.android.internal.util.test.FakeSettingsProvider; 1015d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.server.connectivity.tethering.IControlsTethering; 1025d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.server.connectivity.tethering.IPv6TetheringCoordinator; 1035a7c8a0b24adc0f5d5ce3b98e995ef78096abf5bErik Klineimport com.android.server.connectivity.tethering.OffloadHardwareInterface; 1045d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.server.connectivity.tethering.TetherInterfaceStateMachine; 1055a7c8a0b24adc0f5d5ce3b98e995ef78096abf5bErik Klineimport com.android.server.connectivity.tethering.TetheringDependencies; 1065d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport com.android.server.connectivity.tethering.UpstreamNetworkMonitor; 107ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 1088351faa900acdba1022f03bb3f18e26f539eadaeErik Klineimport org.junit.After; 109497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport org.junit.Before; 110497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport org.junit.Test; 111497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport org.junit.runner.RunWith; 112497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport org.mockito.Mock; 113497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileyimport org.mockito.MockitoAnnotations; 114497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 1155d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport java.net.Inet4Address; 1165d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VANimport java.net.Inet6Address; 1178351faa900acdba1022f03bb3f18e26f539eadaeErik Klineimport java.util.ArrayList; 1188351faa900acdba1022f03bb3f18e26f539eadaeErik Klineimport java.util.Vector; 1198351faa900acdba1022f03bb3f18e26f539eadaeErik Kline 120497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley@RunWith(AndroidJUnit4.class) 121497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley@SmallTest 122497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wileypublic class TetheringTest { 1235d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static final int IFINDEX_OFFSET = 100; 1245d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 125497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; 1265d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; 1275d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0"; 1285d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static final String TEST_USB_IFNAME = "test_rndis0"; 1295d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static final String TEST_WLAN_IFNAME = "test_wlan0"; 130497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 131f3a08b44ed5f3695720e92f7f51218f95018c12aErik Kline @Mock private ApplicationInfo mApplicationInfo; 132497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private Context mContext; 133497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private INetworkManagementService mNMService; 134497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private INetworkStatsService mStatsService; 135497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private INetworkPolicyManager mPolicyManager; 136497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private MockableSystemProperties mSystemProperties; 1375a7c8a0b24adc0f5d5ce3b98e995ef78096abf5bErik Kline @Mock private OffloadHardwareInterface mOffloadHardwareInterface; 138497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private Resources mResources; 139ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline @Mock private UsbManager mUsbManager; 140ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline @Mock private WifiManager mWifiManager; 141497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Mock private CarrierConfigManager mCarrierConfigManager; 1425d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor; 1435d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator; 1445d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; 1455d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Mock private INetd mNetd; 1465d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 1475d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private final MockTetheringDependencies mTetheringDependencies = 1485d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN new MockTetheringDependencies(); 149497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 150497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // Like so many Android system APIs, these cannot be mocked because it is marked final. 151497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // We have to use the real versions. 152497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley private final PersistableBundle mCarrierConfig = new PersistableBundle(); 153497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley private final TestLooper mLooper = new TestLooper(); 154497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 1558351faa900acdba1022f03bb3f18e26f539eadaeErik Kline private Vector<Intent> mIntents; 156ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline private BroadcastInterceptingContext mServiceContext; 15792c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline private MockContentResolver mContentResolver; 1588351faa900acdba1022f03bb3f18e26f539eadaeErik Kline private BroadcastReceiver mBroadcastReceiver; 159497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley private Tethering mTethering; 160497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 161ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline private class MockContext extends BroadcastInterceptingContext { 162ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline MockContext(Context base) { 163ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline super(base); 164ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 165ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 166ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline @Override 167f3a08b44ed5f3695720e92f7f51218f95018c12aErik Kline public ApplicationInfo getApplicationInfo() { return mApplicationInfo; } 168f3a08b44ed5f3695720e92f7f51218f95018c12aErik Kline 169f3a08b44ed5f3695720e92f7f51218f95018c12aErik Kline @Override 17092c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline public ContentResolver getContentResolver() { return mContentResolver; } 17192c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline 17292c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline @Override 17392c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline public String getPackageName() { return "TetheringTest"; } 17492c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline 17592c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline @Override 176ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline public Resources getResources() { return mResources; } 177ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 178ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline @Override 179ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline public Object getSystemService(String name) { 180ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; 181c438e306cc69b9d4d62512030267e93011b29978Erik Kline if (Context.USB_SERVICE.equals(name)) return mUsbManager; 182ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline return super.getSystemService(name); 183ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 184ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 185ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 1865d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public class MockTetheringDependencies extends TetheringDependencies { 1877a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline StateMachine upstreamNetworkMonitorMasterSM; 1887a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline ArrayList<TetherInterfaceStateMachine> ipv6CoordinatorNotifyList; 1897a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline int isTetheringSupportedCalls; 1907a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline 1917a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline public void reset() { 1927a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline upstreamNetworkMonitorMasterSM = null; 1937a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline ipv6CoordinatorNotifyList = null; 1947a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline isTetheringSupportedCalls = 0; 1957a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline } 1965d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 1975d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 1985d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { 1995d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return mOffloadHardwareInterface; 2005d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2015d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2025d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 2035d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, 2045d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN StateMachine target, SharedLog log, int what) { 2055d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN upstreamNetworkMonitorMasterSM = target; 2065d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return mUpstreamNetworkMonitor; 2075d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2085d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2095d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 2105d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public IPv6TetheringCoordinator getIPv6TetheringCoordinator( 2115d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN ArrayList<TetherInterfaceStateMachine> notifyList, SharedLog log) { 2125d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN ipv6CoordinatorNotifyList = notifyList; 2135d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return mIPv6TetheringCoordinator; 2145d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2155d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2165d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 2175d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { 2185d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return mRouterAdvertisementDaemon; 2195d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2205d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2215d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 2225d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public INetd getNetdService() { 2235d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return mNetd; 2245d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2255d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2265d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Override 2275d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public InterfaceParams getInterfaceParams(String ifName) { 2285d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final String[] ifaces = new String[] { TEST_USB_IFNAME, TEST_WLAN_IFNAME, 2295d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_MOBILE_IFNAME }; 2305d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final int index = ArrayUtils.indexOf(ifaces, ifName); 2315d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN assertTrue("Non-mocked interface: " + ifName, index >= 0); 2325d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return new InterfaceParams(ifName, index + IFINDEX_OFFSET, 2335d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN MacAddress.ALL_ZEROS_ADDRESS); 2345d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2357a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline 2367a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline @Override 2377a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline public boolean isTetheringSupported() { 2387a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline isTetheringSupportedCalls++; 2397a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline return true; 2407a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline } 2415d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2425d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2436c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, 2446c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN boolean with464xlat) { 2457a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline final NetworkInfo info = new NetworkInfo(TYPE_MOBILE, 0, null, null); 2465d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN info.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null); 2475d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final LinkProperties prop = new LinkProperties(); 2485d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prop.setInterfaceName(TEST_MOBILE_IFNAME); 2495d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2505d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN if (withIPv4) { 2515d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 2525d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkUtils.numericToInetAddress("10.0.0.1"), TEST_MOBILE_IFNAME)); 2535d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2545d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2555d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN if (withIPv6) { 2565d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prop.addDnsServer(NetworkUtils.numericToInetAddress("2001:db8::2")); 2575d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prop.addLinkAddress( 2585d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN new LinkAddress(NetworkUtils.numericToInetAddress("2001:db8::"), 2595d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkConstants.RFC7421_PREFIX_LENGTH)); 2605d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), 2615d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkUtils.numericToInetAddress("2001:db8::1"), TEST_MOBILE_IFNAME)); 2625d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2635d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2646c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN if (with464xlat) { 2656c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN final LinkProperties stackedLink = new LinkProperties(); 2666c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME); 2676c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 2686c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN NetworkUtils.numericToInetAddress("192.0.0.1"), TEST_XLAT_MOBILE_IFNAME)); 2696c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 2706c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN prop.addStackedLink(stackedLink); 2716c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 2726c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 2735d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final NetworkCapabilities capabilities = new NetworkCapabilities() 2755d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);; 2765d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN return new NetworkState(info, prop, capabilities, new Network(100), null, "netid"); 2775d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2785d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2795d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static NetworkState buildMobileIPv4UpstreamState() { 2806c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN return buildMobileUpstreamState(true, false, false); 2816c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 2826c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 2836c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN private static NetworkState buildMobileIPv6UpstreamState() { 2846c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN return buildMobileUpstreamState(false, true, false); 2855d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2865d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2875d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private static NetworkState buildMobileDualStackUpstreamState() { 2886c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN return buildMobileUpstreamState(true, true, false); 2896c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 2906c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 2916c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN private static NetworkState buildMobile464xlatUpstreamState() { 2926c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN return buildMobileUpstreamState(false, true, true); 2935d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 2945d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 2958351faa900acdba1022f03bb3f18e26f539eadaeErik Kline @Before 2968351faa900acdba1022f03bb3f18e26f539eadaeErik Kline public void setUp() throws Exception { 297497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley MockitoAnnotations.initMocks(this); 298497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range)) 299497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(new String[0]); 300497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs)) 3015d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .thenReturn(new String[] { "test_rndis\\d" }); 302497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs)) 3035d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .thenReturn(new String[]{ "test_wlan\\d" }); 304497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs)) 305497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(new String[0]); 306497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) 307497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(new int[0]); 308ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline when(mNMService.listInterfaces()) 3095d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .thenReturn(new String[] { 3105d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME}); 311ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline when(mNMService.getInterfaceConfig(anyString())) 312ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline .thenReturn(new InterfaceConfiguration()); 3135d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN when(mRouterAdvertisementDaemon.start()) 3145d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .thenReturn(true); 315ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 316ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mServiceContext = new MockContext(mContext); 31792c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline mContentResolver = new MockContentResolver(mServiceContext); 31892c4db04e54a7bb375df01ce6e3fd98d568c6990Erik Kline mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 3198351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mIntents = new Vector<>(); 3208351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mBroadcastReceiver = new BroadcastReceiver() { 3218351faa900acdba1022f03bb3f18e26f539eadaeErik Kline @Override 3228351faa900acdba1022f03bb3f18e26f539eadaeErik Kline public void onReceive(Context context, Intent intent) { 3238351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mIntents.addElement(intent); 3248351faa900acdba1022f03bb3f18e26f539eadaeErik Kline } 3258351faa900acdba1022f03bb3f18e26f539eadaeErik Kline }; 3268351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mServiceContext.registerReceiver(mBroadcastReceiver, 3277a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline new IntentFilter(ACTION_TETHER_STATE_CHANGED)); 3287a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline mTetheringDependencies.reset(); 329ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager, 3305a7c8a0b24adc0f5d5ce3b98e995ef78096abf5bErik Kline mLooper.getLooper(), mSystemProperties, 3315a7c8a0b24adc0f5d5ce3b98e995ef78096abf5bErik Kline mTetheringDependencies); 3325a7dea1a8eb2cf53fc1d5a52004647de94150e62Lorenzo Colitti verify(mNMService).registerTetheringStatsProvider(any(), anyString()); 333497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 334497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 3358351faa900acdba1022f03bb3f18e26f539eadaeErik Kline @After 3368351faa900acdba1022f03bb3f18e26f539eadaeErik Kline public void tearDown() { 3378351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mServiceContext.unregisterReceiver(mBroadcastReceiver); 3388351faa900acdba1022f03bb3f18e26f539eadaeErik Kline } 3398351faa900acdba1022f03bb3f18e26f539eadaeErik Kline 340497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley private void setupForRequiredProvisioning() { 341497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // Produce some acceptable looking provision app setting if requested. 342497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray( 343497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley com.android.internal.R.array.config_mobile_hotspot_provision_app)) 344497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(PROVISIONING_APP_NAME); 345497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // Don't disable tethering provisioning unless requested. 346497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mSystemProperties.getBoolean(eq(Tethering.DISABLE_PROVISIONING_SYSPROP_KEY), 347497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley anyBoolean())).thenReturn(false); 348497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // Act like the CarrierConfigManager is present and ready unless told otherwise. 349497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) 350497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(mCarrierConfigManager); 351497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig); 352497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); 353497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 354497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 355497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Test 356497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley public void canRequireProvisioning() { 357497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley setupForRequiredProvisioning(); 35880b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline sendConfigurationChanged(); 359497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley assertTrue(mTethering.isTetherProvisioningRequired()); 360497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 361497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 362497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Test 363497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley public void toleratesCarrierConfigManagerMissing() { 364497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley setupForRequiredProvisioning(); 365497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) 366497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(null); 36780b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline sendConfigurationChanged(); 368497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // Couldn't get the CarrierConfigManager, but still had a declared provisioning app. 369497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // We therefore still require provisioning. 370497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley assertTrue(mTethering.isTetherProvisioningRequired()); 371497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 372497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 373497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Test 374497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley public void toleratesCarrierConfigMissing() { 375497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley setupForRequiredProvisioning(); 376497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mCarrierConfigManager.getConfig()).thenReturn(null); 37780b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline sendConfigurationChanged(); 378497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley // We still have a provisioning app configured, so still require provisioning. 379497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley assertTrue(mTethering.isTetherProvisioningRequired()); 380497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 381497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley 382497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley @Test 383497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley public void provisioningNotRequiredWhenAppNotFound() { 384497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley setupForRequiredProvisioning(); 385497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray( 386497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley com.android.internal.R.array.config_mobile_hotspot_provision_app)) 387497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(null); 388497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley assertTrue(!mTethering.isTetherProvisioningRequired()); 389497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley when(mResources.getStringArray( 390497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley com.android.internal.R.array.config_mobile_hotspot_provision_app)) 391497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley .thenReturn(new String[] {"malformedApp"}); 392497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley assertTrue(!mTethering.isTetherProvisioningRequired()); 393497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley } 394ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 395ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline private void sendWifiApStateChanged(int state) { 396ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 3972efb827f61db989ab55792052c99713ef5f5eefaErik Kline intent.putExtra(EXTRA_WIFI_AP_STATE, state); 398ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 399ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 400ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 4012efb827f61db989ab55792052c99713ef5f5eefaErik Kline private void sendWifiApStateChanged(int state, String ifname, int ipmode) { 4022efb827f61db989ab55792052c99713ef5f5eefaErik Kline final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 4032efb827f61db989ab55792052c99713ef5f5eefaErik Kline intent.putExtra(EXTRA_WIFI_AP_STATE, state); 4042efb827f61db989ab55792052c99713ef5f5eefaErik Kline intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname); 4052efb827f61db989ab55792052c99713ef5f5eefaErik Kline intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode); 4062efb827f61db989ab55792052c99713ef5f5eefaErik Kline mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 4072efb827f61db989ab55792052c99713ef5f5eefaErik Kline } 4082efb827f61db989ab55792052c99713ef5f5eefaErik Kline 409c438e306cc69b9d4d62512030267e93011b29978Erik Kline private void sendUsbBroadcast(boolean connected, boolean configured, boolean rndisFunction) { 410c438e306cc69b9d4d62512030267e93011b29978Erik Kline final Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 411c438e306cc69b9d4d62512030267e93011b29978Erik Kline intent.putExtra(USB_CONNECTED, connected); 412c438e306cc69b9d4d62512030267e93011b29978Erik Kline intent.putExtra(USB_CONFIGURED, configured); 413c438e306cc69b9d4d62512030267e93011b29978Erik Kline intent.putExtra(USB_FUNCTION_RNDIS, rndisFunction); 414c438e306cc69b9d4d62512030267e93011b29978Erik Kline mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 415c438e306cc69b9d4d62512030267e93011b29978Erik Kline } 416c438e306cc69b9d4d62512030267e93011b29978Erik Kline 41780b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline private void sendConfigurationChanged() { 41880b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 41980b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 42080b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline } 42180b7a9f1b5ba5a6117f6b020121f06a2d0cd1889Erik Kline 4229e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline private void verifyInterfaceServingModeStarted() throws Exception { 4235d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).getInterfaceConfig(TEST_WLAN_IFNAME); 4248351faa900acdba1022f03bb3f18e26f539eadaeErik Kline verify(mNMService, times(1)) 4255d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); 4265d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME); 4278351faa900acdba1022f03bb3f18e26f539eadaeErik Kline } 4288351faa900acdba1022f03bb3f18e26f539eadaeErik Kline 4298351faa900acdba1022f03bb3f18e26f539eadaeErik Kline private void verifyTetheringBroadcast(String ifname, String whichExtra) { 4308351faa900acdba1022f03bb3f18e26f539eadaeErik Kline // Verify that ifname is in the whichExtra array of the tether state changed broadcast. 4318351faa900acdba1022f03bb3f18e26f539eadaeErik Kline final Intent bcast = mIntents.get(0); 4327a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction()); 4338351faa900acdba1022f03bb3f18e26f539eadaeErik Kline final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra); 4348351faa900acdba1022f03bb3f18e26f539eadaeErik Kline assertTrue(ifnames.contains(ifname)); 4358351faa900acdba1022f03bb3f18e26f539eadaeErik Kline mIntents.remove(bcast); 4368351faa900acdba1022f03bb3f18e26f539eadaeErik Kline } 4378351faa900acdba1022f03bb3f18e26f539eadaeErik Kline 438a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void failingLocalOnlyHotspotLegacyApBroadcast( 439a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline boolean emulateInterfaceStatusChanged) throws Exception { 440ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate externally-visible WifiManager effects, causing the 441ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // per-interface state machine to start up, and telling us that 442ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // hotspot mode is to be started. 443a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline if (emulateInterfaceStatusChanged) { 4445d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 445a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 4469e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 447ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 448ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 449a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // If, and only if, Tethering received an interface status changed 450a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // then it creates a TetherInterfaceStateMachine and sends out a 451a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // broadcast indicating that the interface is "available". 452a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline if (emulateInterfaceStatusChanged) { 4537a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls); 4547a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 455a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 4569e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mNMService); 4579e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mWifiManager); 4589e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline } 4599e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline 4605d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private void prepareUsbTethering(NetworkState upstreamState) { 4615d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) 4625d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .thenReturn(upstreamState); 463c438e306cc69b9d4d62512030267e93011b29978Erik Kline 464c438e306cc69b9d4d62512030267e93011b29978Erik Kline // Emulate pressing the USB tethering button in Settings UI. 465c438e306cc69b9d4d62512030267e93011b29978Erik Kline mTethering.startTethering(TETHERING_USB, null, false); 466c438e306cc69b9d4d62512030267e93011b29978Erik Kline mLooper.dispatchAll(); 467327b809ad11a5094248652014227470c4be329e6Jerry Zhang verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 468c438e306cc69b9d4d62512030267e93011b29978Erik Kline 4695d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); 4705d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 4715d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 4725d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Test 4735d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public void testUsbConfiguredBroadcastStartsTethering() throws Exception { 4745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkState upstreamState = buildMobileIPv4UpstreamState(); 4755d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prepareUsbTethering(upstreamState); 4765d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 477c438e306cc69b9d4d62512030267e93011b29978Erik Kline // This should produce no activity of any kind. 478c438e306cc69b9d4d62512030267e93011b29978Erik Kline verifyNoMoreInteractions(mNMService); 479c438e306cc69b9d4d62512030267e93011b29978Erik Kline 480c438e306cc69b9d4d62512030267e93011b29978Erik Kline // Pretend we then receive USB configured broadcast. 481c438e306cc69b9d4d62512030267e93011b29978Erik Kline sendUsbBroadcast(true, true, true); 482c438e306cc69b9d4d62512030267e93011b29978Erik Kline mLooper.dispatchAll(); 483c438e306cc69b9d4d62512030267e93011b29978Erik Kline // Now we should see the start of tethering mechanics (in this case: 484c438e306cc69b9d4d62512030267e93011b29978Erik Kline // tetherMatchingInterfaces() which starts by fetching all interfaces). 485c438e306cc69b9d4d62512030267e93011b29978Erik Kline verify(mNMService, times(1)).listInterfaces(); 4865d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 4875d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN // UpstreamNetworkMonitor should receive selected upstream 4885d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any()); 4895d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); 490c438e306cc69b9d4d62512030267e93011b29978Erik Kline } 491c438e306cc69b9d4d62512030267e93011b29978Erik Kline 492c438e306cc69b9d4d62512030267e93011b29978Erik Kline @Test 493a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception { 494a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline failingLocalOnlyHotspotLegacyApBroadcast(true); 495a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 496a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline 497a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline @Test 498a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception { 499a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline failingLocalOnlyHotspotLegacyApBroadcast(false); 500a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 501a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline 502a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void workingLocalOnlyHotspotEnrichedApBroadcast( 503a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline boolean emulateInterfaceStatusChanged) throws Exception { 5049e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // Emulate externally-visible WifiManager effects, causing the 5059e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // per-interface state machine to start up, and telling us that 5069e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // hotspot mode is to be started. 507a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline if (emulateInterfaceStatusChanged) { 5085d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 509a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 5105d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 5119e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline mLooper.dispatchAll(); 5129e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline 5139e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyInterfaceServingModeStarted(); 5147a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 515ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).setIpForwardingEnabled(true); 516ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).startTethering(any(String[].class)); 517ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 518216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verify(mWifiManager).updateInterfaceIpState( 5195d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); 520216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verifyNoMoreInteractions(mWifiManager); 5217a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 5225d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mUpstreamNetworkMonitor, times(1)).start(); 523ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast(). 5247a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls); 525ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 526ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate externally-visible WifiManager effects, when hotspot mode 527ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // is being torn down. 528ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED); 5295d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 530ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 531ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 5325d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); 533ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // TODO: Why is {g,s}etInterfaceConfig() called more than once? 5345d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME); 535ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, atLeastOnce()) 5365d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); 537ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).stopTethering(); 538ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).setIpForwardingEnabled(false); 539ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 540216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verifyNoMoreInteractions(mWifiManager); 541ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Asking for the last error after the per-interface state machine 542ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // has been reaped yields an unknown interface error. 5437a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME)); 5445d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 5455d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5465d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN /** 5475d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN * Send CMD_IPV6_TETHER_UPDATE to TISMs as would be done by IPv6TetheringCoordinator. 5485d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN */ 5495d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private void sendIPv6TetherUpdates(NetworkState upstreamState) { 5505d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN // IPv6TetheringCoordinator must have been notified of downstream 5515d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream( 5525d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)), 5535d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN eq(IControlsTethering.STATE_TETHERED)); 5545d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5555d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN for (TetherInterfaceStateMachine tism : 5565d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTetheringDependencies.ipv6CoordinatorNotifyList) { 5576c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false); 5585d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN tism.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, 5595d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN upstreamState.linkProperties.isIPv6Provisioned() 5605d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN ? ipv6OnlyState.linkProperties 5615d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN : null); 5625d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 5635d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mLooper.dispatchAll(); 5645d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 5655d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5665d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN private void runUsbTethering(NetworkState upstreamState) { 5675d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN prepareUsbTethering(upstreamState); 5685d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendUsbBroadcast(true, true, true); 5695d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mLooper.dispatchAll(); 5705d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 5715d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5725d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Test 5735d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public void workingMobileUsbTethering_IPv4() throws Exception { 5745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkState upstreamState = buildMobileIPv4UpstreamState(); 5755d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN runUsbTethering(upstreamState); 5765d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5775d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 5785d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 5795d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5805d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendIPv6TetherUpdates(upstreamState); 5815d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull()); 5825d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN } 5835d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 5845d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN @Test 5856c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN public void workingMobileUsbTethering_IPv6() throws Exception { 5866c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN NetworkState upstreamState = buildMobileIPv6UpstreamState(); 5876c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN runUsbTethering(upstreamState); 5886c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 5896c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 5906c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 5916c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 5926c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN sendIPv6TetherUpdates(upstreamState); 5936c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 5946c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 5956c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 5966c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 5976c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN @Test 5985d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN public void workingMobileUsbTethering_DualStack() throws Exception { 5995d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN NetworkState upstreamState = buildMobileDualStackUpstreamState(); 6005d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN runUsbTethering(upstreamState); 6015d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 6025d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6035d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6045d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mRouterAdvertisementDaemon, times(1)).start(); 6055d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 6065d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendIPv6TetherUpdates(upstreamState); 6075d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 6085d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 609ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 610ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 6116c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN @Test 6126c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN public void workingMobileUsbTethering_MultipleUpstreams() throws Exception { 6136c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN NetworkState upstreamState = buildMobile464xlatUpstreamState(); 6146c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN runUsbTethering(upstreamState); 6156c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6166c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); 6176c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6186c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6196c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, 6206c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN TEST_XLAT_MOBILE_IFNAME); 6216c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6226c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN sendIPv6TetherUpdates(upstreamState); 6236c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 6246c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 6256c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 6266c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6276c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN @Test 6286c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN public void workingMobileUsbTethering_v6Then464xlat() throws Exception { 6296c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN // Setup IPv6 6306c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN NetworkState upstreamState = buildMobileIPv6UpstreamState(); 6316c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN runUsbTethering(upstreamState); 6326c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6336c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN // Then 464xlat comes up 6346c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN upstreamState = buildMobile464xlatUpstreamState(); 6356c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) 6366c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN .thenReturn(upstreamState); 6376c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6386c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES. 6396c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN mTetheringDependencies.upstreamNetworkMonitorMasterSM.sendMessage( 6406c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK, 6416c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 6426c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 0, 6436c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN upstreamState); 6446c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN mLooper.dispatchAll(); 6456c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN 6466c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN // Forwarding is added for 464xlat, and was still added only once for v6 6476c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); 6486c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6496c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); 6506c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, 6516c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN TEST_XLAT_MOBILE_IFNAME); 6526c02f9942aaf4f6665018e0c7f07aeceb5ae752eRemi NGUYEN VAN } 6535d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN 654ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline @Test 655a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception { 656a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline workingLocalOnlyHotspotEnrichedApBroadcast(true); 657a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 658a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline 659a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline @Test 660a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception { 661a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline workingLocalOnlyHotspotEnrichedApBroadcast(false); 662a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline } 663a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline 664a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // TODO: Test with and without interfaceStatusChanged(). 665a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline @Test 6669e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline public void failingWifiTetheringLegacyApBroadcast() throws Exception { 6679e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); 6682efb827f61db989ab55792052c99713ef5f5eefaErik Kline 6699e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // Emulate pressing the WiFi tethering button. 670c438e306cc69b9d4d62512030267e93011b29978Erik Kline mTethering.startTethering(TETHERING_WIFI, null, false); 6719e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline mLooper.dispatchAll(); 6729e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verify(mWifiManager, times(1)).startSoftAp(null); 6739e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mWifiManager); 6749e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mNMService); 6759e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline 6769e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // Emulate externally-visible WifiManager effects, causing the 6779e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // per-interface state machine to start up, and telling us that 6789e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline // tethering mode is to be started. 6795d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 6809e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 6819e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline mLooper.dispatchAll(); 6829e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline 6837a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls); 6847a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 6859e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mNMService); 6869e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyNoMoreInteractions(mWifiManager); 6872efb827f61db989ab55792052c99713ef5f5eefaErik Kline } 6882efb827f61db989ab55792052c99713ef5f5eefaErik Kline 689a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // TODO: Test with and without interfaceStatusChanged(). 6909e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline @Test 6919e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline public void workingWifiTetheringEnrichedApBroadcast() throws Exception { 692ceb54c63dc7af8f11ec9eac4993a43b9e788ee2fErik Kline when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); 693ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 694ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate pressing the WiFi tethering button. 695c438e306cc69b9d4d62512030267e93011b29978Erik Kline mTethering.startTethering(TETHERING_WIFI, null, false); 696ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 697ceb54c63dc7af8f11ec9eac4993a43b9e788ee2fErik Kline verify(mWifiManager, times(1)).startSoftAp(null); 698ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mWifiManager); 699ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 700ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 701ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate externally-visible WifiManager effects, causing the 702ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // per-interface state machine to start up, and telling us that 703ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // tethering mode is to be started. 7045d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 7055d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 706ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 707ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 7089e225540687d5d4eb17bdfbe4f062c22ee22b560Erik Kline verifyInterfaceServingModeStarted(); 7097a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 710ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).setIpForwardingEnabled(true); 711ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).startTethering(any(String[].class)); 712ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 713216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verify(mWifiManager).updateInterfaceIpState( 7145d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); 715216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verifyNoMoreInteractions(mWifiManager); 7167a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); 7175d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mUpstreamNetworkMonitor, times(1)).start(); 718ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // In tethering mode, in the default configuration, an explicit request 719ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // for a mobile network is also made. 7205d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest(); 721ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast(). 7227a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls); 723ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 724ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline ///// 725ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // We do not currently emulate any upstream being found. 726ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // 727ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // This is why there are no calls to verify mNMService.enableNat() or 728ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // mNMService.startInterfaceForwarding(). 729ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline ///// 730ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 731ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate pressing the WiFi tethering button. 732c438e306cc69b9d4d62512030267e93011b29978Erik Kline mTethering.stopTethering(TETHERING_WIFI); 733ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 734ceb54c63dc7af8f11ec9eac4993a43b9e788ee2fErik Kline verify(mWifiManager, times(1)).stopSoftAp(); 735ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mWifiManager); 736ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 737ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 738ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Emulate externally-visible WifiManager effects, when tethering mode 739ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // is being torn down. 740ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED); 7415d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 742ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline mLooper.dispatchAll(); 743ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 7445d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); 745ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // TODO: Why is {g,s}etInterfaceConfig() called more than once? 7465d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, atLeastOnce()).getInterfaceConfig(TEST_WLAN_IFNAME); 747ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, atLeastOnce()) 7485d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); 749ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).stopTethering(); 750ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verify(mNMService, times(1)).setIpForwardingEnabled(false); 751ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline verifyNoMoreInteractions(mNMService); 752216af6d3febb109628d9185ec1a619f0e003bcd1Erik Kline verifyNoMoreInteractions(mWifiManager); 753ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // Asking for the last error after the per-interface state machine 754ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // has been reaped yields an unknown interface error. 7557a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME)); 756ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline } 757ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline 758a9cde8b4fb26a963824f297e9b7489bfc35d1512Erik Kline // TODO: Test with and without interfaceStatusChanged(). 7591fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline @Test 7601fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline public void failureEnablingIpForwarding() throws Exception { 7611fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); 7621fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true); 7631fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline 7641fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // Emulate pressing the WiFi tethering button. 765c438e306cc69b9d4d62512030267e93011b29978Erik Kline mTethering.startTethering(TETHERING_WIFI, null, false); 7661fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline mLooper.dispatchAll(); 7671fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verify(mWifiManager, times(1)).startSoftAp(null); 7681fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verifyNoMoreInteractions(mWifiManager); 7691fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verifyNoMoreInteractions(mNMService); 7701fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline 7711fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // Emulate externally-visible WifiManager effects, causing the 7721fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // per-interface state machine to start up, and telling us that 7731fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // tethering mode is to be started. 7745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 7755d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 7761fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline mLooper.dispatchAll(); 7771fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline 778472276a874316b725027098b79e1c9f03c62cad2Erik Kline // We verify get/set called thrice here: once for setup and twice during 7791fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // teardown because all events happen over the course of the single 780472276a874316b725027098b79e1c9f03c62cad2Erik Kline // dispatchAll() above. Note that once the TISM IPv4 address config 781472276a874316b725027098b79e1c9f03c62cad2Erik Kline // code is refactored the two calls during shutdown will revert to one. 7825d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); 783472276a874316b725027098b79e1c9f03c62cad2Erik Kline verify(mNMService, times(3)) 7845d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); 7855d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME); 7861fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verify(mWifiManager).updateInterfaceIpState( 7875d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); 7887a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast(). 7897a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls); 7907a26ba37f6a1205c8914c62c4756f24329317f6bErik Kline verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 7911fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // This is called, but will throw. 7921fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verify(mNMService, times(1)).setIpForwardingEnabled(true); 7931fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // This never gets called because of the exception thrown above. 7941fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verify(mNMService, times(0)).startTethering(any(String[].class)); 7951fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // When the master state machine transitions to an error state it tells 7961fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // downstream interfaces, which causes us to tell Wi-Fi about the error 7971fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // so it can take down AP mode. 7985d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN verify(mNMService, times(1)).untetherInterface(TEST_WLAN_IFNAME); 7991fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verify(mWifiManager).updateInterfaceIpState( 8005d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR); 8011fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline 8021fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verifyNoMoreInteractions(mWifiManager); 8031fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline verifyNoMoreInteractions(mNMService); 8041fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline } 8051fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline 806fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru private void userRestrictionsListenerBehaviour( 807fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList, 808fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru int expectedInteractionsWithShowNotification) throws Exception { 809fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int userId = 0; 810fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final Bundle currRestrictions = new Bundle(); 811fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final Bundle newRestrictions = new Bundle(); 812fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru Tethering tethering = mock(Tethering.class); 813fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru Tethering.TetheringUserRestrictionListener turl = 814fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru new Tethering.TetheringUserRestrictionListener(tethering); 815fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 816fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow); 817fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); 818fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList); 819fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 820fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions); 821fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 822fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru verify(tethering, times(expectedInteractionsWithShowNotification)) 823fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru .showTetheredNotification(anyInt(), eq(false)); 824fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 825fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll(); 826fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 827fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 828fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru @Test 829fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception { 830fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final String[] emptyActiveIfacesList = new String[]{}; 831fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean currDisallow = false; 832fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean nextDisallow = true; 833fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int expectedInteractionsWithShowNotification = 0; 834fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 835fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList, 836fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 837fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 838fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 839fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru @Test 840fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception { 8415d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; 842fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean currDisallow = false; 843fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean nextDisallow = true; 844fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int expectedInteractionsWithShowNotification = 1; 845fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 846fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, 847fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 848fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 849fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 850fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru @Test 851fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception { 852fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final String[] nonEmptyActiveIfacesList = new String[]{}; 853fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean currDisallow = true; 854fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean nextDisallow = false; 855fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int expectedInteractionsWithShowNotification = 0; 856fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 857fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, 858fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 859fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 860fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 861fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru @Test 862fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception { 8635d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; 864fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean currDisallow = true; 865fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final boolean nextDisallow = false; 866fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int expectedInteractionsWithShowNotification = 0; 867fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 868fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, 869fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 870fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 871fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 872fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru @Test 873fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru public void testDisallowTetheringUnchanged() throws Exception { 8745d0dc453e90554e739c5994a417e73a560edc547Remi NGUYEN VAN final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME}; 875fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru final int expectedInteractionsWithShowNotification = 0; 876fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru boolean currDisallow = true; 877fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru boolean nextDisallow = true; 878fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 879fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, 880fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 881fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 882fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru currDisallow = false; 883fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru nextDisallow = false; 884fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 885fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, 886fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru expectedInteractionsWithShowNotification); 887fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru } 888fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 889fa6d5c5ca02f1bfc454bd3cd82e6c043661e7aa7Alexandru-Andrei Rotaru 8901fdc2e23b5d8136e06cafd7de896b49e5f929c7fErik Kline // TODO: Test that a request for hotspot mode doesn't interfere with an 891ea9cc488eb0f096c9fd402eff49e3d30f5b6de2eErik Kline // already operating tethering mode interface. 892497c147b821cf1c441f5047a5035281dc23e8bd9Christopher Wiley} 893