Tethering.java revision 64265d4dcef6b91001f629a5bf5edd013b32b701
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 17package com.android.server.connectivity; 18 19import static android.hardware.usb.UsbManager.USB_CONFIGURED; 20import static android.hardware.usb.UsbManager.USB_CONNECTED; 21import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; 22import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 23import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; 24import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; 25import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; 26import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR; 27import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; 28import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; 29import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED; 30import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; 31import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; 32import static com.android.server.ConnectivityService.SHORT_ARG; 33 34import android.app.Notification; 35import android.app.NotificationManager; 36import android.app.PendingIntent; 37import android.bluetooth.BluetoothAdapter; 38import android.bluetooth.BluetoothPan; 39import android.bluetooth.BluetoothProfile; 40import android.bluetooth.BluetoothProfile.ServiceListener; 41import android.content.BroadcastReceiver; 42import android.content.ComponentName; 43import android.content.Context; 44import android.content.Intent; 45import android.content.IntentFilter; 46import android.content.res.Resources; 47import android.hardware.usb.UsbManager; 48import android.net.ConnectivityManager; 49import android.net.INetworkPolicyManager; 50import android.net.INetworkStatsService; 51import android.net.IpPrefix; 52import android.net.LinkAddress; 53import android.net.LinkProperties; 54import android.net.Network; 55import android.net.NetworkInfo; 56import android.net.NetworkState; 57import android.net.NetworkUtils; 58import android.net.RouteInfo; 59import android.net.util.PrefixUtils; 60import android.net.util.SharedLog; 61import android.net.util.VersionedBroadcastListener; 62import android.net.wifi.WifiManager; 63import android.os.Binder; 64import android.os.Bundle; 65import android.os.Handler; 66import android.os.INetworkManagementService; 67import android.os.Looper; 68import android.os.Message; 69import android.os.Parcel; 70import android.os.PersistableBundle; 71import android.os.RemoteException; 72import android.os.ResultReceiver; 73import android.os.UserHandle; 74import android.os.UserManager; 75import android.os.UserManagerInternal; 76import android.os.UserManagerInternal.UserRestrictionsListener; 77import android.provider.Settings; 78import android.telephony.CarrierConfigManager; 79import android.text.TextUtils; 80import android.util.ArrayMap; 81import android.util.Log; 82import android.util.SparseArray; 83 84import com.android.internal.annotations.VisibleForTesting; 85import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 86import com.android.internal.notification.SystemNotificationChannels; 87import com.android.internal.util.DumpUtils; 88import com.android.internal.util.IndentingPrintWriter; 89import com.android.internal.util.MessageUtils; 90import com.android.internal.util.Protocol; 91import com.android.internal.util.State; 92import com.android.internal.util.StateMachine; 93import com.android.server.LocalServices; 94import com.android.server.connectivity.tethering.IControlsTethering; 95import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; 96import com.android.server.connectivity.tethering.OffloadController; 97import com.android.server.connectivity.tethering.SimChangeListener; 98import com.android.server.connectivity.tethering.TetherInterfaceStateMachine; 99import com.android.server.connectivity.tethering.TetheringConfiguration; 100import com.android.server.connectivity.tethering.TetheringDependencies; 101import com.android.server.connectivity.tethering.UpstreamNetworkMonitor; 102import com.android.server.net.BaseNetworkObserver; 103 104import java.io.FileDescriptor; 105import java.io.PrintWriter; 106import java.net.Inet4Address; 107import java.net.Inet6Address; 108import java.net.InetAddress; 109import java.util.ArrayList; 110import java.util.Arrays; 111import java.util.Collection; 112import java.util.HashSet; 113import java.util.Set; 114 115 116/** 117 * @hide 118 * 119 * This class holds much of the business logic to allow Android devices 120 * to act as IP gateways via USB, BT, and WiFi interfaces. 121 */ 122public class Tethering extends BaseNetworkObserver { 123 124 private final static String TAG = Tethering.class.getSimpleName(); 125 private final static boolean DBG = false; 126 private final static boolean VDBG = false; 127 128 protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; 129 130 private static final Class[] messageClasses = { 131 Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class 132 }; 133 private static final SparseArray<String> sMagicDecoderRing = 134 MessageUtils.findMessageNames(messageClasses); 135 136 // {@link ComponentName} of the Service used to run tether provisioning. 137 private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources 138 .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable)); 139 140 private static class TetherState { 141 public final TetherInterfaceStateMachine stateMachine; 142 public int lastState; 143 public int lastError; 144 145 public TetherState(TetherInterfaceStateMachine sm) { 146 stateMachine = sm; 147 // Assume all state machines start out available and with no errors. 148 lastState = IControlsTethering.STATE_AVAILABLE; 149 lastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; 150 } 151 152 public boolean isCurrentlyServing() { 153 switch (lastState) { 154 case IControlsTethering.STATE_TETHERED: 155 case IControlsTethering.STATE_LOCAL_ONLY: 156 return true; 157 default: 158 return false; 159 } 160 } 161 } 162 163 private final SharedLog mLog = new SharedLog(TAG); 164 165 // used to synchronize public access to members 166 private final Object mPublicSync; 167 private final Context mContext; 168 private final ArrayMap<String, TetherState> mTetherStates; 169 private final BroadcastReceiver mStateReceiver; 170 private final INetworkManagementService mNMService; 171 private final INetworkStatsService mStatsService; 172 private final INetworkPolicyManager mPolicyManager; 173 private final Looper mLooper; 174 private final MockableSystemProperties mSystemProperties; 175 private final StateMachine mTetherMasterSM; 176 private final OffloadController mOffloadController; 177 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor; 178 // TODO: Figure out how to merge this and other downstream-tracking objects 179 // into a single coherent structure. 180 private final HashSet<TetherInterfaceStateMachine> mForwardedDownstreams; 181 private final VersionedBroadcastListener mCarrierConfigChange; 182 // TODO: Delete SimChangeListener; it's obsolete. 183 private final SimChangeListener mSimChange; 184 185 private volatile TetheringConfiguration mConfig; 186 private String mCurrentUpstreamIface; 187 private Notification.Builder mTetheredNotificationBuilder; 188 private int mLastNotificationId; 189 190 private boolean mRndisEnabled; // track the RNDIS function enabled state 191 // True iff. WiFi tethering should be started when soft AP is ready. 192 private boolean mWifiTetherRequested; 193 194 public Tethering(Context context, INetworkManagementService nmService, 195 INetworkStatsService statsService, INetworkPolicyManager policyManager, 196 Looper looper, MockableSystemProperties systemProperties, 197 TetheringDependencies deps) { 198 mLog.mark("constructed"); 199 mContext = context; 200 mNMService = nmService; 201 mStatsService = statsService; 202 mPolicyManager = policyManager; 203 mLooper = looper; 204 mSystemProperties = systemProperties; 205 206 mPublicSync = new Object(); 207 208 mTetherStates = new ArrayMap<>(); 209 210 mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper); 211 mTetherMasterSM.start(); 212 213 final Handler smHandler = mTetherMasterSM.getHandler(); 214 mOffloadController = new OffloadController(smHandler, 215 deps.getOffloadHardwareInterface(smHandler, mLog), 216 mContext.getContentResolver(), mNMService, 217 mLog); 218 mUpstreamNetworkMonitor = new UpstreamNetworkMonitor( 219 mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK); 220 mForwardedDownstreams = new HashSet<>(); 221 222 IntentFilter filter = new IntentFilter(); 223 filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); 224 mCarrierConfigChange = new VersionedBroadcastListener( 225 "CarrierConfigChangeListener", mContext, smHandler, filter, 226 (Intent ignored) -> { 227 mLog.log("OBSERVED carrier config change"); 228 reevaluateSimCardProvisioning(); 229 }); 230 // TODO: Remove SimChangeListener altogether. For now, we retain it 231 // for logging purposes in case we need to debug something that might 232 // be related to changing signals from ACTION_SIM_STATE_CHANGED to 233 // ACTION_CARRIER_CONFIG_CHANGED. 234 mSimChange = new SimChangeListener( 235 mContext, smHandler, () -> { 236 mLog.log("OBSERVED SIM card change"); 237 }); 238 239 mStateReceiver = new StateReceiver(); 240 filter = new IntentFilter(); 241 filter.addAction(UsbManager.ACTION_USB_STATE); 242 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 243 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 244 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 245 mContext.registerReceiver(mStateReceiver, filter, null, smHandler); 246 247 filter = new IntentFilter(); 248 filter.addAction(Intent.ACTION_MEDIA_SHARED); 249 filter.addAction(Intent.ACTION_MEDIA_UNSHARED); 250 filter.addDataScheme("file"); 251 mContext.registerReceiver(mStateReceiver, filter, null, smHandler); 252 253 UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class); 254 255 // this check is useful only for some unit tests; example: ConnectivityServiceTest 256 if (userManager != null) { 257 userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this)); 258 } 259 260 // load device config info 261 updateConfiguration(); 262 } 263 264 // We can't do this once in the Tethering() constructor and cache the value, because the 265 // CONNECTIVITY_SERVICE is registered only after the Tethering() constructor has completed. 266 private ConnectivityManager getConnectivityManager() { 267 return (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 268 } 269 270 private WifiManager getWifiManager() { 271 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 272 } 273 274 // NOTE: This is always invoked on the mLooper thread. 275 private void updateConfiguration() { 276 mConfig = new TetheringConfiguration(mContext, mLog); 277 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); 278 } 279 280 private void maybeUpdateConfiguration() { 281 final int dunCheck = TetheringConfiguration.checkDunRequired(mContext); 282 if (dunCheck == mConfig.dunCheck) return; 283 updateConfiguration(); 284 } 285 286 @Override 287 public void interfaceStatusChanged(String iface, boolean up) { 288 // Never called directly: only called from interfaceLinkStateChanged. 289 // See NetlinkHandler.cpp:71. 290 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up); 291 synchronized (mPublicSync) { 292 if (up) { 293 maybeTrackNewInterfaceLocked(iface); 294 } else { 295 if (ifaceNameToType(iface) == ConnectivityManager.TETHERING_BLUETOOTH) { 296 stopTrackingInterfaceLocked(iface); 297 } else { 298 // Ignore usb0 down after enabling RNDIS. 299 // We will handle disconnect in interfaceRemoved. 300 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status 301 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent. 302 if (VDBG) Log.d(TAG, "ignore interface down for " + iface); 303 } 304 } 305 } 306 } 307 308 @Override 309 public void interfaceLinkStateChanged(String iface, boolean up) { 310 interfaceStatusChanged(iface, up); 311 } 312 313 private int ifaceNameToType(String iface) { 314 final TetheringConfiguration cfg = mConfig; 315 316 if (cfg.isWifi(iface)) { 317 return ConnectivityManager.TETHERING_WIFI; 318 } else if (cfg.isUsb(iface)) { 319 return ConnectivityManager.TETHERING_USB; 320 } else if (cfg.isBluetooth(iface)) { 321 return ConnectivityManager.TETHERING_BLUETOOTH; 322 } 323 return ConnectivityManager.TETHERING_INVALID; 324 } 325 326 @Override 327 public void interfaceAdded(String iface) { 328 if (VDBG) Log.d(TAG, "interfaceAdded " + iface); 329 synchronized (mPublicSync) { 330 maybeTrackNewInterfaceLocked(iface); 331 } 332 } 333 334 @Override 335 public void interfaceRemoved(String iface) { 336 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); 337 synchronized (mPublicSync) { 338 stopTrackingInterfaceLocked(iface); 339 } 340 } 341 342 public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) { 343 if (!isTetherProvisioningRequired()) { 344 enableTetheringInternal(type, true, receiver); 345 return; 346 } 347 348 if (showProvisioningUi) { 349 runUiTetherProvisioningAndEnable(type, receiver); 350 } else { 351 runSilentTetherProvisioningAndEnable(type, receiver); 352 } 353 } 354 355 public void stopTethering(int type) { 356 enableTetheringInternal(type, false, null); 357 if (isTetherProvisioningRequired()) { 358 cancelTetherProvisioningRechecks(type); 359 } 360 } 361 362 /** 363 * Check if the device requires a provisioning check in order to enable tethering. 364 * 365 * @return a boolean - {@code true} indicating tether provisioning is required by the carrier. 366 */ 367 @VisibleForTesting 368 protected boolean isTetherProvisioningRequired() { 369 String[] provisionApp = mContext.getResources().getStringArray( 370 com.android.internal.R.array.config_mobile_hotspot_provision_app); 371 if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false) 372 || provisionApp == null) { 373 return false; 374 } 375 376 if (carrierConfigAffirmsEntitlementCheckNotRequired()) { 377 return false; 378 } 379 return (provisionApp.length == 2); 380 } 381 382 // The logic here is aimed solely at confirming that a CarrierConfig exists 383 // and affirms that entitlement checks are not required. 384 // 385 // TODO: find a better way to express this, or alter the checking process 386 // entirely so that this is more intuitive. 387 private boolean carrierConfigAffirmsEntitlementCheckNotRequired() { 388 // Check carrier config for entitlement checks 389 final CarrierConfigManager configManager = (CarrierConfigManager) mContext 390 .getSystemService(Context.CARRIER_CONFIG_SERVICE); 391 if (configManager == null) return false; 392 393 final PersistableBundle carrierConfig = configManager.getConfig(); 394 if (carrierConfig == null) return false; 395 396 // A CarrierConfigManager was found and it has a config. 397 final boolean isEntitlementCheckRequired = carrierConfig.getBoolean( 398 CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL); 399 return !isEntitlementCheckRequired; 400 } 401 402 // Used by the SIM card change observation code. 403 // TODO: De-duplicate above code. 404 private boolean hasMobileHotspotProvisionApp() { 405 try { 406 if (!mContext.getResources().getString(com.android.internal.R.string. 407 config_mobile_hotspot_provision_app_no_ui).isEmpty()) { 408 Log.d(TAG, "re-evaluate provisioning"); 409 return true; 410 } 411 } catch (Resources.NotFoundException e) {} 412 Log.d(TAG, "no prov-check needed for new SIM"); 413 return false; 414 } 415 416 /** 417 * Enables or disables tethering for the given type. This should only be called once 418 * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks 419 * for the specified interface. 420 */ 421 private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) { 422 boolean isProvisioningRequired = enable && isTetherProvisioningRequired(); 423 int result; 424 switch (type) { 425 case ConnectivityManager.TETHERING_WIFI: 426 result = setWifiTethering(enable); 427 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) { 428 scheduleProvisioningRechecks(type); 429 } 430 sendTetherResult(receiver, result); 431 break; 432 case ConnectivityManager.TETHERING_USB: 433 result = setUsbTethering(enable); 434 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) { 435 scheduleProvisioningRechecks(type); 436 } 437 sendTetherResult(receiver, result); 438 break; 439 case ConnectivityManager.TETHERING_BLUETOOTH: 440 setBluetoothTethering(enable, receiver); 441 break; 442 default: 443 Log.w(TAG, "Invalid tether type."); 444 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE); 445 } 446 } 447 448 private void sendTetherResult(ResultReceiver receiver, int result) { 449 if (receiver != null) { 450 receiver.send(result, null); 451 } 452 } 453 454 private int setWifiTethering(final boolean enable) { 455 int rval = ConnectivityManager.TETHER_ERROR_MASTER_ERROR; 456 final long ident = Binder.clearCallingIdentity(); 457 try { 458 synchronized (mPublicSync) { 459 mWifiTetherRequested = enable; 460 final WifiManager mgr = getWifiManager(); 461 if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) || 462 (!enable && mgr.stopSoftAp())) { 463 rval = ConnectivityManager.TETHER_ERROR_NO_ERROR; 464 } 465 } 466 } finally { 467 Binder.restoreCallingIdentity(ident); 468 } 469 return rval; 470 } 471 472 private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { 473 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 474 if (adapter == null || !adapter.isEnabled()) { 475 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " + 476 (adapter == null)); 477 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL); 478 return; 479 } 480 481 adapter.getProfileProxy(mContext, new ServiceListener() { 482 @Override 483 public void onServiceDisconnected(int profile) { } 484 485 @Override 486 public void onServiceConnected(int profile, BluetoothProfile proxy) { 487 ((BluetoothPan) proxy).setBluetoothTethering(enable); 488 // TODO: Enabling bluetooth tethering can fail asynchronously here. 489 // We should figure out a way to bubble up that failure instead of sending success. 490 int result = ((BluetoothPan) proxy).isTetheringOn() == enable ? 491 ConnectivityManager.TETHER_ERROR_NO_ERROR : 492 ConnectivityManager.TETHER_ERROR_MASTER_ERROR; 493 sendTetherResult(receiver, result); 494 if (enable && isTetherProvisioningRequired()) { 495 scheduleProvisioningRechecks(ConnectivityManager.TETHERING_BLUETOOTH); 496 } 497 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy); 498 } 499 }, BluetoothProfile.PAN); 500 } 501 502 private void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) { 503 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); 504 sendUiTetherProvisionIntent(type, proxyReceiver); 505 } 506 507 private void sendUiTetherProvisionIntent(int type, ResultReceiver receiver) { 508 Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING); 509 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type); 510 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver); 511 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 512 final long ident = Binder.clearCallingIdentity(); 513 try { 514 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 515 } finally { 516 Binder.restoreCallingIdentity(ident); 517 } 518 } 519 520 /** 521 * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result 522 * is successful before firing back up to the wrapped receiver. 523 * 524 * @param type The type of tethering being enabled. 525 * @param receiver A ResultReceiver which will be called back with an int resultCode. 526 * @return The proxy receiver. 527 */ 528 private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) { 529 ResultReceiver rr = new ResultReceiver(null) { 530 @Override 531 protected void onReceiveResult(int resultCode, Bundle resultData) { 532 // If provisioning is successful, enable tethering, otherwise just send the error. 533 if (resultCode == ConnectivityManager.TETHER_ERROR_NO_ERROR) { 534 enableTetheringInternal(type, true, receiver); 535 } else { 536 sendTetherResult(receiver, resultCode); 537 } 538 } 539 }; 540 541 // The following is necessary to avoid unmarshalling issues when sending the receiver 542 // across processes. 543 Parcel parcel = Parcel.obtain(); 544 rr.writeToParcel(parcel,0); 545 parcel.setDataPosition(0); 546 ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel); 547 parcel.recycle(); 548 return receiverForSending; 549 } 550 551 private void scheduleProvisioningRechecks(int type) { 552 Intent intent = new Intent(); 553 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type); 554 intent.putExtra(ConnectivityManager.EXTRA_SET_ALARM, true); 555 intent.setComponent(TETHER_SERVICE); 556 final long ident = Binder.clearCallingIdentity(); 557 try { 558 mContext.startServiceAsUser(intent, UserHandle.CURRENT); 559 } finally { 560 Binder.restoreCallingIdentity(ident); 561 } 562 } 563 564 private void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) { 565 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); 566 sendSilentTetherProvisionIntent(type, proxyReceiver); 567 } 568 569 private void sendSilentTetherProvisionIntent(int type, ResultReceiver receiver) { 570 Intent intent = new Intent(); 571 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type); 572 intent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true); 573 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver); 574 intent.setComponent(TETHER_SERVICE); 575 final long ident = Binder.clearCallingIdentity(); 576 try { 577 mContext.startServiceAsUser(intent, UserHandle.CURRENT); 578 } finally { 579 Binder.restoreCallingIdentity(ident); 580 } 581 } 582 583 private void cancelTetherProvisioningRechecks(int type) { 584 if (getConnectivityManager().isTetheringSupported()) { 585 Intent intent = new Intent(); 586 intent.putExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE, type); 587 intent.setComponent(TETHER_SERVICE); 588 final long ident = Binder.clearCallingIdentity(); 589 try { 590 mContext.startServiceAsUser(intent, UserHandle.CURRENT); 591 } finally { 592 Binder.restoreCallingIdentity(ident); 593 } 594 } 595 } 596 597 // Used by the SIM card change observation code. 598 // TODO: De-duplicate with above code, where possible. 599 private void startProvisionIntent(int tetherType) { 600 final Intent startProvIntent = new Intent(); 601 startProvIntent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, tetherType); 602 startProvIntent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true); 603 startProvIntent.setComponent(TETHER_SERVICE); 604 mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT); 605 } 606 607 public int tether(String iface) { 608 return tether(iface, IControlsTethering.STATE_TETHERED); 609 } 610 611 private int tether(String iface, int requestedState) { 612 if (DBG) Log.d(TAG, "Tethering " + iface); 613 synchronized (mPublicSync) { 614 TetherState tetherState = mTetherStates.get(iface); 615 if (tetherState == null) { 616 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring"); 617 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 618 } 619 // Ignore the error status of the interface. If the interface is available, 620 // the errors are referring to past tethering attempts anyway. 621 if (tetherState.lastState != IControlsTethering.STATE_AVAILABLE) { 622 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring"); 623 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 624 } 625 // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's 626 // queue but not yet processed, this will be a no-op and it will not 627 // return an error. 628 // 629 // TODO: reexamine the threading and messaging model. 630 tetherState.stateMachine.sendMessage( 631 TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, requestedState); 632 return ConnectivityManager.TETHER_ERROR_NO_ERROR; 633 } 634 } 635 636 public int untether(String iface) { 637 if (DBG) Log.d(TAG, "Untethering " + iface); 638 synchronized (mPublicSync) { 639 TetherState tetherState = mTetherStates.get(iface); 640 if (tetherState == null) { 641 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring"); 642 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 643 } 644 if (!tetherState.isCurrentlyServing()) { 645 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring"); 646 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE; 647 } 648 tetherState.stateMachine.sendMessage( 649 TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); 650 return ConnectivityManager.TETHER_ERROR_NO_ERROR; 651 } 652 } 653 654 public void untetherAll() { 655 stopTethering(ConnectivityManager.TETHERING_WIFI); 656 stopTethering(ConnectivityManager.TETHERING_USB); 657 stopTethering(ConnectivityManager.TETHERING_BLUETOOTH); 658 } 659 660 public int getLastTetherError(String iface) { 661 synchronized (mPublicSync) { 662 TetherState tetherState = mTetherStates.get(iface); 663 if (tetherState == null) { 664 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + 665 ", ignoring"); 666 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; 667 } 668 return tetherState.lastError; 669 } 670 } 671 672 // TODO: Figure out how to update for local hotspot mode interfaces. 673 private void sendTetherStateChangedBroadcast() { 674 if (!getConnectivityManager().isTetheringSupported()) return; 675 676 final ArrayList<String> availableList = new ArrayList<>(); 677 final ArrayList<String> tetherList = new ArrayList<>(); 678 final ArrayList<String> localOnlyList = new ArrayList<>(); 679 final ArrayList<String> erroredList = new ArrayList<>(); 680 681 boolean wifiTethered = false; 682 boolean usbTethered = false; 683 boolean bluetoothTethered = false; 684 685 final TetheringConfiguration cfg = mConfig; 686 687 synchronized (mPublicSync) { 688 for (int i = 0; i < mTetherStates.size(); i++) { 689 TetherState tetherState = mTetherStates.valueAt(i); 690 String iface = mTetherStates.keyAt(i); 691 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { 692 erroredList.add(iface); 693 } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) { 694 availableList.add(iface); 695 } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_ONLY) { 696 localOnlyList.add(iface); 697 } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) { 698 if (cfg.isUsb(iface)) { 699 usbTethered = true; 700 } else if (cfg.isWifi(iface)) { 701 wifiTethered = true; 702 } else if (cfg.isBluetooth(iface)) { 703 bluetoothTethered = true; 704 } 705 tetherList.add(iface); 706 } 707 } 708 } 709 final Intent bcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 710 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | 711 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 712 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, availableList); 713 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList); 714 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, tetherList); 715 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, erroredList); 716 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL); 717 if (DBG) { 718 Log.d(TAG, String.format( 719 "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]", 720 "avail", TextUtils.join(",", availableList), 721 "local_only", TextUtils.join(",", localOnlyList), 722 "tether", TextUtils.join(",", tetherList), 723 "error", TextUtils.join(",", erroredList))); 724 } 725 726 if (usbTethered) { 727 if (wifiTethered || bluetoothTethered) { 728 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); 729 } else { 730 showTetheredNotification(SystemMessage.NOTE_TETHER_USB); 731 } 732 } else if (wifiTethered) { 733 if (bluetoothTethered) { 734 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL); 735 } else { 736 /* We now have a status bar icon for WifiTethering, so drop the notification */ 737 clearTetheredNotification(); 738 } 739 } else if (bluetoothTethered) { 740 showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH); 741 } else { 742 clearTetheredNotification(); 743 } 744 } 745 746 private void showTetheredNotification(int id) { 747 showTetheredNotification(id, true); 748 } 749 750 @VisibleForTesting 751 protected void showTetheredNotification(int id, boolean tetheringOn) { 752 NotificationManager notificationManager = 753 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 754 if (notificationManager == null) { 755 return; 756 } 757 int icon = 0; 758 switch(id) { 759 case SystemMessage.NOTE_TETHER_USB: 760 icon = com.android.internal.R.drawable.stat_sys_tether_usb; 761 break; 762 case SystemMessage.NOTE_TETHER_BLUETOOTH: 763 icon = com.android.internal.R.drawable.stat_sys_tether_bluetooth; 764 break; 765 case SystemMessage.NOTE_TETHER_GENERAL: 766 default: 767 icon = com.android.internal.R.drawable.stat_sys_tether_general; 768 break; 769 } 770 771 if (mLastNotificationId != 0) { 772 if (mLastNotificationId == icon) { 773 return; 774 } 775 notificationManager.cancelAsUser(null, mLastNotificationId, 776 UserHandle.ALL); 777 mLastNotificationId = 0; 778 } 779 780 Intent intent = new Intent(); 781 intent.setClassName("com.android.settings", "com.android.settings.TetherSettings"); 782 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 783 784 PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0, 785 null, UserHandle.CURRENT); 786 787 Resources r = Resources.getSystem(); 788 final CharSequence title; 789 final CharSequence message; 790 791 if (tetheringOn) { 792 title = r.getText(com.android.internal.R.string.tethered_notification_title); 793 message = r.getText(com.android.internal.R.string.tethered_notification_message); 794 } else { 795 title = r.getText(com.android.internal.R.string.disable_tether_notification_title); 796 message = r.getText(com.android.internal.R.string.disable_tether_notification_message); 797 } 798 799 if (mTetheredNotificationBuilder == null) { 800 mTetheredNotificationBuilder = 801 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS); 802 mTetheredNotificationBuilder.setWhen(0) 803 .setOngoing(true) 804 .setColor(mContext.getColor( 805 com.android.internal.R.color.system_notification_accent_color)) 806 .setVisibility(Notification.VISIBILITY_PUBLIC) 807 .setCategory(Notification.CATEGORY_STATUS); 808 } 809 mTetheredNotificationBuilder.setSmallIcon(icon) 810 .setContentTitle(title) 811 .setContentText(message) 812 .setContentIntent(pi); 813 mLastNotificationId = id; 814 815 notificationManager.notifyAsUser(null, mLastNotificationId, 816 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL); 817 } 818 819 @VisibleForTesting 820 protected void clearTetheredNotification() { 821 NotificationManager notificationManager = 822 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 823 if (notificationManager != null && mLastNotificationId != 0) { 824 notificationManager.cancelAsUser(null, mLastNotificationId, 825 UserHandle.ALL); 826 mLastNotificationId = 0; 827 } 828 } 829 830 private class StateReceiver extends BroadcastReceiver { 831 @Override 832 public void onReceive(Context content, Intent intent) { 833 final String action = intent.getAction(); 834 if (action == null) return; 835 836 if (action.equals(UsbManager.ACTION_USB_STATE)) { 837 handleUsbAction(intent); 838 } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 839 handleConnectivityAction(intent); 840 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 841 handleWifiApAction(intent); 842 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 843 mLog.log("OBSERVED configuration changed"); 844 updateConfiguration(); 845 } 846 } 847 848 private void handleConnectivityAction(Intent intent) { 849 final NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra( 850 ConnectivityManager.EXTRA_NETWORK_INFO); 851 if (networkInfo == null || 852 networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) { 853 return; 854 } 855 856 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString()); 857 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED); 858 } 859 860 private void handleUsbAction(Intent intent) { 861 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false); 862 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false); 863 final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false); 864 865 mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s", 866 usbConnected, usbConfigured, rndisEnabled)); 867 868 // There are three types of ACTION_USB_STATE: 869 // 870 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0) 871 // Meaning: USB connection has ended either because of 872 // software reset or hard unplug. 873 // 874 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0) 875 // Meaning: the first stage of USB protocol handshake has 876 // occurred but it is not complete. 877 // 878 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1) 879 // Meaning: the USB handshake is completely done and all the 880 // functions are ready to use. 881 // 882 // For more explanation, see b/62552150 . 883 synchronized (Tethering.this.mPublicSync) { 884 if (!usbConnected && mRndisEnabled) { 885 // Turn off tethering if it was enabled and there is a disconnect. 886 tetherMatchingInterfaces( 887 IControlsTethering.STATE_AVAILABLE, 888 ConnectivityManager.TETHERING_USB); 889 } else if (usbConfigured && rndisEnabled) { 890 // Tether if rndis is enabled and usb is configured. 891 tetherMatchingInterfaces( 892 IControlsTethering.STATE_TETHERED, 893 ConnectivityManager.TETHERING_USB); 894 } 895 mRndisEnabled = usbConfigured && rndisEnabled; 896 } 897 } 898 899 private void handleWifiApAction(Intent intent) { 900 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); 901 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME); 902 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED); 903 904 synchronized (Tethering.this.mPublicSync) { 905 switch (curState) { 906 case WifiManager.WIFI_AP_STATE_ENABLING: 907 // We can see this state on the way to both enabled and failure states. 908 break; 909 case WifiManager.WIFI_AP_STATE_ENABLED: 910 enableWifiIpServingLocked(ifname, ipmode); 911 break; 912 case WifiManager.WIFI_AP_STATE_DISABLED: 913 case WifiManager.WIFI_AP_STATE_DISABLING: 914 case WifiManager.WIFI_AP_STATE_FAILED: 915 default: 916 disableWifiIpServingLocked(ifname, curState); 917 break; 918 } 919 } 920 } 921 } 922 923 @VisibleForTesting 924 protected static class TetheringUserRestrictionListener implements UserRestrictionsListener { 925 private final Tethering mWrapper; 926 927 public TetheringUserRestrictionListener(Tethering wrapper) { 928 mWrapper = wrapper; 929 } 930 931 public void onUserRestrictionsChanged(int userId, 932 Bundle newRestrictions, 933 Bundle prevRestrictions) { 934 final boolean newlyDisallowed = 935 newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); 936 final boolean previouslyDisallowed = 937 prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); 938 final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed); 939 940 if (!tetheringDisallowedChanged) { 941 return; 942 } 943 944 mWrapper.clearTetheredNotification(); 945 final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0); 946 947 if (newlyDisallowed && isTetheringActiveOnDevice) { 948 mWrapper.showTetheredNotification( 949 com.android.internal.R.drawable.stat_sys_tether_general, false); 950 mWrapper.untetherAll(); 951 } 952 } 953 } 954 955 private void disableWifiIpServingLocked(String ifname, int apState) { 956 mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState); 957 958 // Regardless of whether we requested this transition, the AP has gone 959 // down. Don't try to tether again unless we're requested to do so. 960 // TODO: Remove this altogether, once Wi-Fi reliably gives us an 961 // interface name with every broadcast. 962 mWifiTetherRequested = false; 963 964 if (!TextUtils.isEmpty(ifname)) { 965 final TetherState ts = mTetherStates.get(ifname); 966 if (ts != null) { 967 ts.stateMachine.unwanted(); 968 return; 969 } 970 } 971 972 for (int i = 0; i < mTetherStates.size(); i++) { 973 TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine; 974 if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) { 975 tism.unwanted(); 976 return; 977 } 978 } 979 980 mLog.log("Error disabling Wi-Fi IP serving; " + 981 (TextUtils.isEmpty(ifname) ? "no interface name specified" 982 : "specified interface: " + ifname)); 983 } 984 985 private void enableWifiIpServingLocked(String ifname, int wifiIpMode) { 986 // Map wifiIpMode values to IControlsTethering serving states, inferring 987 // from mWifiTetherRequested as a final "best guess". 988 final int ipServingMode; 989 switch (wifiIpMode) { 990 case IFACE_IP_MODE_TETHERED: 991 ipServingMode = IControlsTethering.STATE_TETHERED; 992 break; 993 case IFACE_IP_MODE_LOCAL_ONLY: 994 ipServingMode = IControlsTethering.STATE_LOCAL_ONLY; 995 break; 996 default: 997 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode); 998 return; 999 } 1000 1001 if (!TextUtils.isEmpty(ifname)) { 1002 maybeTrackNewInterfaceLocked(ifname, ConnectivityManager.TETHERING_WIFI); 1003 changeInterfaceState(ifname, ipServingMode); 1004 } else { 1005 mLog.e(String.format( 1006 "Cannot enable IP serving in mode %s on missing interface name", 1007 ipServingMode)); 1008 } 1009 } 1010 1011 // TODO: Consider renaming to something more accurate in its description. 1012 // This method: 1013 // - allows requesting either tethering or local hotspot serving states 1014 // - handles both enabling and disabling serving states 1015 // - only tethers the first matching interface in listInterfaces() 1016 // order of a given type 1017 private void tetherMatchingInterfaces(int requestedState, int interfaceType) { 1018 if (VDBG) { 1019 Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")"); 1020 } 1021 1022 String[] ifaces = null; 1023 try { 1024 ifaces = mNMService.listInterfaces(); 1025 } catch (Exception e) { 1026 Log.e(TAG, "Error listing Interfaces", e); 1027 return; 1028 } 1029 String chosenIface = null; 1030 if (ifaces != null) { 1031 for (String iface : ifaces) { 1032 if (ifaceNameToType(iface) == interfaceType) { 1033 chosenIface = iface; 1034 break; 1035 } 1036 } 1037 } 1038 if (chosenIface == null) { 1039 Log.e(TAG, "could not find iface of type " + interfaceType); 1040 return; 1041 } 1042 1043 changeInterfaceState(chosenIface, requestedState); 1044 } 1045 1046 private void changeInterfaceState(String ifname, int requestedState) { 1047 final int result; 1048 switch (requestedState) { 1049 case IControlsTethering.STATE_UNAVAILABLE: 1050 case IControlsTethering.STATE_AVAILABLE: 1051 result = untether(ifname); 1052 break; 1053 case IControlsTethering.STATE_TETHERED: 1054 case IControlsTethering.STATE_LOCAL_ONLY: 1055 result = tether(ifname, requestedState); 1056 break; 1057 default: 1058 Log.wtf(TAG, "Unknown interface state: " + requestedState); 1059 return; 1060 } 1061 if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) { 1062 Log.e(TAG, "unable start or stop tethering on iface " + ifname); 1063 return; 1064 } 1065 } 1066 1067 public TetheringConfiguration getTetheringConfiguration() { 1068 return mConfig; 1069 } 1070 1071 public boolean hasTetherableConfiguration() { 1072 final TetheringConfiguration cfg = mConfig; 1073 final boolean hasDownstreamConfiguration = 1074 (cfg.tetherableUsbRegexs.length != 0) || 1075 (cfg.tetherableWifiRegexs.length != 0) || 1076 (cfg.tetherableBluetoothRegexs.length != 0); 1077 final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty(); 1078 1079 return hasDownstreamConfiguration && hasUpstreamConfiguration; 1080 } 1081 1082 // TODO - update callers to use getTetheringConfiguration(), 1083 // which has only final members. 1084 public String[] getTetherableUsbRegexs() { 1085 return copy(mConfig.tetherableUsbRegexs); 1086 } 1087 1088 public String[] getTetherableWifiRegexs() { 1089 return copy(mConfig.tetherableWifiRegexs); 1090 } 1091 1092 public String[] getTetherableBluetoothRegexs() { 1093 return copy(mConfig.tetherableBluetoothRegexs); 1094 } 1095 1096 public int setUsbTethering(boolean enable) { 1097 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")"); 1098 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); 1099 synchronized (mPublicSync) { 1100 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS 1101 : UsbManager.FUNCTION_NONE); 1102 } 1103 return ConnectivityManager.TETHER_ERROR_NO_ERROR; 1104 } 1105 1106 // TODO review API - figure out how to delete these entirely. 1107 public String[] getTetheredIfaces() { 1108 ArrayList<String> list = new ArrayList<String>(); 1109 synchronized (mPublicSync) { 1110 for (int i = 0; i < mTetherStates.size(); i++) { 1111 TetherState tetherState = mTetherStates.valueAt(i); 1112 if (tetherState.lastState == IControlsTethering.STATE_TETHERED) { 1113 list.add(mTetherStates.keyAt(i)); 1114 } 1115 } 1116 } 1117 return list.toArray(new String[list.size()]); 1118 } 1119 1120 public String[] getTetherableIfaces() { 1121 ArrayList<String> list = new ArrayList<String>(); 1122 synchronized (mPublicSync) { 1123 for (int i = 0; i < mTetherStates.size(); i++) { 1124 TetherState tetherState = mTetherStates.valueAt(i); 1125 if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) { 1126 list.add(mTetherStates.keyAt(i)); 1127 } 1128 } 1129 } 1130 return list.toArray(new String[list.size()]); 1131 } 1132 1133 public String[] getTetheredDhcpRanges() { 1134 return mConfig.dhcpRanges; 1135 } 1136 1137 public String[] getErroredIfaces() { 1138 ArrayList<String> list = new ArrayList<String>(); 1139 synchronized (mPublicSync) { 1140 for (int i = 0; i < mTetherStates.size(); i++) { 1141 TetherState tetherState = mTetherStates.valueAt(i); 1142 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) { 1143 list.add(mTetherStates.keyAt(i)); 1144 } 1145 } 1146 } 1147 return list.toArray(new String[list.size()]); 1148 } 1149 1150 private void logMessage(State state, int what) { 1151 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what))); 1152 } 1153 1154 private boolean upstreamWanted() { 1155 if (!mForwardedDownstreams.isEmpty()) return true; 1156 1157 synchronized (mPublicSync) { 1158 return mWifiTetherRequested; 1159 } 1160 } 1161 1162 // Needed because the canonical source of upstream truth is just the 1163 // upstream interface name, |mCurrentUpstreamIface|. This is ripe for 1164 // future simplification, once the upstream Network is canonical. 1165 private boolean pertainsToCurrentUpstream(NetworkState ns) { 1166 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIface != null) { 1167 for (String ifname : ns.linkProperties.getAllInterfaceNames()) { 1168 if (mCurrentUpstreamIface.equals(ifname)) { 1169 return true; 1170 } 1171 } 1172 } 1173 return false; 1174 } 1175 1176 private void reevaluateSimCardProvisioning() { 1177 if (!hasMobileHotspotProvisionApp()) return; 1178 if (carrierConfigAffirmsEntitlementCheckNotRequired()) return; 1179 1180 ArrayList<Integer> tethered = new ArrayList<>(); 1181 synchronized (mPublicSync) { 1182 for (int i = 0; i < mTetherStates.size(); i++) { 1183 TetherState tetherState = mTetherStates.valueAt(i); 1184 if (tetherState.lastState != IControlsTethering.STATE_TETHERED) { 1185 continue; // Skip interfaces that aren't tethered. 1186 } 1187 String iface = mTetherStates.keyAt(i); 1188 int interfaceType = ifaceNameToType(iface); 1189 if (interfaceType != ConnectivityManager.TETHERING_INVALID) { 1190 tethered.add(interfaceType); 1191 } 1192 } 1193 } 1194 1195 for (int tetherType : tethered) { 1196 startProvisionIntent(tetherType); 1197 } 1198 } 1199 1200 class TetherMasterSM extends StateMachine { 1201 private static final int BASE_MASTER = Protocol.BASE_TETHERING; 1202 // an interface SM has requested Tethering/Local Hotspot 1203 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1; 1204 // an interface SM has unrequested Tethering/Local Hotspot 1205 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2; 1206 // upstream connection change - do the right thing 1207 static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3; 1208 // we don't have a valid upstream conn, check again after a delay 1209 static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4; 1210 // Events from NetworkCallbacks that we process on the master state 1211 // machine thread on behalf of the UpstreamNetworkMonitor. 1212 static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5; 1213 // we treated the error and want now to clear it 1214 static final int CMD_CLEAR_ERROR = BASE_MASTER + 6; 1215 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7; 1216 1217 private final State mInitialState; 1218 private final State mTetherModeAliveState; 1219 1220 private final State mSetIpForwardingEnabledErrorState; 1221 private final State mSetIpForwardingDisabledErrorState; 1222 private final State mStartTetheringErrorState; 1223 private final State mStopTetheringErrorState; 1224 private final State mSetDnsForwardersErrorState; 1225 1226 // This list is a little subtle. It contains all the interfaces that currently are 1227 // requesting tethering, regardless of whether these interfaces are still members of 1228 // mTetherStates. This allows us to maintain the following predicates: 1229 // 1230 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up 1231 // interfaces. 1232 // 2) mNotifyList contains all state machines that may have outstanding tethering state 1233 // that needs to be torn down. 1234 // 1235 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList 1236 // so that the garbage collector does not clean up the state machine before it has a chance 1237 // to tear itself down. 1238 private final ArrayList<TetherInterfaceStateMachine> mNotifyList; 1239 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator; 1240 private final OffloadWrapper mOffload; 1241 1242 private static final int UPSTREAM_SETTLE_TIME_MS = 10000; 1243 1244 TetherMasterSM(String name, Looper looper) { 1245 super(name, looper); 1246 1247 mInitialState = new InitialState(); 1248 mTetherModeAliveState = new TetherModeAliveState(); 1249 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); 1250 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState(); 1251 mStartTetheringErrorState = new StartTetheringErrorState(); 1252 mStopTetheringErrorState = new StopTetheringErrorState(); 1253 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); 1254 1255 addState(mInitialState); 1256 addState(mTetherModeAliveState); 1257 addState(mSetIpForwardingEnabledErrorState); 1258 addState(mSetIpForwardingDisabledErrorState); 1259 addState(mStartTetheringErrorState); 1260 addState(mStopTetheringErrorState); 1261 addState(mSetDnsForwardersErrorState); 1262 1263 mNotifyList = new ArrayList<>(); 1264 mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog); 1265 mOffload = new OffloadWrapper(); 1266 1267 setInitialState(mInitialState); 1268 } 1269 1270 class InitialState extends State { 1271 @Override 1272 public boolean processMessage(Message message) { 1273 logMessage(this, message.what); 1274 switch (message.what) { 1275 case EVENT_IFACE_SERVING_STATE_ACTIVE: 1276 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; 1277 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); 1278 handleInterfaceServingStateActive(message.arg1, who); 1279 transitionTo(mTetherModeAliveState); 1280 break; 1281 case EVENT_IFACE_SERVING_STATE_INACTIVE: 1282 who = (TetherInterfaceStateMachine) message.obj; 1283 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); 1284 handleInterfaceServingStateInactive(who); 1285 break; 1286 case EVENT_IFACE_UPDATE_LINKPROPERTIES: 1287 // Silently ignore these for now. 1288 break; 1289 default: 1290 return NOT_HANDLED; 1291 } 1292 return HANDLED; 1293 } 1294 } 1295 1296 protected boolean turnOnMasterTetherSettings() { 1297 final TetheringConfiguration cfg = mConfig; 1298 try { 1299 mNMService.setIpForwardingEnabled(true); 1300 } catch (Exception e) { 1301 mLog.e(e); 1302 transitionTo(mSetIpForwardingEnabledErrorState); 1303 return false; 1304 } 1305 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode. 1306 try { 1307 // TODO: Find a more accurate method name (startDHCPv4()?). 1308 mNMService.startTethering(cfg.dhcpRanges); 1309 } catch (Exception e) { 1310 try { 1311 mNMService.stopTethering(); 1312 mNMService.startTethering(cfg.dhcpRanges); 1313 } catch (Exception ee) { 1314 mLog.e(ee); 1315 transitionTo(mStartTetheringErrorState); 1316 return false; 1317 } 1318 } 1319 mLog.log("SET master tether settings: ON"); 1320 return true; 1321 } 1322 1323 protected boolean turnOffMasterTetherSettings() { 1324 try { 1325 mNMService.stopTethering(); 1326 } catch (Exception e) { 1327 mLog.e(e); 1328 transitionTo(mStopTetheringErrorState); 1329 return false; 1330 } 1331 try { 1332 mNMService.setIpForwardingEnabled(false); 1333 } catch (Exception e) { 1334 mLog.e(e); 1335 transitionTo(mSetIpForwardingDisabledErrorState); 1336 return false; 1337 } 1338 transitionTo(mInitialState); 1339 mLog.log("SET master tether settings: OFF"); 1340 return true; 1341 } 1342 1343 protected void chooseUpstreamType(boolean tryCell) { 1344 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we 1345 // do not currently know how to watch for changes in DUN settings. 1346 maybeUpdateConfiguration(); 1347 1348 final NetworkState ns = mUpstreamNetworkMonitor.selectPreferredUpstreamType( 1349 mConfig.preferredUpstreamIfaceTypes); 1350 if (ns == null) { 1351 if (tryCell) { 1352 mUpstreamNetworkMonitor.registerMobileNetworkRequest(); 1353 // We think mobile should be coming up; don't set a retry. 1354 } else { 1355 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS); 1356 } 1357 } 1358 mUpstreamNetworkMonitor.setCurrentUpstream((ns != null) ? ns.network : null); 1359 setUpstreamNetwork(ns); 1360 } 1361 1362 protected void setUpstreamNetwork(NetworkState ns) { 1363 String iface = null; 1364 if (ns != null) { 1365 // Find the interface with the default IPv4 route. It may be the 1366 // interface described by linkProperties, or one of the interfaces 1367 // stacked on top of it. 1368 mLog.i("Looking for default routes on: " + ns.linkProperties); 1369 final String iface4 = getIPv4DefaultRouteInterface(ns); 1370 final String iface6 = getIPv6DefaultRouteInterface(ns); 1371 mLog.i("IPv4/IPv6 upstream interface(s): " + iface4 + "/" + iface6); 1372 1373 iface = (iface4 != null) ? iface4 : null /* TODO: iface6 */; 1374 } 1375 1376 if (iface != null) { 1377 setDnsForwarders(ns.network, ns.linkProperties); 1378 } 1379 notifyDownstreamsOfNewUpstreamIface(iface); 1380 if (ns != null && pertainsToCurrentUpstream(ns)) { 1381 // If we already have NetworkState for this network examine 1382 // it immediately, because there likely will be no second 1383 // EVENT_ON_AVAILABLE (it was already received). 1384 handleNewUpstreamNetworkState(ns); 1385 } else if (mCurrentUpstreamIface == null) { 1386 // There are no available upstream networks, or none that 1387 // have an IPv4 default route (current metric for success). 1388 handleNewUpstreamNetworkState(null); 1389 } 1390 } 1391 1392 protected void setDnsForwarders(final Network network, final LinkProperties lp) { 1393 // TODO: Set v4 and/or v6 DNS per available connectivity. 1394 String[] dnsServers = mConfig.defaultIPv4DNS; 1395 final Collection<InetAddress> dnses = lp.getDnsServers(); 1396 // TODO: Properly support the absence of DNS servers. 1397 if (dnses != null && !dnses.isEmpty()) { 1398 // TODO: remove this invocation of NetworkUtils.makeStrings(). 1399 dnsServers = NetworkUtils.makeStrings(dnses); 1400 } 1401 try { 1402 mNMService.setDnsForwarders(network, dnsServers); 1403 mLog.log(String.format( 1404 "SET DNS forwarders: network=%s dnsServers=%s", 1405 network, Arrays.toString(dnsServers))); 1406 } catch (Exception e) { 1407 // TODO: Investigate how this can fail and what exactly 1408 // happens if/when such failures occur. 1409 mLog.e("setting DNS forwarders failed, " + e); 1410 transitionTo(mSetDnsForwardersErrorState); 1411 } 1412 } 1413 1414 protected void notifyDownstreamsOfNewUpstreamIface(String ifaceName) { 1415 mLog.log("Notifying downstreams of upstream=" + ifaceName); 1416 mCurrentUpstreamIface = ifaceName; 1417 for (TetherInterfaceStateMachine sm : mNotifyList) { 1418 sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, 1419 ifaceName); 1420 } 1421 } 1422 1423 protected void handleNewUpstreamNetworkState(NetworkState ns) { 1424 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns); 1425 mOffload.updateUpstreamNetworkState(ns); 1426 } 1427 1428 private void handleInterfaceServingStateActive(int mode, TetherInterfaceStateMachine who) { 1429 if (mNotifyList.indexOf(who) < 0) { 1430 mNotifyList.add(who); 1431 mIPv6TetheringCoordinator.addActiveDownstream(who, mode); 1432 } 1433 1434 if (mode == IControlsTethering.STATE_TETHERED) { 1435 // No need to notify OffloadController just yet as there are no 1436 // "offload-able" prefixes to pass along. This will handled 1437 // when the TISM informs Tethering of its LinkProperties. 1438 mForwardedDownstreams.add(who); 1439 } else { 1440 mOffload.excludeDownstreamInterface(who.interfaceName()); 1441 mForwardedDownstreams.remove(who); 1442 } 1443 1444 // If this is a Wi-Fi interface, notify WifiManager of the active serving state. 1445 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) { 1446 final WifiManager mgr = getWifiManager(); 1447 final String iface = who.interfaceName(); 1448 switch (mode) { 1449 case IControlsTethering.STATE_TETHERED: 1450 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED); 1451 break; 1452 case IControlsTethering.STATE_LOCAL_ONLY: 1453 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY); 1454 break; 1455 default: 1456 Log.wtf(TAG, "Unknown active serving mode: " + mode); 1457 break; 1458 } 1459 } 1460 } 1461 1462 private void handleInterfaceServingStateInactive(TetherInterfaceStateMachine who) { 1463 mNotifyList.remove(who); 1464 mIPv6TetheringCoordinator.removeActiveDownstream(who); 1465 mOffload.excludeDownstreamInterface(who.interfaceName()); 1466 mForwardedDownstreams.remove(who); 1467 1468 // If this is a Wi-Fi interface, tell WifiManager of any errors. 1469 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) { 1470 if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) { 1471 getWifiManager().updateInterfaceIpState( 1472 who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR); 1473 } 1474 } 1475 } 1476 1477 private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) { 1478 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) { 1479 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o); 1480 return; 1481 } 1482 1483 final NetworkState ns = (NetworkState) o; 1484 1485 if (ns == null || !pertainsToCurrentUpstream(ns)) { 1486 // TODO: In future, this is where upstream evaluation and selection 1487 // could be handled for notifications which include sufficient data. 1488 // For example, after CONNECTIVITY_ACTION listening is removed, here 1489 // is where we could observe a Wi-Fi network becoming available and 1490 // passing validation. 1491 if (mCurrentUpstreamIface == null) { 1492 // If we have no upstream interface, try to run through upstream 1493 // selection again. If, for example, IPv4 connectivity has shown up 1494 // after IPv6 (e.g., 464xlat became available) we want the chance to 1495 // notice and act accordingly. 1496 chooseUpstreamType(false); 1497 } 1498 return; 1499 } 1500 1501 switch (arg1) { 1502 case UpstreamNetworkMonitor.EVENT_ON_AVAILABLE: 1503 // The default network changed, or DUN connected 1504 // before this callback was processed. Updates 1505 // for the current NetworkCapabilities and 1506 // LinkProperties have been requested (default 1507 // request) or are being sent shortly (DUN). Do 1508 // nothing until they arrive; if no updates 1509 // arrive there's nothing to do. 1510 break; 1511 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES: 1512 handleNewUpstreamNetworkState(ns); 1513 break; 1514 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES: 1515 setDnsForwarders(ns.network, ns.linkProperties); 1516 handleNewUpstreamNetworkState(ns); 1517 break; 1518 case UpstreamNetworkMonitor.EVENT_ON_LOST: 1519 // TODO: Re-evaluate possible upstreams. Currently upstream 1520 // reevaluation is triggered via received CONNECTIVITY_ACTION 1521 // broadcasts that result in being passed a 1522 // TetherMasterSM.CMD_UPSTREAM_CHANGED. 1523 handleNewUpstreamNetworkState(null); 1524 break; 1525 default: 1526 mLog.e("Unknown arg1 value: " + arg1); 1527 break; 1528 } 1529 } 1530 1531 class TetherModeAliveState extends State { 1532 boolean mUpstreamWanted = false; 1533 boolean mTryCell = true; 1534 1535 @Override 1536 public void enter() { 1537 // If turning on master tether settings fails, we have already 1538 // transitioned to an error state; exit early. 1539 if (!turnOnMasterTetherSettings()) { 1540 return; 1541 } 1542 1543 mCarrierConfigChange.startListening(); 1544 mSimChange.startListening(); 1545 mUpstreamNetworkMonitor.start(); 1546 1547 // TODO: De-duplicate with updateUpstreamWanted() below. 1548 if (upstreamWanted()) { 1549 mUpstreamWanted = true; 1550 mOffload.start(); 1551 chooseUpstreamType(true); 1552 mTryCell = false; 1553 } 1554 } 1555 1556 @Override 1557 public void exit() { 1558 mOffload.stop(); 1559 mUpstreamNetworkMonitor.stop(); 1560 mSimChange.stopListening(); 1561 mCarrierConfigChange.stopListening(); 1562 notifyDownstreamsOfNewUpstreamIface(null); 1563 handleNewUpstreamNetworkState(null); 1564 } 1565 1566 private boolean updateUpstreamWanted() { 1567 final boolean previousUpstreamWanted = mUpstreamWanted; 1568 mUpstreamWanted = upstreamWanted(); 1569 if (mUpstreamWanted != previousUpstreamWanted) { 1570 if (mUpstreamWanted) { 1571 mOffload.start(); 1572 } else { 1573 mOffload.stop(); 1574 } 1575 } 1576 return previousUpstreamWanted; 1577 } 1578 1579 @Override 1580 public boolean processMessage(Message message) { 1581 logMessage(this, message.what); 1582 boolean retValue = true; 1583 switch (message.what) { 1584 case EVENT_IFACE_SERVING_STATE_ACTIVE: { 1585 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; 1586 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); 1587 handleInterfaceServingStateActive(message.arg1, who); 1588 who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, 1589 mCurrentUpstreamIface); 1590 // If there has been a change and an upstream is now 1591 // desired, kick off the selection process. 1592 final boolean previousUpstreamWanted = updateUpstreamWanted(); 1593 if (!previousUpstreamWanted && mUpstreamWanted) { 1594 chooseUpstreamType(true); 1595 } 1596 break; 1597 } 1598 case EVENT_IFACE_SERVING_STATE_INACTIVE: { 1599 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; 1600 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); 1601 handleInterfaceServingStateInactive(who); 1602 1603 if (mNotifyList.isEmpty()) { 1604 // This transitions us out of TetherModeAliveState, 1605 // either to InitialState or an error state. 1606 turnOffMasterTetherSettings(); 1607 break; 1608 } 1609 1610 if (DBG) { 1611 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() + 1612 " live requests:"); 1613 for (TetherInterfaceStateMachine o : mNotifyList) { 1614 Log.d(TAG, " " + o); 1615 } 1616 } 1617 // If there has been a change and an upstream is no 1618 // longer desired, release any mobile requests. 1619 final boolean previousUpstreamWanted = updateUpstreamWanted(); 1620 if (previousUpstreamWanted && !mUpstreamWanted) { 1621 mUpstreamNetworkMonitor.releaseMobileNetworkRequest(); 1622 } 1623 break; 1624 } 1625 case EVENT_IFACE_UPDATE_LINKPROPERTIES: { 1626 final LinkProperties newLp = (LinkProperties) message.obj; 1627 if (message.arg1 == IControlsTethering.STATE_TETHERED) { 1628 mOffload.updateDownstreamLinkProperties(newLp); 1629 } else { 1630 mOffload.excludeDownstreamInterface(newLp.getInterfaceName()); 1631 } 1632 break; 1633 } 1634 case CMD_UPSTREAM_CHANGED: 1635 updateUpstreamWanted(); 1636 if (!mUpstreamWanted) break; 1637 1638 // Need to try DUN immediately if Wi-Fi goes down. 1639 chooseUpstreamType(true); 1640 mTryCell = false; 1641 break; 1642 case CMD_RETRY_UPSTREAM: 1643 updateUpstreamWanted(); 1644 if (!mUpstreamWanted) break; 1645 1646 chooseUpstreamType(mTryCell); 1647 mTryCell = !mTryCell; 1648 break; 1649 case EVENT_UPSTREAM_CALLBACK: { 1650 updateUpstreamWanted(); 1651 if (mUpstreamWanted) { 1652 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj); 1653 } 1654 break; 1655 } 1656 default: 1657 retValue = false; 1658 break; 1659 } 1660 return retValue; 1661 } 1662 } 1663 1664 class ErrorState extends State { 1665 private int mErrorNotification; 1666 1667 @Override 1668 public boolean processMessage(Message message) { 1669 boolean retValue = true; 1670 switch (message.what) { 1671 case EVENT_IFACE_SERVING_STATE_ACTIVE: 1672 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; 1673 who.sendMessage(mErrorNotification); 1674 break; 1675 case CMD_CLEAR_ERROR: 1676 mErrorNotification = ConnectivityManager.TETHER_ERROR_NO_ERROR; 1677 transitionTo(mInitialState); 1678 break; 1679 default: 1680 retValue = false; 1681 } 1682 return retValue; 1683 } 1684 1685 void notify(int msgType) { 1686 mErrorNotification = msgType; 1687 for (TetherInterfaceStateMachine sm : mNotifyList) { 1688 sm.sendMessage(msgType); 1689 } 1690 } 1691 1692 } 1693 1694 class SetIpForwardingEnabledErrorState extends ErrorState { 1695 @Override 1696 public void enter() { 1697 Log.e(TAG, "Error in setIpForwardingEnabled"); 1698 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR); 1699 } 1700 } 1701 1702 class SetIpForwardingDisabledErrorState extends ErrorState { 1703 @Override 1704 public void enter() { 1705 Log.e(TAG, "Error in setIpForwardingDisabled"); 1706 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR); 1707 } 1708 } 1709 1710 class StartTetheringErrorState extends ErrorState { 1711 @Override 1712 public void enter() { 1713 Log.e(TAG, "Error in startTethering"); 1714 notify(TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR); 1715 try { 1716 mNMService.setIpForwardingEnabled(false); 1717 } catch (Exception e) {} 1718 } 1719 } 1720 1721 class StopTetheringErrorState extends ErrorState { 1722 @Override 1723 public void enter() { 1724 Log.e(TAG, "Error in stopTethering"); 1725 notify(TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR); 1726 try { 1727 mNMService.setIpForwardingEnabled(false); 1728 } catch (Exception e) {} 1729 } 1730 } 1731 1732 class SetDnsForwardersErrorState extends ErrorState { 1733 @Override 1734 public void enter() { 1735 Log.e(TAG, "Error in setDnsForwarders"); 1736 notify(TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR); 1737 try { 1738 mNMService.stopTethering(); 1739 } catch (Exception e) {} 1740 try { 1741 mNMService.setIpForwardingEnabled(false); 1742 } catch (Exception e) {} 1743 } 1744 } 1745 1746 // A wrapper class to handle multiple situations where several calls to 1747 // the OffloadController need to happen together. 1748 // 1749 // TODO: This suggests that the interface between OffloadController and 1750 // Tethering is in need of improvement. Refactor these calls into the 1751 // OffloadController implementation. 1752 class OffloadWrapper { 1753 public void start() { 1754 mOffloadController.start(); 1755 sendOffloadExemptPrefixes(); 1756 } 1757 1758 public void stop() { 1759 mOffloadController.stop(); 1760 } 1761 1762 public void updateUpstreamNetworkState(NetworkState ns) { 1763 mOffloadController.setUpstreamLinkProperties( 1764 (ns != null) ? ns.linkProperties : null); 1765 } 1766 1767 public void updateDownstreamLinkProperties(LinkProperties newLp) { 1768 // Update the list of offload-exempt prefixes before adding 1769 // new prefixes on downstream interfaces to the offload HAL. 1770 sendOffloadExemptPrefixes(); 1771 mOffloadController.notifyDownstreamLinkProperties(newLp); 1772 } 1773 1774 public void excludeDownstreamInterface(String ifname) { 1775 // This and other interfaces may be in local-only hotspot mode; 1776 // resend all local prefixes to the OffloadController. 1777 sendOffloadExemptPrefixes(); 1778 mOffloadController.removeDownstreamInterface(ifname); 1779 } 1780 1781 public void sendOffloadExemptPrefixes() { 1782 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes()); 1783 } 1784 1785 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) { 1786 // Add in well-known minimum set. 1787 PrefixUtils.addNonForwardablePrefixes(localPrefixes); 1788 // Add tragically hardcoded prefixes. 1789 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX); 1790 1791 // Maybe add prefixes or addresses for downstreams, depending on 1792 // the IP serving mode of each. 1793 for (TetherInterfaceStateMachine tism : mNotifyList) { 1794 final LinkProperties lp = tism.linkProperties(); 1795 1796 switch (tism.servingMode()) { 1797 case IControlsTethering.STATE_UNAVAILABLE: 1798 case IControlsTethering.STATE_AVAILABLE: 1799 // No usable LinkProperties in these states. 1800 continue; 1801 case IControlsTethering.STATE_TETHERED: 1802 // Only add IPv4 /32 and IPv6 /128 prefixes. The 1803 // directly-connected prefixes will be sent as 1804 // downstream "offload-able" prefixes. 1805 for (LinkAddress addr : lp.getAllLinkAddresses()) { 1806 final InetAddress ip = addr.getAddress(); 1807 if (ip.isLinkLocalAddress()) continue; 1808 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip)); 1809 } 1810 break; 1811 case IControlsTethering.STATE_LOCAL_ONLY: 1812 // Add prefixes covering all local IPs. 1813 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp)); 1814 break; 1815 } 1816 } 1817 1818 mOffloadController.setLocalPrefixes(localPrefixes); 1819 } 1820 } 1821 } 1822 1823 @Override 1824 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 1825 // Binder.java closes the resource for us. 1826 @SuppressWarnings("resource") 1827 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 1828 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1829 1830 pw.println("Tethering:"); 1831 pw.increaseIndent(); 1832 1833 pw.println("Configuration:"); 1834 pw.increaseIndent(); 1835 final TetheringConfiguration cfg = mConfig; 1836 cfg.dump(pw); 1837 pw.decreaseIndent(); 1838 1839 synchronized (mPublicSync) { 1840 pw.println("Tether state:"); 1841 pw.increaseIndent(); 1842 for (int i = 0; i < mTetherStates.size(); i++) { 1843 final String iface = mTetherStates.keyAt(i); 1844 final TetherState tetherState = mTetherStates.valueAt(i); 1845 pw.print(iface + " - "); 1846 1847 switch (tetherState.lastState) { 1848 case IControlsTethering.STATE_UNAVAILABLE: 1849 pw.print("UnavailableState"); 1850 break; 1851 case IControlsTethering.STATE_AVAILABLE: 1852 pw.print("AvailableState"); 1853 break; 1854 case IControlsTethering.STATE_TETHERED: 1855 pw.print("TetheredState"); 1856 break; 1857 case IControlsTethering.STATE_LOCAL_ONLY: 1858 pw.print("LocalHotspotState"); 1859 break; 1860 default: 1861 pw.print("UnknownState"); 1862 break; 1863 } 1864 pw.println(" - lastError = " + tetherState.lastError); 1865 } 1866 pw.println("Upstream wanted: " + upstreamWanted()); 1867 pw.println("Current upstream interface: " + mCurrentUpstreamIface); 1868 pw.decreaseIndent(); 1869 } 1870 1871 pw.println("Hardware offload:"); 1872 pw.increaseIndent(); 1873 mOffloadController.dump(pw); 1874 pw.decreaseIndent(); 1875 1876 pw.println("Log:"); 1877 pw.increaseIndent(); 1878 if (argsContain(args, SHORT_ARG)) { 1879 pw.println("<log removed for brevity>"); 1880 } else { 1881 mLog.dump(fd, pw, args); 1882 } 1883 pw.decreaseIndent(); 1884 1885 pw.decreaseIndent(); 1886 } 1887 1888 private static boolean argsContain(String[] args, String target) { 1889 for (String arg : args) { 1890 if (target.equals(arg)) return true; 1891 } 1892 return false; 1893 } 1894 1895 private IControlsTethering makeControlCallback(String ifname) { 1896 return new IControlsTethering() { 1897 @Override 1898 public void updateInterfaceState( 1899 TetherInterfaceStateMachine who, int state, int lastError) { 1900 notifyInterfaceStateChange(ifname, who, state, lastError); 1901 } 1902 1903 @Override 1904 public void updateLinkProperties( 1905 TetherInterfaceStateMachine who, LinkProperties newLp) { 1906 notifyLinkPropertiesChanged(ifname, who, newLp); 1907 } 1908 }; 1909 } 1910 1911 // TODO: Move into TetherMasterSM. 1912 private void notifyInterfaceStateChange( 1913 String iface, TetherInterfaceStateMachine who, int state, int error) { 1914 synchronized (mPublicSync) { 1915 final TetherState tetherState = mTetherStates.get(iface); 1916 if (tetherState != null && tetherState.stateMachine.equals(who)) { 1917 tetherState.lastState = state; 1918 tetherState.lastError = error; 1919 } else { 1920 if (DBG) Log.d(TAG, "got notification from stale iface " + iface); 1921 } 1922 } 1923 1924 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error)); 1925 1926 try { 1927 // Notify that we're tethering (or not) this interface. 1928 // This is how data saver for instance knows if the user explicitly 1929 // turned on tethering (thus keeping us from being in data saver mode). 1930 mPolicyManager.onTetheringChanged(iface, state == IControlsTethering.STATE_TETHERED); 1931 } catch (RemoteException e) { 1932 // Not really very much we can do here. 1933 } 1934 1935 // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. 1936 // Thus we give a chance for TetherMasterSM to recover to InitialState 1937 // by sending CMD_CLEAR_ERROR 1938 if (error == ConnectivityManager.TETHER_ERROR_MASTER_ERROR) { 1939 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who); 1940 } 1941 int which; 1942 switch (state) { 1943 case IControlsTethering.STATE_UNAVAILABLE: 1944 case IControlsTethering.STATE_AVAILABLE: 1945 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE; 1946 break; 1947 case IControlsTethering.STATE_TETHERED: 1948 case IControlsTethering.STATE_LOCAL_ONLY: 1949 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE; 1950 break; 1951 default: 1952 Log.wtf(TAG, "Unknown interface state: " + state); 1953 return; 1954 } 1955 mTetherMasterSM.sendMessage(which, state, 0, who); 1956 sendTetherStateChangedBroadcast(); 1957 } 1958 1959 private void notifyLinkPropertiesChanged(String iface, TetherInterfaceStateMachine who, 1960 LinkProperties newLp) { 1961 final int state; 1962 synchronized (mPublicSync) { 1963 final TetherState tetherState = mTetherStates.get(iface); 1964 if (tetherState != null && tetherState.stateMachine.equals(who)) { 1965 state = tetherState.lastState; 1966 } else { 1967 mLog.log("got notification from stale iface " + iface); 1968 return; 1969 } 1970 } 1971 1972 mLog.log(String.format( 1973 "OBSERVED LinkProperties update iface=%s state=%s lp=%s", 1974 iface, IControlsTethering.getStateString(state), newLp)); 1975 final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES; 1976 mTetherMasterSM.sendMessage(which, state, 0, newLp); 1977 } 1978 1979 private void maybeTrackNewInterfaceLocked(final String iface) { 1980 // If we don't care about this type of interface, ignore. 1981 final int interfaceType = ifaceNameToType(iface); 1982 if (interfaceType == ConnectivityManager.TETHERING_INVALID) { 1983 mLog.log(iface + " is not a tetherable iface, ignoring"); 1984 return; 1985 } 1986 maybeTrackNewInterfaceLocked(iface, interfaceType); 1987 } 1988 1989 private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) { 1990 // If we have already started a TISM for this interface, skip. 1991 if (mTetherStates.containsKey(iface)) { 1992 mLog.log("active iface (" + iface + ") reported as added, ignoring"); 1993 return; 1994 } 1995 1996 mLog.log("adding TetheringInterfaceStateMachine for: " + iface); 1997 final TetherState tetherState = new TetherState( 1998 new TetherInterfaceStateMachine( 1999 iface, mLooper, interfaceType, mLog, mNMService, mStatsService, 2000 makeControlCallback(iface))); 2001 mTetherStates.put(iface, tetherState); 2002 tetherState.stateMachine.start(); 2003 } 2004 2005 private void stopTrackingInterfaceLocked(final String iface) { 2006 final TetherState tetherState = mTetherStates.get(iface); 2007 if (tetherState == null) { 2008 mLog.log("attempting to remove unknown iface (" + iface + "), ignoring"); 2009 return; 2010 } 2011 tetherState.stateMachine.stop(); 2012 mLog.log("removing TetheringInterfaceStateMachine for: " + iface); 2013 mTetherStates.remove(iface); 2014 } 2015 2016 private static String getIPv4DefaultRouteInterface(NetworkState ns) { 2017 if (ns == null) return null; 2018 return getInterfaceForDestination(ns.linkProperties, Inet4Address.ANY); 2019 } 2020 2021 private static String getIPv6DefaultRouteInterface(NetworkState ns) { 2022 if (ns == null) return null; 2023 // An upstream network's IPv6 capability is currently only useful if it 2024 // can be 64share'd downstream (RFC 7278). For now, that means mobile 2025 // upstream networks only. 2026 if (ns.networkCapabilities == null || 2027 !ns.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { 2028 return null; 2029 } 2030 2031 return getInterfaceForDestination(ns.linkProperties, Inet6Address.ANY); 2032 } 2033 2034 private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) { 2035 final RouteInfo ri = (lp != null) 2036 ? RouteInfo.selectBestRoute(lp.getAllRoutes(), dst) 2037 : null; 2038 return (ri != null) ? ri.getInterface() : null; 2039 } 2040 2041 private static String[] copy(String[] strarray) { 2042 return Arrays.copyOf(strarray, strarray.length); 2043 } 2044} 2045