1 /* 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 17 package com.android.networkstack.tethering; 18 19 import static android.Manifest.permission.NETWORK_SETTINGS; 20 import static android.content.pm.PackageManager.GET_ACTIVITIES; 21 import static android.hardware.usb.UsbManager.USB_CONFIGURED; 22 import static android.hardware.usb.UsbManager.USB_CONNECTED; 23 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM; 24 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; 25 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 26 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 27 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 28 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 29 import static android.net.ConnectivityManager.TYPE_WIFI; 30 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 31 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 32 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; 33 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 34 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 35 import static android.net.RouteInfo.RTN_UNICAST; 36 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; 37 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL; 38 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; 39 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER; 40 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER; 41 import static android.net.TetheringManager.TETHERING_BLUETOOTH; 42 import static android.net.TetheringManager.TETHERING_ETHERNET; 43 import static android.net.TetheringManager.TETHERING_NCM; 44 import static android.net.TetheringManager.TETHERING_USB; 45 import static android.net.TetheringManager.TETHERING_WIFI; 46 import static android.net.TetheringManager.TETHERING_WIFI_P2P; 47 import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; 48 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; 49 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; 50 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; 51 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; 52 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; 53 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; 54 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; 55 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; 56 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; 57 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; 58 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 59 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 60 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 61 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 62 import static android.system.OsConstants.RT_SCOPE_UNIVERSE; 63 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 64 65 import static com.android.modules.utils.build.SdkLevel.isAtLeastS; 66 import static com.android.modules.utils.build.SdkLevel.isAtLeastT; 67 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; 68 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH; 69 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0; 70 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE; 71 import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST; 72 import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST; 73 import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener; 74 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS; 75 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION; 76 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION; 77 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; 78 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES; 79 import static com.android.testutils.TestPermissionUtil.runAsShell; 80 81 import static org.junit.Assert.assertArrayEquals; 82 import static org.junit.Assert.assertEquals; 83 import static org.junit.Assert.assertFalse; 84 import static org.junit.Assert.assertTrue; 85 import static org.junit.Assert.fail; 86 import static org.junit.Assume.assumeFalse; 87 import static org.junit.Assume.assumeTrue; 88 import static org.mockito.ArgumentMatchers.argThat; 89 import static org.mockito.ArgumentMatchers.notNull; 90 import static org.mockito.Matchers.anyInt; 91 import static org.mockito.Matchers.anyString; 92 import static org.mockito.Matchers.eq; 93 import static org.mockito.Mockito.any; 94 import static org.mockito.Mockito.doReturn; 95 import static org.mockito.Mockito.doThrow; 96 import static org.mockito.Mockito.inOrder; 97 import static org.mockito.Mockito.mock; 98 import static org.mockito.Mockito.never; 99 import static org.mockito.Mockito.reset; 100 import static org.mockito.Mockito.spy; 101 import static org.mockito.Mockito.timeout; 102 import static org.mockito.Mockito.times; 103 import static org.mockito.Mockito.verify; 104 import static org.mockito.Mockito.verifyNoMoreInteractions; 105 import static org.mockito.Mockito.when; 106 107 import android.app.usage.NetworkStatsManager; 108 import android.bluetooth.BluetoothAdapter; 109 import android.bluetooth.BluetoothPan; 110 import android.bluetooth.BluetoothProfile; 111 import android.bluetooth.BluetoothProfile.ServiceListener; 112 import android.content.BroadcastReceiver; 113 import android.content.ContentResolver; 114 import android.content.Context; 115 import android.content.Intent; 116 import android.content.IntentFilter; 117 import android.content.pm.ApplicationInfo; 118 import android.content.pm.PackageManager; 119 import android.content.res.Resources; 120 import android.database.ContentObserver; 121 import android.hardware.usb.UsbManager; 122 import android.net.ConnectivityManager.NetworkCallback; 123 import android.net.EthernetManager; 124 import android.net.EthernetManager.TetheredInterfaceCallback; 125 import android.net.EthernetManager.TetheredInterfaceRequest; 126 import android.net.IConnectivityManager; 127 import android.net.IIntResultListener; 128 import android.net.INetd; 129 import android.net.ITetheringEventCallback; 130 import android.net.InetAddresses; 131 import android.net.InterfaceConfigurationParcel; 132 import android.net.IpPrefix; 133 import android.net.LinkAddress; 134 import android.net.LinkProperties; 135 import android.net.MacAddress; 136 import android.net.Network; 137 import android.net.NetworkCapabilities; 138 import android.net.NetworkRequest; 139 import android.net.RouteInfo; 140 import android.net.TetherStatesParcel; 141 import android.net.TetheredClient; 142 import android.net.TetheredClient.AddressInfo; 143 import android.net.TetheringCallbackStartedParcel; 144 import android.net.TetheringConfigurationParcel; 145 import android.net.TetheringInterface; 146 import android.net.TetheringManager; 147 import android.net.TetheringRequestParcel; 148 import android.net.dhcp.DhcpLeaseParcelable; 149 import android.net.dhcp.DhcpServerCallbacks; 150 import android.net.dhcp.DhcpServingParamsParcel; 151 import android.net.dhcp.IDhcpEventCallbacks; 152 import android.net.dhcp.IDhcpServer; 153 import android.net.ip.DadProxy; 154 import android.net.ip.IpNeighborMonitor; 155 import android.net.ip.IpServer; 156 import android.net.ip.RouterAdvertisementDaemon; 157 import android.net.util.NetworkConstants; 158 import android.net.util.SharedLog; 159 import android.net.wifi.SoftApConfiguration; 160 import android.net.wifi.WifiClient; 161 import android.net.wifi.WifiManager; 162 import android.net.wifi.WifiManager.SoftApCallback; 163 import android.net.wifi.p2p.WifiP2pGroup; 164 import android.net.wifi.p2p.WifiP2pInfo; 165 import android.net.wifi.p2p.WifiP2pManager; 166 import android.os.Build; 167 import android.os.Bundle; 168 import android.os.Handler; 169 import android.os.Looper; 170 import android.os.PersistableBundle; 171 import android.os.RemoteException; 172 import android.os.UserHandle; 173 import android.os.UserManager; 174 import android.os.test.TestLooper; 175 import android.provider.Settings; 176 import android.telephony.CarrierConfigManager; 177 import android.telephony.PhoneStateListener; 178 import android.telephony.TelephonyManager; 179 import android.test.mock.MockContentResolver; 180 import android.util.ArraySet; 181 182 import androidx.annotation.NonNull; 183 import androidx.test.filters.SmallTest; 184 import androidx.test.runner.AndroidJUnit4; 185 186 import com.android.internal.util.StateMachine; 187 import com.android.internal.util.test.BroadcastInterceptingContext; 188 import com.android.internal.util.test.FakeSettingsProvider; 189 import com.android.net.module.util.CollectionUtils; 190 import com.android.net.module.util.InterfaceParams; 191 import com.android.networkstack.apishim.common.BluetoothPanShim; 192 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim; 193 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim; 194 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 195 import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent; 196 import com.android.testutils.MiscAsserts; 197 198 import org.junit.After; 199 import org.junit.Before; 200 import org.junit.BeforeClass; 201 import org.junit.Test; 202 import org.junit.runner.RunWith; 203 import org.mockito.ArgumentCaptor; 204 import org.mockito.InOrder; 205 import org.mockito.Mock; 206 import org.mockito.MockitoAnnotations; 207 208 import java.io.FileDescriptor; 209 import java.io.PrintWriter; 210 import java.net.Inet4Address; 211 import java.net.Inet6Address; 212 import java.util.ArrayList; 213 import java.util.Arrays; 214 import java.util.Collection; 215 import java.util.Collections; 216 import java.util.List; 217 import java.util.Set; 218 import java.util.Vector; 219 220 @RunWith(AndroidJUnit4.class) 221 @SmallTest 222 public class TetheringTest { 223 private static final int IFINDEX_OFFSET = 100; 224 225 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; 226 private static final String TEST_DUN_IFNAME = "test_dun0"; 227 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0"; 228 private static final String TEST_RNDIS_IFNAME = "test_rndis0"; 229 private static final String TEST_WIFI_IFNAME = "test_wlan0"; 230 private static final String TEST_WLAN_IFNAME = "test_wlan1"; 231 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0"; 232 private static final String TEST_NCM_IFNAME = "test_ncm0"; 233 private static final String TEST_ETH_IFNAME = "test_eth0"; 234 private static final String TEST_BT_IFNAME = "test_pan0"; 235 private static final String TETHERING_NAME = "Tethering"; 236 private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; 237 private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app"; 238 private static final String TEST_RNDIS_REGEX = "test_rndis\\d"; 239 private static final String TEST_NCM_REGEX = "test_ncm\\d"; 240 private static final String TEST_WIFI_REGEX = "test_wlan\\d"; 241 private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*"; 242 private static final String TEST_BT_REGEX = "test_pan\\d"; 243 244 private static final int CELLULAR_NETID = 100; 245 private static final int WIFI_NETID = 101; 246 private static final int DUN_NETID = 102; 247 248 private static final int TETHER_USB_RNDIS_NCM_FUNCTIONS = 2; 249 250 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000; 251 252 @Mock private ApplicationInfo mApplicationInfo; 253 @Mock private Context mContext; 254 @Mock private NetworkStatsManager mStatsManager; 255 @Mock private OffloadHardwareInterface mOffloadHardwareInterface; 256 @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats; 257 @Mock private Resources mResources; 258 @Mock private TelephonyManager mTelephonyManager; 259 @Mock private UsbManager mUsbManager; 260 @Mock private WifiManager mWifiManager; 261 @Mock private CarrierConfigManager mCarrierConfigManager; 262 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator; 263 @Mock private DadProxy mDadProxy; 264 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; 265 @Mock private IpNeighborMonitor mIpNeighborMonitor; 266 @Mock private IDhcpServer mDhcpServer; 267 @Mock private INetd mNetd; 268 @Mock private UserManager mUserManager; 269 @Mock private EthernetManager mEm; 270 @Mock private TetheringNotificationUpdater mNotificationUpdater; 271 @Mock private BpfCoordinator mBpfCoordinator; 272 @Mock private PackageManager mPackageManager; 273 @Mock private BluetoothAdapter mBluetoothAdapter; 274 @Mock private BluetoothPan mBluetoothPan; 275 @Mock private BluetoothPanShim mBluetoothPanShim; 276 @Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim; 277 278 private final MockIpServerDependencies mIpServerDependencies = 279 spy(new MockIpServerDependencies()); 280 private final MockTetheringDependencies mTetheringDependencies = 281 new MockTetheringDependencies(); 282 283 // Like so many Android system APIs, these cannot be mocked because it is marked final. 284 // We have to use the real versions. 285 private final PersistableBundle mCarrierConfig = new PersistableBundle(); 286 private final TestLooper mLooper = new TestLooper(); 287 288 private Vector<Intent> mIntents; 289 private BroadcastInterceptingContext mServiceContext; 290 private MockContentResolver mContentResolver; 291 private BroadcastReceiver mBroadcastReceiver; 292 private Tethering mTethering; 293 private PhoneStateListener mPhoneStateListener; 294 private InterfaceConfigurationParcel mInterfaceConfiguration; 295 private TetheringConfiguration mConfig; 296 private EntitlementManager mEntitleMgr; 297 private OffloadController mOffloadCtrl; 298 private PrivateAddressCoordinator mPrivateAddressCoordinator; 299 private SoftApCallback mSoftApCallback; 300 private UpstreamNetworkMonitor mUpstreamNetworkMonitor; 301 private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim; 302 303 private TestConnectivityManager mCm; 304 private boolean mForceEthernetServiceUnavailable = false; 305 306 private class TestContext extends BroadcastInterceptingContext { TestContext(Context base)307 TestContext(Context base) { 308 super(base); 309 } 310 311 @Override getApplicationInfo()312 public ApplicationInfo getApplicationInfo() { 313 return mApplicationInfo; 314 } 315 316 @Override getContentResolver()317 public ContentResolver getContentResolver() { 318 return mContentResolver; 319 } 320 321 @Override getPackageName()322 public String getPackageName() { 323 return "TetheringTest"; 324 } 325 326 @Override getResources()327 public Resources getResources() { 328 return mResources; 329 } 330 331 @Override getSystemService(String name)332 public Object getSystemService(String name) { 333 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; 334 if (Context.USB_SERVICE.equals(name)) return mUsbManager; 335 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 336 if (Context.USER_SERVICE.equals(name)) return mUserManager; 337 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 338 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 339 if (Context.ETHERNET_SERVICE.equals(name)) { 340 if (mForceEthernetServiceUnavailable) return null; 341 342 return mEm; 343 } 344 return super.getSystemService(name); 345 } 346 347 @Override getPackageManager()348 public PackageManager getPackageManager() { 349 return mPackageManager; 350 } 351 352 @Override getSystemServiceName(Class<?> serviceClass)353 public String getSystemServiceName(Class<?> serviceClass) { 354 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; 355 return super.getSystemServiceName(serviceClass); 356 } 357 } 358 359 public class MockIpServerDependencies extends IpServer.Dependencies { 360 @Override getDadProxy( Handler handler, InterfaceParams ifParams)361 public DadProxy getDadProxy( 362 Handler handler, InterfaceParams ifParams) { 363 return mDadProxy; 364 } 365 366 @Override getRouterAdvertisementDaemon( InterfaceParams ifParams)367 public RouterAdvertisementDaemon getRouterAdvertisementDaemon( 368 InterfaceParams ifParams) { 369 return mRouterAdvertisementDaemon; 370 } 371 372 @Override getInterfaceParams(String ifName)373 public InterfaceParams getInterfaceParams(String ifName) { 374 assertTrue("Non-mocked interface " + ifName, 375 ifName.equals(TEST_RNDIS_IFNAME) 376 || ifName.equals(TEST_WLAN_IFNAME) 377 || ifName.equals(TEST_WIFI_IFNAME) 378 || ifName.equals(TEST_MOBILE_IFNAME) 379 || ifName.equals(TEST_DUN_IFNAME) 380 || ifName.equals(TEST_P2P_IFNAME) 381 || ifName.equals(TEST_NCM_IFNAME) 382 || ifName.equals(TEST_ETH_IFNAME) 383 || ifName.equals(TEST_BT_IFNAME)); 384 final String[] ifaces = new String[] { 385 TEST_RNDIS_IFNAME, TEST_WLAN_IFNAME, TEST_WIFI_IFNAME, TEST_MOBILE_IFNAME, 386 TEST_DUN_IFNAME, TEST_P2P_IFNAME, TEST_NCM_IFNAME, TEST_ETH_IFNAME}; 387 return new InterfaceParams(ifName, 388 CollectionUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET, 389 MacAddress.ALL_ZEROS_ADDRESS); 390 } 391 392 @Override makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb)393 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, 394 DhcpServerCallbacks cb) { 395 new Thread(() -> { 396 try { 397 cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer); 398 } catch (RemoteException e) { 399 fail(e.getMessage()); 400 } 401 }).run(); 402 } 403 getIpNeighborMonitor(Handler h, SharedLog l, IpNeighborMonitor.NeighborEventConsumer c)404 public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l, 405 IpNeighborMonitor.NeighborEventConsumer c) { 406 return mIpNeighborMonitor; 407 } 408 } 409 410 public class MockTetheringDependencies extends TetheringDependencies { 411 StateMachine mUpstreamNetworkMonitorSM; 412 ArrayList<IpServer> mIpv6CoordinatorNotifyList; 413 414 @Override getBpfCoordinator( BpfCoordinator.Dependencies deps)415 public BpfCoordinator getBpfCoordinator( 416 BpfCoordinator.Dependencies deps) { 417 return mBpfCoordinator; 418 } 419 420 @Override getOffloadHardwareInterface(Handler h, SharedLog log)421 public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { 422 return mOffloadHardwareInterface; 423 } 424 425 @Override getOffloadController(Handler h, SharedLog log, OffloadController.Dependencies deps)426 public OffloadController getOffloadController(Handler h, SharedLog log, 427 OffloadController.Dependencies deps) { 428 mOffloadCtrl = spy(super.getOffloadController(h, log, deps)); 429 // Return real object here instead of mock because 430 // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object. 431 return mOffloadCtrl; 432 } 433 434 @Override getUpstreamNetworkMonitor(Context ctx, StateMachine target, SharedLog log, int what)435 public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, 436 StateMachine target, SharedLog log, int what) { 437 // Use a real object instead of a mock so that some tests can use a real UNM and some 438 // can use a mock. 439 mUpstreamNetworkMonitorSM = target; 440 mUpstreamNetworkMonitor = spy(super.getUpstreamNetworkMonitor(ctx, target, log, what)); 441 return mUpstreamNetworkMonitor; 442 } 443 444 @Override getIPv6TetheringCoordinator( ArrayList<IpServer> notifyList, SharedLog log)445 public IPv6TetheringCoordinator getIPv6TetheringCoordinator( 446 ArrayList<IpServer> notifyList, SharedLog log) { 447 mIpv6CoordinatorNotifyList = notifyList; 448 return mIPv6TetheringCoordinator; 449 } 450 451 @Override getIpServerDependencies()452 public IpServer.Dependencies getIpServerDependencies() { 453 return mIpServerDependencies; 454 } 455 456 @Override getEntitlementManager(Context ctx, Handler h, SharedLog log, Runnable callback)457 public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log, 458 Runnable callback) { 459 mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback)); 460 return mEntitleMgr; 461 } 462 463 @Override generateTetheringConfiguration(Context ctx, SharedLog log, int subId)464 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, 465 int subId) { 466 mConfig = spy(new FakeTetheringConfiguration(ctx, log, subId)); 467 return mConfig; 468 } 469 470 @Override getINetd(Context context)471 public INetd getINetd(Context context) { 472 return mNetd; 473 } 474 475 @Override getTetheringLooper()476 public Looper getTetheringLooper() { 477 return mLooper.getLooper(); 478 } 479 480 @Override getContext()481 public Context getContext() { 482 return mServiceContext; 483 } 484 485 @Override getBluetoothAdapter()486 public BluetoothAdapter getBluetoothAdapter() { 487 return mBluetoothAdapter; 488 } 489 490 @Override getNotificationUpdater(Context ctx, Looper looper)491 public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) { 492 return mNotificationUpdater; 493 } 494 495 @Override isTetheringDenied()496 public boolean isTetheringDenied() { 497 return false; 498 } 499 500 @Override getPrivateAddressCoordinator(Context ctx, TetheringConfiguration cfg)501 public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx, 502 TetheringConfiguration cfg) { 503 mPrivateAddressCoordinator = super.getPrivateAddressCoordinator(ctx, cfg); 504 return mPrivateAddressCoordinator; 505 } 506 507 @Override getBluetoothPanShim(BluetoothPan pan)508 public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) { 509 try { 510 when(mBluetoothPanShim.requestTetheredInterface( 511 any(), any())).thenReturn(mTetheredInterfaceRequestShim); 512 } catch (UnsupportedApiLevelException e) { 513 fail("BluetoothPan#requestTetheredInterface is not supported"); 514 } 515 return mBluetoothPanShim; 516 } 517 } 518 buildUpstreamLinkProperties(String interfaceName, boolean withIPv4, boolean withIPv6, boolean with464xlat)519 private static LinkProperties buildUpstreamLinkProperties(String interfaceName, 520 boolean withIPv4, boolean withIPv6, boolean with464xlat) { 521 final LinkProperties prop = new LinkProperties(); 522 prop.setInterfaceName(interfaceName); 523 524 if (withIPv4) { 525 prop.addLinkAddress(new LinkAddress("10.1.2.3/15")); 526 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 527 InetAddresses.parseNumericAddress("10.0.0.1"), 528 interfaceName, RTN_UNICAST)); 529 } 530 531 if (withIPv6) { 532 prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2")); 533 prop.addLinkAddress( 534 new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), 535 NetworkConstants.RFC7421_PREFIX_LENGTH)); 536 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), 537 InetAddresses.parseNumericAddress("2001:db8::1"), 538 interfaceName, RTN_UNICAST)); 539 } 540 541 if (with464xlat) { 542 final String clatInterface = "v4-" + interfaceName; 543 final LinkProperties stackedLink = new LinkProperties(); 544 stackedLink.setInterfaceName(clatInterface); 545 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 546 InetAddresses.parseNumericAddress("192.0.0.1"), 547 clatInterface, RTN_UNICAST)); 548 549 prop.addStackedLink(stackedLink); 550 } 551 552 return prop; 553 } 554 buildUpstreamCapabilities(int transport, int... otherCaps)555 private static NetworkCapabilities buildUpstreamCapabilities(int transport, int... otherCaps) { 556 // TODO: add NOT_VCN_MANAGED. 557 final NetworkCapabilities nc = new NetworkCapabilities() 558 .addTransportType(transport); 559 for (int cap : otherCaps) { 560 nc.addCapability(cap); 561 } 562 return nc; 563 } 564 buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, boolean with464xlat)565 private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, 566 boolean withIPv6, boolean with464xlat) { 567 return new UpstreamNetworkState( 568 buildUpstreamLinkProperties(TEST_MOBILE_IFNAME, withIPv4, withIPv6, with464xlat), 569 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_INTERNET), 570 new Network(CELLULAR_NETID)); 571 } 572 buildMobileIPv4UpstreamState()573 private static UpstreamNetworkState buildMobileIPv4UpstreamState() { 574 return buildMobileUpstreamState(true, false, false); 575 } 576 buildMobileIPv6UpstreamState()577 private static UpstreamNetworkState buildMobileIPv6UpstreamState() { 578 return buildMobileUpstreamState(false, true, false); 579 } 580 buildMobileDualStackUpstreamState()581 private static UpstreamNetworkState buildMobileDualStackUpstreamState() { 582 return buildMobileUpstreamState(true, true, false); 583 } 584 buildMobile464xlatUpstreamState()585 private static UpstreamNetworkState buildMobile464xlatUpstreamState() { 586 return buildMobileUpstreamState(false, true, true); 587 } 588 buildWifiUpstreamState()589 private static UpstreamNetworkState buildWifiUpstreamState() { 590 return new UpstreamNetworkState( 591 buildUpstreamLinkProperties(TEST_WIFI_IFNAME, true /* IPv4 */, true /* IPv6 */, 592 false /* 464xlat */), 593 buildUpstreamCapabilities(TRANSPORT_WIFI, NET_CAPABILITY_INTERNET), 594 new Network(WIFI_NETID)); 595 } 596 buildDunUpstreamState()597 private static UpstreamNetworkState buildDunUpstreamState() { 598 return new UpstreamNetworkState( 599 buildUpstreamLinkProperties(TEST_DUN_IFNAME, true /* IPv4 */, true /* IPv6 */, 600 false /* 464xlat */), 601 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_DUN), 602 new Network(DUN_NETID)); 603 } 604 605 // See FakeSettingsProvider#clearSettingsProvider() that this also needs to be called before 606 // use. 607 @BeforeClass setupOnce()608 public static void setupOnce() { 609 FakeSettingsProvider.clearSettingsProvider(); 610 } 611 612 @Before setUp()613 public void setUp() throws Exception { 614 MockitoAnnotations.initMocks(this); 615 when(mResources.getStringArray(R.array.config_tether_dhcp_range)) 616 .thenReturn(new String[0]); 617 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 618 false); 619 when(mNetd.interfaceGetList()) 620 .thenReturn(new String[] { 621 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME, 622 TEST_NCM_IFNAME, TEST_ETH_IFNAME, TEST_BT_IFNAME}); 623 when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn(""); 624 mInterfaceConfiguration = new InterfaceConfigurationParcel(); 625 mInterfaceConfiguration.flags = new String[0]; 626 when(mRouterAdvertisementDaemon.start()) 627 .thenReturn(true); 628 initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0, 629 0 /* defaultDisabled */); 630 when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats); 631 632 mServiceContext = new TestContext(mContext); 633 mServiceContext.setUseRegisteredHandlers(true); 634 mContentResolver = new MockContentResolver(mServiceContext); 635 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 636 setTetheringSupported(true /* supported */); 637 mIntents = new Vector<>(); 638 mBroadcastReceiver = new BroadcastReceiver() { 639 @Override 640 public void onReceive(Context context, Intent intent) { 641 mIntents.addElement(intent); 642 } 643 }; 644 mServiceContext.registerReceiver(mBroadcastReceiver, 645 new IntentFilter(ACTION_TETHER_STATE_CHANGED)); 646 647 mCm = spy(new TestConnectivityManager(mServiceContext, mock(IConnectivityManager.class))); 648 649 mTethering = makeTethering(); 650 verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any()); 651 verify(mNetd).registerUnsolicitedEventListener(any()); 652 verifyDefaultNetworkRequestFiled(); 653 654 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = 655 ArgumentCaptor.forClass(PhoneStateListener.class); 656 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(), 657 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)); 658 mPhoneStateListener = phoneListenerCaptor.getValue(); 659 660 final ArgumentCaptor<SoftApCallback> softApCallbackCaptor = 661 ArgumentCaptor.forClass(SoftApCallback.class); 662 verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture()); 663 mSoftApCallback = softApCallbackCaptor.getValue(); 664 665 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true); 666 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 667 } 668 setTetheringSupported(final boolean supported)669 private void setTetheringSupported(final boolean supported) { 670 Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 671 supported ? 1 : 0); 672 when(mUserManager.hasUserRestriction( 673 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported); 674 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 675 TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION); 676 // Setup tetherable configuration. 677 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 678 .thenReturn(new String[] {TEST_RNDIS_REGEX}); 679 when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) 680 .thenReturn(new String[] {TEST_WIFI_REGEX}); 681 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 682 .thenReturn(new String[] {TEST_P2P_REGEX}); 683 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) 684 .thenReturn(new String[] {TEST_BT_REGEX}); 685 when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) 686 .thenReturn(new String[] {TEST_NCM_REGEX}); 687 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true); 688 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( 689 new int[] {TYPE_WIFI, TYPE_MOBILE_DUN}); 690 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); 691 } 692 initTetheringUpstream(UpstreamNetworkState upstreamState)693 private void initTetheringUpstream(UpstreamNetworkState upstreamState) { 694 doReturn(upstreamState).when(mUpstreamNetworkMonitor).getCurrentPreferredUpstream(); 695 doReturn(upstreamState).when(mUpstreamNetworkMonitor).selectPreferredUpstreamType(any()); 696 } 697 makeTethering()698 private Tethering makeTethering() { 699 return new Tethering(mTetheringDependencies); 700 } 701 createTetheringRequestParcel(final int type)702 private TetheringRequestParcel createTetheringRequestParcel(final int type) { 703 return createTetheringRequestParcel(type, null, null, false, CONNECTIVITY_SCOPE_GLOBAL); 704 } 705 createTetheringRequestParcel(final int type, final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt, final int scope)706 private TetheringRequestParcel createTetheringRequestParcel(final int type, 707 final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt, 708 final int scope) { 709 final TetheringRequestParcel request = new TetheringRequestParcel(); 710 request.tetheringType = type; 711 request.localIPv4Address = serverAddr; 712 request.staticClientAddress = clientAddr; 713 request.exemptFromEntitlementCheck = exempt; 714 request.showProvisioningUi = false; 715 request.connectivityScope = scope; 716 717 return request; 718 } 719 720 @After tearDown()721 public void tearDown() { 722 mServiceContext.unregisterReceiver(mBroadcastReceiver); 723 FakeSettingsProvider.clearSettingsProvider(); 724 } 725 sendWifiApStateChanged(int state)726 private void sendWifiApStateChanged(int state) { 727 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 728 intent.putExtra(EXTRA_WIFI_AP_STATE, state); 729 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 730 mLooper.dispatchAll(); 731 } 732 sendWifiApStateChanged(int state, String ifname, int ipmode)733 private void sendWifiApStateChanged(int state, String ifname, int ipmode) { 734 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 735 intent.putExtra(EXTRA_WIFI_AP_STATE, state); 736 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname); 737 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode); 738 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 739 mLooper.dispatchAll(); 740 } 741 742 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = { 743 android.Manifest.permission.ACCESS_FINE_LOCATION, 744 android.Manifest.permission.ACCESS_WIFI_STATE 745 }; 746 sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname)747 private void sendWifiP2pConnectionChanged( 748 boolean isGroupFormed, boolean isGroupOwner, String ifname) { 749 WifiP2pGroup group = null; 750 WifiP2pInfo p2pInfo = new WifiP2pInfo(); 751 p2pInfo.groupFormed = isGroupFormed; 752 if (isGroupFormed) { 753 p2pInfo.isGroupOwner = isGroupOwner; 754 group = mock(WifiP2pGroup.class); 755 when(group.isGroupOwner()).thenReturn(isGroupOwner); 756 when(group.getInterface()).thenReturn(ifname); 757 } 758 759 final Intent intent = mock(Intent.class); 760 when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 761 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo); 762 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group); 763 764 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL, 765 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST); 766 mLooper.dispatchAll(); 767 } 768 769 // enableType: 770 // No function enabled = -1 771 // TETHER_USB_RNDIS_FUNCTION = 0 772 // TETHER_USB_NCM_FUNCTIONS = 1 773 // TETHER_USB_RNDIS_NCM_FUNCTIONS = 2 tetherUsbFunctionMatches(int function, int enabledType)774 private boolean tetherUsbFunctionMatches(int function, int enabledType) { 775 if (enabledType < 0) return false; 776 777 if (enabledType == TETHER_USB_RNDIS_NCM_FUNCTIONS) return function < enabledType; 778 779 return function == enabledType; 780 } 781 sendUsbBroadcast(boolean connected, boolean configured, int function)782 private void sendUsbBroadcast(boolean connected, boolean configured, int function) { 783 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 784 intent.putExtra(USB_CONNECTED, connected); 785 intent.putExtra(USB_CONFIGURED, configured); 786 intent.putExtra(USB_FUNCTION_RNDIS, 787 tetherUsbFunctionMatches(TETHER_USB_RNDIS_FUNCTION, function)); 788 intent.putExtra(USB_FUNCTION_NCM, 789 tetherUsbFunctionMatches(TETHER_USB_NCM_FUNCTION, function)); 790 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 791 mLooper.dispatchAll(); 792 } 793 sendConfigurationChanged()794 private void sendConfigurationChanged() { 795 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 796 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 797 mLooper.dispatchAll(); 798 } 799 verifyDefaultNetworkRequestFiled()800 private void verifyDefaultNetworkRequestFiled() { 801 if (isAtLeastS()) { 802 verify(mCm, times(1)).registerSystemDefaultNetworkCallback( 803 any(NetworkCallback.class), any(Handler.class)); 804 } else { 805 ArgumentCaptor<NetworkRequest> reqCaptor = ArgumentCaptor.forClass( 806 NetworkRequest.class); 807 verify(mCm, times(1)).requestNetwork(reqCaptor.capture(), 808 any(NetworkCallback.class), any(Handler.class)); 809 assertTrue(TestConnectivityManager.looksLikeDefaultRequest(reqCaptor.getValue())); 810 } 811 812 // The default network request is only ever filed once. 813 verifyNoMoreInteractions(mCm); 814 } 815 verifyInterfaceServingModeStarted(String ifname)816 private void verifyInterfaceServingModeStarted(String ifname) throws Exception { 817 verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 818 verify(mNetd, times(1)).tetherInterfaceAdd(ifname); 819 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname); 820 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname), 821 anyString(), anyString()); 822 } 823 verifyTetheringBroadcast(String ifname, String whichExtra)824 private void verifyTetheringBroadcast(String ifname, String whichExtra) { 825 // Verify that ifname is in the whichExtra array of the tether state changed broadcast. 826 final Intent bcast = mIntents.get(0); 827 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction()); 828 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra); 829 assertTrue(ifnames.contains(ifname)); 830 mIntents.remove(bcast); 831 } 832 failingLocalOnlyHotspotLegacyApBroadcast( boolean emulateInterfaceStatusChanged)833 public void failingLocalOnlyHotspotLegacyApBroadcast( 834 boolean emulateInterfaceStatusChanged) throws Exception { 835 // Emulate externally-visible WifiManager effects, causing the 836 // per-interface state machine to start up, and telling us that 837 // hotspot mode is to be started. 838 if (emulateInterfaceStatusChanged) { 839 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 840 } 841 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 842 843 // If, and only if, Tethering received an interface status changed then 844 // it creates a IpServer and sends out a broadcast indicating that the 845 // interface is "available". 846 if (emulateInterfaceStatusChanged) { 847 // There is 1 IpServer state change event: STATE_AVAILABLE 848 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); 849 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 850 verify(mWifiManager).updateInterfaceIpState( 851 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 852 } 853 verifyNoMoreInteractions(mNetd); 854 verifyNoMoreInteractions(mWifiManager); 855 } 856 prepareNcmTethering()857 private void prepareNcmTethering() { 858 // Emulate startTethering(TETHERING_NCM) called 859 mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null); 860 mLooper.dispatchAll(); 861 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); 862 } 863 prepareUsbTethering()864 private void prepareUsbTethering() { 865 // Emulate pressing the USB tethering button in Settings UI. 866 final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB); 867 mTethering.startTethering(request, null); 868 mLooper.dispatchAll(); 869 870 assertEquals(1, mTethering.getActiveTetheringRequests().size()); 871 assertEquals(request, mTethering.getActiveTetheringRequests().get(TETHERING_USB)); 872 873 if (mTethering.getTetheringConfiguration().isUsingNcm()) { 874 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NCM); 875 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true); 876 } else { 877 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 878 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 879 } 880 881 } 882 883 @Test testUsbConfiguredBroadcastStartsTethering()884 public void testUsbConfiguredBroadcastStartsTethering() throws Exception { 885 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 886 initTetheringUpstream(upstreamState); 887 prepareUsbTethering(); 888 889 // This should produce no activity of any kind. 890 verifyNoMoreInteractions(mNetd); 891 892 // Pretend we then receive USB configured broadcast. 893 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 894 // Now we should see the start of tethering mechanics (in this case: 895 // tetherMatchingInterfaces() which starts by fetching all interfaces). 896 verify(mNetd, times(1)).interfaceGetList(); 897 898 // UpstreamNetworkMonitor should receive selected upstream 899 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream(); 900 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); 901 } 902 903 @Test failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged()904 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception { 905 failingLocalOnlyHotspotLegacyApBroadcast(true); 906 } 907 908 @Test failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged()909 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception { 910 failingLocalOnlyHotspotLegacyApBroadcast(false); 911 } 912 workingLocalOnlyHotspotEnrichedApBroadcast( boolean emulateInterfaceStatusChanged)913 public void workingLocalOnlyHotspotEnrichedApBroadcast( 914 boolean emulateInterfaceStatusChanged) throws Exception { 915 // Emulate externally-visible WifiManager effects, causing the 916 // per-interface state machine to start up, and telling us that 917 // hotspot mode is to be started. 918 if (emulateInterfaceStatusChanged) { 919 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 920 } 921 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 922 923 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); 924 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 925 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 926 verify(mNetd, times(1)).tetherStartWithConfiguration(any()); 927 verifyNoMoreInteractions(mNetd); 928 verify(mWifiManager).updateInterfaceIpState( 929 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 930 verify(mWifiManager).updateInterfaceIpState( 931 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); 932 verifyNoMoreInteractions(mWifiManager); 933 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 934 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); 935 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY 936 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 937 938 // Emulate externally-visible WifiManager effects, when hotspot mode 939 // is being torn down. 940 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 941 mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 942 mLooper.dispatchAll(); 943 944 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 945 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); 946 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 947 // interfaceSetCfg() called once for enabling and twice disabling IPv4. 948 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 949 verify(mNetd, times(1)).tetherStop(); 950 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); 951 verify(mWifiManager, times(3)).updateInterfaceIpState( 952 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 953 verifyNoMoreInteractions(mNetd); 954 verifyNoMoreInteractions(mWifiManager); 955 // Asking for the last error after the per-interface state machine 956 // has been reaped yields an unknown interface error. 957 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME)); 958 } 959 960 /** 961 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator. 962 */ sendIPv6TetherUpdates(UpstreamNetworkState upstreamState)963 private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) { 964 // IPv6TetheringCoordinator must have been notified of downstream 965 for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) { 966 UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false); 967 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, 968 upstreamState.linkProperties.isIpv6Provisioned() 969 ? ipv6OnlyState.linkProperties 970 : null); 971 break; 972 } 973 mLooper.dispatchAll(); 974 } 975 runUsbTethering(UpstreamNetworkState upstreamState)976 private void runUsbTethering(UpstreamNetworkState upstreamState) { 977 initTetheringUpstream(upstreamState); 978 prepareUsbTethering(); 979 if (mTethering.getTetheringConfiguration().isUsingNcm()) { 980 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 981 verify(mIPv6TetheringCoordinator).addActiveDownstream( 982 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_NCM_IFNAME)), 983 eq(IpServer.STATE_TETHERED)); 984 } else { 985 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 986 verify(mIPv6TetheringCoordinator).addActiveDownstream( 987 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_RNDIS_IFNAME)), 988 eq(IpServer.STATE_TETHERED)); 989 } 990 991 } 992 assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName)993 private void assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName) { 994 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME) 995 || "T".equals(Build.VERSION.CODENAME)) { 996 verify(mDadProxy, times(numOfCalls)).setUpstreamIface( 997 argThat(ifaceParams -> ifaceName.equals(ifaceParams.name))); 998 } 999 } 1000 1001 @Test workingMobileUsbTethering_IPv4()1002 public void workingMobileUsbTethering_IPv4() throws Exception { 1003 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1004 runUsbTethering(upstreamState); 1005 1006 verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1007 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1008 1009 sendIPv6TetherUpdates(upstreamState); 1010 assertSetIfaceToDadProxy(0 /* numOfCalls */, "" /* ifaceName */); 1011 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull()); 1012 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1013 any(), any()); 1014 } 1015 1016 @Test workingMobileUsbTethering_IPv4LegacyDhcp()1017 public void workingMobileUsbTethering_IPv4LegacyDhcp() { 1018 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 1019 true); 1020 sendConfigurationChanged(); 1021 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1022 runUsbTethering(upstreamState); 1023 sendIPv6TetherUpdates(upstreamState); 1024 1025 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); 1026 } 1027 1028 @Test workingMobileUsbTethering_IPv6()1029 public void workingMobileUsbTethering_IPv6() throws Exception { 1030 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1031 runUsbTethering(upstreamState); 1032 1033 verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1034 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1035 1036 sendIPv6TetherUpdates(upstreamState); 1037 // TODO: add interfaceParams to compare in verify. 1038 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1039 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1040 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1041 } 1042 1043 @Test workingMobileUsbTethering_DualStack()1044 public void workingMobileUsbTethering_DualStack() throws Exception { 1045 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 1046 runUsbTethering(upstreamState); 1047 1048 verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1049 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1050 verify(mRouterAdvertisementDaemon, times(1)).start(); 1051 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1052 any(), any()); 1053 1054 sendIPv6TetherUpdates(upstreamState); 1055 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1056 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1057 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1058 } 1059 1060 @Test workingMobileUsbTethering_MultipleUpstreams()1061 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception { 1062 UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState(); 1063 runUsbTethering(upstreamState); 1064 1065 verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_XLAT_MOBILE_IFNAME); 1066 verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1067 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1068 any(), any()); 1069 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, 1070 TEST_XLAT_MOBILE_IFNAME); 1071 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1072 1073 sendIPv6TetherUpdates(upstreamState); 1074 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1075 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1076 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1077 } 1078 1079 @Test workingMobileUsbTethering_v6Then464xlat()1080 public void workingMobileUsbTethering_v6Then464xlat() throws Exception { 1081 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 1082 TetheringConfiguration.TETHER_USB_NCM_FUNCTION); 1083 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 1084 .thenReturn(new String[] {TEST_NCM_REGEX}); 1085 sendConfigurationChanged(); 1086 1087 // Setup IPv6 1088 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1089 runUsbTethering(upstreamState); 1090 1091 verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1092 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1093 any(), any()); 1094 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1095 1096 // Then 464xlat comes up 1097 upstreamState = buildMobile464xlatUpstreamState(); 1098 initTetheringUpstream(upstreamState); 1099 1100 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES. 1101 mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage( 1102 Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK, 1103 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 1104 0, 1105 upstreamState); 1106 mLooper.dispatchAll(); 1107 1108 // Forwarding is added for 464xlat 1109 verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_XLAT_MOBILE_IFNAME); 1110 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME, 1111 TEST_XLAT_MOBILE_IFNAME); 1112 // Forwarding was not re-added for v6 (still times(1)) 1113 verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1114 verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1115 // DHCP not restarted on downstream (still times(1)) 1116 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1117 any(), any()); 1118 } 1119 1120 @Test configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes()1121 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception { 1122 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); 1123 sendConfigurationChanged(); 1124 1125 // Setup IPv6 1126 final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1127 runUsbTethering(upstreamState); 1128 1129 // UpstreamNetworkMonitor should choose upstream automatically 1130 // (in this specific case: choose the default network). 1131 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream(); 1132 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); 1133 1134 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); 1135 } 1136 verifyDisableTryCellWhenTetheringStop(InOrder inOrder)1137 private void verifyDisableTryCellWhenTetheringStop(InOrder inOrder) { 1138 runStopUSBTethering(); 1139 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1140 } 1141 upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi)1142 private void upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, 1143 TestNetworkAgent mobile, TestNetworkAgent wifi) throws Exception { 1144 // Enable automatic upstream selection. 1145 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic); 1146 sendConfigurationChanged(); 1147 mLooper.dispatchAll(); 1148 1149 // Start USB tethering with no current upstream. 1150 prepareUsbTethering(); 1151 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1152 inOrder.verify(mUpstreamNetworkMonitor).startObserveAllNetworks(); 1153 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1154 1155 // Pretend cellular connected and expect the upstream to be set. 1156 mobile.fakeConnect(); 1157 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST); 1158 mLooper.dispatchAll(); 1159 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1160 1161 // Switch upstream to wifi. 1162 wifi.fakeConnect(); 1163 mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST); 1164 mLooper.dispatchAll(); 1165 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1166 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId); 1167 } 1168 1169 @Test testAutomaticUpstreamSelection()1170 public void testAutomaticUpstreamSelection() throws Exception { 1171 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1172 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1173 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1174 // Enable automatic upstream selection. 1175 upstreamSelectionTestCommon(true, inOrder, mobile, wifi); 1176 1177 // This code has historically been racy, so test different orderings of CONNECTIVITY_ACTION 1178 // broadcasts and callbacks, and add mLooper.dispatchAll() calls between the two. 1179 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1180 1181 // Switch upstreams a few times. 1182 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll); 1183 mLooper.dispatchAll(); 1184 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1185 1186 mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST, doDispatchAll); 1187 mLooper.dispatchAll(); 1188 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1189 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId); 1190 1191 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1192 mLooper.dispatchAll(); 1193 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1194 1195 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1196 mLooper.dispatchAll(); 1197 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1198 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId); 1199 1200 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll); 1201 mLooper.dispatchAll(); 1202 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1203 1204 // Wifi disconnecting should not have any affect since it's not the current upstream. 1205 wifi.fakeDisconnect(); 1206 mLooper.dispatchAll(); 1207 inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any()); 1208 1209 // Lose and regain upstream. 1210 assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1211 .hasIPv4Address()); 1212 mCm.makeDefaultNetwork(null, BROADCAST_FIRST, doDispatchAll); 1213 mLooper.dispatchAll(); 1214 mobile.fakeDisconnect(); 1215 mLooper.dispatchAll(); 1216 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1217 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null); 1218 1219 mobile = new TestNetworkAgent(mCm, buildMobile464xlatUpstreamState()); 1220 mobile.fakeConnect(); 1221 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll); 1222 mLooper.dispatchAll(); 1223 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1224 1225 // Check the IP addresses to ensure that the upstream is indeed not the same as the previous 1226 // mobile upstream, even though the netId is (unrealistically) the same. 1227 assertFalse(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1228 .hasIPv4Address()); 1229 1230 // Lose and regain upstream again. 1231 mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll); 1232 mobile.fakeDisconnect(); 1233 mLooper.dispatchAll(); 1234 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1235 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null); 1236 1237 mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1238 mobile.fakeConnect(); 1239 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll); 1240 mLooper.dispatchAll(); 1241 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1242 1243 assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1244 .hasIPv4Address()); 1245 1246 // Check that the code does not crash if onLinkPropertiesChanged is received after onLost. 1247 mobile.fakeDisconnect(); 1248 mobile.sendLinkProperties(); 1249 mLooper.dispatchAll(); 1250 1251 verifyDisableTryCellWhenTetheringStop(inOrder); 1252 } 1253 1254 @Test testLegacyUpstreamSelection()1255 public void testLegacyUpstreamSelection() throws Exception { 1256 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1257 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1258 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1259 // Enable legacy upstream selection. 1260 upstreamSelectionTestCommon(false, inOrder, mobile, wifi); 1261 1262 // Wifi disconnecting and the default network switch to mobile, the upstream should also 1263 // switch to mobile. 1264 wifi.fakeDisconnect(); 1265 mLooper.dispatchAll(); 1266 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, null); 1267 mLooper.dispatchAll(); 1268 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId); 1269 1270 wifi.fakeConnect(); 1271 mLooper.dispatchAll(); 1272 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST, null); 1273 mLooper.dispatchAll(); 1274 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1275 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId); 1276 1277 verifyDisableTryCellWhenTetheringStop(inOrder); 1278 } 1279 1280 @Test testChooseDunUpstreamByAutomaticMode()1281 public void testChooseDunUpstreamByAutomaticMode() throws Exception { 1282 // Enable automatic upstream selection. 1283 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1284 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1285 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1286 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1287 chooseDunUpstreamTestCommon(true, inOrder, mobile, wifi, dun); 1288 1289 // When default network switch to mobile and wifi is connected (may have low signal), 1290 // automatic mode would request dun again and choose it as upstream. 1291 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1292 mLooper.dispatchAll(); 1293 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1294 ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class); 1295 inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), any()); 1296 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null); 1297 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1298 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1299 mLooper.dispatchAll(); 1300 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId); 1301 1302 // Lose and regain upstream again. 1303 dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1304 mLooper.dispatchAll(); 1305 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1306 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null); 1307 inOrder.verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class)); 1308 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1309 mLooper.dispatchAll(); 1310 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId); 1311 1312 verifyDisableTryCellWhenTetheringStop(inOrder); 1313 } 1314 1315 @Test testChooseDunUpstreamByLegacyMode()1316 public void testChooseDunUpstreamByLegacyMode() throws Exception { 1317 // Enable Legacy upstream selection. 1318 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1319 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1320 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1321 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1322 chooseDunUpstreamTestCommon(false, inOrder, mobile, wifi, dun); 1323 1324 // Legacy mode would keep use wifi as upstream (because it has higher priority in the 1325 // list). 1326 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1327 mLooper.dispatchAll(); 1328 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1329 inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any()); 1330 // BUG: when wifi disconnect, the dun request would not be filed again because wifi is 1331 // no longer be default network which do not have CONNECTIVIY_ACTION broadcast. 1332 wifi.fakeDisconnect(); 1333 mLooper.dispatchAll(); 1334 inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1335 any()); 1336 1337 // Change the legacy priority list that dun is higher than wifi. 1338 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( 1339 new int[] { TYPE_MOBILE_DUN, TYPE_WIFI }); 1340 sendConfigurationChanged(); 1341 mLooper.dispatchAll(); 1342 1343 // Make wifi as default network. Note: mobile also connected. 1344 wifi.fakeConnect(); 1345 mLooper.dispatchAll(); 1346 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1347 mLooper.dispatchAll(); 1348 // BUG: dun has higher priority than wifi but tethering don't file dun request because 1349 // current upstream is wifi. 1350 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1351 inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1352 any()); 1353 1354 verifyDisableTryCellWhenTetheringStop(inOrder); 1355 } 1356 chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)1357 private void chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, 1358 TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun) throws Exception { 1359 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic); 1360 when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true); 1361 sendConfigurationChanged(); 1362 mLooper.dispatchAll(); 1363 1364 // Start USB tethering with no current upstream. 1365 prepareUsbTethering(); 1366 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1367 inOrder.verify(mUpstreamNetworkMonitor).startObserveAllNetworks(); 1368 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1369 ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class); 1370 inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1371 captor.capture()); 1372 final NetworkCallback dunNetworkCallback1 = captor.getValue(); 1373 1374 // Pretend cellular connected and expect the upstream to be set. 1375 mobile.fakeConnect(); 1376 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST); 1377 mLooper.dispatchAll(); 1378 inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(mobile.networkId); 1379 1380 // Pretend dun connected and expect choose dun as upstream. 1381 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1382 dun.fakeConnect(BROADCAST_FIRST, doDispatchAll); 1383 mLooper.dispatchAll(); 1384 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId); 1385 1386 // When wifi connected, unregister dun request and choose wifi as upstream. 1387 wifi.fakeConnect(); 1388 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1389 mLooper.dispatchAll(); 1390 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1391 inOrder.verify(mCm).unregisterNetworkCallback(eq(dunNetworkCallback1)); 1392 inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId); 1393 dun.fakeDisconnect(BROADCAST_FIRST, doDispatchAll); 1394 mLooper.dispatchAll(); 1395 inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any()); 1396 } 1397 runNcmTethering()1398 private void runNcmTethering() { 1399 prepareNcmTethering(); 1400 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 1401 } 1402 1403 @Test workingNcmTethering()1404 public void workingNcmTethering() throws Exception { 1405 runNcmTethering(); 1406 1407 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1408 any(), any()); 1409 } 1410 1411 @Test workingNcmTethering_LegacyDhcp()1412 public void workingNcmTethering_LegacyDhcp() { 1413 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 1414 true); 1415 sendConfigurationChanged(); 1416 runNcmTethering(); 1417 1418 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); 1419 } 1420 1421 @Test workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged()1422 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception { 1423 workingLocalOnlyHotspotEnrichedApBroadcast(true); 1424 } 1425 1426 @Test workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged()1427 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception { 1428 workingLocalOnlyHotspotEnrichedApBroadcast(false); 1429 } 1430 1431 // TODO: Test with and without interfaceStatusChanged(). 1432 @Test failingWifiTetheringLegacyApBroadcast()1433 public void failingWifiTetheringLegacyApBroadcast() throws Exception { 1434 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); 1435 1436 // Emulate pressing the WiFi tethering button. 1437 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); 1438 mLooper.dispatchAll(); 1439 verify(mWifiManager, times(1)).startTetheredHotspot(null); 1440 verifyNoMoreInteractions(mWifiManager); 1441 verifyNoMoreInteractions(mNetd); 1442 1443 // Emulate externally-visible WifiManager effects, causing the 1444 // per-interface state machine to start up, and telling us that 1445 // tethering mode is to be started. 1446 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1447 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 1448 1449 // There is 1 IpServer state change event: STATE_AVAILABLE 1450 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); 1451 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 1452 verify(mWifiManager).updateInterfaceIpState( 1453 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1454 verifyNoMoreInteractions(mNetd); 1455 verifyNoMoreInteractions(mWifiManager); 1456 } 1457 1458 // TODO: Test with and without interfaceStatusChanged(). 1459 @Test workingWifiTetheringEnrichedApBroadcast()1460 public void workingWifiTetheringEnrichedApBroadcast() throws Exception { 1461 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); 1462 1463 // Emulate pressing the WiFi tethering button. 1464 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); 1465 mLooper.dispatchAll(); 1466 verify(mWifiManager, times(1)).startTetheredHotspot(null); 1467 verifyNoMoreInteractions(mWifiManager); 1468 verifyNoMoreInteractions(mNetd); 1469 1470 // Emulate externally-visible WifiManager effects, causing the 1471 // per-interface state machine to start up, and telling us that 1472 // tethering mode is to be started. 1473 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1474 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 1475 1476 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); 1477 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 1478 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 1479 verify(mNetd, times(1)).tetherStartWithConfiguration(any()); 1480 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME), 1481 anyString(), anyString()); 1482 verifyNoMoreInteractions(mNetd); 1483 verify(mWifiManager).updateInterfaceIpState( 1484 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1485 verify(mWifiManager).updateInterfaceIpState( 1486 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); 1487 verifyNoMoreInteractions(mWifiManager); 1488 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); 1489 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); 1490 // In tethering mode, in the default configuration, an explicit request 1491 // for a mobile network is also made. 1492 verify(mUpstreamNetworkMonitor, times(1)).setTryCell(true); 1493 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED 1494 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); 1495 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI)); 1496 1497 ///// 1498 // We do not currently emulate any upstream being found. 1499 // 1500 // This is why there are no calls to verify mNetd.tetherAddForward() or 1501 // mNetd.ipfwdAddInterfaceForward(). 1502 ///// 1503 1504 // Emulate pressing the WiFi tethering button. 1505 mTethering.stopTethering(TETHERING_WIFI); 1506 mLooper.dispatchAll(); 1507 verify(mWifiManager, times(1)).stopSoftAp(); 1508 verifyNoMoreInteractions(mWifiManager); 1509 verifyNoMoreInteractions(mNetd); 1510 1511 // Emulate externally-visible WifiManager effects, when tethering mode 1512 // is being torn down. 1513 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 1514 mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 1515 mLooper.dispatchAll(); 1516 1517 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1518 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); 1519 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 1520 // interfaceSetCfg() called once for enabling and twice for disabling IPv4. 1521 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 1522 verify(mNetd, times(1)).tetherStop(); 1523 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); 1524 verify(mWifiManager, times(3)).updateInterfaceIpState( 1525 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1526 verifyNoMoreInteractions(mNetd); 1527 verifyNoMoreInteractions(mWifiManager); 1528 // Asking for the last error after the per-interface state machine 1529 // has been reaped yields an unknown interface error. 1530 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME)); 1531 } 1532 1533 // TODO: Test with and without interfaceStatusChanged(). 1534 @Test failureEnablingIpForwarding()1535 public void failureEnablingIpForwarding() throws Exception { 1536 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); 1537 doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME); 1538 1539 // Emulate pressing the WiFi tethering button. 1540 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); 1541 mLooper.dispatchAll(); 1542 verify(mWifiManager, times(1)).startTetheredHotspot(null); 1543 verifyNoMoreInteractions(mWifiManager); 1544 verifyNoMoreInteractions(mNetd); 1545 1546 // Emulate externally-visible WifiManager effects, causing the 1547 // per-interface state machine to start up, and telling us that 1548 // tethering mode is to be started. 1549 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1550 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 1551 1552 // We verify get/set called three times here: twice for setup and once during 1553 // teardown because all events happen over the course of the single 1554 // dispatchAll() above. Note that once the IpServer IPv4 address config 1555 // code is refactored the two calls during shutdown will revert to one. 1556 verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName))); 1557 verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME); 1558 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 1559 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME), 1560 anyString(), anyString()); 1561 verify(mWifiManager).updateInterfaceIpState( 1562 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1563 verify(mWifiManager).updateInterfaceIpState( 1564 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); 1565 // There are 3 IpServer state change event: 1566 // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE. 1567 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 1568 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI)); 1569 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 1570 // This is called, but will throw. 1571 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 1572 // This never gets called because of the exception thrown above. 1573 verify(mNetd, times(0)).tetherStartWithConfiguration(any()); 1574 // When the main state machine transitions to an error state it tells 1575 // downstream interfaces, which causes us to tell Wi-Fi about the error 1576 // so it can take down AP mode. 1577 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1578 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); 1579 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 1580 verify(mWifiManager).updateInterfaceIpState( 1581 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR); 1582 1583 verifyNoMoreInteractions(mWifiManager); 1584 verifyNoMoreInteractions(mNetd); 1585 } 1586 makeUserRestrictionActionListener( final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow)1587 private UserRestrictionActionListener makeUserRestrictionActionListener( 1588 final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) { 1589 final Bundle newRestrictions = new Bundle(); 1590 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); 1591 when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions); 1592 1593 final UserRestrictionActionListener ural = 1594 new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater); 1595 ural.mDisallowTethering = currentDisallow; 1596 return ural; 1597 } 1598 runUserRestrictionsChange( boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, int expectedInteractionsWithShowNotification)1599 private void runUserRestrictionsChange( 1600 boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, 1601 int expectedInteractionsWithShowNotification) throws Exception { 1602 final Tethering mockTethering = mock(Tethering.class); 1603 when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive); 1604 1605 final UserRestrictionActionListener ural = 1606 makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow); 1607 ural.onUserRestrictionsChanged(); 1608 1609 verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification)) 1610 .notifyTetheringDisabledByRestriction(); 1611 verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll(); 1612 } 1613 1614 @Test testDisallowTetheringWhenTetheringIsNotActive()1615 public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception { 1616 final boolean isTetheringActive = false; 1617 final boolean currDisallow = false; 1618 final boolean nextDisallow = true; 1619 final int expectedInteractionsWithShowNotification = 0; 1620 1621 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1622 expectedInteractionsWithShowNotification); 1623 } 1624 1625 @Test testDisallowTetheringWhenTetheringIsActive()1626 public void testDisallowTetheringWhenTetheringIsActive() throws Exception { 1627 final boolean isTetheringActive = true; 1628 final boolean currDisallow = false; 1629 final boolean nextDisallow = true; 1630 final int expectedInteractionsWithShowNotification = 1; 1631 1632 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1633 expectedInteractionsWithShowNotification); 1634 } 1635 1636 @Test testAllowTetheringWhenTetheringIsNotActive()1637 public void testAllowTetheringWhenTetheringIsNotActive() throws Exception { 1638 final boolean isTetheringActive = false; 1639 final boolean currDisallow = true; 1640 final boolean nextDisallow = false; 1641 final int expectedInteractionsWithShowNotification = 0; 1642 1643 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1644 expectedInteractionsWithShowNotification); 1645 } 1646 1647 @Test testAllowTetheringWhenTetheringIsActive()1648 public void testAllowTetheringWhenTetheringIsActive() throws Exception { 1649 final boolean isTetheringActive = true; 1650 final boolean currDisallow = true; 1651 final boolean nextDisallow = false; 1652 final int expectedInteractionsWithShowNotification = 0; 1653 1654 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1655 expectedInteractionsWithShowNotification); 1656 } 1657 1658 @Test testDisallowTetheringUnchanged()1659 public void testDisallowTetheringUnchanged() throws Exception { 1660 final boolean isTetheringActive = true; 1661 final int expectedInteractionsWithShowNotification = 0; 1662 boolean currDisallow = true; 1663 boolean nextDisallow = true; 1664 1665 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1666 expectedInteractionsWithShowNotification); 1667 1668 currDisallow = false; 1669 nextDisallow = false; 1670 1671 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 1672 expectedInteractionsWithShowNotification); 1673 } 1674 1675 @Test testUntetherUsbWhenRestrictionIsOn()1676 public void testUntetherUsbWhenRestrictionIsOn() { 1677 // Start usb tethering and check that usb interface is tethered. 1678 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1679 runUsbTethering(upstreamState); 1680 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 1681 assertTrue(mTethering.isTetheringActive()); 1682 assertEquals(0, mTethering.getActiveTetheringRequests().size()); 1683 1684 final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener( 1685 mTethering, false /* currentDisallow */, true /* nextDisallow */); 1686 1687 ural.onUserRestrictionsChanged(); 1688 mLooper.dispatchAll(); 1689 1690 // Verify that restriction notification has showed to user. 1691 verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction(); 1692 // Verify that usb tethering has been disabled. 1693 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 1694 } 1695 1696 private class TestTetheringEventCallback extends ITetheringEventCallback.Stub { 1697 private final ArrayList<Network> mActualUpstreams = new ArrayList<>(); 1698 private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs = 1699 new ArrayList<>(); 1700 private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>(); 1701 private final ArrayList<Integer> mOffloadStatus = new ArrayList<>(); 1702 private final ArrayList<List<TetheredClient>> mTetheredClients = new ArrayList<>(); 1703 private final ArrayList<Long> mSupportedBitmaps = new ArrayList<>(); 1704 1705 // This function will remove the recorded callbacks, so it must be called once for 1706 // each callback. If this is called after multiple callback, the order matters. 1707 // onCallbackCreated counts as the first call to expectUpstreamChanged with 1708 // @see onCallbackCreated. expectUpstreamChanged(Network... networks)1709 public void expectUpstreamChanged(Network... networks) { 1710 if (networks == null) { 1711 assertNoUpstreamChangeCallback(); 1712 return; 1713 } 1714 1715 final ArrayList<Network> expectedUpstreams = 1716 new ArrayList<Network>(Arrays.asList(networks)); 1717 for (Network upstream : expectedUpstreams) { 1718 // throws OOB if no expectations 1719 assertEquals(mActualUpstreams.remove(0), upstream); 1720 } 1721 assertNoUpstreamChangeCallback(); 1722 } 1723 1724 // This function will remove the recorded callbacks, so it must be called once 1725 // for each callback. If this is called after multiple callback, the order matters. 1726 // onCallbackCreated counts as the first call to onConfigurationChanged with 1727 // @see onCallbackCreated. expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs)1728 public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) { 1729 final ArrayList<TetheringConfigurationParcel> expectedTetherConfig = 1730 new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs)); 1731 for (TetheringConfigurationParcel config : expectedTetherConfig) { 1732 // throws OOB if no expectations 1733 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0); 1734 assertTetherConfigParcelEqual(actualConfig, config); 1735 } 1736 assertNoConfigChangeCallback(); 1737 } 1738 expectOffloadStatusChanged(final int expectedStatus)1739 public void expectOffloadStatusChanged(final int expectedStatus) { 1740 assertOffloadStatusChangedCallback(); 1741 assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus)); 1742 } 1743 pollTetherStatesChanged()1744 public TetherStatesParcel pollTetherStatesChanged() { 1745 assertStateChangeCallback(); 1746 return mTetherStates.remove(0); 1747 } 1748 expectTetheredClientChanged(List<TetheredClient> leases)1749 public void expectTetheredClientChanged(List<TetheredClient> leases) { 1750 assertFalse(mTetheredClients.isEmpty()); 1751 final List<TetheredClient> result = mTetheredClients.remove(0); 1752 assertEquals(leases.size(), result.size()); 1753 assertTrue(leases.containsAll(result)); 1754 } 1755 expectSupportedTetheringTypes(Set<Integer> expectedTypes)1756 public void expectSupportedTetheringTypes(Set<Integer> expectedTypes) { 1757 assertEquals(expectedTypes, TetheringManager.unpackBits(mSupportedBitmaps.remove(0))); 1758 } 1759 1760 @Override onUpstreamChanged(Network network)1761 public void onUpstreamChanged(Network network) { 1762 mActualUpstreams.add(network); 1763 } 1764 1765 @Override onConfigurationChanged(TetheringConfigurationParcel config)1766 public void onConfigurationChanged(TetheringConfigurationParcel config) { 1767 mTetheringConfigs.add(config); 1768 } 1769 1770 @Override onTetherStatesChanged(TetherStatesParcel states)1771 public void onTetherStatesChanged(TetherStatesParcel states) { 1772 mTetherStates.add(states); 1773 } 1774 1775 @Override onTetherClientsChanged(List<TetheredClient> clients)1776 public void onTetherClientsChanged(List<TetheredClient> clients) { 1777 mTetheredClients.add(clients); 1778 } 1779 1780 @Override onOffloadStatusChanged(final int status)1781 public void onOffloadStatusChanged(final int status) { 1782 mOffloadStatus.add(status); 1783 } 1784 1785 @Override onCallbackStarted(TetheringCallbackStartedParcel parcel)1786 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 1787 mActualUpstreams.add(parcel.upstreamNetwork); 1788 mTetheringConfigs.add(parcel.config); 1789 mTetherStates.add(parcel.states); 1790 mOffloadStatus.add(parcel.offloadStatus); 1791 mTetheredClients.add(parcel.tetheredClients); 1792 mSupportedBitmaps.add(parcel.supportedTypes); 1793 } 1794 1795 @Override onCallbackStopped(int errorCode)1796 public void onCallbackStopped(int errorCode) { } 1797 1798 @Override onSupportedTetheringTypes(long supportedBitmap)1799 public void onSupportedTetheringTypes(long supportedBitmap) { 1800 mSupportedBitmaps.add(supportedBitmap); 1801 } 1802 assertNoUpstreamChangeCallback()1803 public void assertNoUpstreamChangeCallback() { 1804 assertTrue(mActualUpstreams.isEmpty()); 1805 } 1806 assertNoConfigChangeCallback()1807 public void assertNoConfigChangeCallback() { 1808 assertTrue(mTetheringConfigs.isEmpty()); 1809 } 1810 assertNoStateChangeCallback()1811 public void assertNoStateChangeCallback() { 1812 assertTrue(mTetherStates.isEmpty()); 1813 } 1814 assertStateChangeCallback()1815 public void assertStateChangeCallback() { 1816 assertFalse(mTetherStates.isEmpty()); 1817 } 1818 assertOffloadStatusChangedCallback()1819 public void assertOffloadStatusChangedCallback() { 1820 assertFalse(mOffloadStatus.isEmpty()); 1821 } 1822 assertNoCallback()1823 public void assertNoCallback() { 1824 assertNoUpstreamChangeCallback(); 1825 assertNoConfigChangeCallback(); 1826 assertNoStateChangeCallback(); 1827 assertTrue(mTetheredClients.isEmpty()); 1828 } 1829 assertTetherConfigParcelEqual(@onNull TetheringConfigurationParcel actual, @NonNull TetheringConfigurationParcel expect)1830 private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual, 1831 @NonNull TetheringConfigurationParcel expect) { 1832 assertEquals(actual.subId, expect.subId); 1833 assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs); 1834 assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs); 1835 assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs); 1836 assertEquals(actual.isDunRequired, expect.isDunRequired); 1837 assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically); 1838 assertArrayEquals(actual.preferredUpstreamIfaceTypes, 1839 expect.preferredUpstreamIfaceTypes); 1840 assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges); 1841 assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS); 1842 assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer); 1843 assertArrayEquals(actual.provisioningApp, expect.provisioningApp); 1844 assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi); 1845 assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod); 1846 } 1847 } 1848 assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel)1849 private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) { 1850 assertFalse(parcel == null); 1851 assertEquals(0, parcel.availableList.length); 1852 assertEquals(0, parcel.tetheredList.length); 1853 assertEquals(0, parcel.localOnlyList.length); 1854 assertEquals(0, parcel.erroredIfaceList.length); 1855 assertEquals(0, parcel.lastErrorList.length); 1856 MiscAsserts.assertFieldCountEquals(5, TetherStatesParcel.class); 1857 } 1858 1859 @Test testRegisterTetheringEventCallback()1860 public void testRegisterTetheringEventCallback() throws Exception { 1861 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 1862 TestTetheringEventCallback callback2 = new TestTetheringEventCallback(); 1863 final TetheringInterface wifiIface = new TetheringInterface( 1864 TETHERING_WIFI, TEST_WLAN_IFNAME); 1865 1866 // 1. Register one callback before running any tethering. 1867 mTethering.registerTetheringEventCallback(callback); 1868 mLooper.dispatchAll(); 1869 callback.expectTetheredClientChanged(Collections.emptyList()); 1870 callback.expectUpstreamChanged(new Network[] {null}); 1871 callback.expectConfigurationChanged( 1872 mTethering.getTetheringConfiguration().toStableParcelable()); 1873 TetherStatesParcel tetherState = callback.pollTetherStatesChanged(); 1874 assertTetherStatesNotNullButEmpty(tetherState); 1875 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1876 // 2. Enable wifi tethering. 1877 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 1878 initTetheringUpstream(upstreamState); 1879 when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); 1880 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1881 mLooper.dispatchAll(); 1882 tetherState = callback.pollTetherStatesChanged(); 1883 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 1884 1885 mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); 1886 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 1887 tetherState = callback.pollTetherStatesChanged(); 1888 assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface}); 1889 callback.expectUpstreamChanged(upstreamState.network); 1890 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 1891 1892 // 3. Register second callback. 1893 mTethering.registerTetheringEventCallback(callback2); 1894 mLooper.dispatchAll(); 1895 callback2.expectTetheredClientChanged(Collections.emptyList()); 1896 callback2.expectUpstreamChanged(upstreamState.network); 1897 callback2.expectConfigurationChanged( 1898 mTethering.getTetheringConfiguration().toStableParcelable()); 1899 tetherState = callback2.pollTetherStatesChanged(); 1900 assertEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface}); 1901 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 1902 1903 // 4. Unregister first callback and disable wifi tethering 1904 mTethering.unregisterTetheringEventCallback(callback); 1905 mLooper.dispatchAll(); 1906 mTethering.stopTethering(TETHERING_WIFI); 1907 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED); 1908 if (isAtLeastT()) { 1909 // After T, tethering doesn't support WIFI_AP_STATE_DISABLED with null interface name. 1910 callback2.assertNoStateChangeCallback(); 1911 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, 1912 IFACE_IP_MODE_TETHERED); 1913 } 1914 tetherState = callback2.pollTetherStatesChanged(); 1915 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 1916 mLooper.dispatchAll(); 1917 callback2.expectUpstreamChanged(new Network[] {null}); 1918 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1919 callback.assertNoCallback(); 1920 } 1921 1922 @Test testReportFailCallbackIfOffloadNotSupported()1923 public void testReportFailCallbackIfOffloadNotSupported() throws Exception { 1924 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 1925 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 1926 mTethering.registerTetheringEventCallback(callback); 1927 mLooper.dispatchAll(); 1928 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1929 1930 // 1. Offload fail if no OffloadConfig. 1931 initOffloadConfiguration(false /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0, 1932 0 /* defaultDisabled */); 1933 runUsbTethering(upstreamState); 1934 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); 1935 runStopUSBTethering(); 1936 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1937 reset(mUsbManager, mIPv6TetheringCoordinator); 1938 // 2. Offload fail if no OffloadControl. 1939 initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_NONE, 1940 0 /* defaultDisabled */); 1941 runUsbTethering(upstreamState); 1942 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); 1943 runStopUSBTethering(); 1944 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1945 reset(mUsbManager, mIPv6TetheringCoordinator); 1946 // 3. Offload fail if disabled by settings. 1947 initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0, 1948 1 /* defaultDisabled */); 1949 runUsbTethering(upstreamState); 1950 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); 1951 runStopUSBTethering(); 1952 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 1953 } 1954 runStopUSBTethering()1955 private void runStopUSBTethering() { 1956 mTethering.stopTethering(TETHERING_USB); 1957 mLooper.dispatchAll(); 1958 sendUsbBroadcast(true, true, -1 /* function */); 1959 mLooper.dispatchAll(); 1960 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 1961 } 1962 initOffloadConfiguration(final boolean offloadConfig, @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion, final int defaultDisabled)1963 private void initOffloadConfiguration(final boolean offloadConfig, 1964 @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion, 1965 final int defaultDisabled) { 1966 when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig); 1967 when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControlVersion); 1968 when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn( 1969 defaultDisabled); 1970 } 1971 1972 @Test testMultiSimAware()1973 public void testMultiSimAware() throws Exception { 1974 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); 1975 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId); 1976 1977 final int fakeSubId = 1234; 1978 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); 1979 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); 1980 assertEquals(fakeSubId, newConfig.activeDataSubId); 1981 verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); 1982 } 1983 1984 @Test testNoDuplicatedEthernetRequest()1985 public void testNoDuplicatedEthernetRequest() throws Exception { 1986 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); 1987 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); 1988 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); 1989 mLooper.dispatchAll(); 1990 verify(mEm, times(1)).requestTetheredInterface(any(), any()); 1991 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); 1992 mLooper.dispatchAll(); 1993 verifyNoMoreInteractions(mEm); 1994 mTethering.stopTethering(TETHERING_ETHERNET); 1995 mLooper.dispatchAll(); 1996 verify(mockRequest, times(1)).release(); 1997 mTethering.stopTethering(TETHERING_ETHERNET); 1998 mLooper.dispatchAll(); 1999 verifyNoMoreInteractions(mEm); 2000 } 2001 workingWifiP2pGroupOwner( boolean emulateInterfaceStatusChanged)2002 private void workingWifiP2pGroupOwner( 2003 boolean emulateInterfaceStatusChanged) throws Exception { 2004 if (emulateInterfaceStatusChanged) { 2005 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 2006 } 2007 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 2008 2009 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME); 2010 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER); 2011 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 2012 verify(mNetd, times(1)).tetherStartWithConfiguration(any()); 2013 verifyNoMoreInteractions(mNetd); 2014 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 2015 verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); 2016 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY 2017 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 2018 2019 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 2020 2021 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group 2022 // is being removed. 2023 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME); 2024 mTethering.interfaceRemoved(TEST_P2P_IFNAME); 2025 2026 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 2027 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME); 2028 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 2029 // interfaceSetCfg() called once for enabling and twice for disabling IPv4. 2030 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 2031 verify(mNetd, times(1)).tetherStop(); 2032 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); 2033 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream(); 2034 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); 2035 verifyNoMoreInteractions(mNetd); 2036 // Asking for the last error after the per-interface state machine 2037 // has been reaped yields an unknown interface error. 2038 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 2039 } 2040 workingWifiP2pGroupClient( boolean emulateInterfaceStatusChanged)2041 private void workingWifiP2pGroupClient( 2042 boolean emulateInterfaceStatusChanged) throws Exception { 2043 if (emulateInterfaceStatusChanged) { 2044 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 2045 } 2046 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME); 2047 2048 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 2049 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); 2050 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 2051 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); 2052 verify(mNetd, never()).tetherStartWithConfiguration(any()); 2053 2054 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group 2055 // is being removed. 2056 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME); 2057 mTethering.interfaceRemoved(TEST_P2P_IFNAME); 2058 2059 verify(mNetd, never()).tetherApplyDnsInterfaces(); 2060 verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME); 2061 verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 2062 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 2063 verify(mNetd, never()).tetherStop(); 2064 verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME); 2065 verifyNoMoreInteractions(mNetd); 2066 // Asking for the last error after the per-interface state machine 2067 // has been reaped yields an unknown interface error. 2068 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 2069 } 2070 2071 @Test workingWifiP2pGroupOwnerWithIfaceChanged()2072 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception { 2073 workingWifiP2pGroupOwner(true); 2074 } 2075 2076 @Test workingWifiP2pGroupOwnerSansIfaceChanged()2077 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception { 2078 workingWifiP2pGroupOwner(false); 2079 } 2080 workingWifiP2pGroupOwnerLegacyMode( boolean emulateInterfaceStatusChanged)2081 private void workingWifiP2pGroupOwnerLegacyMode( 2082 boolean emulateInterfaceStatusChanged) throws Exception { 2083 // change to legacy mode and update tethering information by chaning SIM 2084 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 2085 .thenReturn(new String[]{}); 2086 final int fakeSubId = 1234; 2087 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); 2088 2089 if (emulateInterfaceStatusChanged) { 2090 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 2091 } 2092 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 2093 2094 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 2095 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); 2096 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 2097 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); 2098 verify(mNetd, never()).tetherStartWithConfiguration(any()); 2099 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 2100 } 2101 @Test workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged()2102 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception { 2103 workingWifiP2pGroupOwnerLegacyMode(true); 2104 } 2105 2106 @Test workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged()2107 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception { 2108 workingWifiP2pGroupOwnerLegacyMode(false); 2109 } 2110 2111 @Test workingWifiP2pGroupClientWithIfaceChanged()2112 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception { 2113 workingWifiP2pGroupClient(true); 2114 } 2115 2116 @Test workingWifiP2pGroupClientSansIfaceChanged()2117 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception { 2118 workingWifiP2pGroupClient(false); 2119 } 2120 setDataSaverEnabled(boolean enabled)2121 private void setDataSaverEnabled(boolean enabled) { 2122 final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED 2123 : RESTRICT_BACKGROUND_STATUS_DISABLED; 2124 doReturn(status).when(mCm).getRestrictBackgroundStatus(); 2125 2126 final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED); 2127 mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); 2128 mLooper.dispatchAll(); 2129 } 2130 2131 @Test testDataSaverChanged()2132 public void testDataSaverChanged() { 2133 // Start Tethering. 2134 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 2135 runUsbTethering(upstreamState); 2136 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 2137 // Data saver is ON. 2138 setDataSaverEnabled(true); 2139 // Verify that tethering should be disabled. 2140 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2141 sendUsbBroadcast(true, true, -1 /* function */); 2142 mLooper.dispatchAll(); 2143 assertEquals(mTethering.getTetheredIfaces(), new String[0]); 2144 reset(mUsbManager, mIPv6TetheringCoordinator); 2145 2146 runUsbTethering(upstreamState); 2147 // Verify that user can start tethering again without turning OFF data saver. 2148 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 2149 2150 // If data saver is keep ON with change event, tethering should not be OFF this time. 2151 setDataSaverEnabled(true); 2152 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2153 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 2154 2155 // If data saver is turned OFF, it should not change tethering. 2156 setDataSaverEnabled(false); 2157 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2158 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 2159 } 2160 assertContains(Collection<T> collection, T element)2161 private static <T> void assertContains(Collection<T> collection, T element) { 2162 assertTrue(element + " not found in " + collection, collection.contains(element)); 2163 } 2164 2165 private class ResultListener extends IIntResultListener.Stub { 2166 private final int mExpectedResult; 2167 private boolean mHasResult = false; ResultListener(final int expectedResult)2168 ResultListener(final int expectedResult) { 2169 mExpectedResult = expectedResult; 2170 } 2171 2172 @Override onResult(final int resultCode)2173 public void onResult(final int resultCode) { 2174 mHasResult = true; 2175 if (resultCode != mExpectedResult) { 2176 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode); 2177 } 2178 } 2179 assertHasResult()2180 public void assertHasResult() { 2181 if (!mHasResult) fail("No callback result"); 2182 } 2183 } 2184 2185 @Test testMultipleStartTethering()2186 public void testMultipleStartTethering() throws Exception { 2187 final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24"); 2188 final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24"); 2189 final String serverAddr = "192.168.20.1"; 2190 final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2191 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2192 final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2193 2194 // Enable USB tethering and check that Tethering starts USB. 2195 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), firstResult); 2196 mLooper.dispatchAll(); 2197 firstResult.assertHasResult(); 2198 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 2199 verifyNoMoreInteractions(mUsbManager); 2200 2201 // Enable USB tethering again with the same request and expect no change to USB. 2202 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), secondResult); 2203 mLooper.dispatchAll(); 2204 secondResult.assertHasResult(); 2205 verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2206 reset(mUsbManager); 2207 2208 // Enable USB tethering with a different request and expect that USB is stopped and 2209 // started. 2210 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, 2211 serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), thirdResult); 2212 mLooper.dispatchAll(); 2213 thirdResult.assertHasResult(); 2214 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2215 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 2216 2217 // Expect that when USB comes up, the DHCP server is configured with the requested address. 2218 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 2219 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 2220 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 2221 any(), any()); 2222 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); 2223 } 2224 2225 @Test testRequestStaticIp()2226 public void testRequestStaticIp() throws Exception { 2227 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 2228 TetheringConfiguration.TETHER_USB_NCM_FUNCTION); 2229 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 2230 .thenReturn(new String[] {TEST_NCM_REGEX}); 2231 sendConfigurationChanged(); 2232 2233 final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); 2234 final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); 2235 final String serverAddr = "192.168.0.123"; 2236 final int clientAddrParceled = 0xc0a8002a; 2237 final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = 2238 ArgumentCaptor.forClass(DhcpServingParamsParcel.class); 2239 mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, 2240 serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), null); 2241 mLooper.dispatchAll(); 2242 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); 2243 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true); 2244 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 2245 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); 2246 verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), 2247 any()); 2248 final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); 2249 assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); 2250 assertEquals(24, params.serverAddrPrefixLength); 2251 assertEquals(clientAddrParceled, params.singleClientAddr); 2252 } 2253 2254 @Test testUpstreamNetworkChanged()2255 public void testUpstreamNetworkChanged() { 2256 final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM) 2257 mTetheringDependencies.mUpstreamNetworkMonitorSM; 2258 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 2259 initTetheringUpstream(upstreamState); 2260 stateMachine.chooseUpstreamType(true); 2261 2262 verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network)); 2263 verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any()); 2264 } 2265 2266 @Test testUpstreamCapabilitiesChanged()2267 public void testUpstreamCapabilitiesChanged() { 2268 final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM) 2269 mTetheringDependencies.mUpstreamNetworkMonitorSM; 2270 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 2271 initTetheringUpstream(upstreamState); 2272 stateMachine.chooseUpstreamType(true); 2273 2274 stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); 2275 // Should have two onUpstreamCapabilitiesChanged(). 2276 // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES. 2277 verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any()); 2278 reset(mNotificationUpdater); 2279 2280 // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network 2281 // capabilities changed. 2282 final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState( 2283 upstreamState.linkProperties, upstreamState.networkCapabilities, 2284 new Network(WIFI_NETID)); 2285 stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2); 2286 verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any()); 2287 } 2288 2289 @Test testDumpTetheringLog()2290 public void testDumpTetheringLog() throws Exception { 2291 final FileDescriptor mockFd = mock(FileDescriptor.class); 2292 final PrintWriter mockPw = mock(PrintWriter.class); 2293 runUsbTethering(null); 2294 mLooper.startAutoDispatch(); 2295 mTethering.dump(mockFd, mockPw, new String[0]); 2296 verify(mConfig).dump(any()); 2297 verify(mEntitleMgr).dump(any()); 2298 verify(mOffloadCtrl).dump(any()); 2299 mLooper.stopAutoDispatch(); 2300 } 2301 2302 @Test testExemptFromEntitlementCheck()2303 public void testExemptFromEntitlementCheck() throws Exception { 2304 setupForRequiredProvisioning(); 2305 final TetheringRequestParcel wifiNotExemptRequest = 2306 createTetheringRequestParcel(TETHERING_WIFI, null, null, false, 2307 CONNECTIVITY_SCOPE_GLOBAL); 2308 mTethering.startTethering(wifiNotExemptRequest, null); 2309 mLooper.dispatchAll(); 2310 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); 2311 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); 2312 assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); 2313 mTethering.stopTethering(TETHERING_WIFI); 2314 mLooper.dispatchAll(); 2315 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 2316 reset(mEntitleMgr); 2317 2318 setupForRequiredProvisioning(); 2319 final TetheringRequestParcel wifiExemptRequest = 2320 createTetheringRequestParcel(TETHERING_WIFI, null, null, true, 2321 CONNECTIVITY_SCOPE_GLOBAL); 2322 mTethering.startTethering(wifiExemptRequest, null); 2323 mLooper.dispatchAll(); 2324 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); 2325 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); 2326 assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); 2327 mTethering.stopTethering(TETHERING_WIFI); 2328 mLooper.dispatchAll(); 2329 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 2330 reset(mEntitleMgr); 2331 2332 // If one app enables tethering without provisioning check first, then another app enables 2333 // tethering of the same type but does not disable the provisioning check. 2334 setupForRequiredProvisioning(); 2335 mTethering.startTethering(wifiExemptRequest, null); 2336 mLooper.dispatchAll(); 2337 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); 2338 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); 2339 assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); 2340 reset(mEntitleMgr); 2341 setupForRequiredProvisioning(); 2342 mTethering.startTethering(wifiNotExemptRequest, null); 2343 mLooper.dispatchAll(); 2344 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); 2345 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); 2346 assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); 2347 mTethering.stopTethering(TETHERING_WIFI); 2348 mLooper.dispatchAll(); 2349 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 2350 reset(mEntitleMgr); 2351 } 2352 setupForRequiredProvisioning()2353 private void setupForRequiredProvisioning() { 2354 // Produce some acceptable looking provision app setting if requested. 2355 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) 2356 .thenReturn(PROVISIONING_APP_NAME); 2357 when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui)) 2358 .thenReturn(PROVISIONING_NO_UI_APP_NAME); 2359 // Act like the CarrierConfigManager is present and ready unless told otherwise. 2360 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) 2361 .thenReturn(mCarrierConfigManager); 2362 when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig); 2363 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); 2364 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 2365 sendConfigurationChanged(); 2366 } 2367 buildV4UpstreamState(final LinkAddress address, final Network network, final String iface, final int transportType)2368 private static UpstreamNetworkState buildV4UpstreamState(final LinkAddress address, 2369 final Network network, final String iface, final int transportType) { 2370 final LinkProperties prop = new LinkProperties(); 2371 prop.setInterfaceName(iface); 2372 2373 prop.addLinkAddress(address); 2374 2375 final NetworkCapabilities capabilities = new NetworkCapabilities() 2376 .addTransportType(transportType); 2377 return new UpstreamNetworkState(prop, capabilities, network); 2378 } 2379 updateV4Upstream(final LinkAddress ipv4Address, final Network network, final String iface, final int transportType)2380 private void updateV4Upstream(final LinkAddress ipv4Address, final Network network, 2381 final String iface, final int transportType) { 2382 final UpstreamNetworkState upstream = buildV4UpstreamState(ipv4Address, network, iface, 2383 transportType); 2384 mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage( 2385 Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK, 2386 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 2387 0, 2388 upstream); 2389 mLooper.dispatchAll(); 2390 } 2391 2392 @Test testHandleIpConflict()2393 public void testHandleIpConflict() throws Exception { 2394 final Network wifiNetwork = new Network(200); 2395 final Network[] allNetworks = { wifiNetwork }; 2396 doReturn(allNetworks).when(mCm).getAllNetworks(); 2397 runUsbTethering(null); 2398 final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor = 2399 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); 2400 verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture()); 2401 final String ipv4Address = ifaceConfigCaptor.getValue().ipv4Addr; 2402 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 2403 any(), any()); 2404 reset(mUsbManager); 2405 2406 // Cause a prefix conflict by assigning a /30 out of the downstream's /24 to the upstream. 2407 updateV4Upstream(new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), 30), 2408 wifiNetwork, TEST_WIFI_IFNAME, TRANSPORT_WIFI); 2409 // verify turn off usb tethering 2410 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2411 sendUsbBroadcast(true, true, -1 /* function */); 2412 mLooper.dispatchAll(); 2413 // verify restart usb tethering 2414 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 2415 } 2416 2417 @Test testNoAddressAvailable()2418 public void testNoAddressAvailable() throws Exception { 2419 final Network wifiNetwork = new Network(200); 2420 final Network btNetwork = new Network(201); 2421 final Network mobileNetwork = new Network(202); 2422 final Network[] allNetworks = { wifiNetwork, btNetwork, mobileNetwork }; 2423 doReturn(allNetworks).when(mCm).getAllNetworks(); 2424 runUsbTethering(null); 2425 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 2426 any(), any()); 2427 reset(mUsbManager); 2428 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); 2429 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); 2430 final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor = 2431 ArgumentCaptor.forClass(TetheredInterfaceCallback.class); 2432 mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); 2433 mLooper.dispatchAll(); 2434 verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture()); 2435 TetheredInterfaceCallback ethCallback = callbackCaptor.getValue(); 2436 ethCallback.onAvailable(TEST_ETH_IFNAME); 2437 mLooper.dispatchAll(); 2438 reset(mUsbManager, mEm); 2439 2440 updateV4Upstream(new LinkAddress("192.168.0.100/16"), wifiNetwork, TEST_WIFI_IFNAME, 2441 TRANSPORT_WIFI); 2442 updateV4Upstream(new LinkAddress("172.16.0.0/12"), btNetwork, TEST_BT_IFNAME, 2443 TRANSPORT_BLUETOOTH); 2444 updateV4Upstream(new LinkAddress("10.0.0.0/8"), mobileNetwork, TEST_MOBILE_IFNAME, 2445 TRANSPORT_CELLULAR); 2446 2447 mLooper.dispatchAll(); 2448 // verify turn off usb tethering 2449 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2450 // verify turn off ethernet tethering 2451 verify(mockRequest).release(); 2452 sendUsbBroadcast(true, true, -1 /* function */); 2453 ethCallback.onUnavailable(); 2454 mLooper.dispatchAll(); 2455 // verify restart usb tethering 2456 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 2457 // verify restart ethernet tethering 2458 verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture()); 2459 ethCallback = callbackCaptor.getValue(); 2460 ethCallback.onAvailable(TEST_ETH_IFNAME); 2461 2462 reset(mUsbManager, mEm); 2463 when(mNetd.interfaceGetList()) 2464 .thenReturn(new String[] { 2465 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME, 2466 TEST_NCM_IFNAME, TEST_ETH_IFNAME}); 2467 2468 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 2469 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 2470 assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_RNDIS_IFNAME); 2471 assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_ETH_IFNAME); 2472 assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest( 2473 TEST_RNDIS_IFNAME)); 2474 assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(TEST_ETH_IFNAME)); 2475 } 2476 2477 @Test testProvisioningNeededButUnavailable()2478 public void testProvisioningNeededButUnavailable() throws Exception { 2479 assertTrue(mTethering.isTetheringSupported()); 2480 verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 2481 2482 setupForRequiredProvisioning(); 2483 assertTrue(mTethering.isTetheringSupported()); 2484 verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 2485 reset(mPackageManager); 2486 2487 doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo( 2488 PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 2489 setupForRequiredProvisioning(); 2490 assertFalse(mTethering.isTetheringSupported()); 2491 verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 2492 } 2493 2494 @Test testUpdateConnectedClients()2495 public void testUpdateConnectedClients() throws Exception { 2496 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2497 runAsShell(NETWORK_SETTINGS, () -> { 2498 mTethering.registerTetheringEventCallback(callback); 2499 mLooper.dispatchAll(); 2500 }); 2501 callback.expectTetheredClientChanged(Collections.emptyList()); 2502 2503 IDhcpEventCallbacks eventCallbacks; 2504 final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor = 2505 ArgumentCaptor.forClass(IDhcpEventCallbacks.class); 2506 // Run local only tethering. 2507 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 2508 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 2509 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 2510 any(), dhcpEventCbsCaptor.capture()); 2511 eventCallbacks = dhcpEventCbsCaptor.getValue(); 2512 // Update lease for local only tethering. 2513 final MacAddress testMac1 = MacAddress.fromString("11:11:11:11:11:11"); 2514 final ArrayList<DhcpLeaseParcelable> p2pLeases = new ArrayList<>(); 2515 p2pLeases.add(createDhcpLeaseParcelable("clientId1", testMac1, "192.168.50.24", 24, 2516 Long.MAX_VALUE, "test1")); 2517 notifyDhcpLeasesChanged(p2pLeases, eventCallbacks); 2518 final List<TetheredClient> clients = toTetheredClients(p2pLeases, TETHERING_WIFI_P2P); 2519 callback.expectTetheredClientChanged(clients); 2520 reset(mDhcpServer); 2521 2522 // Run wifi tethering. 2523 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2524 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 2525 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 2526 any(), dhcpEventCbsCaptor.capture()); 2527 eventCallbacks = dhcpEventCbsCaptor.getValue(); 2528 // Update mac address from softAp callback before getting dhcp lease. 2529 final ArrayList<WifiClient> wifiClients = new ArrayList<>(); 2530 final MacAddress testMac2 = MacAddress.fromString("22:22:22:22:22:22"); 2531 final WifiClient testClient = mock(WifiClient.class); 2532 when(testClient.getMacAddress()).thenReturn(testMac2); 2533 wifiClients.add(testClient); 2534 mSoftApCallback.onConnectedClientsChanged(wifiClients); 2535 final TetheredClient noAddrClient = new TetheredClient(testMac2, 2536 Collections.emptyList() /* addresses */, TETHERING_WIFI); 2537 clients.add(noAddrClient); 2538 callback.expectTetheredClientChanged(clients); 2539 2540 // Update dhcp lease for wifi tethering. 2541 clients.remove(noAddrClient); 2542 final ArrayList<DhcpLeaseParcelable> wifiLeases = new ArrayList<>(); 2543 wifiLeases.add(createDhcpLeaseParcelable("clientId2", testMac2, "192.168.43.24", 24, 2544 Long.MAX_VALUE, "test2")); 2545 notifyDhcpLeasesChanged(wifiLeases, eventCallbacks); 2546 clients.addAll(toTetheredClients(wifiLeases, TETHERING_WIFI)); 2547 callback.expectTetheredClientChanged(clients); 2548 2549 // Test onStarted callback that register second callback when tethering is running. 2550 TestTetheringEventCallback callback2 = new TestTetheringEventCallback(); 2551 runAsShell(NETWORK_SETTINGS, () -> { 2552 mTethering.registerTetheringEventCallback(callback2); 2553 mLooper.dispatchAll(); 2554 }); 2555 callback2.expectTetheredClientChanged(clients); 2556 } 2557 notifyDhcpLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables, IDhcpEventCallbacks callback)2558 private void notifyDhcpLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables, 2559 IDhcpEventCallbacks callback) throws Exception { 2560 callback.onLeasesChanged(leaseParcelables); 2561 mLooper.dispatchAll(); 2562 } 2563 toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, int type)2564 private List<TetheredClient> toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, 2565 int type) throws Exception { 2566 final ArrayList<TetheredClient> leases = new ArrayList<>(); 2567 for (DhcpLeaseParcelable lease : leaseParcelables) { 2568 final LinkAddress address = new LinkAddress( 2569 intToInet4AddressHTH(lease.netAddr), lease.prefixLength, 2570 0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */, 2571 lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */); 2572 2573 final MacAddress macAddress = MacAddress.fromBytes(lease.hwAddr); 2574 2575 final AddressInfo addressInfo = new TetheredClient.AddressInfo(address, lease.hostname); 2576 leases.add(new TetheredClient( 2577 macAddress, 2578 Collections.singletonList(addressInfo), 2579 type)); 2580 } 2581 2582 return leases; 2583 } 2584 createDhcpLeaseParcelable(final String clientId, final MacAddress hwAddr, final String netAddr, final int prefixLength, final long expTime, final String hostname)2585 private DhcpLeaseParcelable createDhcpLeaseParcelable(final String clientId, 2586 final MacAddress hwAddr, final String netAddr, final int prefixLength, 2587 final long expTime, final String hostname) throws Exception { 2588 final DhcpLeaseParcelable lease = new DhcpLeaseParcelable(); 2589 lease.clientId = clientId.getBytes(); 2590 lease.hwAddr = hwAddr.toByteArray(); 2591 lease.netAddr = inet4AddressToIntHTH( 2592 (Inet4Address) InetAddresses.parseNumericAddress(netAddr)); 2593 lease.prefixLength = prefixLength; 2594 lease.expTime = expTime; 2595 lease.hostname = hostname; 2596 2597 return lease; 2598 } 2599 2600 @Test testBluetoothTethering()2601 public void testBluetoothTethering() throws Exception { 2602 // Switch to @IgnoreUpTo(Build.VERSION_CODES.S_V2) when it is available for AOSP. 2603 assumeTrue(isAtLeastT()); 2604 2605 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 2606 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 2607 mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result); 2608 mLooper.dispatchAll(); 2609 verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */); 2610 result.assertHasResult(); 2611 2612 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 2613 mLooper.dispatchAll(); 2614 verifyNetdCommandForBtSetup(); 2615 2616 // If PAN disconnect, tethering should also be stopped. 2617 mTetheredInterfaceCallbackShim.onUnavailable(); 2618 mLooper.dispatchAll(); 2619 verifyNetdCommandForBtTearDown(); 2620 2621 // Tethering could restart if PAN reconnect. 2622 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 2623 mLooper.dispatchAll(); 2624 verifyNetdCommandForBtSetup(); 2625 2626 // Pretend that bluetooth tethering was disabled. 2627 mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */); 2628 mTethering.stopTethering(TETHERING_BLUETOOTH); 2629 mLooper.dispatchAll(); 2630 verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */); 2631 2632 verifyNetdCommandForBtTearDown(); 2633 } 2634 2635 @Test testBluetoothTetheringBeforeT()2636 public void testBluetoothTetheringBeforeT() throws Exception { 2637 // Switch to @IgnoreAfter(Build.VERSION_CODES.S_V2) when it is available for AOSP. 2638 assumeFalse(isAtLeastT()); 2639 2640 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 2641 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 2642 mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result); 2643 mLooper.dispatchAll(); 2644 verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */); 2645 result.assertHasResult(); 2646 2647 mTethering.interfaceAdded(TEST_BT_IFNAME); 2648 mLooper.dispatchAll(); 2649 2650 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 2651 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true); 2652 final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2653 mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult); 2654 mLooper.dispatchAll(); 2655 tetherResult.assertHasResult(); 2656 2657 verifyNetdCommandForBtSetup(); 2658 2659 // Turning tethering on a second time does not bind to the PAN service again, since it's 2660 // already bound. 2661 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 2662 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2663 mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), secondResult); 2664 mLooper.dispatchAll(); 2665 verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */); 2666 secondResult.assertHasResult(); 2667 2668 mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */); 2669 mTethering.stopTethering(TETHERING_BLUETOOTH); 2670 mLooper.dispatchAll(); 2671 final ResultListener untetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2672 mTethering.untether(TEST_BT_IFNAME, untetherResult); 2673 mLooper.dispatchAll(); 2674 untetherResult.assertHasResult(); 2675 verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */); 2676 2677 verifyNetdCommandForBtTearDown(); 2678 } 2679 2680 @Test testBluetoothServiceDisconnects()2681 public void testBluetoothServiceDisconnects() throws Exception { 2682 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 2683 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 2684 mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result); 2685 mLooper.dispatchAll(); 2686 ServiceListener panListener = verifySetBluetoothTethering(true /* enable */, 2687 true /* bindToPanService */); 2688 result.assertHasResult(); 2689 2690 mTethering.interfaceAdded(TEST_BT_IFNAME); 2691 mLooper.dispatchAll(); 2692 2693 if (isAtLeastT()) { 2694 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 2695 mLooper.dispatchAll(); 2696 } else { 2697 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 2698 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true); 2699 final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 2700 mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult); 2701 mLooper.dispatchAll(); 2702 tetherResult.assertHasResult(); 2703 } 2704 2705 verifyNetdCommandForBtSetup(); 2706 2707 panListener.onServiceDisconnected(BluetoothProfile.PAN); 2708 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 2709 mLooper.dispatchAll(); 2710 2711 verifyNetdCommandForBtTearDown(); 2712 } 2713 mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn)2714 private void mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn) { 2715 when(mBluetoothAdapter.isEnabled()).thenReturn(bluetoothOn); 2716 when(mBluetoothPan.isTetheringOn()).thenReturn(tetheringOn); 2717 } 2718 verifyNetdCommandForBtSetup()2719 private void verifyNetdCommandForBtSetup() throws Exception { 2720 if (isAtLeastT()) { 2721 verify(mNetd).interfaceSetCfg(argThat(cfg -> TEST_BT_IFNAME.equals(cfg.ifName) 2722 && assertContainsFlag(cfg.flags, INetd.IF_STATE_UP))); 2723 } 2724 verify(mNetd).tetherInterfaceAdd(TEST_BT_IFNAME); 2725 verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME); 2726 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME), 2727 anyString(), anyString()); 2728 verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME); 2729 verify(mNetd).tetherStartWithConfiguration(any()); 2730 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME), 2731 anyString(), anyString()); 2732 verifyNoMoreInteractions(mNetd); 2733 reset(mNetd); 2734 } 2735 assertContainsFlag(String[] flags, String match)2736 private boolean assertContainsFlag(String[] flags, String match) { 2737 for (String flag : flags) { 2738 if (flag.equals(match)) return true; 2739 } 2740 return false; 2741 } 2742 verifyNetdCommandForBtTearDown()2743 private void verifyNetdCommandForBtTearDown() throws Exception { 2744 verify(mNetd).tetherApplyDnsInterfaces(); 2745 verify(mNetd).tetherInterfaceRemove(TEST_BT_IFNAME); 2746 verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME); 2747 // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only 2748 // happen after T. Before T, the interface configuration control in bluetooth side. 2749 verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg( 2750 any(InterfaceConfigurationParcel.class)); 2751 verify(mNetd).tetherStop(); 2752 verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME); 2753 reset(mNetd); 2754 } 2755 2756 // If bindToPanService is true, this function would return ServiceListener which could notify 2757 // PanService is connected or disconnected. verifySetBluetoothTethering(final boolean enable, final boolean bindToPanService)2758 private ServiceListener verifySetBluetoothTethering(final boolean enable, 2759 final boolean bindToPanService) throws Exception { 2760 ServiceListener listener = null; 2761 verify(mBluetoothAdapter).isEnabled(); 2762 if (bindToPanService) { 2763 final ArgumentCaptor<ServiceListener> listenerCaptor = 2764 ArgumentCaptor.forClass(ServiceListener.class); 2765 verify(mBluetoothAdapter).getProfileProxy(eq(mServiceContext), listenerCaptor.capture(), 2766 eq(BluetoothProfile.PAN)); 2767 listener = listenerCaptor.getValue(); 2768 listener.onServiceConnected(BluetoothProfile.PAN, mBluetoothPan); 2769 mLooper.dispatchAll(); 2770 } else { 2771 verify(mBluetoothAdapter, never()).getProfileProxy(eq(mServiceContext), any(), 2772 anyInt()); 2773 } 2774 2775 if (isAtLeastT()) { 2776 if (enable) { 2777 final ArgumentCaptor<TetheredInterfaceCallbackShim> callbackCaptor = 2778 ArgumentCaptor.forClass(TetheredInterfaceCallbackShim.class); 2779 verify(mBluetoothPanShim).requestTetheredInterface(any(), callbackCaptor.capture()); 2780 mTetheredInterfaceCallbackShim = callbackCaptor.getValue(); 2781 } else { 2782 verify(mTetheredInterfaceRequestShim).release(); 2783 } 2784 } else { 2785 verify(mBluetoothPan).setBluetoothTethering(enable); 2786 } 2787 verify(mBluetoothPan).isTetheringOn(); 2788 verifyNoMoreInteractions(mBluetoothAdapter, mBluetoothPan); 2789 reset(mBluetoothAdapter, mBluetoothPan); 2790 2791 return listener; 2792 } 2793 runDualStackUsbTethering(final String expectedIface)2794 private void runDualStackUsbTethering(final String expectedIface) throws Exception { 2795 when(mNetd.interfaceGetList()).thenReturn(new String[] {expectedIface}); 2796 when(mRouterAdvertisementDaemon.start()) 2797 .thenReturn(true); 2798 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 2799 runUsbTethering(upstreamState); 2800 2801 verify(mNetd).interfaceGetList(); 2802 verify(mNetd).tetherAddForward(expectedIface, TEST_MOBILE_IFNAME); 2803 verify(mNetd).ipfwdAddInterfaceForward(expectedIface, TEST_MOBILE_IFNAME); 2804 2805 verify(mRouterAdvertisementDaemon).start(); 2806 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 2807 any(), any()); 2808 sendIPv6TetherUpdates(upstreamState); 2809 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 2810 verify(mRouterAdvertisementDaemon).buildNewRa(any(), notNull()); 2811 verify(mNetd).tetherApplyDnsInterfaces(); 2812 } 2813 forceUsbTetheringUse(final int function)2814 private void forceUsbTetheringUse(final int function) { 2815 Settings.Global.putInt(mContentResolver, TETHER_FORCE_USB_FUNCTIONS, function); 2816 final ContentObserver observer = mTethering.getSettingsObserverForTest(); 2817 observer.onChange(false /* selfChange */); 2818 mLooper.dispatchAll(); 2819 } 2820 verifyUsbTetheringStopDueToSettingChange(final String iface)2821 private void verifyUsbTetheringStopDueToSettingChange(final String iface) { 2822 verify(mUsbManager, times(2)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2823 mTethering.interfaceRemoved(iface); 2824 sendUsbBroadcast(true, true, -1 /* no functions enabled */); 2825 reset(mUsbManager, mNetd, mDhcpServer, mRouterAdvertisementDaemon, 2826 mIPv6TetheringCoordinator, mDadProxy); 2827 } 2828 2829 @Test testUsbFunctionConfigurationChange()2830 public void testUsbFunctionConfigurationChange() throws Exception { 2831 // Run TETHERING_NCM. 2832 runNcmTethering(); 2833 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 2834 any(), any()); 2835 2836 // Change the USB tethering function to NCM. Because the USB tethering function was set to 2837 // RNDIS (the default), tethering is stopped. 2838 forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION); 2839 verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME); 2840 2841 // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be 2842 // available. 2843 final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL); 2844 mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), ncmResult); 2845 mLooper.dispatchAll(); 2846 ncmResult.assertHasResult(); 2847 2848 // Run TETHERING_USB with ncm configuration. 2849 runDualStackUsbTethering(TEST_NCM_IFNAME); 2850 2851 // Change configuration to rndis. 2852 forceUsbTetheringUse(TETHER_USB_RNDIS_FUNCTION); 2853 verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME); 2854 2855 // Run TETHERING_USB with rndis configuration. 2856 runDualStackUsbTethering(TEST_RNDIS_IFNAME); 2857 runStopUSBTethering(); 2858 } 2859 getAllSupportedTetheringTypes()2860 public static ArraySet<Integer> getAllSupportedTetheringTypes() { 2861 return new ArraySet<>(new Integer[] { TETHERING_USB, TETHERING_NCM, TETHERING_WIFI, 2862 TETHERING_WIFI_P2P, TETHERING_BLUETOOTH, TETHERING_ETHERNET }); 2863 } 2864 2865 @Test testTetheringSupported()2866 public void testTetheringSupported() throws Exception { 2867 final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes(); 2868 // Check tethering is supported after initialization. 2869 setTetheringSupported(true /* supported */); 2870 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2871 mTethering.registerTetheringEventCallback(callback); 2872 mLooper.dispatchAll(); 2873 updateConfigAndVerifySupported(callback, expectedTypes); 2874 2875 // Could disable tethering supported by settings. 2876 Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 0); 2877 updateConfigAndVerifySupported(callback, new ArraySet<>()); 2878 2879 // Could disable tethering supported by user restriction. 2880 setTetheringSupported(true /* supported */); 2881 updateConfigAndVerifySupported(callback, expectedTypes); 2882 when(mUserManager.hasUserRestriction( 2883 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(true); 2884 updateConfigAndVerifySupported(callback, new ArraySet<>()); 2885 2886 // Tethering is supported if it has any supported downstream. 2887 setTetheringSupported(true /* supported */); 2888 updateConfigAndVerifySupported(callback, expectedTypes); 2889 // Usb tethering is not supported: 2890 expectedTypes.remove(TETHERING_USB); 2891 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 2892 .thenReturn(new String[0]); 2893 updateConfigAndVerifySupported(callback, expectedTypes); 2894 // Wifi tethering is not supported: 2895 expectedTypes.remove(TETHERING_WIFI); 2896 when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) 2897 .thenReturn(new String[0]); 2898 updateConfigAndVerifySupported(callback, expectedTypes); 2899 // Bluetooth tethering is not supported: 2900 expectedTypes.remove(TETHERING_BLUETOOTH); 2901 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) 2902 .thenReturn(new String[0]); 2903 2904 if (isAtLeastT()) { 2905 updateConfigAndVerifySupported(callback, expectedTypes); 2906 2907 // P2p tethering is not supported: 2908 expectedTypes.remove(TETHERING_WIFI_P2P); 2909 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 2910 .thenReturn(new String[0]); 2911 updateConfigAndVerifySupported(callback, expectedTypes); 2912 // Ncm tethering is not supported: 2913 expectedTypes.remove(TETHERING_NCM); 2914 when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) 2915 .thenReturn(new String[0]); 2916 updateConfigAndVerifySupported(callback, expectedTypes); 2917 // Ethernet tethering (last supported type) is not supported: 2918 expectedTypes.remove(TETHERING_ETHERNET); 2919 mForceEthernetServiceUnavailable = true; 2920 updateConfigAndVerifySupported(callback, new ArraySet<>()); 2921 2922 } else { 2923 // If wifi, usb and bluetooth are all not supported, all the types are not supported. 2924 expectedTypes.clear(); 2925 updateConfigAndVerifySupported(callback, expectedTypes); 2926 } 2927 } 2928 updateConfigAndVerifySupported(final TestTetheringEventCallback callback, final ArraySet<Integer> expectedTypes)2929 private void updateConfigAndVerifySupported(final TestTetheringEventCallback callback, 2930 final ArraySet<Integer> expectedTypes) { 2931 sendConfigurationChanged(); 2932 2933 assertEquals(expectedTypes.size() > 0, mTethering.isTetheringSupported()); 2934 callback.expectSupportedTetheringTypes(expectedTypes); 2935 } 2936 // TODO: Test that a request for hotspot mode doesn't interfere with an 2937 // already operating tethering mode interface. 2938 } 2939