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.Manifest.permission.NETWORK_STACK; 21 import static android.content.pm.PackageManager.GET_ACTIVITIES; 22 import static android.content.pm.PackageManager.PERMISSION_DENIED; 23 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 24 import static android.hardware.usb.UsbManager.USB_CONFIGURED; 25 import static android.hardware.usb.UsbManager.USB_CONNECTED; 26 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM; 27 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; 28 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 29 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 30 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; 31 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; 32 import static android.net.ConnectivityManager.TYPE_WIFI; 33 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; 34 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 35 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 36 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; 37 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 38 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 39 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; 40 import static android.net.RouteInfo.RTN_UNICAST; 41 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; 42 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL; 43 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; 44 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER; 45 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER; 46 import static android.net.TetheringManager.TETHERING_BLUETOOTH; 47 import static android.net.TetheringManager.TETHERING_ETHERNET; 48 import static android.net.TetheringManager.TETHERING_NCM; 49 import static android.net.TetheringManager.TETHERING_USB; 50 import static android.net.TetheringManager.TETHERING_VIRTUAL; 51 import static android.net.TetheringManager.TETHERING_WIFI; 52 import static android.net.TetheringManager.TETHERING_WIFI_P2P; 53 import static android.net.TetheringManager.TETHER_ERROR_DUPLICATE_REQUEST; 54 import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; 55 import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR; 56 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; 57 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; 58 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; 59 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST; 60 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; 61 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; 62 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; 63 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; 64 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; 65 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; 66 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; 67 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; 68 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 69 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 70 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 71 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; 72 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; 73 import static android.system.OsConstants.RT_SCOPE_UNIVERSE; 74 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 75 76 import static com.android.modules.utils.build.SdkLevel.isAtLeastS; 77 import static com.android.modules.utils.build.SdkLevel.isAtLeastT; 78 import static com.android.modules.utils.build.SdkLevel.isAtLeastV; 79 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; 80 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH; 81 import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH; 82 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0; 83 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE; 84 import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST; 85 import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST; 86 import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener; 87 import static com.android.networkstack.tethering.TetheringConfiguration.TETHERING_LOCAL_NETWORK_AGENT; 88 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS; 89 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION; 90 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION; 91 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; 92 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES; 93 import static com.android.testutils.TestPermissionUtil.runAsShell; 94 95 import static org.junit.Assert.assertArrayEquals; 96 import static org.junit.Assert.assertEquals; 97 import static org.junit.Assert.assertFalse; 98 import static org.junit.Assert.assertNotNull; 99 import static org.junit.Assert.assertNull; 100 import static org.junit.Assert.assertTrue; 101 import static org.junit.Assert.fail; 102 import static org.junit.Assume.assumeTrue; 103 import static org.mockito.ArgumentMatchers.argThat; 104 import static org.mockito.ArgumentMatchers.notNull; 105 import static org.mockito.ArgumentMatchers.anyInt; 106 import static org.mockito.ArgumentMatchers.anyString; 107 import static org.mockito.ArgumentMatchers.eq; 108 import static org.mockito.Mockito.any; 109 import static org.mockito.Mockito.atLeast; 110 import static org.mockito.Mockito.atLeastOnce; 111 import static org.mockito.Mockito.doReturn; 112 import static org.mockito.Mockito.doThrow; 113 import static org.mockito.Mockito.inOrder; 114 import static org.mockito.Mockito.mock; 115 import static org.mockito.Mockito.never; 116 import static org.mockito.Mockito.reset; 117 import static org.mockito.Mockito.spy; 118 import static org.mockito.Mockito.timeout; 119 import static org.mockito.Mockito.times; 120 import static org.mockito.Mockito.verify; 121 import static org.mockito.Mockito.verifyNoMoreInteractions; 122 import static org.mockito.Mockito.when; 123 124 import android.app.usage.NetworkStatsManager; 125 import android.bluetooth.BluetoothAdapter; 126 import android.bluetooth.BluetoothPan; 127 import android.bluetooth.BluetoothProfile; 128 import android.bluetooth.BluetoothProfile.ServiceListener; 129 import android.content.BroadcastReceiver; 130 import android.content.ContentResolver; 131 import android.content.Context; 132 import android.content.Intent; 133 import android.content.IntentFilter; 134 import android.content.pm.ApplicationInfo; 135 import android.content.pm.PackageManager; 136 import android.content.res.Resources; 137 import android.database.ContentObserver; 138 import android.hardware.usb.UsbManager; 139 import android.net.ConnectivityManager; 140 import android.net.ConnectivityManager.NetworkCallback; 141 import android.net.EthernetManager; 142 import android.net.EthernetManager.TetheredInterfaceCallback; 143 import android.net.EthernetManager.TetheredInterfaceRequest; 144 import android.net.IConnectivityManager; 145 import android.net.IIntResultListener; 146 import android.net.INetd; 147 import android.net.ITetheringEventCallback; 148 import android.net.InetAddresses; 149 import android.net.InterfaceConfigurationParcel; 150 import android.net.IpPrefix; 151 import android.net.LinkAddress; 152 import android.net.LinkProperties; 153 import android.net.MacAddress; 154 import android.net.Network; 155 import android.net.NetworkCapabilities; 156 import android.net.NetworkRequest; 157 import android.net.RouteInfo; 158 import android.net.TetherStatesParcel; 159 import android.net.TetheredClient; 160 import android.net.TetheredClient.AddressInfo; 161 import android.net.TetheringCallbackStartedParcel; 162 import android.net.TetheringConfigurationParcel; 163 import android.net.TetheringInterface; 164 import android.net.TetheringManager; 165 import android.net.TetheringManager.TetheringRequest; 166 import android.net.dhcp.DhcpLeaseParcelable; 167 import android.net.dhcp.DhcpServerCallbacks; 168 import android.net.dhcp.DhcpServingParamsParcel; 169 import android.net.dhcp.IDhcpEventCallbacks; 170 import android.net.dhcp.IDhcpServer; 171 import android.net.ip.DadProxy; 172 import android.net.ip.IpServer; 173 import android.net.ip.RouterAdvertisementDaemon; 174 import android.net.wifi.SoftApConfiguration; 175 import android.net.wifi.SoftApState; 176 import android.net.wifi.WifiClient; 177 import android.net.wifi.WifiManager; 178 import android.net.wifi.WifiManager.SoftApCallback; 179 import android.net.wifi.WifiSsid; 180 import android.net.wifi.p2p.WifiP2pGroup; 181 import android.net.wifi.p2p.WifiP2pInfo; 182 import android.net.wifi.p2p.WifiP2pManager; 183 import android.os.Build; 184 import android.os.Bundle; 185 import android.os.Handler; 186 import android.os.Looper; 187 import android.os.PersistableBundle; 188 import android.os.RemoteException; 189 import android.os.UserHandle; 190 import android.os.UserManager; 191 import android.os.test.TestLooper; 192 import android.provider.Settings; 193 import android.telephony.CarrierConfigManager; 194 import android.telephony.PhoneStateListener; 195 import android.telephony.TelephonyManager; 196 import android.test.mock.MockContentResolver; 197 import android.util.ArrayMap; 198 import android.util.ArraySet; 199 200 import androidx.annotation.NonNull; 201 import androidx.annotation.Nullable; 202 import androidx.test.filters.SmallTest; 203 import androidx.test.runner.AndroidJUnit4; 204 205 import com.android.internal.util.test.BroadcastInterceptingContext; 206 import com.android.internal.util.test.FakeSettingsProvider; 207 import com.android.modules.utils.build.SdkLevel; 208 import com.android.net.module.util.CollectionUtils; 209 import com.android.net.module.util.InterfaceParams; 210 import com.android.net.module.util.PrivateAddressCoordinator; 211 import com.android.net.module.util.RoutingCoordinatorManager; 212 import com.android.net.module.util.RoutingCoordinatorService; 213 import com.android.net.module.util.SharedLog; 214 import com.android.net.module.util.ip.IpNeighborMonitor; 215 import com.android.networkstack.apishim.common.BluetoothPanShim; 216 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim; 217 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim; 218 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 219 import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent; 220 import com.android.networkstack.tethering.metrics.TetheringMetrics; 221 import com.android.testutils.DevSdkIgnoreRule; 222 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 223 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 224 import com.android.testutils.MiscAsserts; 225 import com.android.testutils.com.android.testutils.SetFeatureFlagsRule; 226 227 import org.junit.After; 228 import org.junit.Before; 229 import org.junit.BeforeClass; 230 import org.junit.Rule; 231 import org.junit.Test; 232 import org.junit.runner.RunWith; 233 import org.mockito.ArgumentCaptor; 234 import org.mockito.InOrder; 235 import org.mockito.Mock; 236 import org.mockito.MockitoAnnotations; 237 238 import java.io.FileDescriptor; 239 import java.io.PrintWriter; 240 import java.net.Inet4Address; 241 import java.net.Inet6Address; 242 import java.nio.charset.StandardCharsets; 243 import java.util.ArrayList; 244 import java.util.Arrays; 245 import java.util.Collection; 246 import java.util.Collections; 247 import java.util.List; 248 import java.util.Set; 249 import java.util.Vector; 250 import java.util.concurrent.Executor; 251 252 @RunWith(AndroidJUnit4.class) 253 @SmallTest 254 public class TetheringTest { 255 @Rule public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); 256 257 final ArrayMap<String, Boolean> mFeatureFlags = new ArrayMap<>(); 258 // This will set feature flags from @FeatureFlag annotations 259 // into the map before setUp() runs. 260 @Rule 261 public final SetFeatureFlagsRule mSetFeatureFlagsRule = 262 new SetFeatureFlagsRule((name, enabled) -> { 263 mFeatureFlags.put(name, enabled); 264 return null; 265 }, (name) -> mFeatureFlags.getOrDefault(name, false)); 266 267 private static final int IFINDEX_OFFSET = 100; 268 269 private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; 270 private static final String TEST_DUN_IFNAME = "test_dun0"; 271 private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0"; 272 private static final String TEST_RNDIS_IFNAME = "test_rndis0"; 273 private static final String TEST_WIFI_IFNAME = "test_wlan0"; 274 private static final String TEST_WLAN_IFNAME = "test_wlan1"; 275 private static final String TEST_WLAN2_IFNAME = "test_wlan2"; 276 private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0"; 277 private static final String TEST_NCM_IFNAME = "test_ncm0"; 278 private static final String TEST_ETH_IFNAME = "test_eth0"; 279 private static final String TEST_VIRT_IFNAME = "test_virt0"; 280 private static final String TEST_BT_IFNAME = "test_pan0"; 281 private static final String TETHERING_NAME = "Tethering"; 282 private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; 283 private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app"; 284 private static final String TEST_RNDIS_REGEX = "test_rndis\\d"; 285 private static final String TEST_NCM_REGEX = "test_ncm\\d"; 286 private static final String TEST_WIFI_REGEX = "test_wlan\\d"; 287 private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*"; 288 private static final String TEST_BT_REGEX = "test_pan\\d"; 289 private static final int TEST_CALLER_UID = 1000; 290 private static final int TEST_CALLER_UID_2 = 2000; 291 private static final String TEST_CALLER_PKG = "com.test.tethering"; 292 private static final String TEST_CALLER_PKG_2 = "com.test.tethering2"; 293 private static final int CELLULAR_NETID = 100; 294 private static final int WIFI_NETID = 101; 295 private static final int DUN_NETID = 102; 296 297 private static final int TETHER_USB_RNDIS_NCM_FUNCTIONS = 2; 298 299 private static final int DHCPSERVER_START_TIMEOUT_MS = 1000; 300 301 private static final Network[] NULL_NETWORK = new Network[] {null}; 302 303 @Mock private ApplicationInfo mApplicationInfo; 304 @Mock private Context mContext; 305 @Mock private NetworkStatsManager mStatsManager; 306 @Mock private OffloadHardwareInterface mOffloadHardwareInterface; 307 @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats; 308 @Mock private Resources mResources; 309 @Mock private TelephonyManager mTelephonyManager; 310 @Mock private UsbManager mUsbManager; 311 @Mock private WifiManager mWifiManager; 312 @Mock private CarrierConfigManager mCarrierConfigManager; 313 @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator; 314 @Mock private DadProxy mDadProxy; 315 @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; 316 @Mock private IpNeighborMonitor mIpNeighborMonitor; 317 @Mock private IDhcpServer mDhcpServer; 318 @Mock private INetd mNetd; 319 @Mock private UserManager mUserManager; 320 @Mock private EthernetManager mEm; 321 @Mock private TetheringNotificationUpdater mNotificationUpdater; 322 @Mock private BpfCoordinator mBpfCoordinator; 323 @Mock private PackageManager mPackageManager; 324 @Mock private BluetoothAdapter mBluetoothAdapter; 325 @Mock private BluetoothPan mBluetoothPan; 326 @Mock private BluetoothPanShim mBluetoothPanShim; 327 @Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim; 328 @Mock private TetheringMetrics mTetheringMetrics; 329 @Mock private PrivateAddressCoordinator.Dependencies mPrivateAddressCoordinatorDependencies; 330 331 private MockIpServerDependencies mIpServerDependencies; 332 private final MockTetheringDependencies mTetheringDependencies = 333 new MockTetheringDependencies(); 334 335 // Like so many Android system APIs, these cannot be mocked because it is marked final. 336 // We have to use the real versions. 337 private final PersistableBundle mCarrierConfig = new PersistableBundle(); 338 private TestLooper mLooper; 339 340 private Vector<Intent> mIntents; 341 private BroadcastInterceptingContext mServiceContext; 342 private MockContentResolver mContentResolver; 343 private BroadcastReceiver mBroadcastReceiver; 344 private Tethering mTethering; 345 private TestTetheringEventCallback mTetheringEventCallback; 346 private Tethering.TetherMainSM mTetherMainSM; 347 private PhoneStateListener mPhoneStateListener; 348 private InterfaceConfigurationParcel mInterfaceConfiguration; 349 private TetheringConfiguration mConfig; 350 private EntitlementManager mEntitleMgr; 351 private OffloadController mOffloadCtrl; 352 private SoftApCallback mSoftApCallback; 353 private SoftApCallback mLocalOnlyHotspotCallback; 354 private UpstreamNetworkMonitor mUpstreamNetworkMonitor; 355 private UpstreamNetworkMonitor.EventListener mEventListener; 356 private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim; 357 private RoutingCoordinatorManager mRoutingCoordinatorManager; 358 359 private TestConnectivityManager mCm; 360 private boolean mForceEthernetServiceUnavailable = false; 361 private int mBinderCallingUid = TEST_CALLER_UID; 362 private boolean mTetheringWithSoftApConfigEnabled = SdkLevel.isAtLeastB(); 363 364 private class TestContext extends BroadcastInterceptingContext { TestContext(Context base)365 TestContext(Context base) { 366 super(base); 367 } 368 369 @Override getApplicationInfo()370 public ApplicationInfo getApplicationInfo() { 371 return mApplicationInfo; 372 } 373 374 @Override getContentResolver()375 public ContentResolver getContentResolver() { 376 return mContentResolver; 377 } 378 379 @Override getPackageName()380 public String getPackageName() { 381 return "TetheringTest"; 382 } 383 384 @Override getResources()385 public Resources getResources() { 386 return mResources; 387 } 388 389 @Override getSystemService(String name)390 public Object getSystemService(String name) { 391 if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; 392 if (Context.USB_SERVICE.equals(name)) return mUsbManager; 393 if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; 394 if (Context.USER_SERVICE.equals(name)) return mUserManager; 395 if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; 396 if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; 397 if (Context.ETHERNET_SERVICE.equals(name)) { 398 if (mForceEthernetServiceUnavailable) return null; 399 400 return mEm; 401 } 402 return super.getSystemService(name); 403 } 404 405 @Override getPackageManager()406 public PackageManager getPackageManager() { 407 return mPackageManager; 408 } 409 410 @Override getSystemServiceName(Class<?> serviceClass)411 public String getSystemServiceName(Class<?> serviceClass) { 412 if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; 413 if (ConnectivityManager.class.equals(serviceClass)) return Context.CONNECTIVITY_SERVICE; 414 return super.getSystemServiceName(serviceClass); 415 } 416 } 417 418 public class MockIpServerDependencies extends IpServer.Dependencies { 419 420 private int mOnDhcpServerCreatedResult = STATUS_SUCCESS; 421 422 @Override getDadProxy( Handler handler, InterfaceParams ifParams)423 public DadProxy getDadProxy( 424 Handler handler, InterfaceParams ifParams) { 425 return mDadProxy; 426 } 427 428 @Override getRouterAdvertisementDaemon( InterfaceParams ifParams)429 public RouterAdvertisementDaemon getRouterAdvertisementDaemon( 430 InterfaceParams ifParams) { 431 return mRouterAdvertisementDaemon; 432 } 433 434 @Override getInterfaceParams(String ifName)435 public InterfaceParams getInterfaceParams(String ifName) { 436 assertTrue("Non-mocked interface " + ifName, 437 ifName.equals(TEST_RNDIS_IFNAME) 438 || ifName.equals(TEST_WLAN_IFNAME) 439 || ifName.equals(TEST_WLAN2_IFNAME) 440 || ifName.equals(TEST_WIFI_IFNAME) 441 || ifName.equals(TEST_MOBILE_IFNAME) 442 || ifName.equals(TEST_DUN_IFNAME) 443 || ifName.equals(TEST_P2P_IFNAME) 444 || ifName.equals(TEST_NCM_IFNAME) 445 || ifName.equals(TEST_ETH_IFNAME) 446 || ifName.equals(TEST_BT_IFNAME) 447 || ifName.equals(TEST_VIRT_IFNAME)); 448 final String[] ifaces = new String[] { 449 TEST_RNDIS_IFNAME, TEST_WLAN_IFNAME, TEST_WLAN2_IFNAME, TEST_WIFI_IFNAME, 450 TEST_MOBILE_IFNAME, TEST_DUN_IFNAME, TEST_P2P_IFNAME, TEST_NCM_IFNAME, 451 TEST_ETH_IFNAME, TEST_VIRT_IFNAME}; 452 return new InterfaceParams(ifName, 453 CollectionUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET, 454 MacAddress.ALL_ZEROS_ADDRESS); 455 } 456 457 @SuppressWarnings("DoNotCall") // Ignore warning for synchronous to call to Thread.run() 458 @Override makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb)459 public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, 460 DhcpServerCallbacks cb) { 461 new Thread(() -> { 462 try { 463 cb.onDhcpServerCreated(mOnDhcpServerCreatedResult, mDhcpServer); 464 } catch (RemoteException e) { 465 fail(e.getMessage()); 466 } 467 }).run(); 468 } 469 getIpNeighborMonitor(Handler h, SharedLog l, IpNeighborMonitor.NeighborEventConsumer c)470 public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l, 471 IpNeighborMonitor.NeighborEventConsumer c) { 472 return mIpNeighborMonitor; 473 } 474 setOnDhcpServerCreatedResult(final int result)475 public void setOnDhcpServerCreatedResult(final int result) { 476 mOnDhcpServerCreatedResult = result; 477 } 478 479 @Override isFeatureEnabled(Context context, String name)480 public boolean isFeatureEnabled(Context context, String name) { 481 return mFeatureFlags.getOrDefault(name, false); 482 } 483 } 484 485 public class MockTetheringDependencies extends TetheringDependencies { 486 ArrayList<IpServer> mAllDownstreams; 487 488 @Override makeBpfCoordinator( BpfCoordinator.Dependencies deps)489 public BpfCoordinator makeBpfCoordinator( 490 BpfCoordinator.Dependencies deps) { 491 return mBpfCoordinator; 492 } 493 494 @Override makeOffloadHardwareInterface(Handler h, SharedLog log)495 public OffloadHardwareInterface makeOffloadHardwareInterface(Handler h, SharedLog log) { 496 return mOffloadHardwareInterface; 497 } 498 499 @Override makeOffloadController(Handler h, SharedLog log, OffloadController.Dependencies deps)500 public OffloadController makeOffloadController(Handler h, SharedLog log, 501 OffloadController.Dependencies deps) { 502 mOffloadCtrl = spy(super.makeOffloadController(h, log, deps)); 503 // Return real object here instead of mock because 504 // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object. 505 return mOffloadCtrl; 506 } 507 508 @Override makeUpstreamNetworkMonitor(Context ctx, Handler h, SharedLog log, UpstreamNetworkMonitor.EventListener listener)509 public UpstreamNetworkMonitor makeUpstreamNetworkMonitor(Context ctx, Handler h, 510 SharedLog log, UpstreamNetworkMonitor.EventListener listener) { 511 // Use a real object instead of a mock so that some tests can use a real UNM and some 512 // can use a mock. 513 mEventListener = listener; 514 mUpstreamNetworkMonitor = spy(super.makeUpstreamNetworkMonitor(ctx, h, log, listener)); 515 return mUpstreamNetworkMonitor; 516 } 517 518 @Override makeIPv6TetheringCoordinator( ArrayList<IpServer> notifyList, SharedLog log)519 public IPv6TetheringCoordinator makeIPv6TetheringCoordinator( 520 ArrayList<IpServer> notifyList, SharedLog log) { 521 mAllDownstreams = notifyList; 522 return mIPv6TetheringCoordinator; 523 } 524 525 @Override makeIpServerDependencies()526 public IpServer.Dependencies makeIpServerDependencies() { 527 return mIpServerDependencies; 528 } 529 530 @Override makeEntitlementManager(Context ctx, Handler h, SharedLog log, Runnable callback)531 public EntitlementManager makeEntitlementManager(Context ctx, Handler h, SharedLog log, 532 Runnable callback) { 533 mEntitleMgr = spy(super.makeEntitlementManager(ctx, h, log, callback)); 534 return mEntitleMgr; 535 } 536 537 @Override getRoutingCoordinator( final Context context, SharedLog log)538 public RoutingCoordinatorManager getRoutingCoordinator( 539 final Context context, SharedLog log) { 540 ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); 541 when(mPrivateAddressCoordinatorDependencies.isFeatureEnabled(anyString())) 542 .thenReturn(false); 543 RoutingCoordinatorService service = new RoutingCoordinatorService( 544 getINetd(context, log), 545 cm::getAllNetworks, 546 mPrivateAddressCoordinatorDependencies); 547 mRoutingCoordinatorManager = spy(new RoutingCoordinatorManager(context, service)); 548 return mRoutingCoordinatorManager; 549 } 550 551 @Override generateTetheringConfiguration(Context ctx, SharedLog log, int subId)552 public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, 553 int subId) { 554 mConfig = spy(new FakeTetheringConfiguration(ctx, log, subId)); 555 return mConfig; 556 } 557 558 @Override getINetd(Context context, SharedLog log)559 public INetd getINetd(Context context, SharedLog log) { 560 return mNetd; 561 } 562 563 @Override makeTetheringLooper()564 public Looper makeTetheringLooper() { 565 return mLooper.getLooper(); 566 } 567 568 @Override getContext()569 public Context getContext() { 570 return mServiceContext; 571 } 572 573 @Override getBluetoothAdapter()574 public BluetoothAdapter getBluetoothAdapter() { 575 return mBluetoothAdapter; 576 } 577 578 @Override makeNotificationUpdater(Context ctx, Looper looper)579 public TetheringNotificationUpdater makeNotificationUpdater(Context ctx, Looper looper) { 580 return mNotificationUpdater; 581 } 582 583 @Override isTetheringDenied()584 public boolean isTetheringDenied() { 585 return false; 586 } 587 588 @Override makeTetheringMetrics(Context ctx)589 public TetheringMetrics makeTetheringMetrics(Context ctx) { 590 return mTetheringMetrics; 591 } 592 593 @Override makeBluetoothPanShim(BluetoothPan pan)594 public BluetoothPanShim makeBluetoothPanShim(BluetoothPan pan) { 595 try { 596 when(mBluetoothPanShim.requestTetheredInterface( 597 any(), any())).thenReturn(mTetheredInterfaceRequestShim); 598 } catch (UnsupportedApiLevelException e) { 599 fail("BluetoothPan#requestTetheredInterface is not supported"); 600 } 601 return mBluetoothPanShim; 602 } 603 604 @Override getBinderCallingUid()605 public int getBinderCallingUid() { 606 return mBinderCallingUid; 607 } 608 609 @Override isTetheringWithSoftApConfigEnabled()610 public boolean isTetheringWithSoftApConfigEnabled() { 611 return mTetheringWithSoftApConfigEnabled; 612 } 613 } 614 buildUpstreamLinkProperties(String interfaceName, boolean withIPv4, boolean withIPv6, boolean with464xlat)615 private static LinkProperties buildUpstreamLinkProperties(String interfaceName, 616 boolean withIPv4, boolean withIPv6, boolean with464xlat) { 617 final LinkProperties prop = new LinkProperties(); 618 prop.setInterfaceName(interfaceName); 619 620 if (withIPv4) { 621 prop.addLinkAddress(new LinkAddress("10.1.2.3/15")); 622 prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 623 InetAddresses.parseNumericAddress("10.0.0.1"), 624 interfaceName, RTN_UNICAST)); 625 } 626 627 if (withIPv6) { 628 prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2")); 629 prop.addLinkAddress( 630 new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), 631 RFC7421_PREFIX_LENGTH)); 632 prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), 633 InetAddresses.parseNumericAddress("2001:db8::1"), 634 interfaceName, RTN_UNICAST)); 635 } 636 637 if (with464xlat) { 638 final String clatInterface = "v4-" + interfaceName; 639 final LinkProperties stackedLink = new LinkProperties(); 640 stackedLink.setInterfaceName(clatInterface); 641 stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), 642 InetAddresses.parseNumericAddress("192.0.0.1"), 643 clatInterface, RTN_UNICAST)); 644 645 prop.addStackedLink(stackedLink); 646 } 647 648 return prop; 649 } 650 buildUpstreamCapabilities(int transport, int... otherCaps)651 private static NetworkCapabilities buildUpstreamCapabilities(int transport, int... otherCaps) { 652 // TODO: add NOT_VCN_MANAGED. 653 final NetworkCapabilities nc = new NetworkCapabilities() 654 .addTransportType(transport); 655 for (int cap : otherCaps) { 656 nc.addCapability(cap); 657 } 658 return nc; 659 } 660 buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, boolean with464xlat)661 private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, 662 boolean withIPv6, boolean with464xlat) { 663 return new UpstreamNetworkState( 664 buildUpstreamLinkProperties(TEST_MOBILE_IFNAME, withIPv4, withIPv6, with464xlat), 665 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_INTERNET), 666 new Network(CELLULAR_NETID)); 667 } 668 buildMobileIPv4UpstreamState()669 private static UpstreamNetworkState buildMobileIPv4UpstreamState() { 670 return buildMobileUpstreamState(true, false, false); 671 } 672 buildMobileIPv6UpstreamState()673 private static UpstreamNetworkState buildMobileIPv6UpstreamState() { 674 return buildMobileUpstreamState(false, true, false); 675 } 676 buildMobileDualStackUpstreamState()677 private static UpstreamNetworkState buildMobileDualStackUpstreamState() { 678 return buildMobileUpstreamState(true, true, false); 679 } 680 buildMobile464xlatUpstreamState()681 private static UpstreamNetworkState buildMobile464xlatUpstreamState() { 682 return buildMobileUpstreamState(false, true, true); 683 } 684 buildWifiUpstreamState()685 private static UpstreamNetworkState buildWifiUpstreamState() { 686 return new UpstreamNetworkState( 687 buildUpstreamLinkProperties(TEST_WIFI_IFNAME, true /* IPv4 */, true /* IPv6 */, 688 false /* 464xlat */), 689 buildUpstreamCapabilities(TRANSPORT_WIFI, NET_CAPABILITY_INTERNET), 690 new Network(WIFI_NETID)); 691 } 692 buildDunUpstreamState()693 private static UpstreamNetworkState buildDunUpstreamState() { 694 return new UpstreamNetworkState( 695 buildUpstreamLinkProperties(TEST_DUN_IFNAME, true /* IPv4 */, true /* IPv6 */, 696 false /* 464xlat */), 697 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_DUN), 698 new Network(DUN_NETID)); 699 } 700 701 // See FakeSettingsProvider#clearSettingsProvider() that this also needs to be called before 702 // use. 703 @BeforeClass setupOnce()704 public static void setupOnce() { 705 FakeSettingsProvider.clearSettingsProvider(); 706 } 707 708 @Before setUp()709 public void setUp() throws Exception { 710 MockitoAnnotations.initMocks(this); 711 when(mResources.getStringArray(R.array.config_tether_dhcp_range)) 712 .thenReturn(new String[0]); 713 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 714 false); 715 when(mNetd.interfaceGetList()) 716 .thenReturn(new String[] { 717 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_WLAN2_IFNAME, TEST_RNDIS_IFNAME, 718 TEST_P2P_IFNAME, TEST_NCM_IFNAME, TEST_ETH_IFNAME, TEST_BT_IFNAME, 719 TEST_VIRT_IFNAME}); 720 when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn(""); 721 mInterfaceConfiguration = new InterfaceConfigurationParcel(); 722 mInterfaceConfiguration.flags = new String[0]; 723 when(mRouterAdvertisementDaemon.start()) 724 .thenReturn(true); 725 initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 0 /* defaultDisabled */); 726 when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats); 727 728 mServiceContext = new TestContext(mContext); 729 mServiceContext.setUseRegisteredHandlers(true); 730 mContentResolver = new MockContentResolver(mServiceContext); 731 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 732 setTetheringSupported(true /* supported */); 733 mIntents = new Vector<>(); 734 mBroadcastReceiver = new BroadcastReceiver() { 735 @Override 736 public void onReceive(Context context, Intent intent) { 737 mIntents.addElement(intent); 738 } 739 }; 740 mServiceContext.registerReceiver(mBroadcastReceiver, 741 new IntentFilter(ACTION_TETHER_STATE_CHANGED)); 742 743 mCm = spy(new TestConnectivityManager(mServiceContext, mock(IConnectivityManager.class))); 744 when(mCm.getAllNetworks()).thenReturn(new Network[] {}); 745 746 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true); 747 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true); 748 mIpServerDependencies = spy(new MockIpServerDependencies()); 749 when(mWifiManager.startTetheredHotspot(null)).thenReturn(true); 750 mTetheringWithSoftApConfigEnabled = SdkLevel.isAtLeastB(); 751 } 752 753 // In order to interact with syncSM from the test, tethering must be created in test thread. initTetheringOnTestThread()754 private void initTetheringOnTestThread() throws Exception { 755 mLooper = new TestLooper(); 756 mTethering = new Tethering(mTetheringDependencies); 757 mTetherMainSM = mTethering.getTetherMainSMForTesting(); 758 verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any()); 759 verify(mNetd).registerUnsolicitedEventListener(any()); 760 verifyDefaultNetworkRequestFiled(); 761 mTetheringEventCallback = registerTetheringEventCallback(); 762 763 final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = 764 ArgumentCaptor.forClass(PhoneStateListener.class); 765 verify(mTelephonyManager).listen(phoneListenerCaptor.capture(), 766 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)); 767 mPhoneStateListener = phoneListenerCaptor.getValue(); 768 769 final ArgumentCaptor<SoftApCallback> softApCallbackCaptor = 770 ArgumentCaptor.forClass(SoftApCallback.class); 771 verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture()); 772 mSoftApCallback = softApCallbackCaptor.getValue(); 773 774 if (isAtLeastT()) { 775 final ArgumentCaptor<SoftApCallback> localOnlyCallbackCaptor = 776 ArgumentCaptor.forClass(SoftApCallback.class); 777 verify(mWifiManager).registerLocalOnlyHotspotSoftApCallback(any(), 778 localOnlyCallbackCaptor.capture()); 779 mLocalOnlyHotspotCallback = localOnlyCallbackCaptor.getValue(); 780 } 781 } 782 setTetheringSupported(final boolean supported)783 private void setTetheringSupported(final boolean supported) { 784 Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 785 supported ? 1 : 0); 786 when(mUserManager.hasUserRestriction( 787 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported); 788 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 789 TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION); 790 // Setup tetherable configuration. 791 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 792 .thenReturn(new String[] {TEST_RNDIS_REGEX}); 793 when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) 794 .thenReturn(new String[] {TEST_WIFI_REGEX}); 795 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 796 .thenReturn(new String[] {TEST_P2P_REGEX}); 797 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) 798 .thenReturn(new String[] {TEST_BT_REGEX}); 799 when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) 800 .thenReturn(new String[] {TEST_NCM_REGEX}); 801 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true); 802 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( 803 new int[] {TYPE_WIFI, TYPE_MOBILE_DUN}); 804 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); 805 } 806 initTetheringUpstream(UpstreamNetworkState upstreamState)807 private void initTetheringUpstream(UpstreamNetworkState upstreamState) { 808 doReturn(upstreamState).when(mUpstreamNetworkMonitor).getCurrentPreferredUpstream(); 809 doReturn(upstreamState).when(mUpstreamNetworkMonitor).selectPreferredUpstreamType(any()); 810 } 811 createTetheringRequest(final int type)812 private TetheringRequest createTetheringRequest(final int type) { 813 return createTetheringRequest(type, null, null, false, CONNECTIVITY_SCOPE_GLOBAL, null); 814 } 815 createTetheringRequest(final int type, final LinkAddress localIPv4Address, final LinkAddress staticClientAddress, final boolean exempt, final int scope, final String interfaceName)816 private TetheringRequest createTetheringRequest(final int type, 817 final LinkAddress localIPv4Address, final LinkAddress staticClientAddress, 818 final boolean exempt, final int scope, final String interfaceName) { 819 TetheringRequest.Builder builder = new TetheringRequest.Builder(type) 820 .setExemptFromEntitlementCheck(exempt) 821 .setConnectivityScope(scope) 822 .setShouldShowEntitlementUi(false); 823 if (localIPv4Address != null && staticClientAddress != null) { 824 builder.setStaticIpv4Addresses(localIPv4Address, staticClientAddress); 825 } 826 if (interfaceName != null) { 827 builder.setInterfaceName(interfaceName); 828 } 829 TetheringRequest request = builder.build(); 830 request.setUid(TEST_CALLER_UID); 831 request.setPackageName(TEST_CALLER_PKG); 832 return request; 833 } 834 835 @NonNull registerTetheringEventCallback()836 private TestTetheringEventCallback registerTetheringEventCallback() { 837 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 838 mTethering.registerTetheringEventCallback(callback); 839 mLooper.dispatchAll(); 840 // Pull the first event which is filed immediately after the callback registration. 841 callback.expectUpstreamChanged(NULL_NETWORK); 842 return callback; 843 } 844 845 @After tearDown()846 public void tearDown() { 847 mServiceContext.unregisterReceiver(mBroadcastReceiver); 848 FakeSettingsProvider.clearSettingsProvider(); 849 } 850 sendWifiApStateChanged(int state)851 private void sendWifiApStateChanged(int state) { 852 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 853 intent.putExtra(EXTRA_WIFI_AP_STATE, state); 854 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 855 mLooper.dispatchAll(); 856 } 857 sendWifiApStateChanged(int state, String ifname, int ipmode)858 private void sendWifiApStateChanged(int state, String ifname, int ipmode) { 859 final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 860 intent.putExtra(EXTRA_WIFI_AP_STATE, state); 861 intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname); 862 intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode); 863 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 864 mLooper.dispatchAll(); 865 } 866 sendStartTetheringSoftApCallback(int state, TetheringRequest request, String ifname)867 private void sendStartTetheringSoftApCallback(int state, TetheringRequest request, 868 String ifname) { 869 ArgumentCaptor<SoftApCallback> callbackCaptor = 870 ArgumentCaptor.forClass(SoftApCallback.class); 871 verify(mWifiManager, atLeastOnce()).startTetheredHotspot(any(TetheringRequest.class), 872 any(Executor.class), callbackCaptor.capture()); 873 SoftApState softApState = mock(SoftApState.class); 874 when(softApState.getState()).thenReturn(state); 875 when(softApState.getTetheringRequest()).thenReturn(request); 876 when(softApState.getIface()).thenReturn(ifname); 877 callbackCaptor.getValue().onStateChanged(softApState); 878 mLooper.dispatchAll(); 879 } 880 verifyWifiTetheringRequested()881 private void verifyWifiTetheringRequested() { 882 if (mTetheringDependencies.isTetheringWithSoftApConfigEnabled()) { 883 verify(mWifiManager).startTetheredHotspot(any(), any(), any()); 884 } else { 885 verify(mWifiManager).startTetheredHotspot(null); 886 } 887 verify(mWifiManager, never()).stopSoftAp(); 888 verifyNoMoreInteractions(mWifiManager); 889 } 890 sendSoftApEvent(int state, TetheringRequest request, String ifname)891 private void sendSoftApEvent(int state, TetheringRequest request, String ifname) { 892 if (mTetheringDependencies.isTetheringWithSoftApConfigEnabled()) { 893 sendStartTetheringSoftApCallback(state, request, ifname); 894 } else { 895 sendWifiApStateChanged(state, ifname, IFACE_IP_MODE_TETHERED); 896 } 897 } 898 899 private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = { 900 android.Manifest.permission.ACCESS_FINE_LOCATION, 901 android.Manifest.permission.ACCESS_WIFI_STATE 902 }; 903 sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname)904 private void sendWifiP2pConnectionChanged( 905 boolean isGroupFormed, boolean isGroupOwner, String ifname) { 906 WifiP2pGroup group = null; 907 WifiP2pInfo p2pInfo = new WifiP2pInfo(); 908 p2pInfo.groupFormed = isGroupFormed; 909 if (isGroupFormed) { 910 p2pInfo.isGroupOwner = isGroupOwner; 911 group = mock(WifiP2pGroup.class); 912 when(group.isGroupOwner()).thenReturn(isGroupOwner); 913 when(group.getInterface()).thenReturn(ifname); 914 } 915 916 final Intent intent = mock(Intent.class); 917 when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 918 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo); 919 when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group); 920 921 mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL, 922 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST); 923 mLooper.dispatchAll(); 924 } 925 926 // enableType: 927 // No function enabled = -1 928 // TETHER_USB_RNDIS_FUNCTION = 0 929 // TETHER_USB_NCM_FUNCTIONS = 1 930 // TETHER_USB_RNDIS_NCM_FUNCTIONS = 2 tetherUsbFunctionMatches(int function, int enabledType)931 private boolean tetherUsbFunctionMatches(int function, int enabledType) { 932 if (enabledType < 0) return false; 933 934 if (enabledType == TETHER_USB_RNDIS_NCM_FUNCTIONS) return function < enabledType; 935 936 return function == enabledType; 937 } 938 sendUsbBroadcast(boolean connected, boolean configured, int function)939 private void sendUsbBroadcast(boolean connected, boolean configured, int function) { 940 final Intent intent = new Intent(UsbManager.ACTION_USB_STATE); 941 intent.putExtra(USB_CONNECTED, connected); 942 intent.putExtra(USB_CONFIGURED, configured); 943 intent.putExtra(USB_FUNCTION_RNDIS, 944 tetherUsbFunctionMatches(TETHER_USB_RNDIS_FUNCTION, function)); 945 intent.putExtra(USB_FUNCTION_NCM, 946 tetherUsbFunctionMatches(TETHER_USB_NCM_FUNCTION, function)); 947 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 948 mLooper.dispatchAll(); 949 } 950 sendConfigurationChanged()951 private void sendConfigurationChanged() { 952 final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 953 mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 954 mLooper.dispatchAll(); 955 } 956 verifyDefaultNetworkRequestFiled()957 private void verifyDefaultNetworkRequestFiled() { 958 if (isAtLeastS()) { 959 verify(mCm, times(1)).registerSystemDefaultNetworkCallback( 960 any(NetworkCallback.class), any(Handler.class)); 961 } else { 962 ArgumentCaptor<NetworkRequest> reqCaptor = ArgumentCaptor.forClass( 963 NetworkRequest.class); 964 verify(mCm, times(1)).requestNetwork(reqCaptor.capture(), 965 any(NetworkCallback.class), any(Handler.class)); 966 assertTrue(TestConnectivityManager.looksLikeDefaultRequest(reqCaptor.getValue())); 967 } 968 969 // Ignore calls to {@link ConnectivityManager#getallNetworks}. 970 verify(mCm, atLeast(0)).getAllNetworks(); 971 972 // The default network request is only ever filed once. 973 verifyNoMoreInteractions(mCm); 974 } 975 verifyInterfaceServingModeStarted(String ifname, boolean expectAgentEnabled)976 private void verifyInterfaceServingModeStarted(String ifname, boolean expectAgentEnabled) 977 throws Exception { 978 verify(mNetd).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 979 verify(mNetd).tetherInterfaceAdd(ifname); 980 if (expectAgentEnabled) { 981 verify(mNetd, never()).networkAddInterface(anyInt(), anyString()); 982 verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString()); 983 } else { 984 verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, ifname); 985 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname), 986 anyString(), anyString()); 987 } 988 } 989 verifyTetheringBroadcast(String ifname, String whichExtra)990 private void verifyTetheringBroadcast(String ifname, String whichExtra) { 991 // Verify that ifname is in the whichExtra array of the tether state changed broadcast. 992 final Intent bcast = mIntents.get(0); 993 assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction()); 994 final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra); 995 assertTrue(ifnames.contains(ifname)); 996 mIntents.remove(bcast); 997 } 998 failingLocalOnlyHotspotLegacyApBroadcast( boolean emulateInterfaceStatusChanged)999 public void failingLocalOnlyHotspotLegacyApBroadcast( 1000 boolean emulateInterfaceStatusChanged) throws Exception { 1001 initTetheringOnTestThread(); 1002 // Emulate externally-visible WifiManager effects, causing the 1003 // per-interface state machine to start up, and telling us that 1004 // hotspot mode is to be started. 1005 if (emulateInterfaceStatusChanged) { 1006 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1007 } 1008 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 1009 1010 // If, and only if, Tethering received an interface status changed then 1011 // it creates a IpServer and sends out a broadcast indicating that the 1012 // interface is "available". 1013 if (emulateInterfaceStatusChanged) { 1014 if (!SdkLevel.isAtLeastB()) { 1015 // There is 1 IpServer state change event: STATE_AVAILABLE 1016 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); 1017 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 1018 verify(mWifiManager).updateInterfaceIpState( 1019 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1020 } else { 1021 // Starting in B, ignore the interfaceStatusChanged 1022 verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE); 1023 verify(mWifiManager, never()).updateInterfaceIpState( 1024 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1025 } 1026 } 1027 verifyNoMoreInteractions(mNetd); 1028 verifyNoMoreInteractions(mWifiManager); 1029 } 1030 prepareNcmTethering()1031 private void prepareNcmTethering() { 1032 // Emulate startTethering(TETHERING_NCM) called 1033 mTethering.startTethering(createTetheringRequest(TETHERING_NCM), TEST_CALLER_PKG, 1034 null); 1035 mLooper.dispatchAll(); 1036 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); 1037 } 1038 prepareUsbTethering()1039 private void prepareUsbTethering() { 1040 // Emulate pressing the USB tethering button in Settings UI. 1041 final TetheringRequest request = createTetheringRequest(TETHERING_USB); 1042 mTethering.startTethering(request, TEST_CALLER_PKG, null); 1043 mLooper.dispatchAll(); 1044 1045 assertEquals(1, mTethering.getPendingTetheringRequests().size()); 1046 assertTrue(mTethering.getPendingTetheringRequests().get(0).equals(request)); 1047 1048 if (mTethering.getTetheringConfiguration().isUsingNcm()) { 1049 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NCM); 1050 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true); 1051 } else { 1052 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 1053 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 1054 } 1055 1056 } 1057 1058 @Test testUsbConfiguredBroadcastStartsTethering()1059 public void testUsbConfiguredBroadcastStartsTethering() throws Exception { 1060 initTetheringOnTestThread(); 1061 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1062 initTetheringUpstream(upstreamState); 1063 prepareUsbTethering(); 1064 1065 // This should produce no activity of any kind. 1066 verifyNoMoreInteractions(mNetd); 1067 1068 // Pretend we then receive USB configured broadcast. 1069 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1070 // Now we should see the start of tethering mechanics (in this case: 1071 // tetherMatchingInterfaces() which starts by fetching all interfaces). 1072 verify(mNetd, times(1)).interfaceGetList(); 1073 1074 // Event callback should receive selected upstream 1075 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream(); 1076 mTetheringEventCallback.expectUpstreamChanged(upstreamState.network); 1077 } 1078 1079 @Test failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged()1080 public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception { 1081 failingLocalOnlyHotspotLegacyApBroadcast(true); 1082 } 1083 1084 @Test failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged()1085 public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception { 1086 failingLocalOnlyHotspotLegacyApBroadcast(false); 1087 } 1088 isTetheringNetworkAgentFeatureEnabled()1089 private boolean isTetheringNetworkAgentFeatureEnabled() { 1090 return isAtLeastV() && mFeatureFlags.getOrDefault(TETHERING_LOCAL_NETWORK_AGENT, false); 1091 } 1092 verifyStopHotpot(boolean isLocalOnly)1093 private void verifyStopHotpot(boolean isLocalOnly) throws Exception { 1094 verify(mNetd).tetherApplyDnsInterfaces(); 1095 verify(mNetd).tetherInterfaceRemove(TEST_WLAN_IFNAME); 1096 if (!isLocalOnly && isTetheringNetworkAgentFeatureEnabled()) { 1097 verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString()); 1098 } else { 1099 verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 1100 } 1101 // interfaceSetCfg() called once for enabling and twice disabling IPv4. 1102 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 1103 verify(mNetd).tetherStop(); 1104 verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME); 1105 verify(mWifiManager, times(3)).updateInterfaceIpState( 1106 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1107 verifyNoMoreInteractions(mNetd); 1108 verifyNoMoreInteractions(mWifiManager); 1109 // Asking for the last error after the per-interface state machine 1110 // has been reaped yields an unknown interface error. 1111 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME)); 1112 } 1113 verifyStartHotspot()1114 private void verifyStartHotspot() throws Exception { 1115 verifyStartHotspot(false /* isLocalOnly */); 1116 } 1117 verifyStartHotspot(boolean isLocalOnly)1118 private void verifyStartHotspot(boolean isLocalOnly) throws Exception { 1119 final boolean expectAgentEnabled = !isLocalOnly && isTetheringNetworkAgentFeatureEnabled(); 1120 verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME, expectAgentEnabled); 1121 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 1122 verify(mWifiManager).updateInterfaceIpState( 1123 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 1124 1125 verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME); 1126 verify(mNetd).tetherStartWithConfiguration(any()); 1127 verifyNoMoreInteractions(mNetd); 1128 1129 final int expectedState = isLocalOnly ? IFACE_IP_MODE_LOCAL_ONLY : IFACE_IP_MODE_TETHERED; 1130 verify(mWifiManager).updateInterfaceIpState(TEST_WLAN_IFNAME, expectedState); 1131 verifyNoMoreInteractions(mWifiManager); 1132 1133 verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks(); 1134 if (isLocalOnly) { 1135 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY. 1136 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 1137 } else { 1138 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED. 1139 verify(mNotificationUpdater).onDownstreamChanged(DOWNSTREAM_NONE); 1140 verify(mNotificationUpdater).onDownstreamChanged(eq(1 << TETHERING_WIFI)); 1141 } 1142 } 1143 workingLocalOnlyHotspotEnrichedApBroadcast( boolean emulateInterfaceStatusChanged)1144 public void workingLocalOnlyHotspotEnrichedApBroadcast( 1145 boolean emulateInterfaceStatusChanged) throws Exception { 1146 initTetheringOnTestThread(); 1147 // Emulate externally-visible WifiManager effects, causing the 1148 // per-interface state machine to start up, and telling us that 1149 // hotspot mode is to be started. 1150 if (emulateInterfaceStatusChanged) { 1151 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 1152 } 1153 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 1154 1155 verifyStartHotspot(true /* isLocalOnly */); 1156 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 1157 1158 // Emulate externally-visible WifiManager effects, when hotspot mode 1159 // is being torn down. 1160 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 1161 mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 1162 mLooper.dispatchAll(); 1163 1164 verifyStopHotpot(true /* isLocalOnly */); 1165 } 1166 1167 /** 1168 * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator. 1169 */ sendIPv6TetherUpdates(UpstreamNetworkState upstreamState)1170 private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) { 1171 // IPv6TetheringCoordinator must have been notified of downstream 1172 for (IpServer ipSrv : mTetheringDependencies.mAllDownstreams) { 1173 UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false); 1174 ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, 1175 upstreamState.linkProperties.isIpv6Provisioned() 1176 ? ipv6OnlyState.linkProperties 1177 : null); 1178 break; 1179 } 1180 mLooper.dispatchAll(); 1181 } 1182 runUsbTethering(UpstreamNetworkState upstreamState)1183 private void runUsbTethering(UpstreamNetworkState upstreamState) { 1184 initTetheringUpstream(upstreamState); 1185 prepareUsbTethering(); 1186 if (mTethering.getTetheringConfiguration().isUsingNcm()) { 1187 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 1188 verify(mIPv6TetheringCoordinator).addActiveDownstream( 1189 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_NCM_IFNAME)), 1190 eq(IpServer.STATE_TETHERED)); 1191 } else { 1192 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1193 verify(mIPv6TetheringCoordinator).addActiveDownstream( 1194 argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_RNDIS_IFNAME)), 1195 eq(IpServer.STATE_TETHERED)); 1196 } 1197 1198 } 1199 assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName)1200 private void assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName) { 1201 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME) 1202 || "T".equals(Build.VERSION.CODENAME)) { 1203 verify(mDadProxy, times(numOfCalls)).setUpstreamIface( 1204 argThat(ifaceParams -> ifaceName.equals(ifaceParams.name))); 1205 } 1206 } 1207 1208 @Test workingMobileUsbTethering_IPv4()1209 public void workingMobileUsbTethering_IPv4() throws Exception { 1210 initTetheringOnTestThread(); 1211 UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1212 runUsbTethering(upstreamState); 1213 1214 verify(mRoutingCoordinatorManager, times(1)) 1215 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1216 1217 sendIPv6TetherUpdates(upstreamState); 1218 assertSetIfaceToDadProxy(0 /* numOfCalls */, "" /* ifaceName */); 1219 verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull()); 1220 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1221 any(), any()); 1222 } 1223 1224 @Test workingMobileUsbTethering_IPv4LegacyDhcp()1225 public void workingMobileUsbTethering_IPv4LegacyDhcp() throws Exception { 1226 initTetheringOnTestThread(); 1227 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 1228 true); 1229 sendConfigurationChanged(); 1230 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 1231 runUsbTethering(upstreamState); 1232 sendIPv6TetherUpdates(upstreamState); 1233 1234 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); 1235 } 1236 1237 @Test workingMobileUsbTethering_IPv6()1238 public void workingMobileUsbTethering_IPv6() throws Exception { 1239 initTetheringOnTestThread(); 1240 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1241 runUsbTethering(upstreamState); 1242 1243 verify(mRoutingCoordinatorManager, times(1)) 1244 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1245 1246 sendIPv6TetherUpdates(upstreamState); 1247 // TODO: add interfaceParams to compare in verify. 1248 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1249 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1250 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1251 } 1252 1253 @Test workingMobileUsbTethering_DualStack()1254 public void workingMobileUsbTethering_DualStack() throws Exception { 1255 initTetheringOnTestThread(); 1256 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 1257 runUsbTethering(upstreamState); 1258 1259 verify(mRoutingCoordinatorManager, times(1)) 1260 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1261 verify(mRouterAdvertisementDaemon, times(1)).start(); 1262 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1263 any(), any()); 1264 1265 sendIPv6TetherUpdates(upstreamState); 1266 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1267 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1268 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1269 } 1270 1271 @Test workingMobileUsbTethering_MultipleUpstreams()1272 public void workingMobileUsbTethering_MultipleUpstreams() throws Exception { 1273 initTetheringOnTestThread(); 1274 UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState(); 1275 runUsbTethering(upstreamState); 1276 1277 verify(mRoutingCoordinatorManager, times(1)) 1278 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_XLAT_MOBILE_IFNAME); 1279 verify(mRoutingCoordinatorManager, times(1)) 1280 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME); 1281 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1282 any(), any()); 1283 1284 sendIPv6TetherUpdates(upstreamState); 1285 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 1286 verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); 1287 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 1288 } 1289 1290 @Test workingMobileUsbTethering_v6Then464xlat()1291 public void workingMobileUsbTethering_v6Then464xlat() throws Exception { 1292 initTetheringOnTestThread(); 1293 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 1294 TetheringConfiguration.TETHER_USB_NCM_FUNCTION); 1295 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 1296 .thenReturn(new String[] {TEST_NCM_REGEX}); 1297 sendConfigurationChanged(); 1298 1299 // Setup IPv6 1300 UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1301 runUsbTethering(upstreamState); 1302 1303 verify(mRoutingCoordinatorManager, times(1)) 1304 .addInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1305 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1306 any(), any()); 1307 1308 // Then 464xlat comes up 1309 upstreamState = buildMobile464xlatUpstreamState(); 1310 initTetheringUpstream(upstreamState); 1311 1312 // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES. 1313 mEventListener.onUpstreamEvent(UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 1314 upstreamState); 1315 mLooper.dispatchAll(); 1316 1317 // Forwarding is added for 464xlat 1318 verify(mRoutingCoordinatorManager, times(1)) 1319 .addInterfaceForward(TEST_NCM_IFNAME, TEST_XLAT_MOBILE_IFNAME); 1320 // Forwarding was not re-added for v6 (still times(1)) 1321 verify(mRoutingCoordinatorManager, times(1)) 1322 .addInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME); 1323 // DHCP not restarted on downstream (still times(1)) 1324 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 1325 any(), any()); 1326 } 1327 1328 @Test configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes()1329 public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception { 1330 initTetheringOnTestThread(); 1331 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); 1332 sendConfigurationChanged(); 1333 1334 // Setup IPv6 1335 final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); 1336 runUsbTethering(upstreamState); 1337 1338 // UpstreamNetworkMonitor should choose upstream automatically 1339 // (in this specific case: choose the default network). 1340 verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream(); 1341 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); 1342 1343 mTetheringEventCallback.expectUpstreamChanged(upstreamState.network); 1344 } 1345 verifyDisableTryCellWhenTetheringStop(InOrder inOrder)1346 private void verifyDisableTryCellWhenTetheringStop(InOrder inOrder) { 1347 runStopUSBTethering(); 1348 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1349 } 1350 upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi)1351 private void upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, 1352 TestNetworkAgent mobile, TestNetworkAgent wifi) throws Exception { 1353 // Enable automatic upstream selection. 1354 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic); 1355 sendConfigurationChanged(); 1356 mLooper.dispatchAll(); 1357 1358 // Start USB tethering with no current upstream. 1359 prepareUsbTethering(); 1360 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1361 inOrder.verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks(); 1362 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1363 1364 // Pretend cellular connected and expect the upstream to be set. 1365 mobile.fakeConnect(); 1366 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST); 1367 mLooper.dispatchAll(); 1368 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1369 1370 // Switch upstream to wifi. 1371 wifi.fakeConnect(); 1372 mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST); 1373 mLooper.dispatchAll(); 1374 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1375 mTetheringEventCallback.expectUpstreamChanged(wifi.networkId); 1376 } 1377 verifyAutomaticUpstreamSelection(boolean configAutomatic)1378 private void verifyAutomaticUpstreamSelection(boolean configAutomatic) throws Exception { 1379 initTetheringOnTestThread(); 1380 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1381 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1382 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1383 // Enable automatic upstream selection. 1384 upstreamSelectionTestCommon(configAutomatic, inOrder, mobile, wifi); 1385 1386 // This code has historically been racy, so test different orderings of CONNECTIVITY_ACTION 1387 // broadcasts and callbacks, and add mLooper.dispatchAll() calls between the two. 1388 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1389 1390 // Switch upstreams a few times. 1391 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll); 1392 mLooper.dispatchAll(); 1393 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1394 1395 mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST, doDispatchAll); 1396 mLooper.dispatchAll(); 1397 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1398 mTetheringEventCallback.expectUpstreamChanged(wifi.networkId); 1399 1400 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1401 mLooper.dispatchAll(); 1402 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1403 1404 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1405 mLooper.dispatchAll(); 1406 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1407 mTetheringEventCallback.expectUpstreamChanged(wifi.networkId); 1408 1409 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll); 1410 mLooper.dispatchAll(); 1411 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1412 1413 // Wifi disconnecting should not have any affect since it's not the current upstream. 1414 wifi.fakeDisconnect(); 1415 mLooper.dispatchAll(); 1416 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1417 1418 // Lose and regain upstream. 1419 assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1420 .hasIPv4Address()); 1421 mCm.makeDefaultNetwork(null, BROADCAST_FIRST, doDispatchAll); 1422 mLooper.dispatchAll(); 1423 mobile.fakeDisconnect(); 1424 mLooper.dispatchAll(); 1425 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1426 mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); 1427 1428 mobile = new TestNetworkAgent(mCm, buildMobile464xlatUpstreamState()); 1429 mobile.fakeConnect(); 1430 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll); 1431 mLooper.dispatchAll(); 1432 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1433 1434 // Check the IP addresses to ensure that the upstream is indeed not the same as the previous 1435 // mobile upstream, even though the netId is (unrealistically) the same. 1436 assertFalse(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1437 .hasIPv4Address()); 1438 1439 // Lose and regain upstream again. 1440 mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll); 1441 mobile.fakeDisconnect(); 1442 mLooper.dispatchAll(); 1443 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1444 mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); 1445 1446 mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1447 mobile.fakeConnect(); 1448 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll); 1449 mLooper.dispatchAll(); 1450 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1451 1452 assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties 1453 .hasIPv4Address()); 1454 1455 // Check that the code does not crash if onLinkPropertiesChanged is received after onLost. 1456 mobile.fakeDisconnect(); 1457 mobile.sendLinkProperties(); 1458 mLooper.dispatchAll(); 1459 1460 verifyDisableTryCellWhenTetheringStop(inOrder); 1461 } 1462 1463 @Test testAutomaticUpstreamSelection()1464 public void testAutomaticUpstreamSelection() throws Exception { 1465 verifyAutomaticUpstreamSelection(true /* configAutomatic */); 1466 } 1467 1468 @Test 1469 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) testAutomaticUpstreamSelectionWithConfigDisabled()1470 public void testAutomaticUpstreamSelectionWithConfigDisabled() throws Exception { 1471 // Expect that automatic config can't disable the automatic mode because automatic mode 1472 // is always enabled on U+ device. 1473 verifyAutomaticUpstreamSelection(false /* configAutomatic */); 1474 } 1475 1476 @Test 1477 @IgnoreAfter(Build.VERSION_CODES.TIRAMISU) testLegacyUpstreamSelection()1478 public void testLegacyUpstreamSelection() throws Exception { 1479 initTetheringOnTestThread(); 1480 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1481 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1482 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1483 // Enable legacy upstream selection. 1484 upstreamSelectionTestCommon(false, inOrder, mobile, wifi); 1485 1486 // Wifi disconnecting and the default network switch to mobile, the upstream should also 1487 // switch to mobile. 1488 wifi.fakeDisconnect(); 1489 mLooper.dispatchAll(); 1490 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, null); 1491 mLooper.dispatchAll(); 1492 mTetheringEventCallback.expectUpstreamChanged(mobile.networkId); 1493 1494 wifi.fakeConnect(); 1495 mLooper.dispatchAll(); 1496 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST, null); 1497 mLooper.dispatchAll(); 1498 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1499 mTetheringEventCallback.expectUpstreamChanged(wifi.networkId); 1500 1501 verifyDisableTryCellWhenTetheringStop(inOrder); 1502 } 1503 verifyWifiUpstreamAndUnregisterDunCallback(@onNull final InOrder inOrder, @NonNull final TestNetworkAgent wifi, @NonNull final NetworkCallback currentDunCallack)1504 private void verifyWifiUpstreamAndUnregisterDunCallback(@NonNull final InOrder inOrder, 1505 @NonNull final TestNetworkAgent wifi, @NonNull final NetworkCallback currentDunCallack) 1506 throws Exception { 1507 assertNotNull(currentDunCallack); 1508 1509 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1510 inOrder.verify(mCm).unregisterNetworkCallback(eq(currentDunCallack)); 1511 mTetheringEventCallback.expectUpstreamChanged(wifi.networkId); 1512 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1513 } 1514 1515 @Nullable verifyDunUpstream(@onNull final InOrder inOrder, @NonNull final TestNetworkAgent dun, final boolean needToRequestNetwork)1516 private NetworkCallback verifyDunUpstream(@NonNull final InOrder inOrder, 1517 @NonNull final TestNetworkAgent dun, final boolean needToRequestNetwork) 1518 throws Exception { 1519 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1520 ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class); 1521 NetworkCallback dunNetworkCallback = null; 1522 if (needToRequestNetwork) { 1523 inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1524 captor.capture()); 1525 dunNetworkCallback = captor.getValue(); 1526 } 1527 mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); 1528 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1529 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1530 mLooper.dispatchAll(); 1531 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1532 1533 if (needToRequestNetwork) { 1534 assertNotNull(dunNetworkCallback); 1535 } else { 1536 assertNull(dunNetworkCallback); 1537 } 1538 1539 return dunNetworkCallback; 1540 } 1541 1542 // Overall test coverage: 1543 // - verifyChooseDunUpstreamByAutomaticMode: common, test#1, test#2 1544 // - testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi: test#3, test#4 1545 // - testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi: test#5 1546 // - testChooseDunUpstreamByAutomaticMode_defaultNetworkCell: test#5, test#7 1547 // - testChooseDunUpstreamByAutomaticMode_loseAndRegainDun: test#8 1548 // - testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell: test#9, test#10 1549 // 1550 // Overall test cases: 1551 // +-------+-------+-------+-------+-------+ 1552 // | Test | WiFi | Cellu | Dun | Expec | 1553 // | Case | | alr | | ted | 1554 // | # | | | | Upstr | 1555 // | | | | | eam | 1556 // +-------+-------+-------+-------+-------+ 1557 // | - | | | | - | --+ 1558 // +-------+-------+-------+-------+-------+ | 1559 // | - | | V | | - | | 1560 // +-------+-------+-------+-------+-------+ | 1561 // | - | | V | O | Dun | +-- chooseDunUpstreamTestCommon 1562 // +-------+-------+-------+-------+-------+ | 1563 // | - | V | O | O | WiFi | | 1564 // +-------+-------+-------+-------+-------+ | 1565 // | - | V | O | | WiFi | --+ 1566 // +-------+-------+-------+-------+-------+ 1567 // | | O | V | | - | 1568 // | 1 +-------+-------+-------+-------+ 1569 // | | O | V | O | Dun | 1570 // +-------+-------+-------+-------+-------+ 1571 // | | O | V | | - | 1572 // | 2 +-------+-------+-------+-------+ 1573 // | | O | V | O | Dun | 1574 // +-------+-------+-------+-------+-------+ 1575 // | 3 | V | O | | WiFi | 1576 // +-------+-------+-------+-------+-------+ 1577 // | 4 | V | | | WiFi | 1578 // +-------+-------+-------+-------+-------+ 1579 // | 5 | | | O | Dun | 1580 // +-------+-------+-------+-------+-------+ 1581 // | 6 | | V | O | Dun | 1582 // +-------+-------+-------+-------+-------+ 1583 // | 7 | | | O | Dun | 1584 // +-------+-------+-------+-------+-------+ 1585 // | | | | | - | 1586 // | 8 +-------+-------+-------+-------+ 1587 // | | | | O | Dun | 1588 // +-------+-------+-------+-------+-------+ 1589 // | | V | | O | WiFi | 1590 // | 9 +-------+-------+-------+-------+ 1591 // | | V | | | WiFi | 1592 // +-------+-------+-------+-------+-------+ 1593 // | | O | V | | - | 1594 // | 10 +-------+-------+-------+-------+ 1595 // | | O | V | O | Dun | 1596 // +-------+-------+-------+-------+-------+ 1597 // 1598 // Annotation: 1599 // 1. "V" means that the given network is connected and it is default network. 1600 // 2. "O" means that the given network is connected and it is not default network. 1601 // 1602 1603 // Test case: 1604 // +-------+-------+-------+-------+-------+ 1605 // | Test | WiFi | Cellu | Dun | Expec | 1606 // | Case | | alr | | ted | 1607 // | # | | | | Upstr | 1608 // | | | | | eam | 1609 // +-------+-------+-------+-------+-------+ 1610 // | - | | | | - | --+ 1611 // +-------+-------+-------+-------+-------+ | 1612 // | - | | V | | - | | 1613 // +-------+-------+-------+-------+-------+ | 1614 // | - | | V | O | Dun | +-- chooseDunUpstreamTestCommon 1615 // +-------+-------+-------+-------+-------+ | 1616 // | - | V | O | O | WiFi | | 1617 // +-------+-------+-------+-------+-------+ | 1618 // | - | V | O | | WiFi | --+ 1619 // +-------+-------+-------+-------+-------+ 1620 // | | O | V | | - | 1621 // | 1 +-------+-------+-------+-------+ 1622 // | | O | V | O | Dun | 1623 // +-------+-------+-------+-------+-------+ 1624 // | | O | V | | - | 1625 // | 2 +-------+-------+-------+-------+ 1626 // | | O | V | O | Dun | 1627 // +-------+-------+-------+-------+-------+ 1628 // verifyChooseDunUpstreamByAutomaticMode(boolean configAutomatic)1629 private void verifyChooseDunUpstreamByAutomaticMode(boolean configAutomatic) throws Exception { 1630 initTetheringOnTestThread(); 1631 // Enable automatic upstream selection. 1632 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1633 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1634 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1635 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1636 chooseDunUpstreamTestCommon(configAutomatic, inOrder, mobile, wifi, dun); 1637 1638 // [1] When default network switch to mobile and wifi is connected (may have low signal), 1639 // automatic mode would request dun again and choose it as upstream. 1640 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1641 mLooper.dispatchAll(); 1642 verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */); 1643 1644 // [2] Lose and regain upstream again. 1645 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1646 dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1647 mLooper.dispatchAll(); 1648 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1649 mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); 1650 inOrder.verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class)); 1651 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1652 mLooper.dispatchAll(); 1653 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1654 1655 verifyDisableTryCellWhenTetheringStop(inOrder); 1656 } 1657 1658 @Test testChooseDunUpstreamByAutomaticMode()1659 public void testChooseDunUpstreamByAutomaticMode() throws Exception { 1660 verifyChooseDunUpstreamByAutomaticMode(true /* configAutomatic */); 1661 } 1662 1663 // testChooseDunUpstreamByAutomaticMode_* doesn't verify configAutomatic:false because no 1664 // matter |configAutomatic| set to true or false, the result always be automatic mode. We 1665 // just need one test to make sure this behavior. Don't need to test this configuration 1666 // in all tests. 1667 @Test 1668 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) testChooseDunUpstreamByAutomaticModeWithConfigDisabled()1669 public void testChooseDunUpstreamByAutomaticModeWithConfigDisabled() throws Exception { 1670 verifyChooseDunUpstreamByAutomaticMode(false /* configAutomatic */); 1671 } 1672 1673 // Test case: 1674 // +-------+-------+-------+-------+-------+ 1675 // | Test | WiFi | Cellu | Dun | Expec | 1676 // | Case | | alr | | ted | 1677 // | # | | | | Upstr | 1678 // | | | | | eam | 1679 // +-------+-------+-------+-------+-------+ 1680 // | - | O | V | O | Dun | 1681 // +-------+-------+-------+-------+-------+ 1682 // | 3 | V | O | | WiFi | 1683 // +-------+-------+-------+-------+-------+ 1684 // | 4 | V | | | WiFi | 1685 // +-------+-------+-------+-------+-------+ 1686 // 1687 // See verifyChooseDunUpstreamByAutomaticMode for the annotation. 1688 // 1689 @Test testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi()1690 public void testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi() throws Exception { 1691 initTetheringOnTestThread(); 1692 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1693 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1694 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1695 final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1696 final NetworkCallback dunNetworkCallback1 = setupDunUpstreamTest( 1697 true /* configAutomatic */, inOrder); 1698 1699 // When wifi connected, unregister dun request and choose wifi as upstream. 1700 wifi.fakeConnect(); 1701 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1702 mLooper.dispatchAll(); 1703 verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback1); 1704 1705 // When default network switch to mobile and wifi is connected (may have low signal), 1706 // automatic mode would request dun again and choose it as upstream. 1707 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1708 mLooper.dispatchAll(); 1709 final NetworkCallback dunNetworkCallback2 = verifyDunUpstream(inOrder, dun, 1710 true /* needToRequestNetwork */); 1711 1712 // [3] When default network switch to wifi and mobile is still connected, 1713 // unregister dun request and choose wifi as upstream. 1714 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1715 mLooper.dispatchAll(); 1716 verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback2); 1717 1718 // [4] When mobile is disconnected, keep wifi as upstream. 1719 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1720 mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1721 mLooper.dispatchAll(); 1722 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1723 1724 verifyDisableTryCellWhenTetheringStop(inOrder); 1725 } 1726 1727 // Test case: 1728 // +-------+-------+-------+-------+-------+ 1729 // | Test | WiFi | Cellu | Dun | Expec | 1730 // | Case | | alr | | ted | 1731 // | # | | | | Upstr | 1732 // | | | | | eam | 1733 // +-------+-------+-------+-------+-------+ 1734 // | - | V | | | WiFi | 1735 // +-------+-------+-------+-------+-------+ 1736 // | 5 | | | O | Dun | 1737 // +-------+-------+-------+-------+-------+ 1738 // 1739 // See verifyChooseDunUpstreamByAutomaticMode for the annotation. 1740 // 1741 @Test testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi()1742 public void testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi() throws Exception { 1743 initTetheringOnTestThread(); 1744 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1745 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1746 final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1747 final NetworkCallback dunNetworkCallback = setupDunUpstreamTest( 1748 true /* configAutomatic */, inOrder); 1749 1750 // When wifi connected, unregister dun request and choose wifi as upstream. 1751 wifi.fakeConnect(); 1752 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1753 mLooper.dispatchAll(); 1754 verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback); 1755 1756 // [5] When wifi is disconnected, automatic mode would request dun again and choose it 1757 // as upstream. 1758 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1759 mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll); 1760 wifi.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1761 mLooper.dispatchAll(); 1762 verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */); 1763 1764 verifyDisableTryCellWhenTetheringStop(inOrder); 1765 } 1766 1767 // Test case: 1768 // +-------+-------+-------+-------+-------+ 1769 // | Test | WiFi | Cellu | Dun | Expec | 1770 // | Case | | alr | | ted | 1771 // | # | | | | Upstr | 1772 // | | | | | eam | 1773 // +-------+-------+-------+-------+-------+ 1774 // | - | | | O | Dun | 1775 // +-------+-------+-------+-------+-------+ 1776 // | 6 | | V | O | Dun | 1777 // +-------+-------+-------+-------+-------+ 1778 // | 7 | | | O | Dun | 1779 // +-------+-------+-------+-------+-------+ 1780 // 1781 // See verifyChooseDunUpstreamByAutomaticMode for the annotation. 1782 // 1783 @Test testChooseDunUpstreamByAutomaticMode_defaultNetworkCell()1784 public void testChooseDunUpstreamByAutomaticMode_defaultNetworkCell() throws Exception { 1785 initTetheringOnTestThread(); 1786 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1787 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1788 final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1789 setupDunUpstreamTest(true /* configAutomatic */, inOrder); 1790 1791 // Pretend dun connected and expect choose dun as upstream. 1792 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1793 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1794 mLooper.dispatchAll(); 1795 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1796 1797 // [6] When mobile is connected and default network switch to mobile, keep dun as upstream. 1798 mobile.fakeConnect(); 1799 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1800 mLooper.dispatchAll(); 1801 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1802 1803 // [7] When mobile is disconnected, keep dun as upstream. 1804 mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll); 1805 mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1806 mLooper.dispatchAll(); 1807 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1808 1809 verifyDisableTryCellWhenTetheringStop(inOrder); 1810 } 1811 1812 // Test case: 1813 // +-------+-------+-------+-------+-------+ 1814 // | Test | WiFi | Cellu | Dun | Expec | 1815 // | Case | | alr | | ted | 1816 // | # | | | | Upstr | 1817 // | | | | | eam | 1818 // +-------+-------+-------+-------+-------+ 1819 // | - | | | O | Dun | 1820 // +-------+-------+-------+-------+-------+ 1821 // | | | | | - | 1822 // | 8 +-------+-------+-------+-------+ 1823 // | | | | O | Dun | 1824 // +-------+-------+-------+-------+-------+ 1825 // 1826 // See verifyChooseDunUpstreamByAutomaticMode for the annotation. 1827 // 1828 @Test testChooseDunUpstreamByAutomaticMode_loseAndRegainDun()1829 public void testChooseDunUpstreamByAutomaticMode_loseAndRegainDun() throws Exception { 1830 initTetheringOnTestThread(); 1831 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1832 final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1833 setupDunUpstreamTest(true /* configAutomatic */, inOrder); 1834 1835 // Pretend dun connected and expect choose dun as upstream. 1836 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1837 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1838 mLooper.dispatchAll(); 1839 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1840 1841 // [8] Lose and regain upstream again. 1842 dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1843 mLooper.dispatchAll(); 1844 verifyDunUpstream(inOrder, dun, false /* needToRequestNetwork */); 1845 1846 verifyDisableTryCellWhenTetheringStop(inOrder); 1847 } 1848 1849 // Test case: 1850 // +-------+-------+-------+-------+-------+ 1851 // | Test | WiFi | Cellu | Dun | Expec | 1852 // | Case | | alr | | ted | 1853 // | # | | | | Upstr | 1854 // | | | | | eam | 1855 // +-------+-------+-------+-------+-------+ 1856 // | - | | | O | Dun | 1857 // +-------+-------+-------+-------+-------+ 1858 // | | V | | O | WiFi | 1859 // | 9 +-------+-------+-------+-------+ 1860 // | | V | | | WiFi | 1861 // +-------+-------+-------+-------+-------+ 1862 // | | O | V | | - | 1863 // | 10 +-------+-------+-------+-------+ 1864 // | | O | V | O | Dun | 1865 // +-------+-------+-------+-------+-------+ 1866 // 1867 // See verifyChooseDunUpstreamByAutomaticMode for the annotation. 1868 // 1869 @Test testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell()1870 public void testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell() 1871 throws Exception { 1872 initTetheringOnTestThread(); 1873 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1874 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1875 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1876 final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1877 final NetworkCallback dunNetworkCallback = setupDunUpstreamTest( 1878 true /* configAutomatic */, inOrder); 1879 1880 // Pretend dun connected and expect choose dun as upstream. 1881 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1882 dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll); 1883 mLooper.dispatchAll(); 1884 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1885 1886 // [9] When wifi is connected and default network switch to wifi, unregister dun request 1887 // and choose wifi as upstream. When dun is disconnected, keep wifi as upstream. 1888 wifi.fakeConnect(); 1889 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1890 mLooper.dispatchAll(); 1891 verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback); 1892 dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll); 1893 mLooper.dispatchAll(); 1894 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1895 1896 // [10] When mobile and mobile are connected and default network switch to mobile 1897 // (may have low signal), automatic mode would request dun again and choose it as 1898 // upstream. 1899 mobile.fakeConnect(); 1900 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1901 mLooper.dispatchAll(); 1902 verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */); 1903 1904 verifyDisableTryCellWhenTetheringStop(inOrder); 1905 } 1906 1907 @Test 1908 @IgnoreAfter(Build.VERSION_CODES.TIRAMISU) testChooseDunUpstreamByLegacyMode()1909 public void testChooseDunUpstreamByLegacyMode() throws Exception { 1910 initTetheringOnTestThread(); 1911 // Enable Legacy upstream selection. 1912 TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState()); 1913 TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 1914 TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState()); 1915 InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor); 1916 chooseDunUpstreamTestCommon(false, inOrder, mobile, wifi, dun); 1917 1918 // Legacy mode would keep use wifi as upstream (because it has higher priority in the 1919 // list). 1920 mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST); 1921 mLooper.dispatchAll(); 1922 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1923 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1924 // BUG: when wifi disconnect, the dun request would not be filed again because wifi is 1925 // no longer be default network which do not have CONNECTIVIY_ACTION broadcast. 1926 wifi.fakeDisconnect(); 1927 mLooper.dispatchAll(); 1928 inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1929 any()); 1930 1931 // Change the legacy priority list that dun is higher than wifi. 1932 when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( 1933 new int[] { TYPE_MOBILE_DUN, TYPE_WIFI }); 1934 sendConfigurationChanged(); 1935 mLooper.dispatchAll(); 1936 1937 // Make wifi as default network. Note: mobile also connected. 1938 wifi.fakeConnect(); 1939 mLooper.dispatchAll(); 1940 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1941 mLooper.dispatchAll(); 1942 // BUG: dun has higher priority than wifi but tethering don't file dun request because 1943 // current upstream is wifi. 1944 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false); 1945 inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1946 any()); 1947 1948 verifyDisableTryCellWhenTetheringStop(inOrder); 1949 } 1950 setupDunUpstreamTest(final boolean automatic, InOrder inOrder)1951 private NetworkCallback setupDunUpstreamTest(final boolean automatic, InOrder inOrder) { 1952 when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic); 1953 when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true); 1954 sendConfigurationChanged(); 1955 mLooper.dispatchAll(); 1956 1957 // Start USB tethering with no current upstream. 1958 prepareUsbTethering(); 1959 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 1960 inOrder.verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks(); 1961 inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true); 1962 ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class); 1963 inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), 1964 captor.capture() /* DUN network callback */); 1965 1966 return captor.getValue(); 1967 } 1968 chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)1969 private void chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, 1970 TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun) 1971 throws Exception { 1972 final NetworkCallback dunNetworkCallback = setupDunUpstreamTest(automatic, inOrder); 1973 1974 // Pretend cellular connected and expect the upstream to be not set. 1975 mobile.fakeConnect(); 1976 mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST); 1977 mLooper.dispatchAll(); 1978 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1979 1980 // Pretend dun connected and expect choose dun as upstream. 1981 final Runnable doDispatchAll = () -> mLooper.dispatchAll(); 1982 dun.fakeConnect(BROADCAST_FIRST, doDispatchAll); 1983 mLooper.dispatchAll(); 1984 mTetheringEventCallback.expectUpstreamChanged(dun.networkId); 1985 1986 // When wifi connected, unregister dun request and choose wifi as upstream. 1987 wifi.fakeConnect(); 1988 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 1989 mLooper.dispatchAll(); 1990 verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback); 1991 dun.fakeDisconnect(BROADCAST_FIRST, doDispatchAll); 1992 mLooper.dispatchAll(); 1993 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 1994 } 1995 runNcmTethering()1996 private void runNcmTethering() { 1997 prepareNcmTethering(); 1998 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 1999 } 2000 2001 @Test workingNcmTethering()2002 public void workingNcmTethering() throws Exception { 2003 initTetheringOnTestThread(); 2004 runNcmTethering(); 2005 2006 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 2007 any(), any()); 2008 } 2009 2010 @Test workingNcmTethering_LegacyDhcp()2011 public void workingNcmTethering_LegacyDhcp() throws Exception { 2012 initTetheringOnTestThread(); 2013 when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( 2014 true); 2015 sendConfigurationChanged(); 2016 runNcmTethering(); 2017 2018 verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); 2019 } 2020 2021 @Test workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged()2022 public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception { 2023 workingLocalOnlyHotspotEnrichedApBroadcast(true); 2024 } 2025 2026 @Test workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged()2027 public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception { 2028 workingLocalOnlyHotspotEnrichedApBroadcast(false); 2029 } 2030 2031 @Test failingWifiTetheringLegacyApBroadcast()2032 public void failingWifiTetheringLegacyApBroadcast() throws Exception { 2033 initTetheringOnTestThread(); 2034 2035 // Emulate pressing the WiFi tethering button. 2036 mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG, null); 2037 mLooper.dispatchAll(); 2038 verifyWifiTetheringRequested(); 2039 verifyNoMoreInteractions(mNetd); 2040 2041 // Emulate externally-visible WifiManager effects, causing the 2042 // per-interface state machine to start up, and telling us that 2043 // tethering mode is to be started. 2044 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2045 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); 2046 mLooper.dispatchAll(); 2047 2048 if (!SdkLevel.isAtLeastB()) { 2049 // There is 1 IpServer state change event: STATE_AVAILABLE from interfaceStatusChanged 2050 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); 2051 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 2052 verify(mWifiManager).updateInterfaceIpState( 2053 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2054 } else { 2055 // Starting in B, ignore the interfaceStatusChanged 2056 verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE); 2057 verify(mWifiManager, never()).updateInterfaceIpState( 2058 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2059 } 2060 verifyNoMoreInteractions(mNetd); 2061 verifyNoMoreInteractions(mWifiManager); 2062 } 2063 2064 // TODO: Test with and without interfaceStatusChanged(). 2065 @Test workingWifiTetheringEnrichedApBroadcast()2066 public void workingWifiTetheringEnrichedApBroadcast() throws Exception { 2067 // B+ uses SoftApCallback instead of WIFI_AP_STATE_CHANGED for tethered hotspot. 2068 mTetheringWithSoftApConfigEnabled = false; 2069 initTetheringOnTestThread(); 2070 2071 // Emulate pressing the WiFi tethering button. 2072 mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG, 2073 null); 2074 mLooper.dispatchAll(); 2075 verifyWifiTetheringRequested(); 2076 verifyNoMoreInteractions(mNetd); 2077 2078 // Emulate externally-visible WifiManager effects, causing the 2079 // per-interface state machine to start up, and telling us that 2080 // tethering mode is to be started. 2081 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2082 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 2083 2084 verifyStartHotspot(); 2085 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); 2086 // In tethering mode, in the default configuration, an explicit request 2087 // for a mobile network is also made. 2088 verify(mUpstreamNetworkMonitor, times(1)).setTryCell(true); 2089 2090 ///// 2091 // We do not currently emulate any upstream being found. 2092 // 2093 // This is why there are no calls to verify mNetd.tetherAddForward() or 2094 // mNetd.ipfwdAddInterfaceForward(). 2095 ///// 2096 2097 // Emulate pressing the WiFi tethering button. 2098 mTethering.stopTethering(TETHERING_WIFI); 2099 mLooper.dispatchAll(); 2100 verify(mWifiManager, times(1)).stopSoftAp(); 2101 verifyNoMoreInteractions(mWifiManager); 2102 verifyNoMoreInteractions(mNetd); 2103 2104 // Emulate externally-visible WifiManager effects, when tethering mode 2105 // is being torn down. 2106 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 2107 mTethering.interfaceRemoved(TEST_WLAN_IFNAME); 2108 mLooper.dispatchAll(); 2109 2110 verifyStopHotpot(false /* isLocalOnly */); 2111 } 2112 2113 @Test startWifiTetheringWithSoftApConfigurationSuccess()2114 public void startWifiTetheringWithSoftApConfigurationSuccess() throws Exception { 2115 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2116 initTetheringOnTestThread(); 2117 2118 // Emulate pressing the WiFi tethering button. 2119 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 2120 .setSoftApConfiguration(new SoftApConfiguration.Builder() 2121 .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8))) 2122 .build()) 2123 .build(); 2124 IIntResultListener startResultListener = mock(IIntResultListener.class); 2125 mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener); 2126 mLooper.dispatchAll(); 2127 verifyNoMoreInteractions(mNetd); 2128 verify(startResultListener, never()).onResult(anyInt()); 2129 // Emulate Wifi iface enabled 2130 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 2131 2132 verifyStartHotspot(); 2133 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); 2134 verify(startResultListener).onResult(TETHER_ERROR_NO_ERROR); 2135 } 2136 2137 @Test startWifiTetheringWithSoftApConfigurationFailure()2138 public void startWifiTetheringWithSoftApConfigurationFailure() throws Exception { 2139 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2140 initTetheringOnTestThread(); 2141 2142 // Emulate pressing the WiFi tethering button. 2143 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 2144 .setSoftApConfiguration(new SoftApConfiguration.Builder() 2145 .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8))) 2146 .build()) 2147 .build(); 2148 IIntResultListener startResultListener = mock(IIntResultListener.class); 2149 mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener); 2150 mLooper.dispatchAll(); 2151 verify(startResultListener, never()).onResult(anyInt()); 2152 // Emulate Wifi iface failure 2153 sendStartTetheringSoftApCallback(WIFI_AP_STATE_FAILED, request, TEST_WLAN_IFNAME); 2154 2155 verify(startResultListener).onResult(TETHER_ERROR_INTERNAL_ERROR); 2156 } 2157 2158 @Test startWifiTetheringWithSoftApConfigurationRestartAfterStarting()2159 public void startWifiTetheringWithSoftApConfigurationRestartAfterStarting() throws Exception { 2160 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2161 initTetheringOnTestThread(); 2162 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2163 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() 2164 .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8))) 2165 .build(); 2166 final TetheringInterface wifiIface = new TetheringInterface( 2167 TETHERING_WIFI, TEST_WLAN_IFNAME); 2168 final TetheringInterface wifiIfaceWithConfig = new TetheringInterface( 2169 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig); 2170 2171 // 1. Register one callback before running any tethering. 2172 mTethering.registerTetheringEventCallback(callback); 2173 mLooper.dispatchAll(); 2174 assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged()); 2175 // Emulate pressing the WiFi tethering button. 2176 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 2177 .setSoftApConfiguration(softApConfig) 2178 .build(); 2179 IIntResultListener startResultListener = mock(IIntResultListener.class); 2180 mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener); 2181 mLooper.dispatchAll(); 2182 2183 // Wifi success 2184 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 2185 verifyStartHotspot(); 2186 TetherStatesParcel tetherState = callback.pollTetherStatesChanged(); 2187 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 2188 tetherState = callback.pollTetherStatesChanged(); 2189 assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIfaceWithConfig}); 2190 verify(startResultListener).onResult(TETHER_ERROR_NO_ERROR); 2191 2192 // Restart Wifi 2193 sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, request, TEST_WLAN_IFNAME); 2194 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 2195 2196 // Verify we go from TETHERED -> AVAILABLE -> TETHERED with the same config. 2197 tetherState = callback.pollTetherStatesChanged(); 2198 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 2199 tetherState = callback.pollTetherStatesChanged(); 2200 assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIfaceWithConfig}); 2201 } 2202 2203 @Test startWifiApBroadcastDoesNotStartIpServing()2204 public void startWifiApBroadcastDoesNotStartIpServing() throws Exception { 2205 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2206 initTetheringOnTestThread(); 2207 2208 // Call startTethering for wifi 2209 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 2210 .setSoftApConfiguration(new SoftApConfiguration.Builder() 2211 .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8))) 2212 .build()) 2213 .build(); 2214 IIntResultListener startResultListener = mock(IIntResultListener.class); 2215 mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener); 2216 mLooper.dispatchAll(); 2217 2218 // WIFI_AP_STATE_CHANGED broadcast should be ignored since we should only be using 2219 // SoftApCallback for tethered AP. 2220 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 2221 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 2222 verify(mNetd, never()).tetherStartWithConfiguration(any()); 2223 verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE); 2224 verify(mWifiManager, never()).updateInterfaceIpState( 2225 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2226 assertTrue(mTethering.getServingTetheringRequests().isEmpty()); 2227 } 2228 2229 // TODO: Test with and without interfaceStatusChanged(). 2230 @Test failureEnablingIpForwarding()2231 public void failureEnablingIpForwarding() throws Exception { 2232 initTetheringOnTestThread(); 2233 doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME); 2234 2235 // Emulate pressing the WiFi tethering button. 2236 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 2237 mTethering.startTethering(request, TEST_CALLER_PKG, null); 2238 mLooper.dispatchAll(); 2239 verifyWifiTetheringRequested(); 2240 verifyNoMoreInteractions(mNetd); 2241 verify(mTetheringMetrics).createBuilder(eq(TETHERING_WIFI), anyString()); 2242 2243 // Emulate externally-visible WifiManager effects, causing the 2244 // per-interface state machine to start up, and telling us that 2245 // tethering mode is to be started. 2246 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2247 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 2248 2249 // We verify get/set called three times here: twice for setup and once during 2250 // teardown because all events happen over the course of the single 2251 // dispatchAll() above. Note that once the IpServer IPv4 address config 2252 // code is refactored the two calls during shutdown will revert to one. 2253 verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName))); 2254 verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME); 2255 if (isTetheringNetworkAgentFeatureEnabled()) { 2256 verify(mNetd, never()).networkAddInterface(anyInt(), anyString()); 2257 verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString()); 2258 } else { 2259 verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 2260 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME), 2261 anyString(), anyString()); 2262 } 2263 verify(mWifiManager).updateInterfaceIpState( 2264 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 2265 verify(mWifiManager).updateInterfaceIpState( 2266 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); 2267 // There are 3 IpServer state change event: 2268 // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE. 2269 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 2270 verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI)); 2271 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 2272 // This is called, but will throw. 2273 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 2274 // This never gets called because of the exception thrown above. 2275 verify(mNetd, times(0)).tetherStartWithConfiguration(any()); 2276 // When the main state machine transitions to an error state it tells 2277 // downstream interfaces, which causes us to tell Wi-Fi about the error 2278 // so it can take down AP mode. 2279 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 2280 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); 2281 if (isTetheringNetworkAgentFeatureEnabled()) { 2282 verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString()); 2283 } else { 2284 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); 2285 } 2286 verify(mWifiManager).updateInterfaceIpState( 2287 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR); 2288 2289 verify(mTetheringMetrics, times(0)).maybeUpdateUpstreamType(any()); 2290 verify(mTetheringMetrics, times(1)).updateErrorCode(eq(TETHERING_WIFI), 2291 eq(TETHER_ERROR_INTERNAL_ERROR)); 2292 verify(mTetheringMetrics, times(1)).sendReport(eq(TETHERING_WIFI)); 2293 2294 verifyNoMoreInteractions(mWifiManager); 2295 verifyNoMoreInteractions(mNetd); 2296 } 2297 makeUserRestrictionActionListener( final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow)2298 private UserRestrictionActionListener makeUserRestrictionActionListener( 2299 final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) { 2300 final Bundle newRestrictions = new Bundle(); 2301 newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); 2302 when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions); 2303 2304 final UserRestrictionActionListener ural = 2305 new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater); 2306 ural.mDisallowTethering = currentDisallow; 2307 return ural; 2308 } 2309 runUserRestrictionsChange( boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, int expectedInteractionsWithShowNotification)2310 private void runUserRestrictionsChange( 2311 boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, 2312 int expectedInteractionsWithShowNotification) throws Exception { 2313 final Tethering mockTethering = mock(Tethering.class); 2314 when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive); 2315 2316 final UserRestrictionActionListener ural = 2317 makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow); 2318 ural.onUserRestrictionsChanged(); 2319 2320 verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification)) 2321 .notifyTetheringDisabledByRestriction(); 2322 verify(mockTethering, times(expectedInteractionsWithShowNotification)).stopAllTethering(); 2323 } 2324 2325 @Test testDisallowTetheringWhenTetheringIsNotActive()2326 public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception { 2327 final boolean isTetheringActive = false; 2328 final boolean currDisallow = false; 2329 final boolean nextDisallow = true; 2330 final int expectedInteractionsWithShowNotification = 0; 2331 2332 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2333 expectedInteractionsWithShowNotification); 2334 } 2335 2336 @Test testDisallowTetheringWhenTetheringIsActive()2337 public void testDisallowTetheringWhenTetheringIsActive() throws Exception { 2338 final boolean isTetheringActive = true; 2339 final boolean currDisallow = false; 2340 final boolean nextDisallow = true; 2341 final int expectedInteractionsWithShowNotification = 1; 2342 2343 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2344 expectedInteractionsWithShowNotification); 2345 } 2346 2347 @Test testAllowTetheringWhenTetheringIsNotActive()2348 public void testAllowTetheringWhenTetheringIsNotActive() throws Exception { 2349 final boolean isTetheringActive = false; 2350 final boolean currDisallow = true; 2351 final boolean nextDisallow = false; 2352 final int expectedInteractionsWithShowNotification = 0; 2353 2354 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2355 expectedInteractionsWithShowNotification); 2356 } 2357 2358 @Test testAllowTetheringWhenTetheringIsActive()2359 public void testAllowTetheringWhenTetheringIsActive() throws Exception { 2360 final boolean isTetheringActive = true; 2361 final boolean currDisallow = true; 2362 final boolean nextDisallow = false; 2363 final int expectedInteractionsWithShowNotification = 0; 2364 2365 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2366 expectedInteractionsWithShowNotification); 2367 } 2368 2369 @Test testDisallowTetheringUnchanged()2370 public void testDisallowTetheringUnchanged() throws Exception { 2371 final boolean isTetheringActive = true; 2372 final int expectedInteractionsWithShowNotification = 0; 2373 boolean currDisallow = true; 2374 boolean nextDisallow = true; 2375 2376 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2377 expectedInteractionsWithShowNotification); 2378 2379 currDisallow = false; 2380 nextDisallow = false; 2381 2382 runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, 2383 expectedInteractionsWithShowNotification); 2384 } 2385 2386 @Test testUntetherUsbWhenRestrictionIsOn()2387 public void testUntetherUsbWhenRestrictionIsOn() throws Exception { 2388 initTetheringOnTestThread(); 2389 // Start usb tethering and check that usb interface is tethered. 2390 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 2391 runUsbTethering(upstreamState); 2392 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 2393 assertTrue(mTethering.isTetheringActive()); 2394 assertEquals(0, mTethering.getPendingTetheringRequests().size()); 2395 2396 final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener( 2397 mTethering, false /* currentDisallow */, true /* nextDisallow */); 2398 2399 ural.onUserRestrictionsChanged(); 2400 mLooper.dispatchAll(); 2401 2402 // Verify that restriction notification has showed to user. 2403 verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction(); 2404 // Verify that usb tethering has been disabled. 2405 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 2406 } 2407 2408 private class TestTetheringEventCallback extends ITetheringEventCallback.Stub { 2409 private final ArrayList<Network> mActualUpstreams = new ArrayList<>(); 2410 private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs = 2411 new ArrayList<>(); 2412 private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>(); 2413 private final ArrayList<Integer> mOffloadStatus = new ArrayList<>(); 2414 private final ArrayList<List<TetheredClient>> mTetheredClients = new ArrayList<>(); 2415 private final ArrayList<Long> mSupportedBitmaps = new ArrayList<>(); 2416 2417 // This function will remove the recorded callbacks, so it must be called once for 2418 // each callback. If this is called after multiple callback, the order matters. 2419 // onCallbackCreated counts as the first call to expectUpstreamChanged with 2420 // @see onCallbackCreated. expectUpstreamChanged(Network... networks)2421 public void expectUpstreamChanged(Network... networks) { 2422 if (networks == null) { 2423 assertNoUpstreamChangeCallback(); 2424 return; 2425 } 2426 2427 final ArrayList<Network> expectedUpstreams = 2428 new ArrayList<Network>(Arrays.asList(networks)); 2429 for (Network upstream : expectedUpstreams) { 2430 // throws OOB if no expectations 2431 assertEquals(upstream, mActualUpstreams.remove(0)); 2432 } 2433 assertNoUpstreamChangeCallback(); 2434 } 2435 2436 // This function will remove the recorded callbacks, so it must be called once 2437 // for each callback. If this is called after multiple callback, the order matters. 2438 // onCallbackCreated counts as the first call to onConfigurationChanged with 2439 // @see onCallbackCreated. expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs)2440 public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) { 2441 final ArrayList<TetheringConfigurationParcel> expectedTetherConfig = 2442 new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs)); 2443 for (TetheringConfigurationParcel config : expectedTetherConfig) { 2444 // throws OOB if no expectations 2445 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0); 2446 assertTetherConfigParcelEqual(config, actualConfig); 2447 } 2448 assertNoConfigChangeCallback(); 2449 } 2450 expectOffloadStatusChanged(final int expectedStatus)2451 public void expectOffloadStatusChanged(final int expectedStatus) { 2452 assertOffloadStatusChangedCallback(); 2453 assertEquals(Integer.valueOf(expectedStatus), mOffloadStatus.remove(0)); 2454 } 2455 pollTetherStatesChanged()2456 public TetherStatesParcel pollTetherStatesChanged() { 2457 assertStateChangeCallback(); 2458 return mTetherStates.remove(0); 2459 } 2460 expectTetheredClientChanged(List<TetheredClient> leases)2461 public void expectTetheredClientChanged(List<TetheredClient> leases) { 2462 assertFalse(mTetheredClients.isEmpty()); 2463 final List<TetheredClient> result = mTetheredClients.remove(0); 2464 assertEquals(leases.size(), result.size()); 2465 assertTrue(leases.containsAll(result)); 2466 } 2467 expectSupportedTetheringTypes(Set<Integer> expectedTypes)2468 public void expectSupportedTetheringTypes(Set<Integer> expectedTypes) { 2469 assertEquals(expectedTypes, TetheringManager.unpackBits(mSupportedBitmaps.remove(0))); 2470 } 2471 2472 @Override onUpstreamChanged(Network network)2473 public void onUpstreamChanged(Network network) { 2474 mActualUpstreams.add(network); 2475 } 2476 2477 @Override onConfigurationChanged(TetheringConfigurationParcel config)2478 public void onConfigurationChanged(TetheringConfigurationParcel config) { 2479 mTetheringConfigs.add(config); 2480 } 2481 2482 @Override onTetherStatesChanged(TetherStatesParcel states)2483 public void onTetherStatesChanged(TetherStatesParcel states) { 2484 mTetherStates.add(states); 2485 } 2486 2487 @Override onTetherClientsChanged(List<TetheredClient> clients)2488 public void onTetherClientsChanged(List<TetheredClient> clients) { 2489 mTetheredClients.add(clients); 2490 } 2491 2492 @Override onOffloadStatusChanged(final int status)2493 public void onOffloadStatusChanged(final int status) { 2494 mOffloadStatus.add(status); 2495 } 2496 2497 @Override onCallbackStarted(TetheringCallbackStartedParcel parcel)2498 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 2499 mActualUpstreams.add(parcel.upstreamNetwork); 2500 mTetheringConfigs.add(parcel.config); 2501 mTetherStates.add(parcel.states); 2502 mOffloadStatus.add(parcel.offloadStatus); 2503 mTetheredClients.add(parcel.tetheredClients); 2504 mSupportedBitmaps.add(parcel.supportedTypes); 2505 } 2506 2507 @Override onCallbackStopped(int errorCode)2508 public void onCallbackStopped(int errorCode) { } 2509 2510 @Override onSupportedTetheringTypes(long supportedBitmap)2511 public void onSupportedTetheringTypes(long supportedBitmap) { 2512 mSupportedBitmaps.add(supportedBitmap); 2513 } 2514 assertNoUpstreamChangeCallback()2515 public void assertNoUpstreamChangeCallback() { 2516 assertTrue(mActualUpstreams.isEmpty()); 2517 } 2518 assertNoConfigChangeCallback()2519 public void assertNoConfigChangeCallback() { 2520 assertTrue(mTetheringConfigs.isEmpty()); 2521 } 2522 assertNoStateChangeCallback()2523 public void assertNoStateChangeCallback() { 2524 assertTrue(mTetherStates.isEmpty()); 2525 } 2526 assertStateChangeCallback()2527 public void assertStateChangeCallback() { 2528 assertFalse(mTetherStates.isEmpty()); 2529 } 2530 assertOffloadStatusChangedCallback()2531 public void assertOffloadStatusChangedCallback() { 2532 assertFalse(mOffloadStatus.isEmpty()); 2533 } 2534 assertNoCallback()2535 public void assertNoCallback() { 2536 assertNoUpstreamChangeCallback(); 2537 assertNoConfigChangeCallback(); 2538 assertNoStateChangeCallback(); 2539 assertTrue(mTetheredClients.isEmpty()); 2540 } 2541 assertTetherConfigParcelEqual(@onNull TetheringConfigurationParcel actual, @NonNull TetheringConfigurationParcel expect)2542 private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual, 2543 @NonNull TetheringConfigurationParcel expect) { 2544 assertArrayEquals(expect.tetherableUsbRegexs, actual.tetherableUsbRegexs); 2545 assertArrayEquals(expect.tetherableWifiRegexs, actual.tetherableWifiRegexs); 2546 assertArrayEquals(expect.tetherableBluetoothRegexs, actual.tetherableBluetoothRegexs); 2547 assertArrayEquals(expect.legacyDhcpRanges, actual.legacyDhcpRanges); 2548 assertArrayEquals(expect.provisioningApp, actual.provisioningApp); 2549 assertEquals(expect.provisioningAppNoUi, actual.provisioningAppNoUi); 2550 } 2551 } 2552 assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel)2553 private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) { 2554 assertFalse(parcel == null); 2555 assertEquals(0, parcel.availableList.length); 2556 assertEquals(0, parcel.tetheredList.length); 2557 assertEquals(0, parcel.localOnlyList.length); 2558 assertEquals(0, parcel.erroredIfaceList.length); 2559 assertEquals(0, parcel.lastErrorList.length); 2560 MiscAsserts.assertFieldCountEquals(5, TetherStatesParcel.class); 2561 } 2562 2563 @Test testRegisterTetheringEventCallback()2564 public void testRegisterTetheringEventCallback() throws Exception { 2565 initTetheringOnTestThread(); 2566 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2567 TestTetheringEventCallback callback2 = new TestTetheringEventCallback(); 2568 final TetheringInterface wifiIface = new TetheringInterface( 2569 TETHERING_WIFI, TEST_WLAN_IFNAME); 2570 2571 // 1. Register one callback before running any tethering. 2572 mTethering.registerTetheringEventCallback(callback); 2573 mLooper.dispatchAll(); 2574 callback.expectTetheredClientChanged(Collections.emptyList()); 2575 callback.expectUpstreamChanged(NULL_NETWORK); 2576 callback.expectConfigurationChanged( 2577 mTethering.getTetheringConfiguration().toStableParcelable()); 2578 TetherStatesParcel tetherState = callback.pollTetherStatesChanged(); 2579 assertTetherStatesNotNullButEmpty(tetherState); 2580 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 2581 // 2. Enable wifi tethering. 2582 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 2583 initTetheringUpstream(upstreamState); 2584 2585 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 2586 mTethering.startTethering(request, TEST_CALLER_PKG, 2587 null); 2588 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2589 mLooper.dispatchAll(); 2590 if (SdkLevel.isAtLeastB()) { 2591 // Starting in B, ignore the interfaceStatusChanged 2592 callback.assertNoStateChangeCallback(); 2593 } 2594 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 2595 mLooper.dispatchAll(); 2596 tetherState = callback.pollTetherStatesChanged(); 2597 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 2598 tetherState = callback.pollTetherStatesChanged(); 2599 assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface}); 2600 callback.expectUpstreamChanged(upstreamState.network); 2601 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 2602 2603 // 3. Register second callback. 2604 mTethering.registerTetheringEventCallback(callback2); 2605 mLooper.dispatchAll(); 2606 callback2.expectTetheredClientChanged(Collections.emptyList()); 2607 callback2.expectUpstreamChanged(upstreamState.network); 2608 callback2.expectConfigurationChanged( 2609 mTethering.getTetheringConfiguration().toStableParcelable()); 2610 tetherState = callback2.pollTetherStatesChanged(); 2611 assertEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface}); 2612 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 2613 2614 // 4. Unregister first callback and disable wifi tethering 2615 mTethering.unregisterTetheringEventCallback(callback); 2616 mLooper.dispatchAll(); 2617 mTethering.stopTethering(TETHERING_WIFI); 2618 sendWifiApStateChanged(WIFI_AP_STATE_DISABLED); 2619 if (isAtLeastT()) { 2620 // After T, tethering doesn't support WIFI_AP_STATE_DISABLED with null interface name. 2621 callback2.assertNoStateChangeCallback(); 2622 sendSoftApEvent(WIFI_AP_STATE_DISABLED, request, TEST_WLAN_IFNAME); 2623 } 2624 tetherState = callback2.pollTetherStatesChanged(); 2625 assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface}); 2626 mLooper.dispatchAll(); 2627 callback2.expectUpstreamChanged(NULL_NETWORK); 2628 callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 2629 callback.assertNoCallback(); 2630 } 2631 2632 @Test testSoftApConfigInTetheringEventCallback()2633 public void testSoftApConfigInTetheringEventCallback() throws Exception { 2634 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2635 when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS)) 2636 .thenReturn(PERMISSION_DENIED); 2637 when(mContext.checkCallingOrSelfPermission(NETWORK_STACK)) 2638 .thenReturn(PERMISSION_DENIED); 2639 when(mContext.checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK)) 2640 .thenReturn(PERMISSION_DENIED); 2641 initTetheringOnTestThread(); 2642 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2643 TestTetheringEventCallback differentCallback = new TestTetheringEventCallback(); 2644 TestTetheringEventCallback settingsCallback = new TestTetheringEventCallback(); 2645 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2646 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2647 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2648 .setSoftApConfiguration(softApConfig).build(); 2649 tetheringRequest.setUid(TEST_CALLER_UID); 2650 final TetheringInterface wifiIfaceWithoutConfig = new TetheringInterface( 2651 TETHERING_WIFI, TEST_WLAN_IFNAME, null); 2652 final TetheringInterface wifiIfaceWithConfig = new TetheringInterface( 2653 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig); 2654 2655 // Register callback before running any tethering. 2656 mTethering.registerTetheringEventCallback(callback); 2657 mLooper.dispatchAll(); 2658 callback.expectTetheredClientChanged(Collections.emptyList()); 2659 callback.expectUpstreamChanged(NULL_NETWORK); 2660 callback.expectConfigurationChanged( 2661 mTethering.getTetheringConfiguration().toStableParcelable()); 2662 // Register callback with different UID 2663 mBinderCallingUid = TEST_CALLER_UID + 1; 2664 mTethering.registerTetheringEventCallback(differentCallback); 2665 mLooper.dispatchAll(); 2666 differentCallback.expectTetheredClientChanged(Collections.emptyList()); 2667 differentCallback.expectUpstreamChanged(NULL_NETWORK); 2668 differentCallback.expectConfigurationChanged( 2669 mTethering.getTetheringConfiguration().toStableParcelable()); 2670 // Register Settings callback 2671 when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS)) 2672 .thenReturn(PERMISSION_GRANTED); 2673 mTethering.registerTetheringEventCallback(settingsCallback); 2674 mLooper.dispatchAll(); 2675 settingsCallback.expectTetheredClientChanged(Collections.emptyList()); 2676 settingsCallback.expectUpstreamChanged(NULL_NETWORK); 2677 settingsCallback.expectConfigurationChanged( 2678 mTethering.getTetheringConfiguration().toStableParcelable()); 2679 2680 assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged()); 2681 assertTetherStatesNotNullButEmpty(differentCallback.pollTetherStatesChanged()); 2682 assertTetherStatesNotNullButEmpty(settingsCallback.pollTetherStatesChanged()); 2683 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 2684 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 2685 initTetheringUpstream(upstreamState); 2686 2687 // Enable wifi tethering 2688 mBinderCallingUid = TEST_CALLER_UID; 2689 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null); 2690 mLooper.dispatchAll(); 2691 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 2692 mLooper.dispatchAll(); 2693 // Netd "up" event should not trigger a state change callback in B+. 2694 callback.assertNoStateChangeCallback(); 2695 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, 2696 TEST_WLAN_IFNAME); 2697 // Verify we see Available -> Tethered states 2698 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2699 callback.pollTetherStatesChanged().availableList); 2700 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2701 differentCallback.pollTetherStatesChanged().availableList); 2702 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2703 settingsCallback.pollTetherStatesChanged().availableList); 2704 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig}, 2705 callback.pollTetherStatesChanged().tetheredList); 2706 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2707 differentCallback.pollTetherStatesChanged().tetheredList); 2708 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig}, 2709 settingsCallback.pollTetherStatesChanged().tetheredList); 2710 callback.expectUpstreamChanged(upstreamState.network); 2711 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 2712 2713 // Disable wifi tethering 2714 mTethering.stopTethering(TETHERING_WIFI); 2715 mLooper.dispatchAll(); 2716 sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, tetheringRequest, 2717 TEST_WLAN_IFNAME); 2718 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2719 callback.pollTetherStatesChanged().availableList); 2720 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2721 differentCallback.pollTetherStatesChanged().availableList); 2722 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2723 settingsCallback.pollTetherStatesChanged().availableList); 2724 mLooper.dispatchAll(); 2725 callback.expectUpstreamChanged(NULL_NETWORK); 2726 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 2727 callback.assertNoCallback(); 2728 } 2729 2730 @Test testFuzzyMatchedWifiCannotBeAdded()2731 public void testFuzzyMatchedWifiCannotBeAdded() throws Exception { 2732 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2733 initTetheringOnTestThread(); 2734 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 2735 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2736 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2737 final TetheringInterface wifiIfaceWithoutConfig = new TetheringInterface( 2738 TETHERING_WIFI, TEST_WLAN_IFNAME, null); 2739 final TetheringInterface wifiIfaceWithConfig = new TetheringInterface( 2740 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig); 2741 2742 // Register callback before running any tethering. 2743 mTethering.registerTetheringEventCallback(callback); 2744 mLooper.dispatchAll(); 2745 callback.expectTetheredClientChanged(Collections.emptyList()); 2746 callback.expectUpstreamChanged(NULL_NETWORK); 2747 callback.expectConfigurationChanged( 2748 mTethering.getTetheringConfiguration().toStableParcelable()); 2749 assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged()); 2750 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 2751 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 2752 initTetheringUpstream(upstreamState); 2753 2754 // Start wifi tethering but don't trigger the link layer event yet. 2755 mBinderCallingUid = TEST_CALLER_UID; 2756 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2757 .setSoftApConfiguration(softApConfig).build(); 2758 tetheringRequest.setUid(TEST_CALLER_UID); 2759 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2760 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2761 mLooper.dispatchAll(); 2762 successListener.assertDoesNotHaveResult(); 2763 2764 // Try starting wifi tethering with various fuzzy-matching requests and verify we get 2765 // TETHER_ERROR_DUPLICATE_REQUEST. 2766 2767 // Different static IP addresses 2768 final TetheringRequest differentIpAddr = new TetheringRequest.Builder(TETHERING_WIFI) 2769 .setSoftApConfiguration(softApConfig) 2770 .setStaticIpv4Addresses(new LinkAddress("192.168.0.123/24"), 2771 new LinkAddress("192.168.0.42/24")) 2772 .build(); 2773 differentIpAddr.setUid(TEST_CALLER_UID); 2774 ResultListener differentIpAddrListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2775 mTethering.startTethering(differentIpAddr, TEST_CALLER_PKG, differentIpAddrListener); 2776 mLooper.dispatchAll(); 2777 verifyWifiTetheringRequested(); 2778 differentIpAddrListener.assertHasResult(); 2779 2780 // Different UID 2781 final TetheringRequest differentUid = new TetheringRequest.Builder(TETHERING_WIFI) 2782 .setSoftApConfiguration(softApConfig).build(); 2783 differentUid.setUid(TEST_CALLER_UID + 1); 2784 ResultListener differentUidListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2785 mTethering.startTethering(differentUid, TEST_CALLER_PKG, differentUidListener); 2786 mLooper.dispatchAll(); 2787 differentUidListener.assertHasResult(); 2788 verifyWifiTetheringRequested(); 2789 2790 // Mock the link layer event to start IP serving and verify 2791 // 1) The original request's result listener is called. 2792 // 2) We still get TETHER_ERROR_DUPLICATE_REQUEST for new requests. 2793 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2794 successListener.assertHasResult(); 2795 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig}, 2796 callback.pollTetherStatesChanged().availableList); 2797 assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig}, 2798 callback.pollTetherStatesChanged().tetheredList); 2799 callback.expectUpstreamChanged(upstreamState.network); 2800 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); 2801 differentIpAddrListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2802 differentUidListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2803 mTethering.startTethering(differentIpAddr, TEST_CALLER_PKG, differentIpAddrListener); 2804 mTethering.startTethering(differentUid, TEST_CALLER_PKG, differentUidListener); 2805 mLooper.dispatchAll(); 2806 differentIpAddrListener.assertHasResult(); 2807 differentUidListener.assertHasResult(); 2808 verify(mWifiManager, times(1)).startTetheredHotspot(any(), any(), any()); 2809 verify(mWifiManager, never()).stopSoftAp(); 2810 } 2811 2812 @Test testFuzzyMatchedWifiCanBeAddedAfterIpServerStopped()2813 public void testFuzzyMatchedWifiCanBeAddedAfterIpServerStopped() throws Exception { 2814 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2815 initTetheringOnTestThread(); 2816 2817 // Start wifi tethering and mock the ap state change. 2818 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2819 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2820 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2821 .setSoftApConfiguration(softApConfig).build(); 2822 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2823 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2824 mLooper.dispatchAll(); 2825 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2826 successListener.assertHasResult(); 2827 2828 // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST 2829 ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2830 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener); 2831 mLooper.dispatchAll(); 2832 failureListener.assertHasResult(); 2833 2834 // Trigger Netd callback to stop the IpServer 2835 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, false); 2836 2837 // We should be able to request the same Wifi again 2838 ResultListener successListener2 = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2839 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2); 2840 mLooper.dispatchAll(); 2841 successListener2.assertHasResult(); 2842 } 2843 2844 @Test testFuzzyMatchedWifiCanBeAddedAfterIpServerUnwanted()2845 public void testFuzzyMatchedWifiCanBeAddedAfterIpServerUnwanted() throws Exception { 2846 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2847 initTetheringOnTestThread(); 2848 2849 // Start wifi tethering and mock the ap state change. 2850 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2851 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2852 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2853 .setSoftApConfiguration(softApConfig).build(); 2854 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2855 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2856 mLooper.dispatchAll(); 2857 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2858 successListener.assertHasResult(); 2859 // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST 2860 ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2861 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener); 2862 mLooper.dispatchAll(); 2863 failureListener.assertHasResult(); 2864 2865 // Trigger wifi ap state change to tell IpServer it's unwanted. 2866 sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, tetheringRequest, 2867 TEST_WLAN_IFNAME); 2868 2869 // We should be able to request the same Wifi again 2870 ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR); 2871 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2); 2872 mLooper.dispatchAll(); 2873 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, 2874 TEST_WLAN_IFNAME); 2875 successListener2.assertHasResult(); 2876 } 2877 2878 @Test testFuzzyMatchedWifiCanBeAddedAfterIpServerError()2879 public void testFuzzyMatchedWifiCanBeAddedAfterIpServerError() throws Exception { 2880 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2881 initTetheringOnTestThread(); 2882 2883 // Set up the DHCP server to fail creation. 2884 mIpServerDependencies.setOnDhcpServerCreatedResult(STATUS_UNKNOWN_ERROR); 2885 2886 // Start wifi tethering and mock the ap state change. 2887 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2888 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2889 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2890 .setSoftApConfiguration(softApConfig).build(); 2891 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2892 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2893 mLooper.dispatchAll(); 2894 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2895 successListener.assertHasResult(); 2896 2897 // We should be able to request the same Wifi again since the DHCP server transitioned the 2898 // IpServer back to InitialState. 2899 ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR); 2900 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2); 2901 mLooper.dispatchAll(); 2902 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2903 successListener2.assertHasResult(); 2904 } 2905 2906 @Test testFuzzyMatchedWifiCanBeAddedAfterStoppingPendingRequest()2907 public void testFuzzyMatchedWifiCanBeAddedAfterStoppingPendingRequest() throws Exception { 2908 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2909 initTetheringOnTestThread(); 2910 2911 // Start wifi tethering but keep the request pending by not sending the ap state change. 2912 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2913 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2914 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2915 .setSoftApConfiguration(softApConfig).build(); 2916 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2917 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2918 mLooper.dispatchAll(); 2919 ArgumentCaptor<SoftApCallback> callbackCaptor = 2920 ArgumentCaptor.forClass(SoftApCallback.class); 2921 verify(mWifiManager, atLeastOnce()).startTetheredHotspot(any(TetheringRequest.class), 2922 any(Executor.class), callbackCaptor.capture()); 2923 2924 // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST 2925 ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2926 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener); 2927 mLooper.dispatchAll(); 2928 failureListener.assertHasResult(); 2929 2930 // Stop Wifi tethering. 2931 mTethering.stopTethering(TETHERING_WIFI); 2932 2933 // We should be able to request the same Wifi again 2934 ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR); 2935 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2); 2936 mLooper.dispatchAll(); 2937 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2938 successListener2.assertHasResult(); 2939 2940 // Mock the first request going up and then down from the stop request. 2941 SoftApState softApState = mock(SoftApState.class); 2942 when(softApState.getState()).thenReturn(WIFI_AP_STATE_ENABLED); 2943 when(softApState.getTetheringRequest()).thenReturn(tetheringRequest); 2944 when(softApState.getIface()).thenReturn(TEST_WLAN_IFNAME); 2945 callbackCaptor.getValue().onStateChanged(softApState); 2946 mLooper.dispatchAll(); 2947 successListener.assertHasResult(); 2948 2949 // Mock the second request going up 2950 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2951 successListener2.assertHasResult(); 2952 } 2953 2954 @Test testFuzzyMatchedWifiCanBeAddedAfterStoppingServingRequest()2955 public void testFuzzyMatchedWifiCanBeAddedAfterStoppingServingRequest() throws Exception { 2956 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2957 initTetheringOnTestThread(); 2958 2959 // Start wifi tethering and mock the ap state change. 2960 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid( 2961 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build(); 2962 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 2963 .setSoftApConfiguration(softApConfig).build(); 2964 ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR); 2965 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener); 2966 mLooper.dispatchAll(); 2967 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2968 successListener.assertHasResult(); 2969 2970 // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST 2971 ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST); 2972 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener); 2973 mLooper.dispatchAll(); 2974 failureListener.assertHasResult(); 2975 2976 // Stop Wifi tethering. 2977 mTethering.stopTethering(TETHERING_WIFI); 2978 2979 // We should be able to request the same Wifi again 2980 ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR); 2981 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2); 2982 mLooper.dispatchAll(); 2983 sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME); 2984 successListener2.assertHasResult(); 2985 } 2986 2987 @Test testStopTetheringWithMatchingRequest()2988 public void testStopTetheringWithMatchingRequest() throws Exception { 2989 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 2990 when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS)).thenReturn(PERMISSION_DENIED); 2991 initTetheringOnTestThread(); 2992 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 2993 initTetheringUpstream(upstreamState); 2994 2995 // Enable wifi tethering. 2996 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() 2997 .setSsid("SoftApConfig") 2998 .build(); 2999 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 3000 .setSoftApConfiguration(softApConfig).build(); 3001 tetheringRequest.setUid(TEST_CALLER_UID); 3002 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null); 3003 mLooper.dispatchAll(); 3004 3005 // Stop tethering with non-matching config. Should fail with TETHER_ERROR_UNKNOWN_REQUEST. 3006 SoftApConfiguration softApConfig2 = new SoftApConfiguration.Builder() 3007 .setSsid("SoftApConfig2") 3008 .build(); 3009 IIntResultListener differentConfigListener = mock(IIntResultListener.class); 3010 mTethering.stopTetheringRequest(new TetheringRequest.Builder(TETHERING_WIFI) 3011 .setSoftApConfiguration(softApConfig2).build(), differentConfigListener); 3012 mLooper.dispatchAll(); 3013 verify(differentConfigListener).onResult(eq(TETHER_ERROR_UNKNOWN_REQUEST)); 3014 verify(mWifiManager, never()).stopSoftAp(); 3015 3016 // Stop tethering with non-matching UID. Should fail with TETHER_ERROR_UNKNOWN_REQUEST. 3017 final TetheringRequest nonMatchingUid = new TetheringRequest.Builder(TETHERING_WIFI) 3018 .setSoftApConfiguration(softApConfig).build(); 3019 IIntResultListener nonMatchingUidListener = mock(IIntResultListener.class); 3020 nonMatchingUid.setUid(TEST_CALLER_UID_2); 3021 mTethering.stopTetheringRequest(nonMatchingUid, nonMatchingUidListener); 3022 mLooper.dispatchAll(); 3023 verify(nonMatchingUidListener).onResult(eq(TETHER_ERROR_UNKNOWN_REQUEST)); 3024 verify(mWifiManager, never()).stopSoftAp(); 3025 3026 // Stop tethering with matching request. Should succeed now. 3027 IIntResultListener matchingListener = mock(IIntResultListener.class); 3028 mTethering.stopTetheringRequest(tetheringRequest, matchingListener); 3029 mLooper.dispatchAll(); 3030 verify(matchingListener).onResult(eq(TETHER_ERROR_NO_ERROR)); 3031 verify(mWifiManager).stopSoftAp(); 3032 } 3033 3034 @Test testStopTetheringWithSettingsPermission()3035 public void testStopTetheringWithSettingsPermission() throws Exception { 3036 assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled()); 3037 initTetheringOnTestThread(); 3038 UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 3039 initTetheringUpstream(upstreamState); 3040 3041 // Enable wifi tethering. 3042 SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() 3043 .setSsid("SoftApConfig") 3044 .build(); 3045 final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI) 3046 .setSoftApConfiguration(softApConfig).build(); 3047 tetheringRequest.setUid(TEST_CALLER_UID); 3048 mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null); 3049 mLooper.dispatchAll(); 3050 3051 // Stop tethering with non-matching UID and Settings permission. Should succeed. 3052 final TetheringRequest nonMatchingUid = new TetheringRequest.Builder(TETHERING_WIFI) 3053 .setSoftApConfiguration(softApConfig).build(); 3054 IIntResultListener nonMatchingUidListener = mock(IIntResultListener.class); 3055 nonMatchingUid.setUid(TEST_CALLER_UID_2); 3056 when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS)) 3057 .thenReturn(PERMISSION_GRANTED); 3058 mTethering.stopTetheringRequest(nonMatchingUid, nonMatchingUidListener); 3059 mLooper.dispatchAll(); 3060 verify(nonMatchingUidListener).onResult(eq(TETHER_ERROR_NO_ERROR)); 3061 verify(mWifiManager).stopSoftAp(); 3062 } 3063 3064 @Test testReportFailCallbackIfOffloadNotSupported()3065 public void testReportFailCallbackIfOffloadNotSupported() throws Exception { 3066 initTetheringOnTestThread(); 3067 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 3068 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 3069 mTethering.registerTetheringEventCallback(callback); 3070 mLooper.dispatchAll(); 3071 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 3072 3073 // 1. Offload fail if no IOffloadHal. 3074 initOffloadConfiguration(OFFLOAD_HAL_VERSION_NONE, 0 /* defaultDisabled */); 3075 runUsbTethering(upstreamState); 3076 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); 3077 runStopUSBTethering(); 3078 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 3079 reset(mUsbManager, mIPv6TetheringCoordinator); 3080 // 2. Offload fail if disabled by settings. 3081 initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 1 /* defaultDisabled */); 3082 runUsbTethering(upstreamState); 3083 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); 3084 runStopUSBTethering(); 3085 callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); 3086 } 3087 runStopUSBTethering()3088 private void runStopUSBTethering() { 3089 mTethering.stopTethering(TETHERING_USB); 3090 mLooper.dispatchAll(); 3091 sendUsbBroadcast(true, true, -1 /* function */); 3092 mLooper.dispatchAll(); 3093 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3094 } 3095 initOffloadConfiguration( @ffloadHardwareInterface.OffloadHalVersion final int offloadHalVersion, final int defaultDisabled)3096 private void initOffloadConfiguration( 3097 @OffloadHardwareInterface.OffloadHalVersion final int offloadHalVersion, 3098 final int defaultDisabled) { 3099 when(mOffloadHardwareInterface.initOffload(any())).thenReturn(offloadHalVersion); 3100 when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn( 3101 defaultDisabled); 3102 } 3103 3104 @Test testMultiSimAware()3105 public void testMultiSimAware() throws Exception { 3106 initTetheringOnTestThread(); 3107 final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); 3108 assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId); 3109 3110 final int fakeSubId = 1234; 3111 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); 3112 final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); 3113 assertEquals(fakeSubId, newConfig.activeDataSubId); 3114 verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); 3115 } 3116 3117 @Test testNoDuplicatedEthernetRequest()3118 public void testNoDuplicatedEthernetRequest() throws Exception { 3119 initTetheringOnTestThread(); 3120 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); 3121 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); 3122 mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET), TEST_CALLER_PKG, 3123 null); 3124 mLooper.dispatchAll(); 3125 verify(mEm, times(1)).requestTetheredInterface(any(), any()); 3126 mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET), TEST_CALLER_PKG, 3127 null); 3128 mLooper.dispatchAll(); 3129 verifyNoMoreInteractions(mEm); 3130 mTethering.stopTethering(TETHERING_ETHERNET); 3131 mLooper.dispatchAll(); 3132 verify(mockRequest, times(1)).release(); 3133 mTethering.stopTethering(TETHERING_ETHERNET); 3134 mLooper.dispatchAll(); 3135 verifyNoMoreInteractions(mEm); 3136 } 3137 workingWifiP2pGroupOwner( boolean emulateInterfaceStatusChanged)3138 private void workingWifiP2pGroupOwner( 3139 boolean emulateInterfaceStatusChanged) throws Exception { 3140 initTetheringOnTestThread(); 3141 if (emulateInterfaceStatusChanged) { 3142 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 3143 } 3144 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 3145 3146 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME, false); 3147 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER); 3148 verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); 3149 verify(mNetd, times(1)).tetherStartWithConfiguration(any()); 3150 verifyNoMoreInteractions(mNetd); 3151 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 3152 verify(mUpstreamNetworkMonitor, times(1)).startObserveUpstreamNetworks(); 3153 // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY 3154 verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); 3155 3156 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 3157 3158 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group 3159 // is being removed. 3160 sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME); 3161 mTethering.interfaceRemoved(TEST_P2P_IFNAME); 3162 3163 verify(mNetd, times(1)).tetherApplyDnsInterfaces(); 3164 verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME); 3165 verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 3166 // interfaceSetCfg() called once for enabling and twice for disabling IPv4. 3167 verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 3168 verify(mNetd, times(1)).tetherStop(); 3169 verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); 3170 verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream(); 3171 verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); 3172 verifyNoMoreInteractions(mNetd); 3173 // Asking for the last error after the per-interface state machine 3174 // has been reaped yields an unknown interface error. 3175 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 3176 } 3177 workingWifiP2pGroupClient( boolean emulateInterfaceStatusChanged)3178 private void workingWifiP2pGroupClient( 3179 boolean emulateInterfaceStatusChanged) throws Exception { 3180 initTetheringOnTestThread(); 3181 if (emulateInterfaceStatusChanged) { 3182 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 3183 } 3184 sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME); 3185 3186 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 3187 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); 3188 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 3189 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); 3190 verify(mNetd, never()).tetherStartWithConfiguration(any()); 3191 3192 // Emulate externally-visible WifiP2pManager effects, when wifi p2p group 3193 // is being removed. 3194 sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME); 3195 mTethering.interfaceRemoved(TEST_P2P_IFNAME); 3196 3197 verify(mNetd, never()).tetherApplyDnsInterfaces(); 3198 verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME); 3199 verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 3200 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 3201 verify(mNetd, never()).tetherStop(); 3202 verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME); 3203 verifyNoMoreInteractions(mNetd); 3204 // Asking for the last error after the per-interface state machine 3205 // has been reaped yields an unknown interface error. 3206 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 3207 } 3208 3209 @Test workingWifiP2pGroupOwnerWithIfaceChanged()3210 public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception { 3211 workingWifiP2pGroupOwner(true); 3212 } 3213 3214 @Test workingWifiP2pGroupOwnerSansIfaceChanged()3215 public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception { 3216 workingWifiP2pGroupOwner(false); 3217 } 3218 workingWifiP2pGroupOwnerLegacyMode( boolean emulateInterfaceStatusChanged)3219 private void workingWifiP2pGroupOwnerLegacyMode( 3220 boolean emulateInterfaceStatusChanged) throws Exception { 3221 initTetheringOnTestThread(); 3222 // change to legacy mode and update tethering information by chaning SIM 3223 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 3224 .thenReturn(new String[]{}); 3225 final int fakeSubId = 1234; 3226 mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); 3227 3228 if (emulateInterfaceStatusChanged) { 3229 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 3230 } 3231 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 3232 3233 verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); 3234 verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); 3235 verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); 3236 verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); 3237 verify(mNetd, never()).tetherStartWithConfiguration(any()); 3238 assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 3239 } 3240 @Test workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged()3241 public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception { 3242 workingWifiP2pGroupOwnerLegacyMode(true); 3243 } 3244 3245 @Test workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged()3246 public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception { 3247 workingWifiP2pGroupOwnerLegacyMode(false); 3248 } 3249 3250 @Test workingWifiP2pGroupClientWithIfaceChanged()3251 public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception { 3252 workingWifiP2pGroupClient(true); 3253 } 3254 3255 @Test workingWifiP2pGroupClientSansIfaceChanged()3256 public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception { 3257 workingWifiP2pGroupClient(false); 3258 } 3259 setDataSaverEnabled(boolean enabled)3260 private void setDataSaverEnabled(boolean enabled) { 3261 final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED 3262 : RESTRICT_BACKGROUND_STATUS_DISABLED; 3263 doReturn(status).when(mCm).getRestrictBackgroundStatus(); 3264 3265 final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED); 3266 mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3267 mLooper.dispatchAll(); 3268 } 3269 3270 @Test testDataSaverChanged()3271 public void testDataSaverChanged() throws Exception { 3272 initTetheringOnTestThread(); 3273 // Start Tethering. 3274 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 3275 runUsbTethering(upstreamState); 3276 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 3277 // Data saver is ON. 3278 setDataSaverEnabled(true); 3279 // Verify that tethering should be disabled. 3280 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3281 sendUsbBroadcast(true, true, -1 /* function */); 3282 mLooper.dispatchAll(); 3283 assertEquals(mTethering.getTetheredIfaces(), new String[0]); 3284 reset(mUsbManager, mIPv6TetheringCoordinator); 3285 3286 runUsbTethering(upstreamState); 3287 // Verify that user can start tethering again without turning OFF data saver. 3288 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 3289 3290 // If data saver is keep ON with change event, tethering should not be OFF this time. 3291 setDataSaverEnabled(true); 3292 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3293 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 3294 3295 // If data saver is turned OFF, it should not change tethering. 3296 setDataSaverEnabled(false); 3297 verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3298 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME); 3299 } 3300 assertContains(Collection<T> collection, T element)3301 private static <T> void assertContains(Collection<T> collection, T element) { 3302 assertTrue(element + " not found in " + collection, collection.contains(element)); 3303 } 3304 3305 private class ResultListener extends IIntResultListener.Stub { 3306 private final int mExpectedResult; 3307 private boolean mHasResult = false; ResultListener(final int expectedResult)3308 ResultListener(final int expectedResult) { 3309 mExpectedResult = expectedResult; 3310 } 3311 3312 @Override onResult(final int resultCode)3313 public void onResult(final int resultCode) { 3314 mHasResult = true; 3315 if (resultCode != mExpectedResult) { 3316 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode); 3317 } 3318 } 3319 assertHasResult()3320 public void assertHasResult() { 3321 if (!mHasResult) fail("No callback result"); 3322 } 3323 assertDoesNotHaveResult()3324 public void assertDoesNotHaveResult() { 3325 if (mHasResult) fail("Has callback result"); 3326 } 3327 } 3328 3329 @Test testMultipleStartTetheringLegacy()3330 public void testMultipleStartTetheringLegacy() throws Exception { 3331 mTetheringWithSoftApConfigEnabled = false; 3332 initTetheringOnTestThread(); 3333 final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24"); 3334 final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24"); 3335 final String serverAddr = "192.168.20.1"; 3336 final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR); 3337 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); 3338 final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR); 3339 3340 // Enable USB tethering and check that Tethering starts USB. 3341 mTethering.startTethering(createTetheringRequest(TETHERING_USB), TEST_CALLER_PKG, 3342 firstResult); 3343 mLooper.dispatchAll(); 3344 firstResult.assertHasResult(); 3345 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 3346 verifyNoMoreInteractions(mUsbManager); 3347 3348 // Enable USB tethering again with the same request and expect no change to USB. 3349 mTethering.startTethering(createTetheringRequest(TETHERING_USB), TEST_CALLER_PKG, 3350 secondResult); 3351 mLooper.dispatchAll(); 3352 secondResult.assertHasResult(); 3353 verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3354 reset(mUsbManager); 3355 3356 // Enable USB tethering again with the same request but different uid/package and expect no 3357 // change to USB. 3358 TetheringRequest differentUidPackage = createTetheringRequest(TETHERING_USB); 3359 differentUidPackage.setUid(TEST_CALLER_UID_2); 3360 differentUidPackage.setPackageName(TEST_CALLER_PKG_2); 3361 mTethering.startTethering(differentUidPackage, TEST_CALLER_PKG_2, secondResult); 3362 mLooper.dispatchAll(); 3363 secondResult.assertHasResult(); 3364 verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3365 reset(mUsbManager); 3366 3367 // Enable USB tethering with a different request and expect that USB is stopped and 3368 // started. 3369 mTethering.startTethering(createTetheringRequest(TETHERING_USB, 3370 serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null), 3371 TEST_CALLER_PKG, thirdResult); 3372 mLooper.dispatchAll(); 3373 thirdResult.assertHasResult(); 3374 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3375 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 3376 3377 // Expect that when USB comes up, the DHCP server is configured with the requested address. 3378 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 3379 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 3380 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 3381 any(), any()); 3382 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); 3383 } 3384 3385 @Test testRequestStaticIp()3386 public void testRequestStaticIp() throws Exception { 3387 initTetheringOnTestThread(); 3388 when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn( 3389 TetheringConfiguration.TETHER_USB_NCM_FUNCTION); 3390 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 3391 .thenReturn(new String[] {TEST_NCM_REGEX}); 3392 sendConfigurationChanged(); 3393 3394 final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); 3395 final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); 3396 final String serverAddr = "192.168.0.123"; 3397 final int clientAddrParceled = 0xc0a8002a; 3398 final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = 3399 ArgumentCaptor.forClass(DhcpServingParamsParcel.class); 3400 mTethering.startTethering(createTetheringRequest(TETHERING_USB, 3401 serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null), 3402 TEST_CALLER_PKG, null); 3403 mLooper.dispatchAll(); 3404 verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); 3405 mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true); 3406 sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION); 3407 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); 3408 verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), 3409 any()); 3410 final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); 3411 assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); 3412 assertEquals(24, params.serverAddrPrefixLength); 3413 assertEquals(clientAddrParceled, params.singleClientAddr); 3414 } 3415 3416 @Test 3417 @IgnoreAfter(Build.VERSION_CODES.VANILLA_ICE_CREAM) testRequestStaticIpLegacyTether()3418 public void testRequestStaticIpLegacyTether() throws Exception { 3419 initTetheringOnTestThread(); 3420 3421 // Call startTethering with static ip 3422 final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); 3423 final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); 3424 final String serverAddr = "192.168.0.123"; 3425 final int clientAddrParceled = 0xc0a8002a; 3426 final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = 3427 ArgumentCaptor.forClass(DhcpServingParamsParcel.class); 3428 mTethering.startTethering(createTetheringRequest(TETHERING_WIFI, 3429 serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null), 3430 TEST_CALLER_PKG, null); 3431 mLooper.dispatchAll(); 3432 verifyWifiTetheringRequested(); 3433 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 3434 3435 // Call legacyTether on the interface before the link layer event comes back. 3436 // This happens, for example, in pre-T bluetooth tethering: Settings calls startTethering, 3437 // and then the bluetooth code calls the tether() API. 3438 final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 3439 mTethering.legacyTether(TEST_WLAN_IFNAME, tetherResult); 3440 mLooper.dispatchAll(); 3441 tetherResult.assertHasResult(); 3442 3443 // Verify that the static ip set in startTethering is used 3444 verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); 3445 verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), 3446 any()); 3447 final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); 3448 assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); 3449 assertEquals(24, params.serverAddrPrefixLength); 3450 assertEquals(clientAddrParceled, params.singleClientAddr); 3451 } 3452 3453 @Test testUpstreamNetworkChanged()3454 public void testUpstreamNetworkChanged() throws Exception { 3455 initTetheringOnTestThread(); 3456 final InOrder inOrder = inOrder(mNotificationUpdater); 3457 3458 // Gain upstream. 3459 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 3460 initTetheringUpstream(upstreamState); 3461 mTetherMainSM.chooseUpstreamType(true); 3462 mTetheringEventCallback.expectUpstreamChanged(upstreamState.network); 3463 inOrder.verify(mNotificationUpdater) 3464 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); 3465 3466 // Set the upstream with the same network ID but different object and the same capability. 3467 final UpstreamNetworkState upstreamState2 = buildMobileIPv4UpstreamState(); 3468 initTetheringUpstream(upstreamState2); 3469 mTetherMainSM.chooseUpstreamType(true); 3470 // Expect that no upstream change event and capabilities changed event. 3471 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 3472 inOrder.verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any()); 3473 3474 // Set the upstream with the same network ID but different object and different capability. 3475 final UpstreamNetworkState upstreamState3 = buildMobileIPv4UpstreamState(); 3476 assertFalse(upstreamState3.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)); 3477 upstreamState3.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); 3478 initTetheringUpstream(upstreamState3); 3479 mTetherMainSM.chooseUpstreamType(true); 3480 // Expect that no upstream change event and capabilities changed event. 3481 mTetheringEventCallback.assertNoUpstreamChangeCallback(); 3482 mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState3); 3483 inOrder.verify(mNotificationUpdater) 3484 .onUpstreamCapabilitiesChanged(upstreamState3.networkCapabilities); 3485 3486 3487 // Lose upstream. 3488 initTetheringUpstream(null); 3489 mTetherMainSM.chooseUpstreamType(true); 3490 mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); 3491 inOrder.verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null); 3492 } 3493 3494 @Test testUpstreamCapabilitiesChanged()3495 public void testUpstreamCapabilitiesChanged() throws Exception { 3496 initTetheringOnTestThread(); 3497 final InOrder inOrder = inOrder(mNotificationUpdater); 3498 final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); 3499 initTetheringUpstream(upstreamState); 3500 3501 mTetherMainSM.chooseUpstreamType(true); 3502 inOrder.verify(mNotificationUpdater) 3503 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); 3504 3505 mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); 3506 inOrder.verify(mNotificationUpdater) 3507 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); 3508 3509 // Verify that onUpstreamCapabilitiesChanged is called if current upstream network 3510 // capabilities changed. 3511 // Expect that capability is changed with new capability VALIDATED. 3512 assertFalse(upstreamState.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)); 3513 upstreamState.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); 3514 mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); 3515 inOrder.verify(mNotificationUpdater) 3516 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); 3517 3518 // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network 3519 // capabilities changed. 3520 final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState( 3521 upstreamState.linkProperties, upstreamState.networkCapabilities, 3522 new Network(WIFI_NETID)); 3523 mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2); 3524 inOrder.verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any()); 3525 } 3526 3527 @Test testUpstreamCapabilitiesChanged_startStopTethering()3528 public void testUpstreamCapabilitiesChanged_startStopTethering() throws Exception { 3529 initTetheringOnTestThread(); 3530 final TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); 3531 3532 // Start USB tethering with no current upstream. 3533 prepareUsbTethering(); 3534 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 3535 3536 // Pretend wifi connected and expect the upstream to be set. 3537 wifi.fakeConnect(); 3538 mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); 3539 mLooper.dispatchAll(); 3540 verify(mNotificationUpdater).onUpstreamCapabilitiesChanged( 3541 wifi.networkCapabilities); 3542 3543 // Stop tethering. 3544 // Expect that TetherModeAliveState#exit sends capabilities change notification to null. 3545 runStopUSBTethering(); 3546 verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null); 3547 } 3548 3549 @Test testDumpTetheringLog()3550 public void testDumpTetheringLog() throws Exception { 3551 initTetheringOnTestThread(); 3552 final FileDescriptor mockFd = mock(FileDescriptor.class); 3553 final PrintWriter mockPw = mock(PrintWriter.class); 3554 runUsbTethering(null); 3555 mTethering.dump(mockFd, mockPw, new String[0]); 3556 verify(mConfig).dump(any()); 3557 verify(mEntitleMgr).dump(any()); 3558 verify(mOffloadCtrl).dump(any()); 3559 } 3560 3561 @Test testExemptFromEntitlementCheck()3562 public void testExemptFromEntitlementCheck() throws Exception { 3563 initTetheringOnTestThread(); 3564 setupForRequiredProvisioning(); 3565 final TetheringRequest wifiNotExemptRequest = 3566 createTetheringRequest(TETHERING_WIFI, null, null, false, 3567 CONNECTIVITY_SCOPE_GLOBAL, null); 3568 mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null); 3569 mLooper.dispatchAll(); 3570 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); 3571 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); 3572 assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); 3573 mTethering.stopTethering(TETHERING_WIFI); 3574 mLooper.dispatchAll(); 3575 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 3576 reset(mEntitleMgr); 3577 3578 setupForRequiredProvisioning(); 3579 final TetheringRequest wifiExemptRequest = 3580 createTetheringRequest(TETHERING_WIFI, null, null, true, 3581 CONNECTIVITY_SCOPE_GLOBAL, null); 3582 mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null); 3583 mLooper.dispatchAll(); 3584 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); 3585 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); 3586 assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); 3587 mTethering.stopTethering(TETHERING_WIFI); 3588 mLooper.dispatchAll(); 3589 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 3590 reset(mEntitleMgr); 3591 } 3592 3593 @Test testNonExemptRequestAddedAfterExemptRequestOfSameType()3594 public void testNonExemptRequestAddedAfterExemptRequestOfSameType() throws Exception { 3595 // Note: When fuzzy-matching is enabled, it is not possible yet to have two concurrent 3596 // requests of the same type that are subject to carrier entitlement due to fuzzy-matching. 3597 mTetheringWithSoftApConfigEnabled = false; 3598 initTetheringOnTestThread(); 3599 setupForRequiredProvisioning(); 3600 final TetheringRequest wifiExemptRequest = 3601 createTetheringRequest(TETHERING_WIFI, null, null, true, 3602 CONNECTIVITY_SCOPE_GLOBAL, null); 3603 mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null); 3604 mLooper.dispatchAll(); 3605 verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); 3606 verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); 3607 assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); 3608 reset(mEntitleMgr); 3609 3610 setupForRequiredProvisioning(); 3611 final TetheringRequest wifiNotExemptRequest = 3612 createTetheringRequest(TETHERING_WIFI, null, null, false, 3613 CONNECTIVITY_SCOPE_GLOBAL, null); 3614 mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null); 3615 mLooper.dispatchAll(); 3616 verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); 3617 verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); 3618 verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); 3619 assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); 3620 mTethering.stopTethering(TETHERING_WIFI); 3621 mLooper.dispatchAll(); 3622 verify(mEntitleMgr, times(2)).stopProvisioningIfNeeded(TETHERING_WIFI); 3623 } 3624 setupForRequiredProvisioning()3625 private void setupForRequiredProvisioning() { 3626 // Produce some acceptable looking provision app setting if requested. 3627 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) 3628 .thenReturn(PROVISIONING_APP_NAME); 3629 when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui)) 3630 .thenReturn(PROVISIONING_NO_UI_APP_NAME); 3631 // Act like the CarrierConfigManager is present and ready unless told otherwise. 3632 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) 3633 .thenReturn(mCarrierConfigManager); 3634 when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig); 3635 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); 3636 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); 3637 sendConfigurationChanged(); 3638 } 3639 buildV4UpstreamState(final LinkAddress address, final Network network, final String iface, final int transportType)3640 private static UpstreamNetworkState buildV4UpstreamState(final LinkAddress address, 3641 final Network network, final String iface, final int transportType) { 3642 final LinkProperties prop = new LinkProperties(); 3643 prop.setInterfaceName(iface); 3644 3645 prop.addLinkAddress(address); 3646 3647 final NetworkCapabilities capabilities = new NetworkCapabilities() 3648 .addTransportType(transportType); 3649 return new UpstreamNetworkState(prop, capabilities, network); 3650 } 3651 updateV4Upstream(final LinkAddress ipv4Address, final Network network, final String iface, final int transportType)3652 private void updateV4Upstream(final LinkAddress ipv4Address, final Network network, 3653 final String iface, final int transportType) { 3654 final UpstreamNetworkState upstream = buildV4UpstreamState(ipv4Address, network, iface, 3655 transportType); 3656 mEventListener.onUpstreamEvent(UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, upstream); 3657 mLooper.dispatchAll(); 3658 } 3659 3660 @Test testHandleIpConflict()3661 public void testHandleIpConflict() throws Exception { 3662 initTetheringOnTestThread(); 3663 final Network wifiNetwork = new Network(200); 3664 final Network[] allNetworks = { wifiNetwork }; 3665 doReturn(allNetworks).when(mCm).getAllNetworks(); 3666 InOrder inOrder = inOrder(mUsbManager, mNetd); 3667 runUsbTethering(null); 3668 3669 inOrder.verify(mNetd).tetherInterfaceAdd(TEST_RNDIS_IFNAME); 3670 3671 final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor = 3672 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); 3673 verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture()); 3674 final String ipv4Address = ifaceConfigCaptor.getValue().ipv4Addr; 3675 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 3676 any(), any()); 3677 3678 // Cause a prefix conflict by assigning a /30 out of the downstream's /24 to the upstream. 3679 updateV4Upstream(new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), 30), 3680 wifiNetwork, TEST_WIFI_IFNAME, TRANSPORT_WIFI); 3681 // verify turn off usb tethering 3682 inOrder.verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3683 sendUsbBroadcast(true, true, -1 /* function */); 3684 mLooper.dispatchAll(); 3685 inOrder.verify(mNetd).tetherInterfaceRemove(TEST_RNDIS_IFNAME); 3686 3687 // verify restart usb tethering 3688 inOrder.verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 3689 3690 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 3691 mLooper.dispatchAll(); 3692 inOrder.verify(mNetd).tetherInterfaceAdd(TEST_RNDIS_IFNAME); 3693 } 3694 3695 @Test testNoAddressAvailable()3696 public void testNoAddressAvailable() throws Exception { 3697 initTetheringOnTestThread(); 3698 final Network wifiNetwork = new Network(200); 3699 final Network btNetwork = new Network(201); 3700 final Network mobileNetwork = new Network(202); 3701 final Network[] allNetworks = { wifiNetwork, btNetwork, mobileNetwork }; 3702 doReturn(allNetworks).when(mCm).getAllNetworks(); 3703 runUsbTethering(null); 3704 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 3705 any(), any()); 3706 reset(mUsbManager); 3707 final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); 3708 when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); 3709 final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor = 3710 ArgumentCaptor.forClass(TetheredInterfaceCallback.class); 3711 mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET), 3712 TEST_CALLER_PKG, null); 3713 mLooper.dispatchAll(); 3714 verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture()); 3715 TetheredInterfaceCallback ethCallback = callbackCaptor.getValue(); 3716 ethCallback.onAvailable(TEST_ETH_IFNAME); 3717 mLooper.dispatchAll(); 3718 reset(mUsbManager, mEm); 3719 3720 updateV4Upstream(new LinkAddress("192.168.0.100/16"), wifiNetwork, TEST_WIFI_IFNAME, 3721 TRANSPORT_WIFI); 3722 updateV4Upstream(new LinkAddress("172.16.0.0/12"), btNetwork, TEST_BT_IFNAME, 3723 TRANSPORT_BLUETOOTH); 3724 updateV4Upstream(new LinkAddress("10.0.0.0/8"), mobileNetwork, TEST_MOBILE_IFNAME, 3725 TRANSPORT_CELLULAR); 3726 3727 mLooper.dispatchAll(); 3728 // verify turn off usb tethering 3729 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); 3730 // verify turn off ethernet tethering 3731 verify(mockRequest).release(); 3732 sendUsbBroadcast(true, true, -1 /* function */); 3733 ethCallback.onUnavailable(); 3734 mLooper.dispatchAll(); 3735 // verify restart usb tethering 3736 verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); 3737 // verify restart ethernet tethering 3738 verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture()); 3739 ethCallback = callbackCaptor.getValue(); 3740 ethCallback.onAvailable(TEST_ETH_IFNAME); 3741 3742 reset(mUsbManager, mEm); 3743 when(mNetd.interfaceGetList()) 3744 .thenReturn(new String[] { 3745 TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME, 3746 TEST_NCM_IFNAME, TEST_ETH_IFNAME}); 3747 3748 mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true); 3749 sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); 3750 assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_RNDIS_IFNAME); 3751 assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_ETH_IFNAME); 3752 assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest( 3753 TEST_RNDIS_IFNAME)); 3754 assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(TEST_ETH_IFNAME)); 3755 } 3756 3757 @Test testProvisioningNeededButUnavailable()3758 public void testProvisioningNeededButUnavailable() throws Exception { 3759 initTetheringOnTestThread(); 3760 assertTrue(mTethering.isTetheringSupported()); 3761 verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 3762 3763 setupForRequiredProvisioning(); 3764 assertTrue(mTethering.isTetheringSupported()); 3765 verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 3766 reset(mPackageManager); 3767 3768 doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo( 3769 PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 3770 setupForRequiredProvisioning(); 3771 assertFalse(mTethering.isTetheringSupported()); 3772 verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES); 3773 } 3774 3775 @Test testUpdateConnectedClients()3776 public void testUpdateConnectedClients() throws Exception { 3777 initTetheringOnTestThread(); 3778 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 3779 runAsShell(NETWORK_SETTINGS, () -> { 3780 mTethering.registerTetheringEventCallback(callback); 3781 mLooper.dispatchAll(); 3782 }); 3783 callback.expectTetheredClientChanged(Collections.emptyList()); 3784 3785 IDhcpEventCallbacks eventCallbacks; 3786 final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor = 3787 ArgumentCaptor.forClass(IDhcpEventCallbacks.class); 3788 // Run local only tethering. 3789 mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); 3790 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 3791 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 3792 any(), dhcpEventCbsCaptor.capture()); 3793 eventCallbacks = dhcpEventCbsCaptor.getValue(); 3794 // Update lease for local only tethering. 3795 final MacAddress testMac1 = MacAddress.fromString("11:11:11:11:11:11"); 3796 final DhcpLeaseParcelable p2pLease = createDhcpLeaseParcelable("clientId1", testMac1, 3797 "192.168.50.24", 24, Long.MAX_VALUE, "test1"); 3798 final List<TetheredClient> connectedClients = notifyDhcpLeasesChanged(TETHERING_WIFI_P2P, 3799 eventCallbacks, p2pLease); 3800 callback.expectTetheredClientChanged(connectedClients); 3801 reset(mDhcpServer); 3802 3803 // Run wifi tethering. 3804 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 3805 mTethering.startTethering(request, TEST_CALLER_PKG, null); 3806 mLooper.dispatchAll(); 3807 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 3808 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 3809 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 3810 any(), dhcpEventCbsCaptor.capture()); 3811 eventCallbacks = dhcpEventCbsCaptor.getValue(); 3812 final MacAddress testMac2 = MacAddress.fromString("22:22:22:22:22:22"); 3813 final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId2", testMac2, 3814 "192.168.43.24", 24, Long.MAX_VALUE, "test2"); 3815 verifyHotspotClientUpdate(false /* isLocalOnly */, testMac2, wifiLease, connectedClients, 3816 eventCallbacks, callback); 3817 3818 // Test onStarted callback that register second callback when tethering is running. 3819 TestTetheringEventCallback callback2 = new TestTetheringEventCallback(); 3820 runAsShell(NETWORK_SETTINGS, () -> { 3821 mTethering.registerTetheringEventCallback(callback2); 3822 mLooper.dispatchAll(); 3823 }); 3824 callback2.expectTetheredClientChanged(connectedClients); 3825 } 3826 3827 @Test 3828 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testUpdateConnectedClientsForLocalOnlyHotspot()3829 public void testUpdateConnectedClientsForLocalOnlyHotspot() throws Exception { 3830 initTetheringOnTestThread(); 3831 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 3832 runAsShell(NETWORK_SETTINGS, () -> { 3833 mTethering.registerTetheringEventCallback(callback); 3834 mLooper.dispatchAll(); 3835 }); 3836 callback.expectTetheredClientChanged(Collections.emptyList()); 3837 3838 // Run local only hotspot. 3839 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 3840 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 3841 3842 final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor = 3843 ArgumentCaptor.forClass(IDhcpEventCallbacks.class); 3844 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 3845 any(), dhcpEventCbsCaptor.capture()); 3846 final IDhcpEventCallbacks eventCallbacks = dhcpEventCbsCaptor.getValue(); 3847 3848 final List<TetheredClient> connectedClients = new ArrayList<>(); 3849 final MacAddress testMac = MacAddress.fromString("22:22:22:22:22:22"); 3850 final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId", testMac, 3851 "192.168.43.24", 24, Long.MAX_VALUE, "test"); 3852 verifyHotspotClientUpdate(true /* isLocalOnly */, testMac, wifiLease, connectedClients, 3853 eventCallbacks, callback); 3854 3855 // Client disconnect from local only hotspot. 3856 mLocalOnlyHotspotCallback.onConnectedClientsChanged(Collections.emptyList()); 3857 callback.expectTetheredClientChanged(Collections.emptyList()); 3858 } 3859 3860 @Test 3861 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testConnectedClientsForSapAndLohsConcurrency()3862 public void testConnectedClientsForSapAndLohsConcurrency() throws Exception { 3863 initTetheringOnTestThread(); 3864 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 3865 runAsShell(NETWORK_SETTINGS, () -> { 3866 mTethering.registerTetheringEventCallback(callback); 3867 mLooper.dispatchAll(); 3868 }); 3869 callback.expectTetheredClientChanged(Collections.emptyList()); 3870 3871 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 3872 mTethering.startTethering(request, TEST_CALLER_PKG, null); 3873 mLooper.dispatchAll(); 3874 verifyWifiTetheringRequested(); 3875 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 3876 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 3877 final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor = 3878 ArgumentCaptor.forClass(IDhcpEventCallbacks.class); 3879 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 3880 any(), dhcpEventCbsCaptor.capture()); 3881 IDhcpEventCallbacks eventCallbacks = dhcpEventCbsCaptor.getValue(); 3882 final List<TetheredClient> connectedClients = new ArrayList<>(); 3883 final MacAddress wifiMac = MacAddress.fromString("11:11:11:11:11:11"); 3884 final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId", wifiMac, 3885 "192.168.2.12", 24, Long.MAX_VALUE, "test"); 3886 verifyHotspotClientUpdate(false /* isLocalOnly */, wifiMac, wifiLease, connectedClients, 3887 eventCallbacks, callback); 3888 reset(mDhcpServer); 3889 3890 mTethering.interfaceStatusChanged(TEST_WLAN2_IFNAME, true); 3891 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN2_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 3892 3893 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 3894 any(), dhcpEventCbsCaptor.capture()); 3895 eventCallbacks = dhcpEventCbsCaptor.getValue(); 3896 final MacAddress localOnlyMac = MacAddress.fromString("22:22:22:22:22:22"); 3897 final DhcpLeaseParcelable localOnlyLease = createDhcpLeaseParcelable("clientId", 3898 localOnlyMac, "192.168.43.24", 24, Long.MAX_VALUE, "test"); 3899 verifyHotspotClientUpdate(true /* isLocalOnly */, localOnlyMac, localOnlyLease, 3900 connectedClients, eventCallbacks, callback); 3901 3902 assertTrue(isIpServerActive(TETHERING_WIFI, TEST_WLAN_IFNAME, IpServer.STATE_TETHERED)); 3903 assertTrue(isIpServerActive(TETHERING_WIFI, TEST_WLAN2_IFNAME, IpServer.STATE_LOCAL_ONLY)); 3904 } 3905 isIpServerActive(int type, String ifName, int mode)3906 private boolean isIpServerActive(int type, String ifName, int mode) { 3907 for (IpServer ipSrv : mTetheringDependencies.mAllDownstreams) { 3908 if (ipSrv.interfaceType() == type && ipSrv.interfaceName().equals(ifName) 3909 && ipSrv.servingMode() == mode) { 3910 return true; 3911 } 3912 } 3913 3914 return false; 3915 } 3916 verifyHotspotClientUpdate(final boolean isLocalOnly, final MacAddress testMac, final DhcpLeaseParcelable dhcpLease, final List<TetheredClient> currentClients, final IDhcpEventCallbacks dhcpCallback, final TestTetheringEventCallback callback)3917 private void verifyHotspotClientUpdate(final boolean isLocalOnly, final MacAddress testMac, 3918 final DhcpLeaseParcelable dhcpLease, final List<TetheredClient> currentClients, 3919 final IDhcpEventCallbacks dhcpCallback, final TestTetheringEventCallback callback) 3920 throws Exception { 3921 // Update mac address from softAp callback before getting dhcp lease. 3922 final TetheredClient noAddrClient = notifyConnectedWifiClientsChanged(testMac, isLocalOnly); 3923 final List<TetheredClient> withNoAddrClients = new ArrayList<>(currentClients); 3924 withNoAddrClients.add(noAddrClient); 3925 callback.expectTetheredClientChanged(withNoAddrClients); 3926 3927 // Update dhcp lease for hotspot. 3928 currentClients.addAll(notifyDhcpLeasesChanged(TETHERING_WIFI, dhcpCallback, dhcpLease)); 3929 callback.expectTetheredClientChanged(currentClients); 3930 } 3931 notifyConnectedWifiClientsChanged(final MacAddress mac, boolean isLocalOnly)3932 private TetheredClient notifyConnectedWifiClientsChanged(final MacAddress mac, 3933 boolean isLocalOnly) throws Exception { 3934 final ArrayList<WifiClient> wifiClients = new ArrayList<>(); 3935 final WifiClient testClient = mock(WifiClient.class); 3936 when(testClient.getMacAddress()).thenReturn(mac); 3937 wifiClients.add(testClient); 3938 if (isLocalOnly) { 3939 mLocalOnlyHotspotCallback.onConnectedClientsChanged(wifiClients); 3940 } else { 3941 mSoftApCallback.onConnectedClientsChanged(wifiClients); 3942 } 3943 return new TetheredClient(mac, Collections.emptyList() /* addresses */, TETHERING_WIFI); 3944 } 3945 notifyDhcpLeasesChanged(int type, IDhcpEventCallbacks callback, DhcpLeaseParcelable... leases)3946 private List<TetheredClient> notifyDhcpLeasesChanged(int type, IDhcpEventCallbacks callback, 3947 DhcpLeaseParcelable... leases) throws Exception { 3948 final List<DhcpLeaseParcelable> dhcpLeases = Arrays.asList(leases); 3949 callback.onLeasesChanged(dhcpLeases); 3950 mLooper.dispatchAll(); 3951 3952 return toTetheredClients(dhcpLeases, type); 3953 } 3954 toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, int type)3955 private List<TetheredClient> toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, 3956 int type) throws Exception { 3957 final ArrayList<TetheredClient> clients = new ArrayList<>(); 3958 for (DhcpLeaseParcelable lease : leaseParcelables) { 3959 final LinkAddress address = new LinkAddress( 3960 intToInet4AddressHTH(lease.netAddr), lease.prefixLength, 3961 0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */, 3962 lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */); 3963 3964 final MacAddress macAddress = MacAddress.fromBytes(lease.hwAddr); 3965 3966 final AddressInfo addressInfo = new TetheredClient.AddressInfo(address, lease.hostname); 3967 clients.add(new TetheredClient( 3968 macAddress, 3969 Collections.singletonList(addressInfo), 3970 type)); 3971 } 3972 3973 return clients; 3974 } 3975 createDhcpLeaseParcelable(final String clientId, final MacAddress hwAddr, final String netAddr, final int prefixLength, final long expTime, final String hostname)3976 private DhcpLeaseParcelable createDhcpLeaseParcelable(final String clientId, 3977 final MacAddress hwAddr, final String netAddr, final int prefixLength, 3978 final long expTime, final String hostname) throws Exception { 3979 final DhcpLeaseParcelable lease = new DhcpLeaseParcelable(); 3980 lease.clientId = clientId.getBytes(); 3981 lease.hwAddr = hwAddr.toByteArray(); 3982 lease.netAddr = inet4AddressToIntHTH( 3983 (Inet4Address) InetAddresses.parseNumericAddress(netAddr)); 3984 lease.prefixLength = prefixLength; 3985 lease.expTime = expTime; 3986 lease.hostname = hostname; 3987 3988 return lease; 3989 } 3990 3991 @Test 3992 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testBluetoothTethering()3993 public void testBluetoothTethering() throws Exception { 3994 initTetheringOnTestThread(); 3995 3996 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 3997 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 3998 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 3999 TEST_CALLER_PKG, result); 4000 mLooper.dispatchAll(); 4001 verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */); 4002 result.assertHasResult(); 4003 4004 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 4005 mLooper.dispatchAll(); 4006 verifyNetdCommandForBtSetup(); 4007 4008 // If PAN disconnect, tethering should also be stopped. 4009 mTetheredInterfaceCallbackShim.onUnavailable(); 4010 mLooper.dispatchAll(); 4011 verifyNetdCommandForBtTearDown(); 4012 4013 // Tethering could restart if PAN reconnect. 4014 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 4015 mLooper.dispatchAll(); 4016 verifyNetdCommandForBtSetup(); 4017 4018 // Pretend that bluetooth tethering was disabled. 4019 mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */); 4020 mTethering.stopTethering(TETHERING_BLUETOOTH); 4021 mLooper.dispatchAll(); 4022 verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */); 4023 4024 verifyNetdCommandForBtTearDown(); 4025 } 4026 4027 @Test 4028 @IgnoreAfter(Build.VERSION_CODES.S_V2) testBluetoothTetheringBeforeT()4029 public void testBluetoothTetheringBeforeT() throws Exception { 4030 initTetheringOnTestThread(); 4031 4032 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 4033 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 4034 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4035 TEST_CALLER_PKG, result); 4036 mLooper.dispatchAll(); 4037 verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */); 4038 result.assertHasResult(); 4039 4040 mTethering.interfaceAdded(TEST_BT_IFNAME); 4041 mLooper.dispatchAll(); 4042 4043 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 4044 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true); 4045 final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 4046 mTethering.legacyTether(TEST_BT_IFNAME, tetherResult); 4047 mLooper.dispatchAll(); 4048 tetherResult.assertHasResult(); 4049 4050 verifyNetdCommandForBtSetup(); 4051 4052 // Turning tethering on a second time does not bind to the PAN service again, since it's 4053 // already bound. 4054 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 4055 final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); 4056 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4057 TEST_CALLER_PKG, secondResult); 4058 mLooper.dispatchAll(); 4059 verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */); 4060 secondResult.assertHasResult(); 4061 4062 mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */); 4063 mTethering.stopTethering(TETHERING_BLUETOOTH); 4064 mLooper.dispatchAll(); 4065 final ResultListener untetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 4066 mTethering.legacyUntether(TEST_BT_IFNAME, untetherResult); 4067 mLooper.dispatchAll(); 4068 untetherResult.assertHasResult(); 4069 verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */); 4070 4071 verifyNetdCommandForBtTearDown(); 4072 } 4073 4074 @Test testBluetoothServiceDisconnects()4075 public void testBluetoothServiceDisconnects() throws Exception { 4076 initTetheringOnTestThread(); 4077 final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR); 4078 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 4079 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4080 TEST_CALLER_PKG, result); 4081 mLooper.dispatchAll(); 4082 ServiceListener panListener = verifySetBluetoothTethering(true /* enable */, 4083 true /* bindToPanService */); 4084 result.assertHasResult(); 4085 4086 mTethering.interfaceAdded(TEST_BT_IFNAME); 4087 mLooper.dispatchAll(); 4088 4089 if (isAtLeastT()) { 4090 mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME); 4091 mLooper.dispatchAll(); 4092 } else { 4093 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 4094 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true); 4095 final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR); 4096 mTethering.legacyTether(TEST_BT_IFNAME, tetherResult); 4097 mLooper.dispatchAll(); 4098 tetherResult.assertHasResult(); 4099 } 4100 4101 verifyNetdCommandForBtSetup(); 4102 4103 panListener.onServiceDisconnected(BluetoothProfile.PAN); 4104 mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false); 4105 mLooper.dispatchAll(); 4106 4107 verifyNetdCommandForBtTearDown(); 4108 } 4109 4110 @Test testPendingPanEnableRequestFailedUponDisableRequest()4111 public void testPendingPanEnableRequestFailedUponDisableRequest() throws Exception { 4112 initTetheringOnTestThread(); 4113 4114 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 4115 final ResultListener failedEnable = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL); 4116 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4117 TEST_CALLER_PKG, failedEnable); 4118 mLooper.dispatchAll(); 4119 failedEnable.assertDoesNotHaveResult(); 4120 4121 // Stop tethering before the pan service connects. This should fail the enable request. 4122 mTethering.stopTethering(TETHERING_BLUETOOTH); 4123 mLooper.dispatchAll(); 4124 failedEnable.assertHasResult(); 4125 } 4126 4127 @Test testStartBluetoothTetheringFailsWhenTheresAnExistingRequestWaitingForPanService()4128 public void testStartBluetoothTetheringFailsWhenTheresAnExistingRequestWaitingForPanService() 4129 throws Exception { 4130 mTetheringWithSoftApConfigEnabled = false; 4131 initTetheringOnTestThread(); 4132 4133 mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */); 4134 final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR); 4135 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4136 TEST_CALLER_PKG, firstResult); 4137 mLooper.dispatchAll(); 4138 firstResult.assertDoesNotHaveResult(); 4139 4140 // Second request should fail. 4141 final ResultListener secondResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL); 4142 mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH), 4143 TEST_CALLER_PKG, secondResult); 4144 mLooper.dispatchAll(); 4145 secondResult.assertHasResult(); 4146 firstResult.assertDoesNotHaveResult(); 4147 4148 // Bind to PAN service should succeed for first listener only. If the second result is 4149 // called with TETHER_ERROR_NO_ERROR, ResultListener will fail an assertion. 4150 verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */); 4151 firstResult.assertHasResult(); 4152 } 4153 mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn)4154 private void mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn) { 4155 when(mBluetoothAdapter.isEnabled()).thenReturn(bluetoothOn); 4156 when(mBluetoothPan.isTetheringOn()).thenReturn(tetheringOn); 4157 } 4158 verifyNetdCommandForBtSetup()4159 private void verifyNetdCommandForBtSetup() throws Exception { 4160 if (isAtLeastT()) { 4161 verify(mNetd).interfaceSetCfg(argThat(cfg -> TEST_BT_IFNAME.equals(cfg.ifName) 4162 && assertContainsFlag(cfg.flags, INetd.IF_STATE_UP))); 4163 } 4164 verify(mNetd).tetherInterfaceAdd(TEST_BT_IFNAME); 4165 if (isTetheringNetworkAgentFeatureEnabled()) { 4166 verify(mNetd, never()).networkAddInterface(anyInt(), anyString()); 4167 verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString()); 4168 } else { 4169 verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME); 4170 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME), 4171 anyString(), anyString()); 4172 } 4173 verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME); 4174 verify(mNetd).tetherStartWithConfiguration(any()); 4175 if (isTetheringNetworkAgentFeatureEnabled()) { 4176 verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString()); 4177 } else { 4178 verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME), 4179 anyString(), anyString()); 4180 } 4181 verifyNoMoreInteractions(mNetd); 4182 reset(mNetd); 4183 } 4184 assertContainsFlag(String[] flags, String match)4185 private boolean assertContainsFlag(String[] flags, String match) { 4186 for (String flag : flags) { 4187 if (flag.equals(match)) return true; 4188 } 4189 return false; 4190 } 4191 verifyNetdCommandForBtTearDown()4192 private void verifyNetdCommandForBtTearDown() throws Exception { 4193 verify(mNetd).tetherApplyDnsInterfaces(); 4194 verify(mNetd).tetherInterfaceRemove(TEST_BT_IFNAME); 4195 if (isTetheringNetworkAgentFeatureEnabled()) { 4196 verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString()); 4197 } else { 4198 verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME); 4199 } 4200 // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only 4201 // happen after T. Before T, the interface configuration control in bluetooth side. 4202 verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg( 4203 any(InterfaceConfigurationParcel.class)); 4204 verify(mNetd).tetherStop(); 4205 verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME); 4206 reset(mNetd); 4207 } 4208 4209 // If bindToPanService is true, this function would return ServiceListener which could notify 4210 // PanService is connected or disconnected. verifySetBluetoothTethering(final boolean enable, final boolean bindToPanService)4211 private ServiceListener verifySetBluetoothTethering(final boolean enable, 4212 final boolean bindToPanService) throws Exception { 4213 ServiceListener listener = null; 4214 verify(mBluetoothAdapter, atLeastOnce()).isEnabled(); 4215 if (bindToPanService) { 4216 final ArgumentCaptor<ServiceListener> listenerCaptor = 4217 ArgumentCaptor.forClass(ServiceListener.class); 4218 verify(mBluetoothAdapter).getProfileProxy(eq(mServiceContext), listenerCaptor.capture(), 4219 eq(BluetoothProfile.PAN)); 4220 listener = listenerCaptor.getValue(); 4221 listener.onServiceConnected(BluetoothProfile.PAN, mBluetoothPan); 4222 mLooper.dispatchAll(); 4223 } else { 4224 verify(mBluetoothAdapter, never()).getProfileProxy(eq(mServiceContext), any(), 4225 anyInt()); 4226 } 4227 4228 if (isAtLeastT()) { 4229 if (enable) { 4230 final ArgumentCaptor<TetheredInterfaceCallbackShim> callbackCaptor = 4231 ArgumentCaptor.forClass(TetheredInterfaceCallbackShim.class); 4232 verify(mBluetoothPanShim).requestTetheredInterface(any(), callbackCaptor.capture()); 4233 mTetheredInterfaceCallbackShim = callbackCaptor.getValue(); 4234 } else { 4235 verify(mTetheredInterfaceRequestShim).release(); 4236 } 4237 } else { 4238 verify(mBluetoothPan).setBluetoothTethering(enable); 4239 } 4240 verify(mBluetoothPan).isTetheringOn(); 4241 verifyNoMoreInteractions(mBluetoothAdapter, mBluetoothPan); 4242 reset(mBluetoothAdapter, mBluetoothPan); 4243 4244 return listener; 4245 } 4246 runDualStackUsbTethering(final String expectedIface)4247 private void runDualStackUsbTethering(final String expectedIface) throws Exception { 4248 when(mNetd.interfaceGetList()).thenReturn(new String[] {expectedIface}); 4249 when(mRouterAdvertisementDaemon.start()) 4250 .thenReturn(true); 4251 final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); 4252 runUsbTethering(upstreamState); 4253 4254 verify(mNetd).interfaceGetList(); 4255 verify(mRoutingCoordinatorManager).addInterfaceForward(expectedIface, TEST_MOBILE_IFNAME); 4256 4257 verify(mRouterAdvertisementDaemon).start(); 4258 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks( 4259 any(), any()); 4260 sendIPv6TetherUpdates(upstreamState); 4261 assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */); 4262 verify(mRouterAdvertisementDaemon).buildNewRa(any(), notNull()); 4263 verify(mNetd).tetherApplyDnsInterfaces(); 4264 } 4265 forceUsbTetheringUse(final int function)4266 private void forceUsbTetheringUse(final int function) { 4267 setSetting(TETHER_FORCE_USB_FUNCTIONS, function); 4268 } 4269 setSetting(final String key, final int value)4270 private void setSetting(final String key, final int value) { 4271 Settings.Global.putInt(mContentResolver, key, value); 4272 final ContentObserver observer = mTethering.getSettingsObserverForTest(); 4273 observer.onChange(false /* selfChange */, Settings.Global.getUriFor(key)); 4274 mLooper.dispatchAll(); 4275 } 4276 verifyUsbTetheringStopDueToSettingChange(final String iface)4277 private void verifyUsbTetheringStopDueToSettingChange(final String iface) { 4278 verify(mUsbManager, times(2)).setCurrentFunctions(UsbManager.FUNCTION_NONE); 4279 mTethering.interfaceRemoved(iface); 4280 sendUsbBroadcast(true, true, -1 /* no functions enabled */); 4281 reset(mUsbManager, mNetd, mDhcpServer, mRouterAdvertisementDaemon, 4282 mIPv6TetheringCoordinator, mDadProxy); 4283 } 4284 4285 @Test testUsbFunctionConfigurationChange()4286 public void testUsbFunctionConfigurationChange() throws Exception { 4287 initTetheringOnTestThread(); 4288 // Run TETHERING_NCM. 4289 runNcmTethering(); 4290 verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( 4291 any(), any()); 4292 verify(mTetheringMetrics).createBuilder(eq(TETHERING_NCM), anyString()); 4293 verify(mTetheringMetrics, times(1)).maybeUpdateUpstreamType(any()); 4294 4295 // Change the USB tethering function to NCM. Because the USB tethering function was set to 4296 // RNDIS (the default), tethering is stopped. 4297 forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION); 4298 verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME); 4299 verify(mTetheringMetrics).updateErrorCode(anyInt(), eq(TETHER_ERROR_NO_ERROR)); 4300 verify(mTetheringMetrics).sendReport(eq(TETHERING_NCM)); 4301 4302 // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be 4303 // available. 4304 final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL); 4305 mTethering.startTethering(createTetheringRequest(TETHERING_NCM), TEST_CALLER_PKG, 4306 ncmResult); 4307 mLooper.dispatchAll(); 4308 ncmResult.assertHasResult(); 4309 verify(mTetheringMetrics, times(2)).createBuilder(eq(TETHERING_NCM), anyString()); 4310 verify(mTetheringMetrics, times(1)).maybeUpdateUpstreamType(any()); 4311 verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_NCM), 4312 eq(TETHER_ERROR_SERVICE_UNAVAIL)); 4313 verify(mTetheringMetrics, times(2)).sendReport(eq(TETHERING_NCM)); 4314 4315 // Run TETHERING_USB with ncm configuration. 4316 runDualStackUsbTethering(TEST_NCM_IFNAME); 4317 4318 // Change configuration to rndis. 4319 forceUsbTetheringUse(TETHER_USB_RNDIS_FUNCTION); 4320 verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME); 4321 4322 // Run TETHERING_USB with rndis configuration. 4323 runDualStackUsbTethering(TEST_RNDIS_IFNAME); 4324 runStopUSBTethering(); 4325 } 4326 getAllSupportedTetheringTypes()4327 public static ArraySet<Integer> getAllSupportedTetheringTypes() { 4328 return new ArraySet<>(new Integer[] { TETHERING_USB, TETHERING_NCM, TETHERING_WIFI, 4329 TETHERING_WIFI_P2P, TETHERING_BLUETOOTH, TETHERING_ETHERNET }); 4330 } 4331 setUserRestricted(boolean restricted)4332 private void setUserRestricted(boolean restricted) { 4333 final Bundle restrictions = new Bundle(); 4334 restrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, restricted); 4335 when(mUserManager.getUserRestrictions()).thenReturn(restrictions); 4336 when(mUserManager.hasUserRestriction( 4337 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(restricted); 4338 4339 final Intent intent = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); 4340 mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); 4341 mLooper.dispatchAll(); 4342 } 4343 4344 @Test testTetheringSupported()4345 public void testTetheringSupported() throws Exception { 4346 initTetheringOnTestThread(); 4347 final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes(); 4348 // Check tethering is supported after initialization. 4349 TestTetheringEventCallback callback = new TestTetheringEventCallback(); 4350 mTethering.registerTetheringEventCallback(callback); 4351 mLooper.dispatchAll(); 4352 verifySupported(callback, expectedTypes); 4353 4354 // Could change tethering supported by settings. 4355 setSetting(Settings.Global.TETHER_SUPPORTED, 0); 4356 verifySupported(callback, new ArraySet<>()); 4357 setSetting(Settings.Global.TETHER_SUPPORTED, 1); 4358 verifySupported(callback, expectedTypes); 4359 4360 // Could change tethering supported by user restriction. 4361 setUserRestricted(true /* restricted */); 4362 verifySupported(callback, new ArraySet<>()); 4363 setUserRestricted(false /* restricted */); 4364 verifySupported(callback, expectedTypes); 4365 4366 // Usb tethering is not supported: 4367 expectedTypes.remove(TETHERING_USB); 4368 when(mResources.getStringArray(R.array.config_tether_usb_regexs)) 4369 .thenReturn(new String[0]); 4370 sendConfigurationChanged(); 4371 verifySupported(callback, expectedTypes); 4372 // Wifi tethering is not supported: 4373 expectedTypes.remove(TETHERING_WIFI); 4374 when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) 4375 .thenReturn(new String[0]); 4376 sendConfigurationChanged(); 4377 verifySupported(callback, expectedTypes); 4378 // Bluetooth tethering is not supported: 4379 expectedTypes.remove(TETHERING_BLUETOOTH); 4380 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) 4381 .thenReturn(new String[0]); 4382 4383 if (isAtLeastT()) { 4384 sendConfigurationChanged(); 4385 verifySupported(callback, expectedTypes); 4386 4387 // P2p tethering is not supported: 4388 expectedTypes.remove(TETHERING_WIFI_P2P); 4389 when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) 4390 .thenReturn(new String[0]); 4391 sendConfigurationChanged(); 4392 verifySupported(callback, expectedTypes); 4393 // Ncm tethering is not supported: 4394 expectedTypes.remove(TETHERING_NCM); 4395 when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) 4396 .thenReturn(new String[0]); 4397 sendConfigurationChanged(); 4398 verifySupported(callback, expectedTypes); 4399 // Ethernet tethering (last supported type) is not supported: 4400 expectedTypes.remove(TETHERING_ETHERNET); 4401 mForceEthernetServiceUnavailable = true; 4402 sendConfigurationChanged(); 4403 verifySupported(callback, new ArraySet<>()); 4404 } else { 4405 // If wifi, usb and bluetooth are all not supported, all the types are not supported. 4406 sendConfigurationChanged(); 4407 verifySupported(callback, new ArraySet<>()); 4408 } 4409 } 4410 verifySupported(final TestTetheringEventCallback callback, final ArraySet<Integer> expectedTypes)4411 private void verifySupported(final TestTetheringEventCallback callback, 4412 final ArraySet<Integer> expectedTypes) { 4413 assertEquals(expectedTypes.size() > 0, mTethering.isTetheringSupported()); 4414 callback.expectSupportedTetheringTypes(expectedTypes); 4415 } 4416 4417 @Test testIpv4AddressForSapAndLohsConcurrency()4418 public void testIpv4AddressForSapAndLohsConcurrency() throws Exception { 4419 initTetheringOnTestThread(); 4420 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 4421 mTethering.startTethering(request, TEST_CALLER_PKG, null); 4422 mLooper.dispatchAll(); 4423 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 4424 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 4425 4426 ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor = 4427 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); 4428 verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture()); 4429 InterfaceConfigurationParcel ifaceConfig = ifaceConfigCaptor.getValue(); 4430 final IpPrefix sapPrefix = new IpPrefix( 4431 InetAddresses.parseNumericAddress(ifaceConfig.ipv4Addr), ifaceConfig.prefixLength); 4432 4433 mTethering.interfaceStatusChanged(TEST_WLAN2_IFNAME, true); 4434 sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN2_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); 4435 4436 ifaceConfigCaptor = ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); 4437 verify(mNetd, times(2)).interfaceSetCfg(ifaceConfigCaptor.capture()); 4438 ifaceConfig = ifaceConfigCaptor.getValue(); 4439 final IpPrefix lohsPrefix = new IpPrefix( 4440 InetAddresses.parseNumericAddress(ifaceConfig.ipv4Addr), ifaceConfig.prefixLength); 4441 assertFalse(sapPrefix.equals(lohsPrefix)); 4442 } 4443 4444 @Test testFailStartTetheredHotspotWithoutRequest()4445 public void testFailStartTetheredHotspotWithoutRequest() throws Exception { 4446 mTetheringWithSoftApConfigEnabled = false; 4447 initTetheringOnTestThread(); 4448 when(mWifiManager.startTetheredHotspot(null)).thenReturn(false); 4449 4450 ResultListener result = new ResultListener(TETHER_ERROR_INTERNAL_ERROR); 4451 mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG, result); 4452 mLooper.dispatchAll(); 4453 verify(mWifiManager).startTetheredHotspot(null); 4454 verifyNoMoreInteractions(mWifiManager); 4455 result.assertHasResult(); 4456 assertTrue(mTethering.getPendingTetheringRequests().isEmpty()); 4457 } 4458 4459 @Test testWifiTetheringWhenP2pActive()4460 public void testWifiTetheringWhenP2pActive() throws Exception { 4461 initTetheringOnTestThread(); 4462 // Enable wifi P2P. 4463 sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); 4464 verifyInterfaceServingModeStarted(TEST_P2P_IFNAME, false); 4465 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER); 4466 verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); 4467 verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks(); 4468 // Verify never enable upstream if only P2P active. 4469 verify(mUpstreamNetworkMonitor, never()).setTryCell(true); 4470 assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME)); 4471 4472 // Emulate pressing the WiFi tethering button. 4473 TetheringRequest request = createTetheringRequest(TETHERING_WIFI); 4474 mTethering.startTethering(request, TEST_CALLER_PKG, null); 4475 mLooper.dispatchAll(); 4476 verifyWifiTetheringRequested(); 4477 4478 mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); 4479 sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME); 4480 4481 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); 4482 verify(mWifiManager).updateInterfaceIpState( 4483 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); 4484 4485 verify(mWifiManager).updateInterfaceIpState(TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); 4486 verifyNoMoreInteractions(mWifiManager); 4487 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); 4488 4489 verify(mUpstreamNetworkMonitor).setTryCell(true); 4490 } 4491 4492 // TODO: Test that a request for hotspot mode doesn't interfere with an 4493 // already operating tethering mode interface. 4494 4495 @Test testVirtualTetheringWithInterfaceName()4496 public void testVirtualTetheringWithInterfaceName() throws Exception { 4497 initTetheringOnTestThread(); 4498 final TetheringRequest virtualTetheringRequest = 4499 createTetheringRequest(TETHERING_VIRTUAL, null, null, false, 4500 CONNECTIVITY_SCOPE_GLOBAL, TEST_VIRT_IFNAME); 4501 assertEquals(TEST_VIRT_IFNAME, virtualTetheringRequest.getInterfaceName()); 4502 mTethering.startTethering(virtualTetheringRequest, TEST_CALLER_PKG, null); 4503 mLooper.dispatchAll(); 4504 assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_VIRT_IFNAME); 4505 mTethering.stopTethering(TETHERING_VIRTUAL); 4506 mLooper.dispatchAll(); 4507 } 4508 } 4509