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