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