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 TetherState(TetherInterfaceStateMachine sm)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 isCurrentlyServing()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 Tethering(Context context, INetworkManagementService nmService, INetworkStatsService statsService, INetworkPolicyManager policyManager, Looper looper, MockableSystemProperties systemProperties, TetheringDependencies deps)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 startStateMachineUpdaters()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 getWifiManager()296 private WifiManager getWifiManager() { 297 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 298 } 299 300 // NOTE: This is always invoked on the mLooper thread. updateConfiguration()301 private void updateConfiguration() { 302 mConfig = new TetheringConfiguration(mContext, mLog); 303 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); 304 } 305 maybeUpdateConfiguration()306 private void maybeUpdateConfiguration() { 307 final int dunCheck = TetheringConfiguration.checkDunRequired(mContext); 308 if (dunCheck == mConfig.dunCheck) return; 309 updateConfiguration(); 310 } 311 312 @Override interfaceStatusChanged(String iface, boolean up)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 interfaceLinkStateChanged(String iface, boolean up)335 public void interfaceLinkStateChanged(String iface, boolean up) { 336 interfaceStatusChanged(iface, up); 337 } 338 ifaceNameToType(String iface)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 interfaceAdded(String iface)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 interfaceRemoved(String iface)361 public void interfaceRemoved(String iface) { 362 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); 363 synchronized (mPublicSync) { 364 stopTrackingInterfaceLocked(iface); 365 } 366 } 367 startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi)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 stopTethering(int type)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 isTetherProvisioningRequired()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. carrierConfigAffirmsEntitlementCheckNotRequired()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 */ enableTetheringInternal(int type, boolean enable, ResultReceiver receiver)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 sendTetherResult(ResultReceiver receiver, int result)458 private void sendTetherResult(ResultReceiver receiver, int result) { 459 if (receiver != null) { 460 receiver.send(result, null); 461 } 462 } 463 setWifiTethering(final boolean enable)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 setBluetoothTethering(final boolean enable, final ResultReceiver receiver)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 runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver)512 private void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) { 513 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); 514 sendUiTetherProvisionIntent(type, proxyReceiver); 515 } 516 sendUiTetherProvisionIntent(int type, ResultReceiver receiver)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 */ getProxyReceiver(final int type, final ResultReceiver receiver)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 scheduleProvisioningRechecks(int type)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 runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver)574 private void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) { 575 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); 576 sendSilentTetherProvisionIntent(type, proxyReceiver); 577 } 578 sendSilentTetherProvisionIntent(int type, ResultReceiver receiver)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 cancelTetherProvisioningRechecks(int type)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. startProvisionIntent(int tetherType)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 tether(String iface)617 public int tether(String iface) { 618 return tether(iface, IControlsTethering.STATE_TETHERED); 619 } 620 tether(String iface, int requestedState)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 untether(String iface)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 untetherAll()664 public void untetherAll() { 665 stopTethering(TETHERING_WIFI); 666 stopTethering(TETHERING_USB); 667 stopTethering(TETHERING_BLUETOOTH); 668 } 669 getLastTetherError(String iface)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. sendTetherStateChangedBroadcast()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 showTetheredNotification(int id)756 private void showTetheredNotification(int id) { 757 showTetheredNotification(id, true); 758 } 759 760 @VisibleForTesting showTetheredNotification(int id, boolean tetheringOn)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 clearTetheredNotification()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 onReceive(Context content, Intent intent)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 handleConnectivityAction(Intent intent)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 handleUsbAction(Intent intent)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 handleWifiApAction(Intent intent)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 TetheringUserRestrictionListener(Tethering wrapper)933 public TetheringUserRestrictionListener(Tethering wrapper) { 934 mWrapper = wrapper; 935 } 936 onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)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 disableWifiIpServingLocked(String ifname, int apState)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 enableWifiIpServingLocked(String ifname, int wifiIpMode)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 tetherMatchingInterfaces(int requestedState, int interfaceType)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 changeInterfaceState(String ifname, int requestedState)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 getTetheringConfiguration()1073 public TetheringConfiguration getTetheringConfiguration() { 1074 return mConfig; 1075 } 1076 hasTetherableConfiguration()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. getTetherableUsbRegexs()1090 public String[] getTetherableUsbRegexs() { 1091 return copy(mConfig.tetherableUsbRegexs); 1092 } 1093 getTetherableWifiRegexs()1094 public String[] getTetherableWifiRegexs() { 1095 return copy(mConfig.tetherableWifiRegexs); 1096 } 1097 getTetherableBluetoothRegexs()1098 public String[] getTetherableBluetoothRegexs() { 1099 return copy(mConfig.tetherableBluetoothRegexs); 1100 } 1101 setUsbTethering(boolean enable)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. getTetheredIfaces()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 getTetherableIfaces()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 getTetheredDhcpRanges()1139 public String[] getTetheredDhcpRanges() { 1140 return mConfig.dhcpRanges; 1141 } 1142 getErroredIfaces()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 logMessage(State state, int what)1156 private void logMessage(State state, int what) { 1157 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what))); 1158 } 1159 upstreamWanted()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|. pertainsToCurrentUpstream(NetworkState ns)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 reevaluateSimCardProvisioning()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 TetherMasterSM(String name, Looper looper, TetheringDependencies deps)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 processMessage(Message message)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 turnOnMasterTetherSettings()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 turnOffMasterTetherSettings()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 chooseUpstreamType(boolean tryCell)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 setUpstreamNetwork(NetworkState ns)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 setDnsForwarders(final Network network, final LinkProperties lp)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 notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces)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 handleNewUpstreamNetworkState(NetworkState ns)1422 protected void handleNewUpstreamNetworkState(NetworkState ns) { 1423 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns); 1424 mOffload.updateUpstreamNetworkState(ns); 1425 } 1426 handleInterfaceServingStateActive(int mode, TetherInterfaceStateMachine who)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 handleInterfaceServingStateInactive(TetherInterfaceStateMachine who)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 handleUpstreamNetworkMonitorCallback(int arg1, Object o)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 enter()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 exit()1554 public void exit() { 1555 mOffload.stop(); 1556 mUpstreamNetworkMonitor.stop(); 1557 mSimChange.stopListening(); 1558 notifyDownstreamsOfNewUpstreamIface(null); 1559 handleNewUpstreamNetworkState(null); 1560 } 1561 updateUpstreamWanted()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 processMessage(Message message)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 processMessage(Message message)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 notify(int msgType)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 enter()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 enter()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 enter()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 enter()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 enter()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 { start()1749 public void start() { 1750 mOffloadController.start(); 1751 sendOffloadExemptPrefixes(); 1752 } 1753 stop()1754 public void stop() { 1755 mOffloadController.stop(); 1756 } 1757 updateUpstreamNetworkState(NetworkState ns)1758 public void updateUpstreamNetworkState(NetworkState ns) { 1759 mOffloadController.setUpstreamLinkProperties( 1760 (ns != null) ? ns.linkProperties : null); 1761 } 1762 updateDownstreamLinkProperties(LinkProperties newLp)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 excludeDownstreamInterface(String ifname)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 sendOffloadExemptPrefixes()1777 public void sendOffloadExemptPrefixes() { 1778 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes()); 1779 } 1780 sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes)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 dump(FileDescriptor fd, PrintWriter writer, String[] args)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 argsContain(String[] args, String target)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 makeControlCallback(String ifname)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