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