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