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