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