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