1 /* 2 * Copyright (C) 2010 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.PERMISSION_GRANTED; 22 import static android.hardware.usb.UsbManager.USB_CONFIGURED; 23 import static android.hardware.usb.UsbManager.USB_CONNECTED; 24 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM; 25 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; 26 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 27 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 28 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; 29 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; 30 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; 31 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL; 32 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; 33 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER; 34 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER; 35 import static android.net.TetheringManager.EXTRA_ERRORED_TETHER; 36 import static android.net.TetheringManager.TETHERING_BLUETOOTH; 37 import static android.net.TetheringManager.TETHERING_ETHERNET; 38 import static android.net.TetheringManager.TETHERING_INVALID; 39 import static android.net.TetheringManager.TETHERING_NCM; 40 import static android.net.TetheringManager.TETHERING_USB; 41 import static android.net.TetheringManager.TETHERING_VIRTUAL; 42 import static android.net.TetheringManager.TETHERING_WIFI; 43 import static android.net.TetheringManager.TETHERING_WIFI_P2P; 44 import static android.net.TetheringManager.TETHERING_WIGIG; 45 import static android.net.TetheringManager.TETHER_ERROR_BLUETOOTH_SERVICE_PENDING; 46 import static android.net.TetheringManager.TETHER_ERROR_DUPLICATE_REQUEST; 47 import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR; 48 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; 49 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; 50 import static android.net.TetheringManager.TETHER_ERROR_SOFT_AP_CALLBACK_PENDING; 51 import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE; 52 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; 53 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST; 54 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE; 55 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; 56 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; 57 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; 58 import static android.net.TetheringManager.TetheringRequest.REQUEST_TYPE_PLACEHOLDER; 59 import static android.net.TetheringManager.toIfaces; 60 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; 61 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; 62 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; 63 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR; 64 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 65 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 66 import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED; 67 import static android.net.wifi.WifiManager.SoftApCallback; 68 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 69 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; 70 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 71 72 import static com.android.networkstack.tethering.RequestTracker.AddResult.FAILURE_DUPLICATE_REQUEST_ERROR; 73 import static com.android.networkstack.tethering.RequestTracker.AddResult.FAILURE_DUPLICATE_REQUEST_RESTART; 74 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS; 75 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; 76 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.isCellular; 77 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED; 78 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI; 79 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P; 80 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS; 81 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS; 82 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WITH_PLACEHOLDER_REQUEST; 83 import static com.android.networkstack.tethering.util.TetheringMessageBase.BASE_MAIN_SM; 84 import static com.android.networkstack.tethering.util.TetheringUtils.createImplicitLocalOnlyTetheringRequest; 85 import static com.android.networkstack.tethering.util.TetheringUtils.createLegacyGlobalScopeTetheringRequest; 86 import static com.android.networkstack.tethering.util.TetheringUtils.createPlaceholderRequest; 87 88 import android.app.usage.NetworkStatsManager; 89 import android.bluetooth.BluetoothAdapter; 90 import android.bluetooth.BluetoothPan; 91 import android.bluetooth.BluetoothProfile; 92 import android.bluetooth.BluetoothProfile.ServiceListener; 93 import android.content.BroadcastReceiver; 94 import android.content.Context; 95 import android.content.Intent; 96 import android.content.IntentFilter; 97 import android.content.pm.PackageManager; 98 import android.database.ContentObserver; 99 import android.hardware.usb.UsbManager; 100 import android.net.ConnectivityManager; 101 import android.net.EthernetManager; 102 import android.net.IIntResultListener; 103 import android.net.INetd; 104 import android.net.ITetheringEventCallback; 105 import android.net.IpPrefix; 106 import android.net.LinkAddress; 107 import android.net.LinkProperties; 108 import android.net.Network; 109 import android.net.NetworkInfo; 110 import android.net.TetherStatesParcel; 111 import android.net.TetheredClient; 112 import android.net.TetheringCallbackStartedParcel; 113 import android.net.TetheringConfigurationParcel; 114 import android.net.TetheringInterface; 115 import android.net.TetheringManager.TetheringRequest; 116 import android.net.Uri; 117 import android.net.ip.IpServer; 118 import android.net.wifi.SoftApState; 119 import android.net.wifi.WifiClient; 120 import android.net.wifi.WifiManager; 121 import android.net.wifi.p2p.WifiP2pGroup; 122 import android.net.wifi.p2p.WifiP2pInfo; 123 import android.net.wifi.p2p.WifiP2pManager; 124 import android.os.Binder; 125 import android.os.Bundle; 126 import android.os.Handler; 127 import android.os.Looper; 128 import android.os.Message; 129 import android.os.Process; 130 import android.os.RemoteCallbackList; 131 import android.os.RemoteException; 132 import android.os.ResultReceiver; 133 import android.os.ServiceSpecificException; 134 import android.os.UserHandle; 135 import android.os.UserManager; 136 import android.provider.Settings; 137 import android.telephony.PhoneStateListener; 138 import android.telephony.TelephonyManager; 139 import android.text.TextUtils; 140 import android.util.ArrayMap; 141 import android.util.Log; 142 import android.util.SparseArray; 143 144 import androidx.annotation.NonNull; 145 import androidx.annotation.Nullable; 146 147 import com.android.internal.annotations.VisibleForTesting; 148 import com.android.internal.util.IndentingPrintWriter; 149 import com.android.internal.util.MessageUtils; 150 import com.android.internal.util.State; 151 import com.android.internal.util.StateMachine; 152 import com.android.modules.utils.build.SdkLevel; 153 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 154 import com.android.net.module.util.CollectionUtils; 155 import com.android.net.module.util.HandlerUtils; 156 import com.android.net.module.util.NetdUtils; 157 import com.android.net.module.util.RoutingCoordinatorManager; 158 import com.android.net.module.util.SharedLog; 159 import com.android.net.module.util.TerribleErrorLog; 160 import com.android.networkstack.apishim.common.BluetoothPanShim; 161 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim; 162 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim; 163 import com.android.networkstack.apishim.common.UnsupportedApiLevelException; 164 import com.android.networkstack.tethering.metrics.TetheringMetrics; 165 import com.android.networkstack.tethering.metrics.TetheringStatsLog; 166 import com.android.networkstack.tethering.util.InterfaceSet; 167 import com.android.networkstack.tethering.util.PrefixUtils; 168 import com.android.networkstack.tethering.util.VersionedBroadcastListener; 169 import com.android.networkstack.tethering.wear.WearableConnectionManager; 170 171 import java.io.FileDescriptor; 172 import java.io.PrintWriter; 173 import java.net.InetAddress; 174 import java.util.ArrayList; 175 import java.util.Arrays; 176 import java.util.Collection; 177 import java.util.Collections; 178 import java.util.HashSet; 179 import java.util.List; 180 import java.util.Objects; 181 import java.util.Set; 182 import java.util.concurrent.Executor; 183 import java.util.concurrent.RejectedExecutionException; 184 185 /** 186 * 187 * This class holds much of the business logic to allow Android devices 188 * to act as IP gateways via USB, BT, and WiFi interfaces. 189 */ 190 public class Tethering { 191 192 private static final String TAG = Tethering.class.getSimpleName(); 193 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); 194 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); 195 196 private static final Class[] sMessageClasses = { 197 Tethering.class, TetherMainSM.class, IpServer.class 198 }; 199 private static final SparseArray<String> sMagicDecoderRing = 200 MessageUtils.findMessageNames(sMessageClasses); 201 202 private static final int DUMP_TIMEOUT_MS = 10_000; 203 204 // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h 205 private static final int NETID_UNSET = 0; 206 207 private static class TetherState { 208 public final IpServer ipServer; 209 public int lastState; 210 public int lastError; 211 // This field only valid for TETHERING_USB and TETHERING_NCM. 212 // TODO: Change this from boolean to int for extension. 213 public final boolean isNcm; 214 TetherState(IpServer ipServer, boolean isNcm)215 TetherState(IpServer ipServer, boolean isNcm) { 216 this.ipServer = ipServer; 217 // Assume all state machines start out available and with no errors. 218 lastState = IpServer.STATE_AVAILABLE; 219 lastError = TETHER_ERROR_NO_ERROR; 220 this.isNcm = isNcm; 221 } 222 isCurrentlyServing()223 public boolean isCurrentlyServing() { 224 switch (lastState) { 225 case IpServer.STATE_TETHERED: 226 case IpServer.STATE_LOCAL_ONLY: 227 return true; 228 default: 229 return false; 230 } 231 } 232 } 233 234 /** 235 * Cookie added when registering {@link android.net.TetheringManager.TetheringEventCallback}. 236 */ 237 private static class CallbackCookie { 238 public final int uid; 239 public final boolean hasSystemPrivilege; 240 CallbackCookie(int uid, boolean hasSystemPrivilege)241 private CallbackCookie(int uid, boolean hasSystemPrivilege) { 242 this.uid = uid; 243 this.hasSystemPrivilege = hasSystemPrivilege; 244 } 245 } 246 247 private final SharedLog mLog = new SharedLog(TAG); 248 private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks = 249 new RemoteCallbackList<>(); 250 private final RequestTracker mRequestTracker; 251 252 private final Context mContext; 253 private final ArrayMap<String, TetherState> mTetherStates; 254 private final BroadcastReceiver mStateReceiver; 255 private final Looper mLooper; 256 private final TetherMainSM mTetherMainSM; 257 private final OffloadController mOffloadController; 258 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor; 259 private final VersionedBroadcastListener mCarrierConfigChange; 260 private final TetheringDependencies mDeps; 261 private final EntitlementManager mEntitlementMgr; 262 private final Handler mHandler; 263 private final INetd mNetd; 264 private final NetdCallback mNetdCallback; 265 private final RoutingCoordinatorManager mRoutingCoordinator; 266 private final UserRestrictionActionListener mTetheringRestriction; 267 private final ActiveDataSubIdListener mActiveDataSubIdListener; 268 private final ConnectedClientsTracker mConnectedClientsTracker; 269 private final TetheringThreadExecutor mExecutor; 270 private final TetheringNotificationUpdater mNotificationUpdater; 271 private final UserManager mUserManager; 272 private final BpfCoordinator mBpfCoordinator; 273 private final TetheringMetrics mTetheringMetrics; 274 private final WearableConnectionManager mWearableConnectionManager; 275 private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; 276 277 private volatile TetheringConfiguration mConfig; 278 private InterfaceSet mCurrentUpstreamIfaceSet; 279 280 private boolean mRndisEnabled; // track the RNDIS function enabled state 281 private boolean mNcmEnabled; // track the NCM function enabled state 282 private Network mTetherUpstream; 283 private boolean mDataSaverEnabled = false; 284 private String mWifiP2pTetherInterface = null; 285 private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED; 286 287 private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest; 288 private TetheredInterfaceRequestShim mBluetoothIfaceRequest; 289 private String mConfiguredEthernetIface; 290 private String mConfiguredBluetoothIface; 291 private String mConfiguredVirtualIface; 292 private EthernetCallback mEthernetCallback; 293 private TetheredInterfaceCallbackShim mBluetoothCallback; 294 private SettingsObserver mSettingsObserver; 295 private BluetoothPan mBluetoothPan; 296 private PanServiceListener mBluetoothPanListener; 297 // Pending listener for starting Bluetooth tethering before the PAN service is connected. Once 298 // the service is connected, the bluetooth iface will be requested and the listener will be 299 // called. 300 private IIntResultListener mPendingPanRequestListener; 301 // AIDL doesn't support Set<Integer>. Maintain a int bitmap here. When the bitmap is passed to 302 // TetheringManager, TetheringManager would convert it to a set of Integer types. 303 // mSupportedTypeBitmap should always be updated inside tethering internal thread but it may be 304 // read from binder thread which called TetheringService directly. 305 private volatile long mSupportedTypeBitmap; 306 Tethering(TetheringDependencies deps)307 public Tethering(TetheringDependencies deps) { 308 mLog.mark("Tethering.constructed"); 309 mDeps = deps; 310 mContext = mDeps.getContext(); 311 mNetd = mDeps.getINetd(mContext, mLog); 312 mRoutingCoordinator = mDeps.getRoutingCoordinator(mContext, mLog); 313 mLooper = mDeps.makeTetheringLooper(); 314 mNotificationUpdater = mDeps.makeNotificationUpdater(mContext, mLooper); 315 mTetheringMetrics = mDeps.makeTetheringMetrics(mContext); 316 mRequestTracker = new RequestTracker(isTetheringWithSoftApConfigEnabled()); 317 318 mTetherStates = new ArrayMap<>(); 319 mConnectedClientsTracker = new ConnectedClientsTracker(); 320 321 mTetherMainSM = new TetherMainSM("TetherMain", mLooper, deps); 322 mTetherMainSM.start(); 323 324 mHandler = mTetherMainSM.getHandler(); 325 mOffloadController = mDeps.makeOffloadController(mHandler, mLog, 326 new OffloadController.Dependencies() { 327 328 @Override 329 public TetheringConfiguration getTetherConfig() { 330 return mConfig; 331 } 332 }); 333 mUpstreamNetworkMonitor = mDeps.makeUpstreamNetworkMonitor(mContext, mHandler, mLog, 334 (what, obj) -> { 335 mTetherMainSM.sendMessage(TetherMainSM.EVENT_UPSTREAM_CALLBACK, what, 0, obj); 336 }); 337 338 IntentFilter filter = new IntentFilter(); 339 filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); 340 // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream 341 // permission is changed according to entitlement check result. 342 mEntitlementMgr = mDeps.makeEntitlementManager(mContext, mHandler, mLog, 343 () -> mTetherMainSM.sendMessage( 344 TetherMainSM.EVENT_UPSTREAM_PERMISSION_CHANGED)); 345 mEntitlementMgr.setOnTetherProvisioningFailedListener((downstream, reason) -> { 346 mLog.log("OBSERVED OnTetherProvisioningFailed : " + reason); 347 stopTethering(downstream); 348 }); 349 mEntitlementMgr.setTetheringConfigurationFetcher(() -> { 350 return mConfig; 351 }); 352 353 mCarrierConfigChange = new VersionedBroadcastListener( 354 "CarrierConfigChangeListener", mContext, mHandler, filter, 355 (Intent ignored) -> { 356 mLog.log("OBSERVED carrier config change"); 357 updateConfiguration(); 358 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); 359 }); 360 361 mSettingsObserver = new SettingsObserver(mContext, mHandler); 362 mSettingsObserver.startObserve(); 363 364 mStateReceiver = new StateReceiver(); 365 366 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 367 mTetheringRestriction = new UserRestrictionActionListener( 368 mUserManager, this, mNotificationUpdater); 369 mExecutor = new TetheringThreadExecutor(mHandler); 370 mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor); 371 mNetdCallback = new NetdCallback(); 372 373 // Load tethering configuration. 374 updateConfiguration(); 375 mConfig.readEnableSyncSM(mContext); 376 377 // Must be initialized after tethering configuration is loaded because BpfCoordinator 378 // constructor needs to use the configuration. 379 mBpfCoordinator = mDeps.makeBpfCoordinator( 380 new BpfCoordinator.Dependencies() { 381 @NonNull 382 public Handler getHandler() { 383 return mHandler; 384 } 385 386 @NonNull 387 public Context getContext() { 388 return mContext; 389 } 390 391 @NonNull 392 public INetd getNetd() { 393 return mNetd; 394 } 395 396 @NonNull 397 public NetworkStatsManager getNetworkStatsManager() { 398 return mContext.getSystemService(NetworkStatsManager.class); 399 } 400 401 @NonNull 402 public SharedLog getSharedLog() { 403 return mLog; 404 } 405 406 @Nullable 407 public TetheringConfiguration getTetherConfig() { 408 return mConfig; 409 } 410 }); 411 412 if (SdkLevel.isAtLeastT() && mConfig.isWearTetheringEnabled()) { 413 mWearableConnectionManager = mDeps.makeWearableConnectionManager(mContext); 414 } else { 415 mWearableConnectionManager = null; 416 } 417 418 startStateMachineUpdaters(); 419 } 420 421 private class SettingsObserver extends ContentObserver { 422 private final Uri mForceUsbFunctions; 423 private final Uri mTetherSupported; 424 private final Context mContext; 425 SettingsObserver(Context ctx, Handler handler)426 SettingsObserver(Context ctx, Handler handler) { 427 super(handler); 428 mContext = ctx; 429 mForceUsbFunctions = Settings.Global.getUriFor(TETHER_FORCE_USB_FUNCTIONS); 430 mTetherSupported = Settings.Global.getUriFor(Settings.Global.TETHER_SUPPORTED); 431 } 432 startObserve()433 public void startObserve() { 434 mContext.getContentResolver().registerContentObserver(mForceUsbFunctions, false, this); 435 mContext.getContentResolver().registerContentObserver(mTetherSupported, false, this); 436 } 437 438 @Override onChange(boolean selfChange)439 public void onChange(boolean selfChange) { 440 Log.wtf(TAG, "Should never be reached."); 441 } 442 443 @Override onChange(boolean selfChange, Uri uri)444 public void onChange(boolean selfChange, Uri uri) { 445 if (mForceUsbFunctions.equals(uri)) { 446 mLog.i("OBSERVED TETHER_FORCE_USB_FUNCTIONS settings change"); 447 final boolean isUsingNcm = mConfig.isUsingNcm(); 448 updateConfiguration(); 449 if (isUsingNcm != mConfig.isUsingNcm()) { 450 stopTetheringInternal(TETHERING_USB); 451 stopTetheringInternal(TETHERING_NCM); 452 } 453 } else if (mTetherSupported.equals(uri)) { 454 mLog.i("OBSERVED TETHER_SUPPORTED settings change"); 455 updateSupportedDownstreams(mConfig); 456 } else { 457 mLog.e("Unexpected settings change: " + uri); 458 } 459 } 460 } 461 462 @VisibleForTesting getSettingsObserverForTest()463 ContentObserver getSettingsObserverForTest() { 464 return mSettingsObserver; 465 } 466 isTetheringWithSoftApConfigEnabled()467 boolean isTetheringWithSoftApConfigEnabled() { 468 return mDeps.isTetheringWithSoftApConfigEnabled(); 469 } 470 471 /** 472 * Start to register callbacks. 473 * Call this function when tethering is ready to handle callback events. 474 */ startStateMachineUpdaters()475 private void startStateMachineUpdaters() { 476 try { 477 mNetd.registerUnsolicitedEventListener(mNetdCallback); 478 } catch (RemoteException e) { 479 mLog.e("Unable to register netd UnsolicitedEventListener"); 480 } 481 mCarrierConfigChange.startListening(); 482 mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener, 483 PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); 484 485 IntentFilter filter = new IntentFilter(); 486 filter.addAction(UsbManager.ACTION_USB_STATE); 487 filter.addAction(CONNECTIVITY_ACTION); 488 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 489 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 490 filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 491 filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); 492 filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED); 493 mContext.registerReceiver(mStateReceiver, filter, null, mHandler); 494 495 final IntentFilter noUpstreamFilter = new IntentFilter(); 496 noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING); 497 mContext.registerReceiver( 498 mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler); 499 500 final WifiManager wifiManager = getWifiManager(); 501 if (wifiManager != null) { 502 wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback()); 503 if (SdkLevel.isAtLeastT()) { 504 // Although WifiManager#registerLocalOnlyHotspotSoftApCallback document that it need 505 // NEARBY_WIFI_DEVICES permission, but actually a caller who have NETWORK_STACK 506 // or MAINLINE_NETWORK_STACK permission can also use this API. 507 wifiManager.registerLocalOnlyHotspotSoftApCallback(mExecutor, 508 new LocalOnlyHotspotCallback()); 509 } 510 } 511 512 startTrackDefaultNetwork(); 513 } 514 515 private class TetheringThreadExecutor implements Executor { 516 private final Handler mTetherHandler; TetheringThreadExecutor(Handler handler)517 TetheringThreadExecutor(Handler handler) { 518 mTetherHandler = handler; 519 } 520 @Override execute(Runnable command)521 public void execute(Runnable command) { 522 if (!mTetherHandler.post(command)) { 523 throw new RejectedExecutionException(mTetherHandler + " is shutting down"); 524 } 525 } 526 } 527 528 private class ActiveDataSubIdListener extends PhoneStateListener { ActiveDataSubIdListener(Executor executor)529 ActiveDataSubIdListener(Executor executor) { 530 super(executor); 531 } 532 533 @Override onActiveDataSubscriptionIdChanged(int subId)534 public void onActiveDataSubscriptionIdChanged(int subId) { 535 mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId 536 + " to " + subId); 537 if (subId == mActiveDataSubId) return; 538 539 mActiveDataSubId = subId; 540 updateConfiguration(); 541 mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId); 542 // To avoid launching unexpected provisioning checks, ignore re-provisioning 543 // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() 544 // will be triggered again when CarrierConfig is loaded. 545 if (TetheringConfiguration.getCarrierConfig(mContext, subId) != null) { 546 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); 547 } else { 548 mLog.log("IGNORED reevaluate provisioning, no carrier config loaded"); 549 } 550 } 551 } 552 getWifiManager()553 private WifiManager getWifiManager() { 554 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 555 } 556 557 // NOTE: This is always invoked on the mLooper thread. updateConfiguration()558 private void updateConfiguration() { 559 mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId); 560 mUpstreamNetworkMonitor.setUpstreamConfig(mConfig.chooseUpstreamAutomatically, 561 mConfig.isDunRequired); 562 reportConfigurationChanged(mConfig.toStableParcelable()); 563 564 updateSupportedDownstreams(mConfig); 565 } 566 maybeDunSettingChanged()567 private void maybeDunSettingChanged() { 568 final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext); 569 if (isDunRequired == mConfig.isDunRequired) return; 570 updateConfiguration(); 571 } 572 573 private class NetdCallback extends BaseNetdUnsolicitedEventListener { 574 @Override onInterfaceChanged(String ifName, boolean up)575 public void onInterfaceChanged(String ifName, boolean up) { 576 mHandler.post(() -> interfaceStatusChanged(ifName, up)); 577 } 578 579 @Override onInterfaceLinkStateChanged(String ifName, boolean up)580 public void onInterfaceLinkStateChanged(String ifName, boolean up) { 581 mHandler.post(() -> interfaceLinkStateChanged(ifName, up)); 582 } 583 584 @Override onInterfaceAdded(String ifName)585 public void onInterfaceAdded(String ifName) { 586 mHandler.post(() -> interfaceAdded(ifName)); 587 } 588 589 @Override onInterfaceRemoved(String ifName)590 public void onInterfaceRemoved(String ifName) { 591 mHandler.post(() -> interfaceRemoved(ifName)); 592 } 593 } 594 595 private class TetheringSoftApCallback implements SoftApCallback { 596 @Override onConnectedClientsChanged(final List<WifiClient> clients)597 public void onConnectedClientsChanged(final List<WifiClient> clients) { 598 updateConnectedClients(clients, null); 599 } 600 } 601 602 private class LocalOnlyHotspotCallback implements SoftApCallback { 603 @Override onConnectedClientsChanged(final List<WifiClient> clients)604 public void onConnectedClientsChanged(final List<WifiClient> clients) { 605 updateConnectedClients(null, clients); 606 } 607 } 608 609 // This method needs to exist because TETHERING_BLUETOOTH before Android T and TETHERING_WIGIG 610 // can't use enableIpServing. processInterfaceStateChange(final String iface, boolean enabled)611 private void processInterfaceStateChange(final String iface, boolean enabled) { 612 final int type = ifaceNameToType(iface); 613 // Do not listen to USB interface state changes or USB interface add/removes. USB tethering 614 // is driven only by USB_ACTION broadcasts. 615 if (type == TETHERING_USB || type == TETHERING_NCM) return; 616 617 // On T+, BLUETOOTH uses enableIpServing. 618 if (type == TETHERING_BLUETOOTH && SdkLevel.isAtLeastT()) return; 619 620 // Cannot happen: on S+, tetherableWigigRegexps is always empty. 621 if (type == TETHERING_WIGIG && SdkLevel.isAtLeastS()) return; 622 623 // After V, disallow this legacy codepath from starting tethering of any type: 624 // everything must call ensureIpServerStarted directly. 625 // 626 // Don't touch the teardown path for now. It's more complicated because: 627 // - ensureIpServerStarted and ensureIpServerStopped act on different 628 // tethering types. 629 // - Depending on the type, ensureIpServerStopped is either called twice (once 630 // on interface down and once on interface removed) or just once (on 631 // interface removed). 632 // 633 // Note that this only affects WIFI and WIFI_P2P. The other types are either 634 // ignored above, or ignored by ensureIpServerStarted. Note that even for WIFI 635 // and WIFI_P2P, this code should not ever run in normal use, because the 636 // hotspot and p2p code do not call tether(). It's possible that this could 637 // happen in the field due to unforeseen OEM modifications. If it does happen, 638 // a terrible error is logged in tether(). 639 // TODO: fix the teardown path to stop depending on interface state notifications. 640 // These are not necessary since most/all link layers have their own teardown 641 // notifications, and can race with those notifications. 642 if (enabled && SdkLevel.isAtLeastB()) { 643 return; 644 } 645 646 if (enabled) { 647 ensureIpServerStartedForInterface(iface); 648 } else { 649 ensureIpServerStopped(iface); 650 } 651 } 652 interfaceStatusChanged(String iface, boolean up)653 void interfaceStatusChanged(String iface, boolean up) { 654 // Never called directly: only called from interfaceLinkStateChanged. 655 // See NetlinkHandler.cpp: notifyInterfaceChanged. 656 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up); 657 658 final int type = ifaceNameToType(iface); 659 if (!up && type != TETHERING_BLUETOOTH && type != TETHERING_WIGIG) { 660 // Ignore usb interface down after enabling RNDIS. 661 // We will handle disconnect in interfaceRemoved. 662 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status 663 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent. 664 if (VDBG) Log.d(TAG, "ignore interface down for " + iface); 665 return; 666 } 667 668 processInterfaceStateChange(iface, up); 669 } 670 interfaceLinkStateChanged(String iface, boolean up)671 void interfaceLinkStateChanged(String iface, boolean up) { 672 interfaceStatusChanged(iface, up); 673 } 674 ifaceNameToType(String iface)675 private int ifaceNameToType(String iface) { 676 final TetheringConfiguration cfg = mConfig; 677 678 if (cfg.isWifi(iface)) { 679 return TETHERING_WIFI; 680 } else if (cfg.isWigig(iface)) { 681 return TETHERING_WIGIG; 682 } else if (cfg.isWifiP2p(iface)) { 683 return TETHERING_WIFI_P2P; 684 } else if (cfg.isUsb(iface)) { 685 return TETHERING_USB; 686 } else if (cfg.isBluetooth(iface)) { 687 return TETHERING_BLUETOOTH; 688 } else if (cfg.isNcm(iface)) { 689 return TETHERING_NCM; 690 } 691 return TETHERING_INVALID; 692 } 693 interfaceAdded(String iface)694 void interfaceAdded(String iface) { 695 if (VDBG) Log.d(TAG, "interfaceAdded " + iface); 696 processInterfaceStateChange(iface, true /* enabled */); 697 } 698 interfaceRemoved(String iface)699 void interfaceRemoved(String iface) { 700 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); 701 processInterfaceStateChange(iface, false /* enabled */); 702 } 703 startTethering(final TetheringRequest request, final String callerPkg, final IIntResultListener listener)704 void startTethering(final TetheringRequest request, final String callerPkg, 705 final IIntResultListener listener) { 706 mHandler.post(() -> { 707 final int type = request.getTetheringType(); 708 RequestTracker.AddResult result = mRequestTracker.addPendingRequest(request); 709 // If tethering is already pending with a conflicting request, stop tethering before 710 // starting. 711 if (result == FAILURE_DUPLICATE_REQUEST_RESTART) { 712 stopTetheringInternal(type); // Also removes the request from the tracker. 713 mRequestTracker.addPendingRequest(request); 714 } else if (result == FAILURE_DUPLICATE_REQUEST_ERROR) { 715 // Reject any fuzzy matched request. 716 // TODO: Add a CTS test to verify back-to-back start/stop calls succeed. This must 717 // be for a non-Wifi type, since Wifi will reject the start calls if it hasn't 718 // brought down the SoftAP yet. 719 sendTetherResult(listener, TETHER_ERROR_DUPLICATE_REQUEST); 720 return; 721 } 722 723 if (request.isExemptFromEntitlementCheck()) { 724 mEntitlementMgr.setExemptedDownstreamType(type); 725 } else { 726 mEntitlementMgr.startProvisioningIfNeeded(type, 727 request.getShouldShowEntitlementUi()); 728 } 729 enableTetheringInternal(true /* enabled */, request, listener); 730 mTetheringMetrics.createBuilder(type, callerPkg); 731 }); 732 } 733 stopTethering(int type)734 void stopTethering(int type) { 735 mHandler.post(() -> { 736 stopTetheringInternal(type); 737 }); 738 } 739 stopTetheringRequest(@onNull final TetheringRequest request, @NonNull final IIntResultListener listener)740 void stopTetheringRequest(@NonNull final TetheringRequest request, 741 @NonNull final IIntResultListener listener) { 742 if (!isTetheringWithSoftApConfigEnabled()) return; 743 final boolean hasNetworkSettings = hasCallingPermission(NETWORK_SETTINGS); 744 mHandler.post(() -> { 745 if (mRequestTracker.findFuzzyMatchedRequest(request, !hasNetworkSettings) != null) { 746 final int type = request.getTetheringType(); 747 stopTetheringInternal(type); 748 // TODO: We should send the success result after the waiting for tethering to 749 // actually stop. 750 sendTetherResult(listener, TETHER_ERROR_NO_ERROR); 751 return; 752 } 753 754 // Request doesn't match any active requests, ignore. 755 sendTetherResult(listener, TETHER_ERROR_UNKNOWN_REQUEST); 756 }); 757 } 758 stopTetheringInternal(int type)759 void stopTetheringInternal(int type) { 760 mRequestTracker.removeAllPendingRequests(type); 761 mRequestTracker.removeAllServingRequests(type); 762 763 // Using a placeholder here is ok since none of the disable APIs use the request for 764 // anything. We simply need the tethering type to know which link layer to poke for removal. 765 // TODO: Remove the placeholder here and loop through each pending/serving request. 766 enableTetheringInternal(false /* disabled */, createPlaceholderRequest(type), null); 767 mEntitlementMgr.stopProvisioningIfNeeded(type); 768 } 769 770 /** 771 * Enables or disables tethering for the given type. If provisioning is required, it will 772 * schedule provisioning rechecks for the specified interface. 773 */ enableTetheringInternal(boolean enable, @NonNull final TetheringRequest request, final IIntResultListener listener)774 private void enableTetheringInternal(boolean enable, @NonNull final TetheringRequest request, 775 final IIntResultListener listener) { 776 final int type = request.getTetheringType(); 777 final int result; 778 switch (type) { 779 case TETHERING_WIFI: 780 result = setWifiTethering(enable, request, listener); 781 break; 782 case TETHERING_USB: 783 result = setUsbTethering(enable); 784 break; 785 case TETHERING_BLUETOOTH: 786 result = setBluetoothTethering(enable, listener); 787 break; 788 case TETHERING_NCM: 789 result = setNcmTethering(enable); 790 break; 791 case TETHERING_ETHERNET: 792 result = setEthernetTethering(enable); 793 break; 794 case TETHERING_VIRTUAL: 795 result = setVirtualMachineTethering(enable, request); 796 break; 797 default: 798 Log.w(TAG, "Invalid tether type."); 799 result = TETHER_ERROR_UNKNOWN_TYPE; 800 } 801 802 // The result of Bluetooth tethering will be sent after the pan service connects. 803 if (result == TETHER_ERROR_BLUETOOTH_SERVICE_PENDING) return; 804 805 // The result of Wifi tethering will be sent after the SoftApCallback result. 806 if (result == TETHER_ERROR_SOFT_AP_CALLBACK_PENDING) return; 807 808 sendTetherResultAndRemoveOnError(request, listener, result); 809 } 810 sendTetherResult(final IIntResultListener listener, final int result)811 private void sendTetherResult(final IIntResultListener listener, final int result) { 812 if (listener != null) { 813 try { 814 listener.onResult(result); 815 } catch (RemoteException e) { 816 } 817 } 818 } 819 sendTetherResultAndRemoveOnError(TetheringRequest request, final IIntResultListener listener, final int result)820 private void sendTetherResultAndRemoveOnError(TetheringRequest request, 821 final IIntResultListener listener, final int result) { 822 sendTetherResult(listener, result); 823 824 if (result != TETHER_ERROR_NO_ERROR) { 825 mRequestTracker.removePendingRequest(request); 826 final int type = request.getTetheringType(); 827 mTetheringMetrics.updateErrorCode(type, result); 828 mTetheringMetrics.sendReport(type); 829 } 830 } 831 setWifiTethering(final boolean enable, TetheringRequest request, IIntResultListener listener)832 private int setWifiTethering(final boolean enable, TetheringRequest request, 833 IIntResultListener listener) { 834 final long ident = Binder.clearCallingIdentity(); 835 try { 836 final WifiManager mgr = getWifiManager(); 837 if (mgr == null) { 838 mLog.e("setWifiTethering: failed to get WifiManager!"); 839 return TETHER_ERROR_SERVICE_UNAVAIL; 840 } 841 final boolean success; 842 if (enable) { 843 if (isTetheringWithSoftApConfigEnabled()) { 844 // Notes: 845 // - A call to startTetheredHotspot can only succeed if the SoftAp is idle. If 846 // the SoftAp is running or is being disabled, the call will fail. 847 // - If a call to startTetheredHotspot fails, the callback is immediately called 848 // with WIFI_AP_STATE_FAILED and a null interface. 849 // - If a call to startTetheredHotspot succeeds, the passed-in callback is the 850 // only callback that will receive future WIFI_AP_STATE_ENABLED and 851 // WIFI_AP_STATE_DISABLED events in the future, until another call to 852 // startTetheredHotspot succeeds, at which point the old callback will stop 853 // receiving any events. 854 // - Wifi may decide to restart the hotspot at any time (such as for a CC 855 // change), and if it does so, it will send WIFI_AP_STATE_DISABLED and then 856 // either WIFI_AP_STATE_ENABLED or (if restarting fails) WIFI_AP_STATE_FAILED. 857 mgr.startTetheredHotspot(request, mExecutor, 858 new StartTetheringSoftApCallback(listener)); 859 // Result isn't used since we get the real result via 860 // StartTetheringSoftApCallback. 861 return TETHER_ERROR_SOFT_AP_CALLBACK_PENDING; 862 } 863 success = mgr.startTetheredHotspot(null); 864 } else { 865 success = mgr.stopSoftAp(); 866 } 867 868 if (success) { 869 return TETHER_ERROR_NO_ERROR; 870 } 871 } finally { 872 Binder.restoreCallingIdentity(ident); 873 } 874 875 return TETHER_ERROR_INTERNAL_ERROR; 876 } 877 setBluetoothTethering(final boolean enable, final IIntResultListener listener)878 private int setBluetoothTethering(final boolean enable, final IIntResultListener listener) { 879 final BluetoothAdapter adapter = mDeps.getBluetoothAdapter(); 880 if (adapter == null || !adapter.isEnabled()) { 881 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " 882 + (adapter == null)); 883 return TETHER_ERROR_SERVICE_UNAVAIL; 884 } 885 886 if (mBluetoothPanListener != null && mBluetoothPanListener.isConnected()) { 887 // The PAN service is connected. Enable or disable bluetooth tethering. 888 // When bluetooth tethering is enabled, any time a PAN client pairs with this 889 // host, bluetooth will bring up a bt-pan interface and notify tethering to 890 // enable IP serving. 891 return setBluetoothTetheringSettings(mBluetoothPan, enable); 892 } 893 894 if (!enable) { 895 // The service is not connected. If disabling tethering, there's no point starting 896 // the service just to stop tethering since tethering is not started. Just remove 897 // any pending request to enable tethering, and notify them that they have failed. 898 if (mPendingPanRequestListener != null) { 899 sendTetherResult(mPendingPanRequestListener, TETHER_ERROR_SERVICE_UNAVAIL); 900 } 901 mPendingPanRequestListener = null; 902 return TETHER_ERROR_NO_ERROR; 903 } 904 905 // Only allow one pending request at a time. 906 if (mPendingPanRequestListener != null) { 907 return TETHER_ERROR_SERVICE_UNAVAIL; 908 } 909 910 mPendingPanRequestListener = listener; 911 912 // Bluetooth tethering is not a popular feature. To avoid bind to bluetooth pan service all 913 // the time but user never use bluetooth tethering. mBluetoothPanListener is created first 914 // time someone calls a bluetooth tethering method (even if it's just to disable tethering 915 // when it's already disabled) and never unset after that. 916 if (mBluetoothPanListener == null) { 917 mBluetoothPanListener = new PanServiceListener(); 918 adapter.getProfileProxy(mContext, mBluetoothPanListener, BluetoothProfile.PAN); 919 } 920 return TETHER_ERROR_BLUETOOTH_SERVICE_PENDING; 921 } 922 923 private class PanServiceListener implements ServiceListener { 924 private boolean mIsConnected = false; 925 926 @Override onServiceConnected(int profile, BluetoothProfile proxy)927 public void onServiceConnected(int profile, BluetoothProfile proxy) { 928 // Posting this to handling onServiceConnected in tethering handler thread may have 929 // race condition that bluetooth service may disconnected when tethering thread 930 // actaully handle onServiceconnected. If this race happen, calling 931 // BluetoothPan#setBluetoothTethering would silently fail. It is fine because pan 932 // service is unreachable and both bluetooth and bluetooth tethering settings are off. 933 mHandler.post(() -> { 934 mBluetoothPan = (BluetoothPan) proxy; 935 mIsConnected = true; 936 937 if (mPendingPanRequestListener != null) { 938 final int result = setBluetoothTetheringSettings(mBluetoothPan, 939 true /* enable */); 940 sendTetherResultAndRemoveOnError( 941 mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH), 942 mPendingPanRequestListener, 943 result); 944 } 945 mPendingPanRequestListener = null; 946 }); 947 } 948 949 @Override onServiceDisconnected(int profile)950 public void onServiceDisconnected(int profile) { 951 mHandler.post(() -> { 952 // onServiceDisconnected means Bluetooth is off (or crashed) and is not 953 // reachable before next onServiceConnected. 954 mIsConnected = false; 955 956 if (mPendingPanRequestListener != null) { 957 sendTetherResultAndRemoveOnError( 958 mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH), 959 mPendingPanRequestListener, 960 TETHER_ERROR_SERVICE_UNAVAIL); 961 } 962 mPendingPanRequestListener = null; 963 mBluetoothIfaceRequest = null; 964 mBluetoothCallback = null; 965 maybeDisableBluetoothIpServing(); 966 }); 967 } 968 isConnected()969 public boolean isConnected() { 970 return mIsConnected; 971 } 972 } 973 setBluetoothTetheringSettings(@onNull final BluetoothPan bluetoothPan, final boolean enable)974 private int setBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan, 975 final boolean enable) { 976 if (SdkLevel.isAtLeastT()) { 977 changeBluetoothTetheringSettings(bluetoothPan, enable); 978 } else { 979 changeBluetoothTetheringSettingsPreT(bluetoothPan, enable); 980 } 981 982 // Enabling bluetooth tethering settings can silently fail. Send internal error if the 983 // result is not expected. 984 return bluetoothPan.isTetheringOn() == enable 985 ? TETHER_ERROR_NO_ERROR : TETHER_ERROR_INTERNAL_ERROR; 986 } 987 changeBluetoothTetheringSettingsPreT(@onNull final BluetoothPan bluetoothPan, final boolean enable)988 private void changeBluetoothTetheringSettingsPreT(@NonNull final BluetoothPan bluetoothPan, 989 final boolean enable) { 990 bluetoothPan.setBluetoothTethering(enable); 991 } 992 changeBluetoothTetheringSettings(@onNull final BluetoothPan bluetoothPan, final boolean enable)993 private void changeBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan, 994 final boolean enable) { 995 final BluetoothPanShim panShim = mDeps.makeBluetoothPanShim(bluetoothPan); 996 if (enable) { 997 if (mBluetoothIfaceRequest != null) { 998 Log.d(TAG, "Bluetooth tethering settings already enabled"); 999 return; 1000 } 1001 1002 mBluetoothCallback = new BluetoothCallback(); 1003 try { 1004 mBluetoothIfaceRequest = panShim.requestTetheredInterface(mExecutor, 1005 mBluetoothCallback); 1006 } catch (UnsupportedApiLevelException e) { 1007 Log.wtf(TAG, "Use unsupported API, " + e); 1008 } 1009 } else { 1010 if (mBluetoothIfaceRequest == null) { 1011 Log.d(TAG, "Bluetooth tethering settings already disabled"); 1012 return; 1013 } 1014 1015 mBluetoothIfaceRequest.release(); 1016 mBluetoothIfaceRequest = null; 1017 mBluetoothCallback = null; 1018 // If bluetooth request is released, tethering won't able to receive 1019 // onUnavailable callback, explicitly disable bluetooth IpServer manually. 1020 maybeDisableBluetoothIpServing(); 1021 } 1022 } 1023 1024 // BluetoothCallback is only called after T. Before T, PanService would call tether/untether to 1025 // notify bluetooth interface status. 1026 private class BluetoothCallback implements TetheredInterfaceCallbackShim { 1027 @Override onAvailable(String iface)1028 public void onAvailable(String iface) { 1029 if (this != mBluetoothCallback) return; 1030 1031 final TetheringRequest request = 1032 mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH); 1033 enableIpServing(request, iface); 1034 mConfiguredBluetoothIface = iface; 1035 } 1036 1037 @Override onUnavailable()1038 public void onUnavailable() { 1039 if (this != mBluetoothCallback) return; 1040 1041 maybeDisableBluetoothIpServing(); 1042 } 1043 } 1044 maybeDisableBluetoothIpServing()1045 private void maybeDisableBluetoothIpServing() { 1046 if (mConfiguredBluetoothIface == null) return; 1047 1048 ensureIpServerStopped(mConfiguredBluetoothIface); 1049 mConfiguredBluetoothIface = null; 1050 } 1051 setEthernetTethering(final boolean enable)1052 private int setEthernetTethering(final boolean enable) { 1053 final EthernetManager em = (EthernetManager) mContext.getSystemService( 1054 Context.ETHERNET_SERVICE); 1055 if (enable) { 1056 if (mEthernetCallback != null) { 1057 Log.d(TAG, "Ethernet tethering already started"); 1058 return TETHER_ERROR_NO_ERROR; 1059 } 1060 1061 mEthernetCallback = new EthernetCallback(); 1062 mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback); 1063 } else { 1064 stopEthernetTethering(); 1065 } 1066 return TETHER_ERROR_NO_ERROR; 1067 } 1068 stopEthernetTethering()1069 private void stopEthernetTethering() { 1070 if (mConfiguredEthernetIface != null) { 1071 ensureIpServerStopped(mConfiguredEthernetIface); 1072 mConfiguredEthernetIface = null; 1073 } 1074 if (mEthernetCallback != null) { 1075 mEthernetIfaceRequest.release(); 1076 mEthernetCallback = null; 1077 mEthernetIfaceRequest = null; 1078 } 1079 } 1080 1081 private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback { 1082 @Override onAvailable(String iface)1083 public void onAvailable(String iface) { 1084 if (this != mEthernetCallback) { 1085 // Ethernet callback arrived after Ethernet tethering stopped. Ignore. 1086 return; 1087 } 1088 1089 final TetheringRequest request = mRequestTracker.getOrCreatePendingRequest( 1090 TETHERING_ETHERNET); 1091 enableIpServing(request, iface); 1092 mConfiguredEthernetIface = iface; 1093 } 1094 1095 @Override onUnavailable()1096 public void onUnavailable() { 1097 if (this != mEthernetCallback) { 1098 // onAvailable called after stopping Ethernet tethering. 1099 return; 1100 } 1101 stopEthernetTethering(); 1102 } 1103 } 1104 setVirtualMachineTethering(final boolean enable, @NonNull final TetheringRequest request)1105 private int setVirtualMachineTethering(final boolean enable, 1106 @NonNull final TetheringRequest request) { 1107 final String iface = request.getInterfaceName(); 1108 if (enable) { 1109 if (TextUtils.isEmpty(iface)) { 1110 mConfiguredVirtualIface = "avf_tap_fixed"; 1111 } else { 1112 mConfiguredVirtualIface = iface; 1113 } 1114 enableIpServing(request, mConfiguredVirtualIface); 1115 } else if (mConfiguredVirtualIface != null) { 1116 ensureIpServerStopped(mConfiguredVirtualIface); 1117 mConfiguredVirtualIface = null; 1118 } 1119 return TETHER_ERROR_NO_ERROR; 1120 } 1121 handleLegacyTether(String iface, final IIntResultListener listener)1122 private void handleLegacyTether(String iface, final IIntResultListener listener) { 1123 if (SdkLevel.isAtLeastB()) { 1124 // After V, the TetheringManager and ConnectivityManager tether and untether methods 1125 // throw UnsupportedOperationException, so this cannot happen in normal use. Ensure 1126 // that this code cannot run even if callers use raw binder calls or other 1127 // unsupported methods. 1128 return; 1129 } 1130 1131 final int type = ifaceNameToType(iface); 1132 if (type == TETHERING_INVALID) { 1133 Log.e(TAG, "Ignoring call to legacy tether for unknown iface " + iface); 1134 sendTetherResult(listener, TETHER_ERROR_UNKNOWN_IFACE); 1135 } 1136 1137 TetheringRequest request = mRequestTracker.getNextPendingRequest(type); 1138 if (request == null) { 1139 request = createLegacyGlobalScopeTetheringRequest(type); 1140 } 1141 int result = tetherInternal(request, iface); 1142 switch (type) { 1143 case TETHERING_WIFI: 1144 TerribleErrorLog.logTerribleError(TetheringStatsLog::write, 1145 "Legacy tether API called on Wifi iface " + iface, 1146 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1147 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI); 1148 if (result == TETHER_ERROR_NO_ERROR) { 1149 TerribleErrorLog.logTerribleError(TetheringStatsLog::write, 1150 "Legacy tether API succeeded on Wifi iface " + iface, 1151 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1152 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS); 1153 } 1154 break; 1155 case TETHERING_WIFI_P2P: 1156 TerribleErrorLog.logTerribleError(TetheringStatsLog::write, 1157 "Legacy tether API called on Wifi P2P iface " + iface, 1158 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1159 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P); 1160 if (result == TETHER_ERROR_NO_ERROR) { 1161 TerribleErrorLog.logTerribleError(TetheringStatsLog::write, 1162 "Legacy tether API succeeded on Wifi P2P iface " + iface, 1163 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1164 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS); 1165 } 1166 break; 1167 default: 1168 // Do nothing 1169 break; 1170 } 1171 sendTetherResult(listener, result); 1172 } 1173 1174 /** 1175 * Legacy tether API that starts tethering with CONNECTIVITY_SCOPE_GLOBAL on the given iface. 1176 * 1177 * This API relies on the IpServer having been started for the interface by 1178 * processInterfaceStateChanged beforehand, which is only possible for 1179 * - WIGIG Pre-S 1180 * - BLUETOOTH Pre-T 1181 * - WIFI 1182 * - WIFI_P2P. 1183 * Note that WIFI and WIFI_P2P already start tethering on their respective ifaces via 1184 * WIFI_(AP/P2P_STATE_CHANGED broadcasts, which makes this API redundant for those types unless 1185 * those broadcasts are disabled by OEM. 1186 */ legacyTether(String iface, final IIntResultListener listener)1187 void legacyTether(String iface, final IIntResultListener listener) { 1188 mHandler.post(() -> handleLegacyTether(iface, listener)); 1189 } 1190 tetherInternal(@onNull TetheringRequest request, String iface)1191 private int tetherInternal(@NonNull TetheringRequest request, String iface) { 1192 if (DBG) Log.d(TAG, "Tethering " + iface); 1193 TetherState tetherState = mTetherStates.get(iface); 1194 if (tetherState == null) { 1195 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring"); 1196 return TETHER_ERROR_UNKNOWN_IFACE; 1197 } 1198 // Ignore the error status of the interface. If the interface is available, 1199 // the errors are referring to past tethering attempts anyway. 1200 if (tetherState.lastState != IpServer.STATE_AVAILABLE) { 1201 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring"); 1202 return TETHER_ERROR_UNAVAIL_IFACE; 1203 } 1204 mRequestTracker.promoteRequestToServing(tetherState.ipServer, request); 1205 // NOTE: If a CMD_TETHER_REQUESTED message is already in the IpServer's queue but not yet 1206 // processed, this will be a no-op and it will not return an error. 1207 tetherState.ipServer.enable(request); 1208 if (request.getRequestType() == REQUEST_TYPE_PLACEHOLDER) { 1209 TerribleErrorLog.logTerribleError(TetheringStatsLog::write, 1210 "Started tethering with placeholder request: " + request, 1211 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED, 1212 CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WITH_PLACEHOLDER_REQUEST); 1213 } 1214 return TETHER_ERROR_NO_ERROR; 1215 } 1216 legacyUntether(String iface, final IIntResultListener listener)1217 void legacyUntether(String iface, final IIntResultListener listener) { 1218 if (SdkLevel.isAtLeastB()) { 1219 // After V, the TetheringManager and ConnectivityManager tether and untether methods 1220 // throw UnsupportedOperationException, so this cannot happen in normal use. Ensure 1221 // that this code cannot run even if callers use raw binder calls or other 1222 // unsupported methods. 1223 return; 1224 } 1225 mHandler.post(() -> { 1226 sendTetherResult(listener, legacyUntetherInternal(iface)); 1227 }); 1228 } 1229 legacyUntetherInternal(String iface)1230 int legacyUntetherInternal(String iface) { 1231 if (DBG) Log.d(TAG, "Untethering " + iface); 1232 TetherState tetherState = mTetherStates.get(iface); 1233 if (tetherState == null) { 1234 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); 1235 return TETHER_ERROR_UNKNOWN_IFACE; 1236 } 1237 if (!tetherState.isCurrentlyServing()) { 1238 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring"); 1239 return TETHER_ERROR_UNAVAIL_IFACE; 1240 } 1241 ensureIpServerUnwanted(tetherState.ipServer); 1242 return TETHER_ERROR_NO_ERROR; 1243 } 1244 stopAllTethering()1245 void stopAllTethering() { 1246 stopTethering(TETHERING_WIFI); 1247 stopTethering(TETHERING_WIFI_P2P); 1248 stopTethering(TETHERING_USB); 1249 stopTethering(TETHERING_BLUETOOTH); 1250 stopTethering(TETHERING_ETHERNET); 1251 } 1252 1253 @VisibleForTesting getLastErrorForTest(String iface)1254 int getLastErrorForTest(String iface) { 1255 TetherState tetherState = mTetherStates.get(iface); 1256 if (tetherState == null) { 1257 Log.e(TAG, "Tried to getLastErrorForTest on an unknown iface :" + iface 1258 + ", ignoring"); 1259 return TETHER_ERROR_UNKNOWN_IFACE; 1260 } 1261 return tetherState.lastError; 1262 } 1263 isTetherProvisioningRequired()1264 boolean isTetherProvisioningRequired() { 1265 final TetheringConfiguration cfg = mConfig; 1266 return mEntitlementMgr.isTetherProvisioningRequired(cfg); 1267 } 1268 getServedUsbType(boolean forNcmFunction)1269 private int getServedUsbType(boolean forNcmFunction) { 1270 // TETHERING_NCM is only used if the device does not use NCM for regular USB tethering. 1271 if (forNcmFunction && !mConfig.isUsingNcm()) return TETHERING_NCM; 1272 1273 return TETHERING_USB; 1274 } 1275 1276 // TODO: Figure out how to update for local hotspot mode interfaces. notifyTetherStatesChanged()1277 private void notifyTetherStatesChanged() { 1278 if (!isTetheringSupported()) return; 1279 1280 sendTetherStatesChangedCallback(); 1281 sendTetherStatesChangedBroadcast(); 1282 1283 int downstreamTypesMask = DOWNSTREAM_NONE; 1284 for (int i = 0; i < mTetherStates.size(); i++) { 1285 final TetherState tetherState = mTetherStates.valueAt(i); 1286 final int type = tetherState.ipServer.interfaceType(); 1287 if (tetherState.lastState != IpServer.STATE_TETHERED) continue; 1288 switch (type) { 1289 case TETHERING_USB: 1290 case TETHERING_WIFI: 1291 case TETHERING_BLUETOOTH: 1292 downstreamTypesMask |= (1 << type); 1293 break; 1294 default: 1295 // Do nothing. 1296 break; 1297 } 1298 } 1299 mNotificationUpdater.onDownstreamChanged(downstreamTypesMask); 1300 } 1301 1302 /** 1303 * Builds a TetherStatesParcel for the specified CallbackCookie. SoftApConfiguration will only 1304 * be included if the cookie has the same uid as the app that specified the configuration, or 1305 * if the cookie has system privilege. 1306 * 1307 * @param cookie CallbackCookie of the receiving app. 1308 * @return TetherStatesParcel with information redacted for the specified cookie. 1309 */ buildTetherStatesParcel(CallbackCookie cookie)1310 private TetherStatesParcel buildTetherStatesParcel(CallbackCookie cookie) { 1311 final ArrayList<TetheringInterface> available = new ArrayList<>(); 1312 final ArrayList<TetheringInterface> tethered = new ArrayList<>(); 1313 final ArrayList<TetheringInterface> localOnly = new ArrayList<>(); 1314 final ArrayList<TetheringInterface> errored = new ArrayList<>(); 1315 final ArrayList<Integer> lastErrors = new ArrayList<>(); 1316 1317 for (int i = 0; i < mTetherStates.size(); i++) { 1318 final TetherState tetherState = mTetherStates.valueAt(i); 1319 final int type = tetherState.ipServer.interfaceType(); 1320 final String iface = mTetherStates.keyAt(i); 1321 // Note: serving requests are only populated on B+. B+ also uses the sync state 1322 // machine by default. This ensures that the serving request is (correctly) populated 1323 // after the IpServer enters the available state and before it enters the serving 1324 // state. 1325 final TetheringRequest request = 1326 mRequestTracker.getServingRequest(tetherState.ipServer); 1327 final boolean includeSoftApConfig = request != null && cookie != null 1328 && (cookie.uid == request.getUid() || cookie.hasSystemPrivilege); 1329 final TetheringInterface tetheringIface = new TetheringInterface(type, iface, 1330 includeSoftApConfig ? request.getSoftApConfiguration() : null); 1331 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) { 1332 errored.add(tetheringIface); 1333 lastErrors.add(tetherState.lastError); 1334 } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) { 1335 available.add(tetheringIface); 1336 } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) { 1337 localOnly.add(tetheringIface); 1338 } else if (tetherState.lastState == IpServer.STATE_TETHERED) { 1339 switch (type) { 1340 case TETHERING_USB: 1341 case TETHERING_WIFI: 1342 case TETHERING_BLUETOOTH: 1343 break; 1344 default: 1345 // Do nothing. 1346 break; 1347 } 1348 tethered.add(tetheringIface); 1349 } 1350 } 1351 1352 final TetherStatesParcel parcel = new TetherStatesParcel(); 1353 parcel.availableList = available.toArray(new TetheringInterface[0]); 1354 parcel.tetheredList = tethered.toArray(new TetheringInterface[0]); 1355 parcel.localOnlyList = localOnly.toArray(new TetheringInterface[0]); 1356 parcel.erroredIfaceList = errored.toArray(new TetheringInterface[0]); 1357 parcel.lastErrorList = new int[lastErrors.size()]; 1358 for (int i = 0; i < lastErrors.size(); i++) { 1359 parcel.lastErrorList[i] = lastErrors.get(i); 1360 } 1361 return parcel; 1362 } 1363 sendTetherStatesChangedBroadcast()1364 private void sendTetherStatesChangedBroadcast() { 1365 final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED); 1366 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1367 1368 TetherStatesParcel parcel = buildTetherStatesParcel(null /* cookie */); 1369 bcast.putStringArrayListExtra( 1370 EXTRA_AVAILABLE_TETHER, toIfaces(Arrays.asList(parcel.availableList))); 1371 bcast.putStringArrayListExtra( 1372 EXTRA_ACTIVE_LOCAL_ONLY, toIfaces(Arrays.asList(parcel.localOnlyList))); 1373 bcast.putStringArrayListExtra( 1374 EXTRA_ACTIVE_TETHER, toIfaces(Arrays.asList(parcel.tetheredList))); 1375 bcast.putStringArrayListExtra( 1376 EXTRA_ERRORED_TETHER, toIfaces(Arrays.asList(parcel.erroredIfaceList))); 1377 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL); 1378 } 1379 1380 private class StateReceiver extends BroadcastReceiver { 1381 @Override onReceive(Context content, Intent intent)1382 public void onReceive(Context content, Intent intent) { 1383 final String action = intent.getAction(); 1384 if (action == null) return; 1385 1386 if (action.equals(UsbManager.ACTION_USB_STATE)) { 1387 handleUsbAction(intent); 1388 } else if (action.equals(CONNECTIVITY_ACTION)) { 1389 handleConnectivityAction(intent); 1390 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 1391 handleWifiApAction(intent); 1392 } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { 1393 handleWifiP2pAction(intent); 1394 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 1395 mLog.log("OBSERVED configuration changed"); 1396 updateConfiguration(); 1397 } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { 1398 mLog.log("OBSERVED user restrictions changed"); 1399 handleUserRestrictionAction(); 1400 } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) { 1401 mLog.log("OBSERVED data saver changed"); 1402 handleDataSaverChanged(); 1403 } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) { 1404 stopAllTethering(); 1405 } 1406 } 1407 handleConnectivityAction(Intent intent)1408 private void handleConnectivityAction(Intent intent) { 1409 // CONNECTIVITY_ACTION is not handled since U+ device. 1410 if (SdkLevel.isAtLeastU()) return; 1411 1412 final NetworkInfo networkInfo = 1413 (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO); 1414 if (networkInfo == null 1415 || networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) { 1416 return; 1417 } 1418 1419 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString()); 1420 mTetherMainSM.sendMessage(TetherMainSM.CMD_UPSTREAM_CHANGED); 1421 } 1422 handleUsbAction(Intent intent)1423 private void handleUsbAction(Intent intent) { 1424 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false); 1425 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false); 1426 final boolean usbRndis = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false); 1427 final boolean usbNcm = intent.getBooleanExtra(USB_FUNCTION_NCM, false); 1428 1429 mLog.i(String.format("USB bcast connected:%s configured:%s rndis:%s ncm:%s", 1430 usbConnected, usbConfigured, usbRndis, usbNcm)); 1431 1432 // There are three types of ACTION_USB_STATE: 1433 // 1434 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0) 1435 // Meaning: USB connection has ended either because of 1436 // software reset or hard unplug. 1437 // 1438 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0) 1439 // Meaning: the first stage of USB protocol handshake has 1440 // occurred but it is not complete. 1441 // 1442 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1) 1443 // Meaning: the USB handshake is completely done and all the 1444 // functions are ready to use. 1445 // 1446 // For more explanation, see b/62552150 . 1447 boolean rndisEnabled = usbConfigured && usbRndis; 1448 boolean ncmEnabled = usbConfigured && usbNcm; 1449 if (!usbConnected) { 1450 // Don't stop provisioning if function is disabled but usb is still connected. The 1451 // function may be disable/enable to handle ip conflict condition (disabling the 1452 // function is necessary to ensure the connected device sees a disconnect). 1453 // Normally the provisioning should be stopped by stopTethering(int) 1454 maybeStopUsbProvisioning(); 1455 rndisEnabled = false; 1456 ncmEnabled = false; 1457 } 1458 1459 if (mRndisEnabled != rndisEnabled) { 1460 changeUsbIpServing(rndisEnabled, false /* forNcmFunction */); 1461 mRndisEnabled = rndisEnabled; 1462 } 1463 1464 if (mNcmEnabled != ncmEnabled) { 1465 changeUsbIpServing(ncmEnabled, true /* forNcmFunction */); 1466 mNcmEnabled = ncmEnabled; 1467 } 1468 } 1469 changeUsbIpServing(boolean enable, boolean forNcmFunction)1470 private void changeUsbIpServing(boolean enable, boolean forNcmFunction) { 1471 if (enable) { 1472 // enable ip serving if function is enabled and usb is configured. 1473 enableUsbIpServing(forNcmFunction); 1474 } else { 1475 disableUsbIpServing(forNcmFunction); 1476 } 1477 } 1478 maybeStopUsbProvisioning()1479 private void maybeStopUsbProvisioning() { 1480 for (int i = 0; i < mTetherStates.size(); i++) { 1481 final int type = mTetherStates.valueAt(i).ipServer.interfaceType(); 1482 if (type == TETHERING_USB || type == TETHERING_NCM) { 1483 mEntitlementMgr.stopProvisioningIfNeeded(type); 1484 } 1485 } 1486 } 1487 handleWifiApAction(Intent intent)1488 private void handleWifiApAction(Intent intent) { 1489 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); 1490 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME); 1491 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED); 1492 1493 // In B+, Tethered AP is handled by StartTetheringSoftApCallback. 1494 if (isTetheringWithSoftApConfigEnabled() && ipmode == IFACE_IP_MODE_TETHERED) return; 1495 1496 switch (curState) { 1497 case WifiManager.WIFI_AP_STATE_ENABLING: 1498 // We can see this state on the way to both enabled and failure states. 1499 break; 1500 case WifiManager.WIFI_AP_STATE_ENABLED: 1501 enableWifiIpServing(ifname, ipmode); 1502 break; 1503 case WifiManager.WIFI_AP_STATE_DISABLING: 1504 // We can see this state on the way to disabled. 1505 break; 1506 case WifiManager.WIFI_AP_STATE_DISABLED: 1507 case WifiManager.WIFI_AP_STATE_FAILED: 1508 default: 1509 disableWifiIpServing(ifname, curState); 1510 break; 1511 } 1512 } 1513 isGroupOwner(WifiP2pGroup group)1514 private boolean isGroupOwner(WifiP2pGroup group) { 1515 return group != null && group.isGroupOwner() 1516 && !TextUtils.isEmpty(group.getInterface()); 1517 } 1518 handleWifiP2pAction(Intent intent)1519 private void handleWifiP2pAction(Intent intent) { 1520 if (mConfig.isWifiP2pLegacyTetheringMode()) return; 1521 1522 final WifiP2pInfo p2pInfo = 1523 (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO); 1524 final WifiP2pGroup group = 1525 (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP); 1526 1527 mLog.i("WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group); 1528 1529 // if no group is formed, bring it down if needed. 1530 if (p2pInfo == null || !p2pInfo.groupFormed) { 1531 disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface); 1532 mWifiP2pTetherInterface = null; 1533 return; 1534 } 1535 1536 // If there is a group but the device is not the owner, bail out. 1537 if (!isGroupOwner(group)) return; 1538 1539 // If already serving from the correct interface, nothing to do. 1540 if (group.getInterface().equals(mWifiP2pTetherInterface)) return; 1541 1542 // If already serving from another interface, turn it down first. 1543 if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) { 1544 mLog.w("P2P tethered interface " + mWifiP2pTetherInterface 1545 + "is different from current interface " 1546 + group.getInterface() + ", re-tether it"); 1547 disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface); 1548 } 1549 1550 // Finally bring up serving on the new interface 1551 mWifiP2pTetherInterface = group.getInterface(); 1552 enableWifiP2pIpServing(mWifiP2pTetherInterface); 1553 } 1554 handleUserRestrictionAction()1555 private void handleUserRestrictionAction() { 1556 if (mTetheringRestriction.onUserRestrictionsChanged()) { 1557 updateSupportedDownstreams(mConfig); 1558 } 1559 } 1560 handleDataSaverChanged()1561 private void handleDataSaverChanged() { 1562 final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService( 1563 Context.CONNECTIVITY_SERVICE); 1564 final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus() 1565 != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; 1566 1567 if (mDataSaverEnabled == isDataSaverEnabled) return; 1568 1569 mDataSaverEnabled = isDataSaverEnabled; 1570 if (mDataSaverEnabled) { 1571 stopAllTethering(); 1572 } 1573 } 1574 } 1575 1576 class StartTetheringSoftApCallback implements SoftApCallback { 1577 1578 @Nullable 1579 IIntResultListener mPendingListener; 1580 StartTetheringSoftApCallback(IIntResultListener pendingListener)1581 StartTetheringSoftApCallback(IIntResultListener pendingListener) { 1582 mPendingListener = pendingListener; 1583 } 1584 1585 @Override onStateChanged(SoftApState softApState)1586 public void onStateChanged(SoftApState softApState) { 1587 final int state = softApState.getState(); 1588 final String iface = softApState.getIface(); 1589 final TetheringRequest request = softApState.getTetheringRequest(); 1590 switch (softApState.getState()) { 1591 case WifiManager.WIFI_AP_STATE_ENABLED: 1592 enableIpServing(request, iface); 1593 // If stopTethering has already been called, IP serving will still be started, 1594 // but as soon as the wifi code processes the stop, WIFI_AP_STATE_DISABLED will 1595 // be sent and tethering will be stopped again. 1596 sendTetherResultAndRemoveOnError(request, mPendingListener, 1597 TETHER_ERROR_NO_ERROR); 1598 mPendingListener = null; 1599 break; 1600 case WifiManager.WIFI_AP_STATE_FAILED: 1601 // TODO: if a call to startTethering happens just after a call to stopTethering, 1602 // the start will fail because hotspot is still being disabled. This likely 1603 // cannot be fixed in tethering code but must be fixed in WiFi. 1604 sendTetherResultAndRemoveOnError(request, mPendingListener, 1605 TETHER_ERROR_INTERNAL_ERROR); 1606 mPendingListener = null; 1607 break; 1608 case WifiManager.WIFI_AP_STATE_DISABLED: 1609 // TODO(b/403164072): SoftAP may restart due to CC change, in which we'll get 1610 // DISABLED -> ENABLED (or FAILED). Before the transition back to ENABLED is 1611 // complete, it is possible that a new Wifi request is accepted since there's no 1612 // active request to fuzzy-match it, which will unexpectedly cause Wifi to 1613 // overwrite this SoftApCallback. This should be fixed in Wifi to disallow any 1614 // new calls to startTetheredHotspot while SoftAP is restarting. 1615 disableWifiIpServing(iface, state); 1616 break; 1617 default: 1618 break; 1619 } 1620 } 1621 } 1622 1623 @VisibleForTesting getPendingTetheringRequests()1624 List<TetheringRequest> getPendingTetheringRequests() { 1625 return mRequestTracker.getPendingTetheringRequests(); 1626 } 1627 1628 @VisibleForTesting getServingTetheringRequests()1629 List<TetheringRequest> getServingTetheringRequests() { 1630 return mRequestTracker.getServingTetheringRequests(); 1631 } 1632 1633 @VisibleForTesting isTetheringActive()1634 boolean isTetheringActive() { 1635 return getTetheredIfaces().length > 0; 1636 } 1637 1638 // TODO: Refine TetheringTest then remove UserRestrictionActionListener class and handle 1639 // onUserRestrictionsChanged inside Tethering#handleUserRestrictionAction directly. 1640 @VisibleForTesting 1641 protected static class UserRestrictionActionListener { 1642 private final UserManager mUserMgr; 1643 private final Tethering mTethering; 1644 private final TetheringNotificationUpdater mNotificationUpdater; 1645 public boolean mDisallowTethering; 1646 UserRestrictionActionListener(@onNull UserManager um, @NonNull Tethering tethering, @NonNull TetheringNotificationUpdater updater)1647 public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering tethering, 1648 @NonNull TetheringNotificationUpdater updater) { 1649 mUserMgr = um; 1650 mTethering = tethering; 1651 mNotificationUpdater = updater; 1652 mDisallowTethering = false; 1653 } 1654 1655 // return whether tethering disallowed is changed. onUserRestrictionsChanged()1656 public boolean onUserRestrictionsChanged() { 1657 // getUserRestrictions gets restriction for this process' user, which is the primary 1658 // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary 1659 // user. See UserManager.DISALLOW_CONFIG_TETHERING. 1660 final Bundle restrictions = mUserMgr.getUserRestrictions(); 1661 final boolean newlyDisallowed = 1662 restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); 1663 final boolean prevDisallowed = mDisallowTethering; 1664 mDisallowTethering = newlyDisallowed; 1665 1666 final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed); 1667 if (!tetheringDisallowedChanged) return false; 1668 1669 if (!newlyDisallowed) { 1670 // Clear the restricted notification when user is allowed to have tethering 1671 // function. 1672 mNotificationUpdater.tetheringRestrictionLifted(); 1673 return true; 1674 } 1675 1676 if (mTethering.isTetheringActive()) { 1677 // Restricted notification is shown when tethering function is disallowed on 1678 // user's device. 1679 mNotificationUpdater.notifyTetheringDisabledByRestriction(); 1680 1681 // Untether from all downstreams since tethering is disallowed. 1682 mTethering.stopAllTethering(); 1683 } 1684 1685 return true; 1686 // TODO(b/148139325): send tetheringSupported on restriction change 1687 } 1688 } 1689 enableIpServing(@onNull TetheringRequest request, String ifname)1690 private void enableIpServing(@NonNull TetheringRequest request, String ifname) { 1691 enableIpServing(request, ifname, false /* isNcm */); 1692 } 1693 enableIpServing(@onNull TetheringRequest request, String ifname, boolean isNcm)1694 private void enableIpServing(@NonNull TetheringRequest request, String ifname, boolean isNcm) { 1695 ensureIpServerStartedForType(ifname, request.getTetheringType(), isNcm); 1696 if (tetherInternal(request, ifname) != TETHER_ERROR_NO_ERROR) { 1697 Log.e(TAG, "unable start tethering on iface " + ifname); 1698 } 1699 } 1700 disableWifiIpServingCommon(int tetheringType, String ifname)1701 private void disableWifiIpServingCommon(int tetheringType, String ifname) { 1702 if (!TextUtils.isEmpty(ifname) && mTetherStates.containsKey(ifname)) { 1703 ensureIpServerUnwanted(mTetherStates.get(ifname).ipServer); 1704 return; 1705 } 1706 1707 if (SdkLevel.isAtLeastT()) { 1708 mLog.e("Tethering no longer handle untracked interface after T: " + ifname); 1709 return; 1710 } 1711 1712 // Attempt to guess the interface name before T. Pure AOSP code should never enter here 1713 // because WIFI_AP_STATE_CHANGED intent always include ifname and it should be tracked 1714 // by mTetherStates. In case OEMs have some modification in wifi side which pass null 1715 // or empty ifname. Before T, tethering allow to disable the first wifi ipServer if 1716 // given ifname don't match any tracking ipServer. 1717 for (int i = 0; i < mTetherStates.size(); i++) { 1718 final IpServer ipServer = mTetherStates.valueAt(i).ipServer; 1719 if (ipServer.interfaceType() == tetheringType) { 1720 ensureIpServerUnwanted(ipServer); 1721 return; 1722 } 1723 } 1724 mLog.log("Error disabling Wi-Fi IP serving; " 1725 + (TextUtils.isEmpty(ifname) ? "no interface name specified" 1726 : "specified interface: " + ifname)); 1727 } 1728 disableWifiIpServing(String ifname, int apState)1729 private void disableWifiIpServing(String ifname, int apState) { 1730 mLog.log("Canceling WiFi tethering request - interface=" + ifname + " state=" + apState); 1731 1732 disableWifiIpServingCommon(TETHERING_WIFI, ifname); 1733 } 1734 enableWifiP2pIpServing(String ifname)1735 private void enableWifiP2pIpServing(String ifname) { 1736 if (TextUtils.isEmpty(ifname)) { 1737 mLog.e("Cannot enable P2P IP serving with invalid interface"); 1738 return; 1739 } 1740 1741 // After T, tethering always trust the iface pass by state change intent. This allow 1742 // tethering to deprecate tetherable p2p regexs after T. 1743 final int type = SdkLevel.isAtLeastT() ? TETHERING_WIFI_P2P : ifaceNameToType(ifname); 1744 if (!checkTetherableType(type)) { 1745 mLog.e(ifname + " is not a tetherable iface, ignoring"); 1746 return; 1747 } 1748 // No need to call getOrCreatePendingRequest. There can never be explicit requests for 1749 // TETHERING_WIFI_P2P because enableTetheringInternal ignores that type. 1750 final TetheringRequest request = createImplicitLocalOnlyTetheringRequest(type); 1751 enableIpServing(request, ifname); 1752 } 1753 disableWifiP2pIpServingIfNeeded(String ifname)1754 private void disableWifiP2pIpServingIfNeeded(String ifname) { 1755 if (TextUtils.isEmpty(ifname)) return; 1756 1757 mLog.log("Canceling P2P tethering request - interface=" + ifname); 1758 disableWifiIpServingCommon(TETHERING_WIFI_P2P, ifname); 1759 } 1760 1761 // TODO: fold this in to enableWifiIpServing. We cannot do this at the moment because there 1762 // are tests that send wifi AP broadcasts with a null interface. But if this can't happen on 1763 // real devices, we should fix those tests to always pass in an interface. maybeInferWifiTetheringType(String ifname)1764 private int maybeInferWifiTetheringType(String ifname) { 1765 return SdkLevel.isAtLeastT() ? TETHERING_WIFI : ifaceNameToType(ifname); 1766 } 1767 enableWifiIpServing(String ifname, int wifiIpMode)1768 private void enableWifiIpServing(String ifname, int wifiIpMode) { 1769 mLog.log("request WiFi tethering - interface=" + ifname + " state=" + wifiIpMode); 1770 1771 // Map wifiIpMode values to IpServer.Callback serving states. 1772 TetheringRequest request; 1773 final int type; 1774 switch (wifiIpMode) { 1775 case IFACE_IP_MODE_TETHERED: 1776 type = maybeInferWifiTetheringType(ifname); 1777 request = mRequestTracker.getOrCreatePendingRequest(type); 1778 // Wifi requests will always have CONNECTIVITY_SCOPE_GLOBAL, because 1779 // TetheringRequest.Builder will not allow callers to set CONNECTIVITY_SCOPE_LOCAL 1780 // for TETHERING_WIFI. However, if maybeInferWifiTetheringType returns a non-Wifi 1781 // type (which could happen on a pre-T implementation of Wi-Fi if the regexps are 1782 // misconfigured), then force the connectivity scope to global in order to match the 1783 // historical behavior. 1784 request.getParcel().connectivityScope = CONNECTIVITY_SCOPE_GLOBAL; 1785 break; 1786 case IFACE_IP_MODE_LOCAL_ONLY: 1787 type = maybeInferWifiTetheringType(ifname); 1788 request = createImplicitLocalOnlyTetheringRequest(type); 1789 break; 1790 default: 1791 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode); 1792 return; 1793 } 1794 1795 // After T, tethering always trust the iface pass by state change intent. This allow 1796 // tethering to deprecate tetherable wifi regexs after T. 1797 if (!checkTetherableType(type)) { 1798 mLog.e(ifname + " is not a tetherable iface, ignoring"); 1799 return; 1800 } 1801 1802 if (!TextUtils.isEmpty(ifname)) { 1803 enableIpServing(request, ifname); 1804 } else { 1805 mLog.e("Cannot enable IP serving on missing interface name"); 1806 } 1807 } 1808 1809 // TODO: Pass TetheringRequest into this method. The code can look at the existing requests 1810 // to see which one matches the function that was enabled. That will tell the code what 1811 // tethering type was requested, without having to guess it from the configuration. 1812 // This method: 1813 // - allows requesting either tethering or local hotspot serving states 1814 // - only tethers the first matching interface in listInterfaces() 1815 // order of a given type enableUsbIpServing(boolean forNcmFunction)1816 private void enableUsbIpServing(boolean forNcmFunction) { 1817 // Note: TetheringConfiguration#isUsingNcm can change between the call to 1818 // startTethering(TETHERING_USB) and the ACTION_USB_STATE broadcast. If the USB tethering 1819 // function changes from NCM to RNDIS, this can lead to Tethering starting NCM tethering 1820 // as local-only. But if this happens, the SettingsObserver will call stopTetheringInternal 1821 // for both TETHERING_USB and TETHERING_NCM, so the local-only NCM interface will be 1822 // stopped immediately. 1823 final int tetheringType = getServedUsbType(forNcmFunction); 1824 String[] ifaces = null; 1825 try { 1826 ifaces = mNetd.interfaceGetList(); 1827 } catch (RemoteException | ServiceSpecificException e) { 1828 mLog.e("Cannot enableUsbIpServing due to error listing Interfaces" + e); 1829 return; 1830 } 1831 1832 final TetheringRequest request = mRequestTracker.getOrCreatePendingRequest(tetheringType); 1833 if (ifaces != null) { 1834 for (String iface : ifaces) { 1835 if (ifaceNameToType(iface) == tetheringType) { 1836 enableIpServing(request, iface, forNcmFunction); 1837 return; 1838 } 1839 } 1840 } 1841 1842 mLog.e("could not enable IpServer for function " + (forNcmFunction ? "NCM" : "RNDIS")); 1843 } 1844 disableUsbIpServing(boolean forNcmFunction)1845 private void disableUsbIpServing(boolean forNcmFunction) { 1846 for (int i = 0; i < mTetherStates.size(); i++) { 1847 final TetherState state = mTetherStates.valueAt(i); 1848 final int type = state.ipServer.interfaceType(); 1849 if (type != TETHERING_USB && type != TETHERING_NCM) continue; 1850 1851 if (state.isNcm == forNcmFunction) { 1852 ensureIpServerStopped(state.ipServer.interfaceName()); 1853 } 1854 } 1855 } 1856 getTetheringConfiguration()1857 TetheringConfiguration getTetheringConfiguration() { 1858 return mConfig; 1859 } 1860 isEthernetSupported()1861 private boolean isEthernetSupported() { 1862 return mContext.getSystemService(Context.ETHERNET_SERVICE) != null; 1863 } 1864 setUsbTethering(boolean enable, IIntResultListener listener)1865 void setUsbTethering(boolean enable, IIntResultListener listener) { 1866 mHandler.post(() -> { 1867 sendTetherResult(listener, setUsbTethering(enable)); 1868 }); 1869 } 1870 setUsbTethering(boolean enable)1871 private int setUsbTethering(boolean enable) { 1872 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")"); 1873 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); 1874 if (usbManager == null) { 1875 mLog.e("setUsbTethering: failed to get UsbManager!"); 1876 return TETHER_ERROR_SERVICE_UNAVAIL; 1877 } 1878 1879 final long usbFunction = mConfig.isUsingNcm() 1880 ? UsbManager.FUNCTION_NCM : UsbManager.FUNCTION_RNDIS; 1881 usbManager.setCurrentFunctions(enable ? usbFunction : UsbManager.FUNCTION_NONE); 1882 1883 return TETHER_ERROR_NO_ERROR; 1884 } 1885 setNcmTethering(boolean enable)1886 private int setNcmTethering(boolean enable) { 1887 if (VDBG) Log.d(TAG, "setNcmTethering(" + enable + ")"); 1888 1889 // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be 1890 // available. 1891 if (mConfig.isUsingNcm() && enable) return TETHER_ERROR_SERVICE_UNAVAIL; 1892 1893 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); 1894 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_NCM : UsbManager.FUNCTION_NONE); 1895 return TETHER_ERROR_NO_ERROR; 1896 } 1897 1898 // TODO review API - figure out how to delete these entirely. getTetheredIfaces()1899 String[] getTetheredIfaces() { 1900 ArrayList<String> list = new ArrayList<String>(); 1901 for (int i = 0; i < mTetherStates.size(); i++) { 1902 TetherState tetherState = mTetherStates.valueAt(i); 1903 if (tetherState.lastState == IpServer.STATE_TETHERED) { 1904 list.add(mTetherStates.keyAt(i)); 1905 } 1906 } 1907 return list.toArray(new String[list.size()]); 1908 } 1909 getTetherableIfacesForTest()1910 String[] getTetherableIfacesForTest() { 1911 ArrayList<String> list = new ArrayList<String>(); 1912 for (int i = 0; i < mTetherStates.size(); i++) { 1913 TetherState tetherState = mTetherStates.valueAt(i); 1914 if (tetherState.lastState == IpServer.STATE_AVAILABLE) { 1915 list.add(mTetherStates.keyAt(i)); 1916 } 1917 } 1918 return list.toArray(new String[list.size()]); 1919 } 1920 logMessage(State state, int what)1921 private void logMessage(State state, int what) { 1922 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what))); 1923 } 1924 1925 // Needed because the canonical source of upstream truth is just the 1926 // upstream interface set, |mCurrentUpstreamIfaceSet|. pertainsToCurrentUpstream(UpstreamNetworkState ns)1927 private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) { 1928 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) { 1929 for (String ifname : ns.linkProperties.getAllInterfaceNames()) { 1930 if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) { 1931 return true; 1932 } 1933 } 1934 } 1935 return false; 1936 } 1937 1938 class TetherMainSM extends StateMachine { 1939 // an interface SM has requested Tethering/Local Hotspot 1940 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MAIN_SM + 1; 1941 // an interface SM has unrequested Tethering/Local Hotspot 1942 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MAIN_SM + 2; 1943 // upstream connection change - do the right thing 1944 static final int CMD_UPSTREAM_CHANGED = BASE_MAIN_SM + 3; 1945 // we don't have a valid upstream conn, check again after a delay 1946 static final int CMD_RETRY_UPSTREAM = BASE_MAIN_SM + 4; 1947 // Events from NetworkCallbacks that we process on the main state 1948 // machine thread on behalf of the UpstreamNetworkMonitor. 1949 static final int EVENT_UPSTREAM_CALLBACK = BASE_MAIN_SM + 5; 1950 // we treated the error and want now to clear it 1951 static final int CMD_CLEAR_ERROR = BASE_MAIN_SM + 6; 1952 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MAIN_SM + 7; 1953 // Events from EntitlementManager to choose upstream again. 1954 static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MAIN_SM + 8; 1955 // Internal request from IpServer to enable or disable downstream. 1956 static final int EVENT_REQUEST_CHANGE_DOWNSTREAM = BASE_MAIN_SM + 9; 1957 private final State mInitialState; 1958 private final State mTetherModeAliveState; 1959 1960 private final State mSetIpForwardingEnabledErrorState; 1961 private final State mSetIpForwardingDisabledErrorState; 1962 private final State mStartTetheringErrorState; 1963 private final State mStopTetheringErrorState; 1964 private final State mSetDnsForwardersErrorState; 1965 1966 // This list is a little subtle. It contains all the interfaces that currently are 1967 // requesting tethering, regardless of whether these interfaces are still members of 1968 // mTetherStates. This allows us to maintain the following predicates: 1969 // 1970 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up 1971 // interfaces. 1972 // 2) mNotifyList contains all state machines that may have outstanding tethering state 1973 // that needs to be torn down. 1974 // 3) Use mNotifyList for predictable ordering order for ConnectedClientsTracker. 1975 // 1976 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList 1977 // so that the garbage collector does not clean up the state machine before it has a chance 1978 // to tear itself down. 1979 private final ArrayList<IpServer> mNotifyList; 1980 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator; 1981 private final OffloadWrapper mOffload; 1982 // TODO: Figure out how to merge this and other downstream-tracking objects 1983 // into a single coherent structure. 1984 private final HashSet<IpServer> mForwardedDownstreams; 1985 1986 private static final int UPSTREAM_SETTLE_TIME_MS = 10000; 1987 TetherMainSM(String name, Looper looper, TetheringDependencies deps)1988 TetherMainSM(String name, Looper looper, TetheringDependencies deps) { 1989 super(name, looper); 1990 1991 mForwardedDownstreams = new HashSet<>(); 1992 mInitialState = new InitialState(); 1993 mTetherModeAliveState = new TetherModeAliveState(); 1994 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); 1995 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState(); 1996 mStartTetheringErrorState = new StartTetheringErrorState(); 1997 mStopTetheringErrorState = new StopTetheringErrorState(); 1998 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); 1999 2000 addState(mInitialState); 2001 addState(mTetherModeAliveState); 2002 addState(mSetIpForwardingEnabledErrorState); 2003 addState(mSetIpForwardingDisabledErrorState); 2004 addState(mStartTetheringErrorState); 2005 addState(mStopTetheringErrorState); 2006 addState(mSetDnsForwardersErrorState); 2007 2008 mNotifyList = new ArrayList<>(); 2009 mIPv6TetheringCoordinator = deps.makeIPv6TetheringCoordinator(mNotifyList, mLog); 2010 mOffload = new OffloadWrapper(); 2011 2012 setInitialState(mInitialState); 2013 } 2014 2015 /** 2016 * Returns all downstreams that are serving clients, regardless of they are actually 2017 * tethered or localOnly. This must be called on the tethering thread (not thread-safe). 2018 */ 2019 @NonNull getAllDownstreams()2020 public List<IpServer> getAllDownstreams() { 2021 return mNotifyList; 2022 } 2023 2024 class InitialState extends State { 2025 @Override processMessage(Message message)2026 public boolean processMessage(Message message) { 2027 logMessage(this, message.what); 2028 switch (message.what) { 2029 case EVENT_IFACE_SERVING_STATE_ACTIVE: { 2030 final IpServer who = (IpServer) message.obj; 2031 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); 2032 handleInterfaceServingStateActive(message.arg1, who); 2033 transitionTo(mTetherModeAliveState); 2034 break; 2035 } 2036 case EVENT_IFACE_SERVING_STATE_INACTIVE: { 2037 final IpServer who = (IpServer) message.obj; 2038 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); 2039 handleInterfaceServingStateInactive(who); 2040 break; 2041 } 2042 case EVENT_IFACE_UPDATE_LINKPROPERTIES: 2043 // Silently ignore these for now. 2044 break; 2045 default: 2046 return NOT_HANDLED; 2047 } 2048 return HANDLED; 2049 } 2050 } 2051 turnOnMainTetherSettings()2052 protected boolean turnOnMainTetherSettings() { 2053 final TetheringConfiguration cfg = mConfig; 2054 try { 2055 mNetd.ipfwdEnableForwarding(TAG); 2056 } catch (RemoteException | ServiceSpecificException e) { 2057 mLog.e(e); 2058 transitionTo(mSetIpForwardingEnabledErrorState); 2059 return false; 2060 } 2061 2062 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode. 2063 // Legacy DHCP server is disabled if passed an empty ranges array 2064 final String[] dhcpRanges = cfg.useLegacyDhcpServer() 2065 ? cfg.legacyDhcpRanges : new String[0]; 2066 try { 2067 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges); 2068 } catch (RemoteException | ServiceSpecificException e) { 2069 try { 2070 // Stop and retry. 2071 mNetd.tetherStop(); 2072 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges); 2073 } catch (RemoteException | ServiceSpecificException ee) { 2074 mLog.e(ee); 2075 transitionTo(mStartTetheringErrorState); 2076 return false; 2077 } 2078 } 2079 mLog.log("SET main tether settings: ON"); 2080 return true; 2081 } 2082 turnOffMainTetherSettings()2083 protected boolean turnOffMainTetherSettings() { 2084 try { 2085 mNetd.tetherStop(); 2086 } catch (RemoteException | ServiceSpecificException e) { 2087 mLog.e(e); 2088 transitionTo(mStopTetheringErrorState); 2089 return false; 2090 } 2091 try { 2092 mNetd.ipfwdDisableForwarding(TAG); 2093 } catch (RemoteException | ServiceSpecificException e) { 2094 mLog.e(e); 2095 transitionTo(mSetIpForwardingDisabledErrorState); 2096 return false; 2097 } 2098 transitionTo(mInitialState); 2099 mLog.log("SET main tether settings: OFF"); 2100 return true; 2101 } 2102 chooseUpstreamType(boolean tryCell)2103 protected void chooseUpstreamType(boolean tryCell) { 2104 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we 2105 // do not currently know how to watch for changes in DUN settings. 2106 maybeDunSettingChanged(); 2107 2108 final TetheringConfiguration config = mConfig; 2109 final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically) 2110 ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream() 2111 : mUpstreamNetworkMonitor.selectPreferredUpstreamType( 2112 config.preferredUpstreamIfaceTypes); 2113 2114 if (ns == null) { 2115 if (tryCell) { 2116 mUpstreamNetworkMonitor.setTryCell(true); 2117 // We think mobile should be coming up; don't set a retry. 2118 } else { 2119 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS); 2120 } 2121 } else if (!isCellular(ns)) { 2122 mUpstreamNetworkMonitor.setTryCell(false); 2123 } 2124 2125 setUpstreamNetwork(ns); 2126 final Network newUpstream = (ns != null) ? ns.network : null; 2127 if (!Objects.equals(mTetherUpstream, newUpstream)) { 2128 mTetherUpstream = newUpstream; 2129 reportUpstreamChanged(mTetherUpstream); 2130 // Need to notify capabilities change after upstream network changed because 2131 // upstream may switch to existing network which don't have 2132 // UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES callback. 2133 mNotificationUpdater.onUpstreamCapabilitiesChanged( 2134 (ns != null) ? ns.networkCapabilities : null); 2135 } 2136 mTetheringMetrics.maybeUpdateUpstreamType(ns); 2137 } 2138 setUpstreamNetwork(UpstreamNetworkState ns)2139 protected void setUpstreamNetwork(UpstreamNetworkState ns) { 2140 InterfaceSet ifaces = null; 2141 if (ns != null) { 2142 // Find the interface with the default IPv4 route. It may be the 2143 // interface described by linkProperties, or one of the interfaces 2144 // stacked on top of it. 2145 mLog.i("Looking for default routes on: " + ns.linkProperties); 2146 ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns); 2147 mLog.i("Found upstream interface(s): " + ifaces); 2148 } 2149 2150 if (ifaces != null) { 2151 setDnsForwarders(ns.network, ns.linkProperties); 2152 } 2153 notifyDownstreamsOfNewUpstreamIface(ifaces); 2154 if (ns != null && pertainsToCurrentUpstream(ns)) { 2155 // If we already have UpstreamNetworkState for this network update it immediately. 2156 handleNewUpstreamNetworkState(ns); 2157 } else if (mCurrentUpstreamIfaceSet == null) { 2158 // There are no available upstream networks. 2159 handleNewUpstreamNetworkState(null); 2160 } 2161 } 2162 setDnsForwarders(final Network network, final LinkProperties lp)2163 protected void setDnsForwarders(final Network network, final LinkProperties lp) { 2164 // TODO: Set v4 and/or v6 DNS per available connectivity. 2165 final Collection<InetAddress> dnses = lp.getDnsServers(); 2166 // TODO: Properly support the absence of DNS servers. 2167 final String[] dnsServers; 2168 if (dnses != null && !dnses.isEmpty()) { 2169 dnsServers = new String[dnses.size()]; 2170 int i = 0; 2171 for (InetAddress dns : dnses) { 2172 dnsServers[i++] = dns.getHostAddress(); 2173 } 2174 } else { 2175 dnsServers = mConfig.defaultIPv4DNS; 2176 } 2177 final int netId = (network != null) ? network.getNetId() : NETID_UNSET; 2178 try { 2179 mNetd.tetherDnsSet(netId, dnsServers); 2180 mLog.log(String.format( 2181 "SET DNS forwarders: network=%s dnsServers=%s", 2182 network, Arrays.toString(dnsServers))); 2183 } catch (RemoteException | ServiceSpecificException e) { 2184 // TODO: Investigate how this can fail and what exactly 2185 // happens if/when such failures occur. 2186 mLog.e("setting DNS forwarders failed, " + e); 2187 transitionTo(mSetDnsForwardersErrorState); 2188 } 2189 } 2190 notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces)2191 protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) { 2192 mCurrentUpstreamIfaceSet = ifaces; 2193 for (IpServer ipServer : mNotifyList) { 2194 ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces); 2195 } 2196 } 2197 handleNewUpstreamNetworkState(UpstreamNetworkState ns)2198 protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) { 2199 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns); 2200 mOffload.updateUpstreamNetworkState(ns); 2201 mBpfCoordinator.updateUpstreamNetworkState(ns); 2202 } 2203 handleInterfaceServingStateActive(int mode, IpServer who)2204 private void handleInterfaceServingStateActive(int mode, IpServer who) { 2205 if (mNotifyList.indexOf(who) < 0) { 2206 mNotifyList.add(who); 2207 mIPv6TetheringCoordinator.addActiveDownstream(who, mode); 2208 } 2209 2210 if (mode == IpServer.STATE_TETHERED) { 2211 // No need to notify OffloadController just yet as there are no 2212 // "offload-able" prefixes to pass along. This will handled 2213 // when the TISM informs Tethering of its LinkProperties. 2214 mForwardedDownstreams.add(who); 2215 } else { 2216 mOffload.excludeDownstreamInterface(who.interfaceName()); 2217 mForwardedDownstreams.remove(who); 2218 } 2219 2220 // If this is a Wi-Fi interface, notify WifiManager of the active serving state. 2221 if (who.interfaceType() == TETHERING_WIFI) { 2222 final WifiManager mgr = getWifiManager(); 2223 final String iface = who.interfaceName(); 2224 switch (mode) { 2225 case IpServer.STATE_TETHERED: 2226 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED); 2227 break; 2228 case IpServer.STATE_LOCAL_ONLY: 2229 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY); 2230 break; 2231 default: 2232 Log.wtf(TAG, "Unknown active serving mode: " + mode); 2233 break; 2234 } 2235 } 2236 } 2237 handleInterfaceServingStateInactive(IpServer who)2238 private void handleInterfaceServingStateInactive(IpServer who) { 2239 mNotifyList.remove(who); 2240 mIPv6TetheringCoordinator.removeActiveDownstream(who); 2241 mOffload.excludeDownstreamInterface(who.interfaceName()); 2242 mForwardedDownstreams.remove(who); 2243 maybeDhcpLeasesChanged(); 2244 2245 // If this is a Wi-Fi interface, tell WifiManager of any errors 2246 // or the inactive serving state. 2247 if (who.interfaceType() == TETHERING_WIFI) { 2248 final WifiManager mgr = getWifiManager(); 2249 final String iface = who.interfaceName(); 2250 if (mgr == null) { 2251 Log.wtf(TAG, "Skipping WifiManager notification about inactive tethering"); 2252 } else if (who.lastError() != TETHER_ERROR_NO_ERROR) { 2253 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_CONFIGURATION_ERROR); 2254 } else { 2255 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_UNSPECIFIED); 2256 } 2257 } 2258 } 2259 2260 @VisibleForTesting handleUpstreamNetworkMonitorCallback(int arg1, Object o)2261 void handleUpstreamNetworkMonitorCallback(int arg1, Object o) { 2262 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) { 2263 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o); 2264 return; 2265 } 2266 2267 final UpstreamNetworkState ns = (UpstreamNetworkState) o; 2268 switch (arg1) { 2269 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: 2270 mRoutingCoordinator.updateUpstreamPrefix( 2271 ns.linkProperties, ns.networkCapabilities, ns.network); 2272 break; 2273 case UpstreamNetworkMonitor.EVENT_ON_LOST: 2274 mRoutingCoordinator.removeUpstreamPrefix(ns.network); 2275 break; 2276 } 2277 2278 if (mConfig.chooseUpstreamAutomatically 2279 && arg1 == UpstreamNetworkMonitor.EVENT_DEFAULT_SWITCHED) { 2280 chooseUpstreamType(true); 2281 return; 2282 } 2283 2284 if (ns == null || !pertainsToCurrentUpstream(ns)) { 2285 // TODO: In future, this is where upstream evaluation and selection 2286 // could be handled for notifications which include sufficient data. 2287 // For example, after CONNECTIVITY_ACTION listening is removed, here 2288 // is where we could observe a Wi-Fi network becoming available and 2289 // passing validation. 2290 if (mCurrentUpstreamIfaceSet == null) { 2291 // If we have no upstream interface, try to run through upstream 2292 // selection again. If, for example, IPv4 connectivity has shown up 2293 // after IPv6 (e.g., 464xlat became available) we want the chance to 2294 // notice and act accordingly. 2295 chooseUpstreamType(false); 2296 } 2297 return; 2298 } 2299 2300 switch (arg1) { 2301 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES: 2302 if (ns.network.equals(mTetherUpstream)) { 2303 mNotificationUpdater.onUpstreamCapabilitiesChanged(ns.networkCapabilities); 2304 } 2305 handleNewUpstreamNetworkState(ns); 2306 break; 2307 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: 2308 chooseUpstreamType(false); 2309 break; 2310 case UpstreamNetworkMonitor.EVENT_ON_LOST: 2311 // TODO: Re-evaluate possible upstreams. Currently upstream 2312 // reevaluation is triggered via received CONNECTIVITY_ACTION 2313 // broadcasts that result in being passed a 2314 // TetherMainSM.CMD_UPSTREAM_CHANGED. 2315 handleNewUpstreamNetworkState(null); 2316 2317 if (SdkLevel.isAtLeastU()) { 2318 // Need to try DUN immediately if Wi-Fi goes down. 2319 chooseUpstreamType(true); 2320 } 2321 break; 2322 default: 2323 mLog.e("Unknown arg1 value: " + arg1); 2324 break; 2325 } 2326 } 2327 upstreamWanted()2328 private boolean upstreamWanted() { 2329 return !mForwardedDownstreams.isEmpty(); 2330 } 2331 2332 class TetherModeAliveState extends State { 2333 boolean mUpstreamWanted = false; 2334 boolean mTryCell = true; 2335 2336 @Override enter()2337 public void enter() { 2338 // If turning on main tether settings fails, we have already 2339 // transitioned to an error state; exit early. 2340 if (!turnOnMainTetherSettings()) { 2341 return; 2342 } 2343 2344 mRoutingCoordinator.maybeRemoveDeprecatedUpstreams(); 2345 mUpstreamNetworkMonitor.startObserveUpstreamNetworks(); 2346 2347 // TODO: De-duplicate with updateUpstreamWanted() below. 2348 if (upstreamWanted()) { 2349 mUpstreamWanted = true; 2350 mOffload.start(); 2351 chooseUpstreamType(true); 2352 mTryCell = false; 2353 } 2354 mTetheringMetrics.initUpstreamUsageBaseline(); 2355 } 2356 2357 @Override exit()2358 public void exit() { 2359 mOffload.stop(); 2360 mUpstreamNetworkMonitor.stop(); 2361 notifyDownstreamsOfNewUpstreamIface(null); 2362 handleNewUpstreamNetworkState(null); 2363 if (mTetherUpstream != null) { 2364 mTetherUpstream = null; 2365 reportUpstreamChanged(null); 2366 mNotificationUpdater.onUpstreamCapabilitiesChanged(null); 2367 } 2368 mTetheringMetrics.cleanup(); 2369 } 2370 updateUpstreamWanted()2371 private boolean updateUpstreamWanted() { 2372 final boolean previousUpstreamWanted = mUpstreamWanted; 2373 mUpstreamWanted = upstreamWanted(); 2374 if (mUpstreamWanted != previousUpstreamWanted) { 2375 if (mUpstreamWanted) { 2376 mOffload.start(); 2377 } else { 2378 mOffload.stop(); 2379 } 2380 } 2381 return previousUpstreamWanted; 2382 } 2383 2384 @Override processMessage(Message message)2385 public boolean processMessage(Message message) { 2386 logMessage(this, message.what); 2387 boolean retValue = true; 2388 switch (message.what) { 2389 case EVENT_IFACE_SERVING_STATE_ACTIVE: { 2390 IpServer who = (IpServer) message.obj; 2391 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); 2392 handleInterfaceServingStateActive(message.arg1, who); 2393 who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, 2394 mCurrentUpstreamIfaceSet); 2395 // If there has been a change and an upstream is now 2396 // desired, kick off the selection process. 2397 final boolean previousUpstreamWanted = updateUpstreamWanted(); 2398 if (!previousUpstreamWanted && mUpstreamWanted) { 2399 chooseUpstreamType(true); 2400 } 2401 break; 2402 } 2403 case EVENT_IFACE_SERVING_STATE_INACTIVE: { 2404 IpServer who = (IpServer) message.obj; 2405 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); 2406 handleInterfaceServingStateInactive(who); 2407 2408 if (mNotifyList.isEmpty()) { 2409 // This transitions us out of TetherModeAliveState, 2410 // either to InitialState or an error state. 2411 turnOffMainTetherSettings(); 2412 break; 2413 } 2414 2415 if (DBG) { 2416 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() 2417 + " live requests:"); 2418 for (IpServer o : mNotifyList) { 2419 Log.d(TAG, " " + o); 2420 } 2421 } 2422 // If there has been a change and an upstream is no 2423 // longer desired, release any mobile requests. 2424 final boolean previousUpstreamWanted = updateUpstreamWanted(); 2425 if (previousUpstreamWanted && !mUpstreamWanted) { 2426 mUpstreamNetworkMonitor.setTryCell(false); 2427 } 2428 break; 2429 } 2430 case EVENT_IFACE_UPDATE_LINKPROPERTIES: { 2431 final LinkProperties newLp = (LinkProperties) message.obj; 2432 if (message.arg1 == IpServer.STATE_TETHERED) { 2433 mOffload.updateDownstreamLinkProperties(newLp); 2434 } else { 2435 mOffload.excludeDownstreamInterface(newLp.getInterfaceName()); 2436 } 2437 break; 2438 } 2439 case EVENT_UPSTREAM_PERMISSION_CHANGED: 2440 case CMD_UPSTREAM_CHANGED: 2441 updateUpstreamWanted(); 2442 if (!mUpstreamWanted) break; 2443 2444 // Need to try DUN immediately if Wi-Fi goes down. 2445 chooseUpstreamType(true); 2446 mTryCell = false; 2447 break; 2448 case CMD_RETRY_UPSTREAM: 2449 updateUpstreamWanted(); 2450 if (!mUpstreamWanted) break; 2451 2452 chooseUpstreamType(mTryCell); 2453 mTryCell = !mTryCell; 2454 break; 2455 case EVENT_UPSTREAM_CALLBACK: { 2456 updateUpstreamWanted(); 2457 if (mUpstreamWanted) { 2458 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj); 2459 } 2460 break; 2461 } 2462 case EVENT_REQUEST_CHANGE_DOWNSTREAM: { 2463 final int type = message.arg1; 2464 final Boolean enabled = (Boolean) message.obj; 2465 // Using a placeholder here is ok since we just need to the type of 2466 // tethering to poke the link layer. When the link layer comes up, we won't 2467 // have a pending request to use, but this matches the historical behavior. 2468 // TODO: Get the TetheringRequest from IpServer and make sure to put it in 2469 // the pending list too. 2470 enableTetheringInternal(enabled, createPlaceholderRequest(type), null); 2471 break; 2472 } 2473 default: 2474 retValue = false; 2475 break; 2476 } 2477 return retValue; 2478 } 2479 } 2480 2481 class ErrorState extends State { 2482 private int mErrorNotification; 2483 2484 @Override processMessage(Message message)2485 public boolean processMessage(Message message) { 2486 boolean retValue = true; 2487 switch (message.what) { 2488 case EVENT_IFACE_SERVING_STATE_ACTIVE: 2489 IpServer who = (IpServer) message.obj; 2490 who.sendMessage(mErrorNotification); 2491 break; 2492 case CMD_CLEAR_ERROR: 2493 mErrorNotification = TETHER_ERROR_NO_ERROR; 2494 transitionTo(mInitialState); 2495 break; 2496 default: 2497 retValue = false; 2498 } 2499 return retValue; 2500 } 2501 notify(int msgType)2502 void notify(int msgType) { 2503 mErrorNotification = msgType; 2504 for (IpServer ipServer : mNotifyList) { 2505 ipServer.sendMessage(msgType); 2506 } 2507 } 2508 2509 } 2510 2511 class SetIpForwardingEnabledErrorState extends ErrorState { 2512 @Override enter()2513 public void enter() { 2514 Log.e(TAG, "Error in setIpForwardingEnabled"); 2515 notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR); 2516 } 2517 } 2518 2519 class SetIpForwardingDisabledErrorState extends ErrorState { 2520 @Override enter()2521 public void enter() { 2522 Log.e(TAG, "Error in setIpForwardingDisabled"); 2523 notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR); 2524 } 2525 } 2526 2527 class StartTetheringErrorState extends ErrorState { 2528 @Override enter()2529 public void enter() { 2530 Log.e(TAG, "Error in startTethering"); 2531 notify(IpServer.CMD_START_TETHERING_ERROR); 2532 try { 2533 mNetd.ipfwdDisableForwarding(TAG); 2534 } catch (RemoteException | ServiceSpecificException e) { } 2535 } 2536 } 2537 2538 class StopTetheringErrorState extends ErrorState { 2539 @Override enter()2540 public void enter() { 2541 Log.e(TAG, "Error in stopTethering"); 2542 notify(IpServer.CMD_STOP_TETHERING_ERROR); 2543 try { 2544 mNetd.ipfwdDisableForwarding(TAG); 2545 } catch (RemoteException | ServiceSpecificException e) { } 2546 } 2547 } 2548 2549 class SetDnsForwardersErrorState extends ErrorState { 2550 @Override enter()2551 public void enter() { 2552 Log.e(TAG, "Error in setDnsForwarders"); 2553 notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR); 2554 try { 2555 mNetd.tetherStop(); 2556 } catch (RemoteException | ServiceSpecificException e) { } 2557 try { 2558 mNetd.ipfwdDisableForwarding(TAG); 2559 } catch (RemoteException | ServiceSpecificException e) { } 2560 } 2561 } 2562 2563 // A wrapper class to handle multiple situations where several calls to 2564 // the OffloadController need to happen together. 2565 // 2566 // TODO: This suggests that the interface between OffloadController and 2567 // Tethering is in need of improvement. Refactor these calls into the 2568 // OffloadController implementation. 2569 class OffloadWrapper { start()2570 public void start() { 2571 final int status = mOffloadController.start() ? TETHER_HARDWARE_OFFLOAD_STARTED 2572 : TETHER_HARDWARE_OFFLOAD_FAILED; 2573 updateOffloadStatus(status); 2574 sendOffloadExemptPrefixes(); 2575 } 2576 stop()2577 public void stop() { 2578 mOffloadController.stop(); 2579 updateOffloadStatus(TETHER_HARDWARE_OFFLOAD_STOPPED); 2580 } 2581 updateUpstreamNetworkState(UpstreamNetworkState ns)2582 public void updateUpstreamNetworkState(UpstreamNetworkState ns) { 2583 mOffloadController.setUpstreamLinkProperties( 2584 (ns != null) ? ns.linkProperties : null); 2585 } 2586 updateDownstreamLinkProperties(LinkProperties newLp)2587 public void updateDownstreamLinkProperties(LinkProperties newLp) { 2588 // Update the list of offload-exempt prefixes before adding 2589 // new prefixes on downstream interfaces to the offload HAL. 2590 sendOffloadExemptPrefixes(); 2591 mOffloadController.notifyDownstreamLinkProperties(newLp); 2592 } 2593 excludeDownstreamInterface(String ifname)2594 public void excludeDownstreamInterface(String ifname) { 2595 // This and other interfaces may be in local-only hotspot mode; 2596 // resend all local prefixes to the OffloadController. 2597 sendOffloadExemptPrefixes(); 2598 mOffloadController.removeDownstreamInterface(ifname); 2599 } 2600 sendOffloadExemptPrefixes()2601 public void sendOffloadExemptPrefixes() { 2602 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes()); 2603 } 2604 sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes)2605 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) { 2606 // Add in well-known minimum set. 2607 PrefixUtils.addNonForwardablePrefixes(localPrefixes); 2608 // Add tragically hardcoded prefixes. 2609 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX); 2610 2611 // Maybe add prefixes or addresses for downstreams, depending on 2612 // the IP serving mode of each. 2613 for (IpServer ipServer : mNotifyList) { 2614 final LinkProperties lp = ipServer.linkProperties(); 2615 2616 switch (ipServer.servingMode()) { 2617 case IpServer.STATE_UNAVAILABLE: 2618 case IpServer.STATE_AVAILABLE: 2619 // No usable LinkProperties in these states. 2620 continue; 2621 case IpServer.STATE_TETHERED: 2622 // Only add IPv4 /32 and IPv6 /128 prefixes. The 2623 // directly-connected prefixes will be sent as 2624 // downstream "offload-able" prefixes. 2625 for (LinkAddress addr : lp.getAllLinkAddresses()) { 2626 final InetAddress ip = addr.getAddress(); 2627 if (ip.isLinkLocalAddress()) continue; 2628 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip)); 2629 } 2630 break; 2631 case IpServer.STATE_LOCAL_ONLY: 2632 // Add prefixes covering all local IPs. 2633 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp)); 2634 break; 2635 } 2636 } 2637 2638 mOffloadController.setLocalPrefixes(localPrefixes); 2639 } 2640 updateOffloadStatus(final int newStatus)2641 private void updateOffloadStatus(final int newStatus) { 2642 if (newStatus == mOffloadStatus) return; 2643 2644 mOffloadStatus = newStatus; 2645 reportOffloadStatusChanged(mOffloadStatus); 2646 } 2647 } 2648 } 2649 startTrackDefaultNetwork()2650 private void startTrackDefaultNetwork() { 2651 mUpstreamNetworkMonitor.startTrackDefaultNetwork(mEntitlementMgr); 2652 } 2653 2654 /** Get the latest value of the tethering entitlement check. */ requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi)2655 void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, 2656 boolean showEntitlementUi) { 2657 if (receiver == null) return; 2658 2659 mHandler.post(() -> { 2660 mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver, 2661 showEntitlementUi); 2662 }); 2663 } 2664 2665 /** Register tethering event callback */ registerTetheringEventCallback(ITetheringEventCallback callback)2666 void registerTetheringEventCallback(ITetheringEventCallback callback) { 2667 final int uid = mDeps.getBinderCallingUid(); 2668 final boolean hasSystemPrivilege = hasCallingPermission(NETWORK_SETTINGS) 2669 || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK) 2670 || hasCallingPermission(NETWORK_STACK); 2671 mHandler.post(() -> { 2672 CallbackCookie cookie = new CallbackCookie(uid, hasSystemPrivilege); 2673 mTetheringEventCallbacks.register(callback, cookie); 2674 final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel(); 2675 parcel.supportedTypes = mSupportedTypeBitmap; 2676 parcel.upstreamNetwork = mTetherUpstream; 2677 parcel.config = mConfig.toStableParcelable(); 2678 parcel.states = buildTetherStatesParcel(cookie); 2679 parcel.tetheredClients = hasSystemPrivilege 2680 ? mConnectedClientsTracker.getLastTetheredClients() 2681 : Collections.emptyList(); 2682 parcel.offloadStatus = mOffloadStatus; 2683 try { 2684 callback.onCallbackStarted(parcel); 2685 } catch (RemoteException e) { 2686 // Not really very much to do here. 2687 } 2688 }); 2689 } 2690 hasCallingPermission(@onNull String permission)2691 private boolean hasCallingPermission(@NonNull String permission) { 2692 return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; 2693 } 2694 2695 /** Unregister tethering event callback */ unregisterTetheringEventCallback(ITetheringEventCallback callback)2696 void unregisterTetheringEventCallback(ITetheringEventCallback callback) { 2697 mHandler.post(() -> { 2698 mTetheringEventCallbacks.unregister(callback); 2699 }); 2700 } 2701 reportTetheringSupportedChange(final long supportedBitmap)2702 private void reportTetheringSupportedChange(final long supportedBitmap) { 2703 final int length = mTetheringEventCallbacks.beginBroadcast(); 2704 try { 2705 for (int i = 0; i < length; i++) { 2706 try { 2707 mTetheringEventCallbacks.getBroadcastItem(i).onSupportedTetheringTypes( 2708 supportedBitmap); 2709 } catch (RemoteException e) { 2710 // Not really very much to do here. 2711 } 2712 } 2713 } finally { 2714 mTetheringEventCallbacks.finishBroadcast(); 2715 } 2716 } 2717 reportUpstreamChanged(final Network network)2718 private void reportUpstreamChanged(final Network network) { 2719 final int length = mTetheringEventCallbacks.beginBroadcast(); 2720 try { 2721 for (int i = 0; i < length; i++) { 2722 try { 2723 mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network); 2724 } catch (RemoteException e) { 2725 // Not really very much to do here. 2726 } 2727 } 2728 } finally { 2729 mTetheringEventCallbacks.finishBroadcast(); 2730 } 2731 } 2732 reportConfigurationChanged(TetheringConfigurationParcel config)2733 private void reportConfigurationChanged(TetheringConfigurationParcel config) { 2734 final int length = mTetheringEventCallbacks.beginBroadcast(); 2735 try { 2736 for (int i = 0; i < length; i++) { 2737 try { 2738 mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config); 2739 // TODO(b/148139325): send tetheringSupported on configuration change 2740 } catch (RemoteException e) { 2741 // Not really very much to do here. 2742 } 2743 } 2744 } finally { 2745 mTetheringEventCallbacks.finishBroadcast(); 2746 } 2747 } 2748 sendTetherStatesChangedCallback()2749 private void sendTetherStatesChangedCallback() { 2750 final int length = mTetheringEventCallbacks.beginBroadcast(); 2751 try { 2752 for (int i = 0; i < length; i++) { 2753 try { 2754 TetherStatesParcel parcel = buildTetherStatesParcel( 2755 (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i)); 2756 mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(parcel); 2757 } catch (RemoteException e) { 2758 // Not really very much to do here. 2759 } 2760 } 2761 } finally { 2762 mTetheringEventCallbacks.finishBroadcast(); 2763 } 2764 2765 if (DBG) { 2766 // Use a CallbackCookie with system privilege so nothing is redacted. 2767 TetherStatesParcel parcel = buildTetherStatesParcel( 2768 new CallbackCookie(Process.SYSTEM_UID, true /* hasSystemPrivilege */)); 2769 Log.d(TAG, String.format( 2770 "sendTetherStatesChangedCallback %s=[%s] %s=[%s] %s=[%s] %s=[%s]", 2771 "avail", TextUtils.join(",", Arrays.asList(parcel.availableList)), 2772 "local_only", TextUtils.join(",", Arrays.asList(parcel.localOnlyList)), 2773 "tether", TextUtils.join(",", Arrays.asList(parcel.tetheredList)), 2774 "error", TextUtils.join(",", Arrays.asList(parcel.erroredIfaceList)))); 2775 } 2776 } 2777 reportTetherClientsChanged(List<TetheredClient> clients)2778 private void reportTetherClientsChanged(List<TetheredClient> clients) { 2779 final int length = mTetheringEventCallbacks.beginBroadcast(); 2780 try { 2781 for (int i = 0; i < length; i++) { 2782 try { 2783 final CallbackCookie cookie = 2784 (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i); 2785 if (!cookie.hasSystemPrivilege) continue; 2786 mTetheringEventCallbacks.getBroadcastItem(i).onTetherClientsChanged(clients); 2787 } catch (RemoteException e) { 2788 // Not really very much to do here. 2789 } 2790 } 2791 } finally { 2792 mTetheringEventCallbacks.finishBroadcast(); 2793 } 2794 } 2795 reportOffloadStatusChanged(final int status)2796 private void reportOffloadStatusChanged(final int status) { 2797 final int length = mTetheringEventCallbacks.beginBroadcast(); 2798 try { 2799 for (int i = 0; i < length; i++) { 2800 try { 2801 mTetheringEventCallbacks.getBroadcastItem(i).onOffloadStatusChanged(status); 2802 } catch (RemoteException e) { 2803 // Not really very much to do here. 2804 } 2805 } 2806 } finally { 2807 mTetheringEventCallbacks.finishBroadcast(); 2808 } 2809 } 2810 updateSupportedDownstreams(final TetheringConfiguration config)2811 private void updateSupportedDownstreams(final TetheringConfiguration config) { 2812 final long preSupportedBitmap = mSupportedTypeBitmap; 2813 2814 if (!isTetheringAllowed() || mEntitlementMgr.isProvisioningNeededButUnavailable()) { 2815 mSupportedTypeBitmap = 0; 2816 } else { 2817 mSupportedTypeBitmap = makeSupportedDownstreams(config); 2818 } 2819 2820 if (preSupportedBitmap != mSupportedTypeBitmap) { 2821 reportTetheringSupportedChange(mSupportedTypeBitmap); 2822 } 2823 } 2824 makeSupportedDownstreams(final TetheringConfiguration config)2825 private long makeSupportedDownstreams(final TetheringConfiguration config) { 2826 long types = 0; 2827 if (config.tetherableUsbRegexs.length != 0) types |= (1 << TETHERING_USB); 2828 2829 if (config.tetherableWifiRegexs.length != 0) types |= (1 << TETHERING_WIFI); 2830 2831 if (config.tetherableBluetoothRegexs.length != 0) types |= (1 << TETHERING_BLUETOOTH); 2832 2833 // Before T, isTetheringSupported would return true if wifi, usb and bluetooth tethering are 2834 // disabled (whole tethering settings would be hidden). This means tethering would also not 2835 // support wifi p2p, ethernet tethering and mirrorlink. This is wrong but probably there are 2836 // some devices in the field rely on this to disable tethering entirely. 2837 if (!SdkLevel.isAtLeastT() && types == 0) return types; 2838 2839 if (config.tetherableNcmRegexs.length != 0) types |= (1 << TETHERING_NCM); 2840 2841 if (config.tetherableWifiP2pRegexs.length != 0) types |= (1 << TETHERING_WIFI_P2P); 2842 2843 if (isEthernetSupported()) types |= (1 << TETHERING_ETHERNET); 2844 2845 return types; 2846 } 2847 2848 // if ro.tether.denied = true we default to no tethering 2849 // gservices could set the secure setting to 1 though to enable it on a build where it 2850 // had previously been turned off. isTetheringAllowed()2851 boolean isTetheringAllowed() { 2852 final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1; 2853 final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(), 2854 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0; 2855 return tetherSupported 2856 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); 2857 } 2858 isTetheringSupported()2859 boolean isTetheringSupported() { 2860 return mSupportedTypeBitmap > 0; 2861 } 2862 dumpBpf(IndentingPrintWriter pw)2863 private void dumpBpf(IndentingPrintWriter pw) { 2864 pw.println("BPF offload:"); 2865 pw.increaseIndent(); 2866 mBpfCoordinator.dump(pw); 2867 pw.decreaseIndent(); 2868 } 2869 doDump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2870 void doDump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) { 2871 // Binder.java closes the resource for us. 2872 @SuppressWarnings("resource") final IndentingPrintWriter pw = new IndentingPrintWriter( 2873 writer, " "); 2874 2875 // Used for testing instead of human debug. 2876 if (CollectionUtils.contains(args, "bpfRawMap")) { 2877 mBpfCoordinator.dumpRawMap(pw, args); 2878 return; 2879 } 2880 2881 if (CollectionUtils.contains(args, "bpf")) { 2882 dumpBpf(pw); 2883 return; 2884 } 2885 2886 pw.println("Tethering:"); 2887 pw.increaseIndent(); 2888 2889 pw.println("Callbacks registered: " 2890 + mTetheringEventCallbacks.getRegisteredCallbackCount()); 2891 2892 pw.println("Configuration:"); 2893 pw.increaseIndent(); 2894 final TetheringConfiguration cfg = mConfig; 2895 cfg.dump(pw); 2896 pw.decreaseIndent(); 2897 2898 pw.println("Entitlement:"); 2899 pw.increaseIndent(); 2900 mEntitlementMgr.dump(pw); 2901 pw.decreaseIndent(); 2902 2903 pw.println("Tether state:"); 2904 pw.increaseIndent(); 2905 for (int i = 0; i < mTetherStates.size(); i++) { 2906 final String iface = mTetherStates.keyAt(i); 2907 final TetherState tetherState = mTetherStates.valueAt(i); 2908 pw.print(iface + " - "); 2909 2910 switch (tetherState.lastState) { 2911 case IpServer.STATE_UNAVAILABLE: 2912 pw.print("UnavailableState"); 2913 break; 2914 case IpServer.STATE_AVAILABLE: 2915 pw.print("AvailableState"); 2916 break; 2917 case IpServer.STATE_TETHERED: 2918 pw.print("TetheredState"); 2919 break; 2920 case IpServer.STATE_LOCAL_ONLY: 2921 pw.print("LocalHotspotState"); 2922 break; 2923 default: 2924 pw.print("UnknownState"); 2925 break; 2926 } 2927 pw.println(" - lastError = " + tetherState.lastError); 2928 } 2929 pw.println("Upstream wanted: " + mTetherMainSM.upstreamWanted()); 2930 pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet); 2931 pw.decreaseIndent(); 2932 2933 pw.println("Hardware offload:"); 2934 pw.increaseIndent(); 2935 mOffloadController.dump(pw); 2936 pw.decreaseIndent(); 2937 2938 dumpBpf(pw); 2939 2940 if (mWearableConnectionManager != null) { 2941 pw.println("WearableConnectionManager:"); 2942 pw.increaseIndent(); 2943 mWearableConnectionManager.dump(pw); 2944 pw.decreaseIndent(); 2945 } 2946 2947 pw.println("Log:"); 2948 pw.increaseIndent(); 2949 if (CollectionUtils.contains(args, "--short")) { 2950 pw.println("<log removed for brevity>"); 2951 } else { 2952 mLog.dump(fd, pw, args); 2953 } 2954 pw.decreaseIndent(); 2955 2956 pw.decreaseIndent(); 2957 } 2958 dump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2959 void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) { 2960 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 2961 != PERMISSION_GRANTED) { 2962 writer.println("Permission Denial: can't dump."); 2963 return; 2964 } 2965 2966 if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> doDump(fd, writer, args), 2967 DUMP_TIMEOUT_MS)) { 2968 writer.println("Dump timeout after " + DUMP_TIMEOUT_MS + "ms"); 2969 } 2970 } 2971 maybeDhcpLeasesChanged()2972 private void maybeDhcpLeasesChanged() { 2973 // null means wifi clients did not change. 2974 updateConnectedClients(null, null); 2975 } 2976 updateConnectedClients(final List<WifiClient> wifiClients, final List<WifiClient> localOnlyClients)2977 private void updateConnectedClients(final List<WifiClient> wifiClients, 2978 final List<WifiClient> localOnlyClients) { 2979 if (mConnectedClientsTracker.updateConnectedClients(mTetherMainSM.getAllDownstreams(), 2980 wifiClients, localOnlyClients)) { 2981 reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients()); 2982 } 2983 } 2984 2985 private class ControlCallback extends IpServer.Callback { 2986 @Override updateInterfaceState(IpServer who, int state, int lastError)2987 public void updateInterfaceState(IpServer who, int state, int lastError) { 2988 final String iface = who.interfaceName(); 2989 final TetherState tetherState = mTetherStates.get(iface); 2990 if (tetherState != null && tetherState.ipServer.equals(who)) { 2991 tetherState.lastState = state; 2992 tetherState.lastError = lastError; 2993 } else { 2994 // Note: Even if an IpServer exists for this iface, it may be different from "who" 2995 // if a new IpServer fills the gap before the IpServer.STATE_UNAVAILABLE transition. 2996 // TODO: remove this comment once the sync state machine is enabled everywhere. 2997 if (DBG) Log.d(TAG, "got notification from stale iface " + iface); 2998 } 2999 3000 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, lastError)); 3001 3002 // If TetherMainSM is in ErrorState, TetherMainSM stays there. 3003 // Thus we give a chance for TetherMainSM to recover to InitialState 3004 // by sending CMD_CLEAR_ERROR 3005 if (lastError == TETHER_ERROR_INTERNAL_ERROR) { 3006 mTetherMainSM.sendMessage(TetherMainSM.CMD_CLEAR_ERROR, who); 3007 } 3008 int which; 3009 switch (state) { 3010 case IpServer.STATE_UNAVAILABLE: 3011 which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE; 3012 break; 3013 case IpServer.STATE_AVAILABLE: 3014 if (lastError != TETHER_ERROR_NO_ERROR) { 3015 // IpServer transitioned from an enabled state (STATE_TETHERED or 3016 // STATE_LOCAL_ONLY) back to STATE_AVAILABLE due to an error, so make sure 3017 // we remove the serving request from RequestTracker. 3018 // TODO: don't continue to use IpServers after they have hit an error, and 3019 // instead move them to STATE_UNAVAILABLE. This code can then 3020 // unconditionally remove the serving request whenever the IpServer enters 3021 // STATE_UNAVAILABLE. 3022 mRequestTracker.removeServingRequest(who); 3023 } 3024 which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE; 3025 break; 3026 case IpServer.STATE_TETHERED: 3027 case IpServer.STATE_LOCAL_ONLY: 3028 which = TetherMainSM.EVENT_IFACE_SERVING_STATE_ACTIVE; 3029 break; 3030 default: 3031 Log.wtf(TAG, "Unknown interface state: " + state); 3032 return; 3033 } 3034 mTetherMainSM.sendMessage(which, state, 0, who); 3035 notifyTetherStatesChanged(); 3036 } 3037 3038 @Override updateLinkProperties(IpServer who, LinkProperties newLp)3039 public void updateLinkProperties(IpServer who, LinkProperties newLp) { 3040 final String iface = who.interfaceName(); 3041 final int state; 3042 final TetherState tetherState = mTetherStates.get(iface); 3043 if (tetherState != null && tetherState.ipServer.equals(who)) { 3044 state = tetherState.lastState; 3045 } else { 3046 mLog.log("got notification from stale iface " + iface); 3047 return; 3048 } 3049 3050 mLog.log(String.format( 3051 "OBSERVED LinkProperties update iface=%s state=%s lp=%s", 3052 iface, IpServer.getStateString(state), newLp)); 3053 final int which = TetherMainSM.EVENT_IFACE_UPDATE_LINKPROPERTIES; 3054 mTetherMainSM.sendMessage(which, state, 0, newLp); 3055 } 3056 3057 @Override dhcpLeasesChanged()3058 public void dhcpLeasesChanged() { 3059 maybeDhcpLeasesChanged(); 3060 } 3061 3062 @Override requestEnableTethering(int tetheringType, boolean enabled)3063 public void requestEnableTethering(int tetheringType, boolean enabled) { 3064 mTetherMainSM.sendMessage(TetherMainSM.EVENT_REQUEST_CHANGE_DOWNSTREAM, 3065 tetheringType, 0, enabled ? Boolean.TRUE : Boolean.FALSE); 3066 } 3067 } 3068 hasSystemFeature(final String feature)3069 private boolean hasSystemFeature(final String feature) { 3070 return mContext.getPackageManager().hasSystemFeature(feature); 3071 } 3072 checkTetherableType(int type)3073 private boolean checkTetherableType(int type) { 3074 if ((type == TETHERING_WIFI || type == TETHERING_WIGIG) 3075 && !hasSystemFeature(PackageManager.FEATURE_WIFI)) { 3076 return false; 3077 } 3078 3079 if (type == TETHERING_WIFI_P2P && !hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) { 3080 return false; 3081 } 3082 3083 return type != TETHERING_INVALID; 3084 } 3085 ensureIpServerStartedForInterface(final String iface)3086 private void ensureIpServerStartedForInterface(final String iface) { 3087 // If we don't care about this type of interface, ignore. 3088 final int interfaceType = ifaceNameToType(iface); 3089 if (!checkTetherableType(interfaceType)) { 3090 mLog.log(iface + " is used for " + interfaceType + " which is not tetherable" 3091 + " (-1 == INVALID is expected on upstream interface)"); 3092 return; 3093 } 3094 3095 ensureIpServerStartedForType(iface, interfaceType, false /* isNcm */); 3096 } 3097 ensureIpServerStartedForType(final String iface, int interfaceType, boolean isNcm)3098 private void ensureIpServerStartedForType(final String iface, int interfaceType, 3099 boolean isNcm) { 3100 // If we have already started a TISM for this interface, skip. 3101 if (mTetherStates.containsKey(iface)) { 3102 mLog.log("active iface (" + iface + ") reported as added, ignoring"); 3103 return; 3104 } 3105 3106 mLog.i("adding IpServer for: " + iface); 3107 final TetherState tetherState = new TetherState( 3108 new IpServer(iface, mContext, mHandler, interfaceType, mLog, mNetd, mBpfCoordinator, 3109 mRoutingCoordinator, new ControlCallback(), mConfig, mTetheringMetrics, 3110 mDeps.makeIpServerDependencies()), isNcm); 3111 mTetherStates.put(iface, tetherState); 3112 tetherState.ipServer.start(); 3113 } 3114 ensureIpServerStopped(final String iface)3115 private void ensureIpServerStopped(final String iface) { 3116 final TetherState tetherState = mTetherStates.get(iface); 3117 if (tetherState == null) return; 3118 3119 mRequestTracker.removeServingRequest(tetherState.ipServer); 3120 tetherState.ipServer.stop(); 3121 mLog.i("removing IpServer for: " + iface); 3122 mTetherStates.remove(iface); 3123 } 3124 ensureIpServerUnwanted(final IpServer ipServer)3125 private void ensureIpServerUnwanted(final IpServer ipServer) { 3126 mLog.i("unrequesting IpServer: " + ipServer); 3127 mRequestTracker.removeServingRequest(ipServer); 3128 ipServer.unwanted(); 3129 } 3130 copy(String[] strarray)3131 private static String[] copy(String[] strarray) { 3132 return Arrays.copyOf(strarray, strarray.length); 3133 } 3134 setPreferTestNetworks(final boolean prefer, IIntResultListener listener)3135 void setPreferTestNetworks(final boolean prefer, IIntResultListener listener) { 3136 mHandler.post(() -> { 3137 mUpstreamNetworkMonitor.setPreferTestNetworks(prefer); 3138 sendTetherResult(listener, TETHER_ERROR_NO_ERROR); 3139 }); 3140 } 3141 3142 @VisibleForTesting getTetherMainSMForTesting()3143 public TetherMainSM getTetherMainSMForTesting() { 3144 return mTetherMainSM; 3145 } 3146 } 3147