1 /* 2 * Copyright (C) 2019 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 package android.net; 17 18 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 19 20 import android.Manifest; 21 import android.annotation.FlaggedApi; 22 import android.annotation.IntDef; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.RequiresPermission; 26 import android.annotation.SuppressLint; 27 import android.annotation.SystemApi; 28 import android.content.Context; 29 import android.net.wifi.SoftApConfiguration; 30 import android.net.wifi.WifiManager; 31 import android.os.Build; 32 import android.os.Bundle; 33 import android.os.ConditionVariable; 34 import android.os.IBinder; 35 import android.os.Parcel; 36 import android.os.Parcelable; 37 import android.os.Process; 38 import android.os.RemoteException; 39 import android.os.ResultReceiver; 40 import android.text.TextUtils; 41 import android.util.ArrayMap; 42 import android.util.ArraySet; 43 import android.util.Log; 44 45 import com.android.internal.annotations.GuardedBy; 46 import com.android.modules.utils.build.SdkLevel; 47 import com.android.net.flags.Flags; 48 49 import java.lang.annotation.Retention; 50 import java.lang.annotation.RetentionPolicy; 51 import java.lang.ref.WeakReference; 52 import java.util.ArrayList; 53 import java.util.Arrays; 54 import java.util.Collection; 55 import java.util.Collections; 56 import java.util.HashMap; 57 import java.util.List; 58 import java.util.Objects; 59 import java.util.Set; 60 import java.util.StringJoiner; 61 import java.util.concurrent.Executor; 62 import java.util.function.Supplier; 63 64 /** 65 * This class provides the APIs to control the tethering service. 66 * <p> The primary responsibilities of this class are to provide the APIs for applications to 67 * start tethering, stop tethering, query configuration and query status. 68 * 69 */ 70 @SuppressLint({"NotCloseable", "UnflaggedApi"}) 71 public class TetheringManager { 72 private static final String TAG = TetheringManager.class.getSimpleName(); 73 private static final int DEFAULT_TIMEOUT_MS = 60_000; 74 private static final long CONNECTOR_POLL_INTERVAL_MILLIS = 200L; 75 76 @GuardedBy("mConnectorWaitQueue") 77 @Nullable 78 private ITetheringConnector mConnector; 79 @GuardedBy("mConnectorWaitQueue") 80 @NonNull 81 private final List<ConnectorConsumer> mConnectorWaitQueue = new ArrayList<>(); 82 private final Supplier<IBinder> mConnectorSupplier; 83 84 private final TetheringCallbackInternal mCallback; 85 private final Context mContext; 86 private final ArrayMap<TetheringEventCallback, ITetheringEventCallback> 87 mTetheringEventCallbacks = new ArrayMap<>(); 88 89 private volatile TetheringConfigurationParcel mTetheringConfiguration; 90 private volatile TetherStatesParcel mTetherStatesParcel; 91 92 /** 93 * Broadcast Action: A tetherable connection has come or gone. 94 * Uses {@code TetheringManager.EXTRA_AVAILABLE_TETHER}, 95 * {@code TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY}, 96 * {@code TetheringManager.EXTRA_ACTIVE_TETHER}, and 97 * {@code TetheringManager.EXTRA_ERRORED_TETHER} to indicate 98 * the current state of tethering. Each include a list of 99 * interface names in that state (may be empty). 100 * @hide 101 * 102 * @deprecated New client should use TetheringEventCallback instead. 103 */ 104 @Deprecated 105 @SystemApi 106 public static final String ACTION_TETHER_STATE_CHANGED = 107 "android.net.conn.TETHER_STATE_CHANGED"; 108 109 /** 110 * gives a String[] listing all the interfaces configured for 111 * tethering and currently available for tethering. 112 * @hide 113 */ 114 @SystemApi 115 public static final String EXTRA_AVAILABLE_TETHER = "availableArray"; 116 117 /** 118 * gives a String[] listing all the interfaces currently in local-only 119 * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding) 120 * @hide 121 */ 122 @SystemApi 123 public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY"; 124 125 /** 126 * gives a String[] listing all the interfaces currently tethered 127 * (ie, has DHCPv4 support and packets potentially forwarded/NATed) 128 * @hide 129 */ 130 @SystemApi 131 public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; 132 133 /** 134 * gives a String[] listing all the interfaces we tried to tether and 135 * failed. Use {@link #getLastTetherError} to find the error code 136 * for any interfaces listed here. 137 * @hide 138 */ 139 @SystemApi 140 public static final String EXTRA_ERRORED_TETHER = "erroredArray"; 141 142 /** @hide */ 143 @Retention(RetentionPolicy.SOURCE) 144 @IntDef(flag = false, value = { 145 TETHERING_WIFI, 146 TETHERING_USB, 147 TETHERING_BLUETOOTH, 148 TETHERING_WIFI_P2P, 149 TETHERING_NCM, 150 TETHERING_ETHERNET, 151 TETHERING_VIRTUAL, 152 }) 153 public @interface TetheringType { 154 } 155 156 /** 157 * Invalid tethering type. 158 * @see #startTethering. 159 * @hide 160 */ 161 @SystemApi 162 public static final int TETHERING_INVALID = -1; 163 164 /** 165 * Wifi tethering type. 166 * @see #startTethering. 167 */ 168 @SuppressLint("UnflaggedApi") 169 public static final int TETHERING_WIFI = 0; 170 171 /** 172 * USB tethering type. 173 * @see #startTethering. 174 * @hide 175 */ 176 @SystemApi 177 public static final int TETHERING_USB = 1; 178 179 /** 180 * Bluetooth tethering type. 181 * @see #startTethering. 182 * @hide 183 */ 184 @SystemApi 185 public static final int TETHERING_BLUETOOTH = 2; 186 187 /** 188 * Wifi P2p tethering type. 189 * Wifi P2p tethering is set through events automatically, and don't 190 * need to start from #startTethering. 191 * @hide 192 */ 193 @SystemApi 194 public static final int TETHERING_WIFI_P2P = 3; 195 196 /** 197 * Ncm local tethering type. 198 * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback) 199 * @hide 200 */ 201 @SystemApi 202 public static final int TETHERING_NCM = 4; 203 204 /** 205 * Ethernet tethering type. 206 * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback) 207 * @hide 208 */ 209 @SystemApi 210 public static final int TETHERING_ETHERNET = 5; 211 212 /** 213 * WIGIG tethering type. Use a separate type to prevent 214 * conflicts with TETHERING_WIFI 215 * This type is only used internally by the tethering module 216 * @hide 217 */ 218 public static final int TETHERING_WIGIG = 6; 219 220 /** 221 * VIRTUAL tethering type. 222 * 223 * This tethering type is for providing external network to virtual machines 224 * running on top of Android devices, which are created and managed by 225 * AVF(Android Virtualization Framework). 226 * @hide 227 */ 228 @FlaggedApi(Flags.FLAG_TETHERING_REQUEST_VIRTUAL) 229 @SystemApi 230 public static final int TETHERING_VIRTUAL = 7; 231 232 /** 233 * The int value of last tethering type. 234 * @hide 235 */ 236 public static final int MAX_TETHERING_TYPE = TETHERING_VIRTUAL; 237 typeToString(@etheringType int type)238 private static String typeToString(@TetheringType int type) { 239 switch (type) { 240 case TETHERING_INVALID: return "TETHERING_INVALID"; 241 case TETHERING_WIFI: return "TETHERING_WIFI"; 242 case TETHERING_USB: return "TETHERING_USB"; 243 case TETHERING_BLUETOOTH: return "TETHERING_BLUETOOTH"; 244 case TETHERING_WIFI_P2P: return "TETHERING_WIFI_P2P"; 245 case TETHERING_NCM: return "TETHERING_NCM"; 246 case TETHERING_ETHERNET: return "TETHERING_ETHERNET"; 247 default: 248 return "TETHERING_UNKNOWN(" + type + ")"; 249 } 250 } 251 252 /** @hide */ 253 @Retention(RetentionPolicy.SOURCE) 254 @IntDef(value = { 255 TETHER_ERROR_NO_ERROR, 256 TETHER_ERROR_PROVISIONING_FAILED, 257 TETHER_ERROR_ENTITLEMENT_UNKNOWN, 258 }) 259 public @interface EntitlementResult { 260 } 261 262 /** @hide */ 263 @Retention(RetentionPolicy.SOURCE) 264 @IntDef(value = { 265 TETHER_ERROR_NO_ERROR, 266 TETHER_ERROR_UNKNOWN_IFACE, 267 TETHER_ERROR_SERVICE_UNAVAIL, 268 TETHER_ERROR_INTERNAL_ERROR, 269 TETHER_ERROR_TETHER_IFACE_ERROR, 270 TETHER_ERROR_ENABLE_FORWARDING_ERROR, 271 TETHER_ERROR_DISABLE_FORWARDING_ERROR, 272 TETHER_ERROR_IFACE_CFG_ERROR, 273 TETHER_ERROR_DHCPSERVER_ERROR, 274 }) 275 public @interface TetheringIfaceError { 276 } 277 278 /** @hide */ 279 @Retention(RetentionPolicy.SOURCE) 280 @IntDef(value = { 281 TETHER_ERROR_SERVICE_UNAVAIL, 282 TETHER_ERROR_UNSUPPORTED, 283 TETHER_ERROR_INTERNAL_ERROR, 284 TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, 285 TETHER_ERROR_UNKNOWN_TYPE, 286 TETHER_ERROR_DUPLICATE_REQUEST, 287 }) 288 public @interface StartTetheringError { 289 } 290 291 /** @hide */ 292 @Retention(RetentionPolicy.SOURCE) 293 @IntDef(value = { 294 TETHER_ERROR_NO_ERROR, 295 TETHER_ERROR_UNKNOWN_REQUEST, 296 }) 297 public @interface StopTetheringError { 298 } 299 300 @SuppressLint("UnflaggedApi") 301 public static final int TETHER_ERROR_NO_ERROR = 0; 302 @SuppressLint("UnflaggedApi") 303 public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; 304 @SuppressLint("UnflaggedApi") 305 public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; 306 @SuppressLint("UnflaggedApi") 307 public static final int TETHER_ERROR_UNSUPPORTED = 3; 308 @SuppressLint("UnflaggedApi") 309 public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; 310 @SuppressLint("UnflaggedApi") 311 public static final int TETHER_ERROR_INTERNAL_ERROR = 5; 312 @SuppressLint("UnflaggedApi") 313 public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; 314 @SuppressLint("UnflaggedApi") 315 public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; 316 @SuppressLint("UnflaggedApi") 317 public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; 318 @SuppressLint("UnflaggedApi") 319 public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; 320 @SuppressLint("UnflaggedApi") 321 public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; 322 @SuppressLint("UnflaggedApi") 323 public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; 324 @SuppressLint("UnflaggedApi") 325 public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; 326 @SuppressLint("UnflaggedApi") 327 public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; 328 @SuppressLint("UnflaggedApi") 329 public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; 330 @SuppressLint("UnflaggedApi") 331 public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; 332 @SuppressLint("UnflaggedApi") 333 public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; 334 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 335 public static final int TETHER_ERROR_UNKNOWN_REQUEST = 17; 336 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 337 public static final int TETHER_ERROR_DUPLICATE_REQUEST = 18; 338 /** 339 * Never used outside Tethering.java. 340 * @hide 341 */ 342 public static final int TETHER_ERROR_BLUETOOTH_SERVICE_PENDING = 19; 343 /** 344 * Never used outside Tethering.java. 345 * @hide 346 */ 347 public static final int TETHER_ERROR_SOFT_AP_CALLBACK_PENDING = 20; 348 349 /** @hide */ 350 @Retention(RetentionPolicy.SOURCE) 351 @IntDef(flag = false, value = { 352 TETHER_HARDWARE_OFFLOAD_STOPPED, 353 TETHER_HARDWARE_OFFLOAD_STARTED, 354 TETHER_HARDWARE_OFFLOAD_FAILED, 355 }) 356 public @interface TetherOffloadStatus { 357 } 358 359 /** 360 * Tethering offload status is stopped. 361 * @hide 362 */ 363 @SystemApi 364 public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; 365 /** 366 * Tethering offload status is started. 367 * @hide 368 */ 369 @SystemApi 370 public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; 371 /** 372 * Fail to start tethering offload. 373 * @hide 374 */ 375 @SystemApi 376 public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; 377 378 /** 379 * Create a TetheringManager object for interacting with the tethering service. 380 * 381 * @param context Context for the manager. 382 * @param connectorSupplier Supplier for the manager connector; may return null while the 383 * service is not connected. 384 * {@hide} 385 */ 386 @SystemApi(client = MODULE_LIBRARIES) TetheringManager(@onNull final Context context, @NonNull Supplier<IBinder> connectorSupplier)387 public TetheringManager(@NonNull final Context context, 388 @NonNull Supplier<IBinder> connectorSupplier) { 389 mContext = context; 390 mCallback = new TetheringCallbackInternal(this); 391 mConnectorSupplier = connectorSupplier; 392 393 final String pkgName = mContext.getOpPackageName(); 394 395 final IBinder connector = mConnectorSupplier.get(); 396 // If the connector is available on start, do not start a polling thread. This introduces 397 // differences in the thread that sends the oneway binder calls to the service between the 398 // first few seconds after boot and later, but it avoids always having differences between 399 // the first usage of TetheringManager from a process and subsequent usages (so the 400 // difference is only on boot). On boot binder calls may be queued until the service comes 401 // up and be sent from a worker thread; later, they are always sent from the caller thread. 402 // Considering that it's just oneway binder calls, and ordering is preserved, this seems 403 // better than inconsistent behavior persisting after boot. 404 // If system server restarted, mConnectorSupplier might temporarily return a stale (i.e. 405 // dead) version of TetheringService. 406 if (connector != null && connector.isBinderAlive()) { 407 mConnector = ITetheringConnector.Stub.asInterface(connector); 408 } else { 409 startPollingForConnector(); 410 } 411 412 Log.i(TAG, "registerTetheringEventCallback:" + pkgName); 413 getConnector(c -> c.registerTetheringEventCallback(mCallback, pkgName)); 414 } 415 416 /** @hide */ 417 @Override finalize()418 protected void finalize() throws Throwable { 419 final String pkgName = mContext.getOpPackageName(); 420 Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName); 421 // 1. It's generally not recommended to perform long operations in finalize, but while 422 // unregisterTetheringEventCallback does an IPC, it's a oneway IPC so should not block. 423 // 2. If the connector is not yet connected, TetheringManager is impossible to finalize 424 // because the connector polling thread strong reference the TetheringManager object. So 425 // it's guaranteed that registerTetheringEventCallback was already called before calling 426 // unregisterTetheringEventCallback in finalize. 427 if (mConnector == null) Log.wtf(TAG, "null connector in finalize!"); 428 getConnector(c -> c.unregisterTetheringEventCallback(mCallback, pkgName)); 429 430 super.finalize(); 431 } 432 startPollingForConnector()433 private void startPollingForConnector() { 434 new Thread(() -> { 435 while (true) { 436 try { 437 Thread.sleep(CONNECTOR_POLL_INTERVAL_MILLIS); 438 } catch (InterruptedException e) { 439 // Not much to do here, the system needs to wait for the connector 440 } 441 final IBinder connector = mConnectorSupplier.get(); 442 if (connector != null && connector.isBinderAlive()) { 443 onTetheringConnected(ITetheringConnector.Stub.asInterface(connector)); 444 return; 445 } 446 } 447 }).start(); 448 } 449 450 private interface ConnectorConsumer { onConnectorAvailable(ITetheringConnector connector)451 void onConnectorAvailable(ITetheringConnector connector) throws RemoteException; 452 } 453 onTetheringConnected(ITetheringConnector connector)454 private void onTetheringConnected(ITetheringConnector connector) { 455 // Process the connector wait queue in order, including any items that are added 456 // while processing. 457 // 458 // 1. Copy the queue to a local variable under lock. 459 // 2. Drain the local queue with the lock released (otherwise, enqueuing future commands 460 // would block on the lock). 461 // 3. Acquire the lock again. If any new tasks were queued during step 2, goto 1. 462 // If not, set mConnector to non-null so future tasks are run immediately, not queued. 463 // 464 // For this to work, all calls to the tethering service must use getConnector(), which 465 // ensures that tasks are added to the queue with the lock held. 466 // 467 // Once mConnector is set to non-null, it will never be null again. If the network stack 468 // process crashes, no recovery is possible. 469 // TODO: evaluate whether it is possible to recover from network stack process crashes 470 // (though in most cases the system will have crashed when the network stack process 471 // crashes). 472 do { 473 final List<ConnectorConsumer> localWaitQueue; 474 synchronized (mConnectorWaitQueue) { 475 localWaitQueue = new ArrayList<>(mConnectorWaitQueue); 476 mConnectorWaitQueue.clear(); 477 } 478 479 // Allow more tasks to be added at the end without blocking while draining the queue. 480 for (ConnectorConsumer task : localWaitQueue) { 481 try { 482 task.onConnectorAvailable(connector); 483 } catch (RemoteException e) { 484 // Most likely the network stack process crashed, which is likely to crash the 485 // system. Keep processing other requests but report the error loudly. 486 Log.wtf(TAG, "Error processing request for the tethering connector", e); 487 } 488 } 489 490 synchronized (mConnectorWaitQueue) { 491 if (mConnectorWaitQueue.size() == 0) { 492 mConnector = connector; 493 return; 494 } 495 } 496 } while (true); 497 } 498 499 /** 500 * Asynchronously get the ITetheringConnector to execute some operation. 501 * 502 * <p>If the connector is already available, the operation will be executed on the caller's 503 * thread. Otherwise it will be queued and executed on a worker thread. The operation should be 504 * limited to performing oneway binder calls to minimize differences due to threading. 505 */ getConnector(ConnectorConsumer consumer)506 private void getConnector(ConnectorConsumer consumer) { 507 final ITetheringConnector connector; 508 synchronized (mConnectorWaitQueue) { 509 connector = mConnector; 510 if (connector == null) { 511 mConnectorWaitQueue.add(consumer); 512 return; 513 } 514 } 515 516 try { 517 consumer.onConnectorAvailable(connector); 518 } catch (RemoteException e) { 519 throw new IllegalStateException(e); 520 } 521 } 522 523 private interface RequestHelper { runRequest(ITetheringConnector connector, IIntResultListener listener)524 void runRequest(ITetheringConnector connector, IIntResultListener listener); 525 } 526 527 // Used to dispatch legacy ConnectivityManager methods that expect tethering to be able to 528 // return results and perform operations synchronously. 529 // TODO: remove once there are no callers of these legacy methods. 530 private static class RequestDispatcher { 531 private final ConditionVariable mWaiting; 532 public volatile int mRemoteResult; 533 534 private final IIntResultListener mListener = new IIntResultListener.Stub() { 535 @Override 536 public void onResult(final int resultCode) { 537 mRemoteResult = resultCode; 538 mWaiting.open(); 539 } 540 }; 541 RequestDispatcher()542 RequestDispatcher() { 543 mWaiting = new ConditionVariable(); 544 } 545 waitForResult(final RequestHelper request, final TetheringManager mgr)546 int waitForResult(final RequestHelper request, final TetheringManager mgr) { 547 mgr.getConnector(c -> request.runRequest(c, mListener)); 548 if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) { 549 throw new IllegalStateException("Callback timeout"); 550 } 551 552 throwIfPermissionFailure(mRemoteResult); 553 554 return mRemoteResult; 555 } 556 } 557 throwIfPermissionFailure(final int errorCode)558 private static void throwIfPermissionFailure(final int errorCode) { 559 switch (errorCode) { 560 case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION: 561 throw new SecurityException("No android.permission.TETHER_PRIVILEGED" 562 + " or android.permission.WRITE_SETTINGS permission"); 563 case TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION: 564 throw new SecurityException( 565 "No android.permission.ACCESS_NETWORK_STATE permission"); 566 } 567 } 568 569 /** 570 * A request for a tethered interface. 571 * 572 * There are two reasons why this doesn't implement CLoseable: 573 * 1. To consistency with the existing EthernetManager.TetheredInterfaceRequest, which is 574 * already released. 575 * 2. This is not synchronous, so it's not useful to use try-with-resources. 576 * 577 * {@hide} 578 */ 579 @SystemApi(client = MODULE_LIBRARIES) 580 @SuppressLint("NotCloseable") 581 public interface TetheredInterfaceRequest { 582 /** 583 * Release the request to tear down tethered interface. 584 */ release()585 void release(); 586 } 587 588 /** 589 * Callback for requestTetheredInterface. 590 * 591 * {@hide} 592 */ 593 @SystemApi(client = MODULE_LIBRARIES) 594 public interface TetheredInterfaceCallback { 595 /** 596 * Called when the tethered interface is available. 597 * @param iface The name of the interface. 598 */ onAvailable(@onNull String iface)599 void onAvailable(@NonNull String iface); 600 601 /** 602 * Called when the tethered interface is now unavailable. 603 */ onUnavailable()604 void onUnavailable(); 605 } 606 607 private static class TetheringCallbackInternal extends ITetheringEventCallback.Stub { 608 private volatile int mError = TETHER_ERROR_NO_ERROR; 609 private final ConditionVariable mWaitForCallback = new ConditionVariable(); 610 // This object is never garbage collected because the Tethering code running in 611 // the system server always maintains a reference to it for as long as 612 // mCallback is registered. 613 // 614 // Don't keep a strong reference to TetheringManager because otherwise 615 // TetheringManager cannot be garbage collected, and because TetheringManager 616 // stores the Context that it was created from, this will prevent the calling 617 // Activity from being garbage collected as well. 618 private final WeakReference<TetheringManager> mTetheringMgrRef; 619 TetheringCallbackInternal(final TetheringManager tm)620 TetheringCallbackInternal(final TetheringManager tm) { 621 mTetheringMgrRef = new WeakReference<>(tm); 622 } 623 624 @Override onCallbackStarted(TetheringCallbackStartedParcel parcel)625 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 626 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 627 if (tetheringMgr != null) { 628 tetheringMgr.mTetheringConfiguration = parcel.config; 629 tetheringMgr.mTetherStatesParcel = parcel.states; 630 mWaitForCallback.open(); 631 } 632 } 633 634 @Override onCallbackStopped(int errorCode)635 public void onCallbackStopped(int errorCode) { 636 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 637 if (tetheringMgr != null) { 638 mError = errorCode; 639 mWaitForCallback.open(); 640 } 641 } 642 643 @Override onSupportedTetheringTypes(long supportedBitmap)644 public void onSupportedTetheringTypes(long supportedBitmap) { } 645 646 @Override onUpstreamChanged(Network network)647 public void onUpstreamChanged(Network network) { } 648 649 @Override onConfigurationChanged(TetheringConfigurationParcel config)650 public void onConfigurationChanged(TetheringConfigurationParcel config) { 651 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 652 if (tetheringMgr != null) tetheringMgr.mTetheringConfiguration = config; 653 } 654 655 @Override onTetherStatesChanged(TetherStatesParcel states)656 public void onTetherStatesChanged(TetherStatesParcel states) { 657 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 658 if (tetheringMgr != null) tetheringMgr.mTetherStatesParcel = states; 659 } 660 661 @Override onTetherClientsChanged(List<TetheredClient> clients)662 public void onTetherClientsChanged(List<TetheredClient> clients) { } 663 664 @Override onOffloadStatusChanged(int status)665 public void onOffloadStatusChanged(int status) { } 666 waitForStarted()667 public void waitForStarted() { 668 mWaitForCallback.block(DEFAULT_TIMEOUT_MS); 669 throwIfPermissionFailure(mError); 670 } 671 } 672 unsupportedAfterV()673 private void unsupportedAfterV() { 674 if (SdkLevel.isAtLeastB()) { 675 throw new UnsupportedOperationException("Not supported after SDK version " 676 + Build.VERSION_CODES.VANILLA_ICE_CREAM); 677 } 678 } 679 680 /** 681 * Attempt to tether the named interface. This will setup a dhcp server 682 * on the interface, forward and NAT IP v4 packets and forward DNS requests 683 * to the best active upstream network interface. Note that if no upstream 684 * IP network interface is available, dhcp will still run and traffic will be 685 * allowed between the tethered devices and this device, though upstream net 686 * access will of course fail until an upstream network interface becomes 687 * active. 688 * 689 * @deprecated Legacy tethering API. Callers should instead use 690 * {@link #startTethering(int, Executor, StartTetheringCallback)}. 691 * On SDK versions after {@link Build.VERSION_CODES.VANILLA_ICE_CREAM}, this will 692 * throw an UnsupportedOperationException. 693 * 694 * @param iface the interface name to tether. 695 * @return error a {@code TETHER_ERROR} value indicating success or failure type 696 * 697 * {@hide} 698 */ 699 @Deprecated 700 @SystemApi(client = MODULE_LIBRARIES) tether(@onNull final String iface)701 public int tether(@NonNull final String iface) { 702 unsupportedAfterV(); 703 704 final String callerPkg = mContext.getOpPackageName(); 705 Log.i(TAG, "tether caller:" + callerPkg); 706 final RequestDispatcher dispatcher = new RequestDispatcher(); 707 708 return dispatcher.waitForResult((connector, listener) -> { 709 try { 710 connector.tether(iface, callerPkg, getAttributionTag(), listener); 711 } catch (RemoteException e) { 712 throw new IllegalStateException(e); 713 } 714 }, this); 715 } 716 717 /** 718 * @return the context's attribution tag 719 */ 720 private @Nullable String getAttributionTag() { 721 return mContext.getAttributionTag(); 722 } 723 724 /** 725 * Stop tethering the named interface. 726 * 727 * @deprecated Legacy tethering API. Callers should instead use 728 * {@link #stopTethering(int)}. 729 * On SDK versions after {@link Build.VERSION_CODES.VANILLA_ICE_CREAM}, this will 730 * throw an UnsupportedOperationException. 731 * 732 * {@hide} 733 */ 734 @Deprecated 735 @SystemApi(client = MODULE_LIBRARIES) 736 public int untether(@NonNull final String iface) { 737 unsupportedAfterV(); 738 739 final String callerPkg = mContext.getOpPackageName(); 740 Log.i(TAG, "untether caller:" + callerPkg); 741 742 final RequestDispatcher dispatcher = new RequestDispatcher(); 743 744 return dispatcher.waitForResult((connector, listener) -> { 745 try { 746 connector.untether(iface, callerPkg, getAttributionTag(), listener); 747 } catch (RemoteException e) { 748 throw new IllegalStateException(e); 749 } 750 }, this); 751 } 752 753 /** 754 * Attempt to both alter the mode of USB and Tethering of USB. 755 * 756 * @deprecated New clients should not use this API anymore. All clients should use 757 * #startTethering or #stopTethering which encapsulate proper entitlement logic. If the API is 758 * used and an entitlement check is needed, downstream USB tethering will be enabled but will 759 * not have any upstream. 760 * 761 * {@hide} 762 */ 763 @Deprecated 764 @SystemApi(client = MODULE_LIBRARIES) 765 public int setUsbTethering(final boolean enable) { 766 final String callerPkg = mContext.getOpPackageName(); 767 Log.i(TAG, "setUsbTethering caller:" + callerPkg); 768 769 final RequestDispatcher dispatcher = new RequestDispatcher(); 770 771 return dispatcher.waitForResult((connector, listener) -> { 772 try { 773 connector.setUsbTethering(enable, callerPkg, getAttributionTag(), 774 listener); 775 } catch (RemoteException e) { 776 throw new IllegalStateException(e); 777 } 778 }, this); 779 } 780 781 /** 782 * Indicates that this tethering connection will provide connectivity beyond this device (e.g., 783 * global Internet access). 784 */ 785 @SuppressLint("UnflaggedApi") 786 public static final int CONNECTIVITY_SCOPE_GLOBAL = 1; 787 788 /** 789 * Indicates that this tethering connection will only provide local connectivity. 790 * @hide 791 */ 792 @SystemApi 793 public static final int CONNECTIVITY_SCOPE_LOCAL = 2; 794 795 /** 796 * Connectivity scopes for {@link TetheringRequest.Builder#setConnectivityScope}. 797 * @hide 798 */ 799 @Retention(RetentionPolicy.SOURCE) 800 @IntDef(prefix = "CONNECTIVITY_SCOPE_", value = { 801 CONNECTIVITY_SCOPE_GLOBAL, 802 CONNECTIVITY_SCOPE_LOCAL, 803 }) 804 public @interface ConnectivityScope {} 805 806 private static String connectivityScopeToString(@ConnectivityScope int scope) { 807 switch (scope) { 808 case CONNECTIVITY_SCOPE_GLOBAL: 809 return "CONNECTIVITY_SCOPE_GLOBAL"; 810 case CONNECTIVITY_SCOPE_LOCAL: 811 return "CONNECTIVITY_SCOPE_LOCAL"; 812 default: 813 return "CONNECTIVITY_SCOPE_UNKNOWN(" + scope + ")"; 814 } 815 } 816 817 /** 818 * Use with {@link #startTethering} to specify additional parameters when starting tethering. 819 */ 820 @SuppressLint("UnflaggedApi") 821 public static final class TetheringRequest implements Parcelable { 822 /** 823 * Tethering started by an explicit call to startTethering. 824 * @hide 825 */ 826 public static final int REQUEST_TYPE_EXPLICIT = 0; 827 828 /** 829 * Tethering implicitly started by broadcasts (LOHS and P2P). Can never be pending. 830 * @hide 831 */ 832 public static final int REQUEST_TYPE_IMPLICIT = 1; 833 834 /** 835 * Tethering started by the legacy tether() call. Can only happen on V-. 836 * @hide 837 */ 838 public static final int REQUEST_TYPE_LEGACY = 2; 839 840 /** 841 * Tethering started but there was no pending request found. This may happen if Tethering is 842 * started and immediately stopped before the link layer goes up, or if we get a link layer 843 * event without a prior call to startTethering (e.g. adb shell cmd wifi start-softap). 844 * @hide 845 */ 846 public static final int REQUEST_TYPE_PLACEHOLDER = 3; 847 848 /** 849 * Type of request, used to keep track of whether the request was explicitly sent by 850 * startTethering, implicitly created by broadcasts, or via legacy tether(). 851 * @hide 852 */ 853 @Retention(RetentionPolicy.SOURCE) 854 @IntDef(prefix = "TYPE_", value = { 855 REQUEST_TYPE_EXPLICIT, 856 REQUEST_TYPE_IMPLICIT, 857 REQUEST_TYPE_LEGACY, 858 REQUEST_TYPE_PLACEHOLDER, 859 }) 860 public @interface RequestType {} 861 862 /** A configuration set for TetheringRequest. */ 863 private final TetheringRequestParcel mRequestParcel; 864 865 /** 866 * @hide 867 */ 868 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 869 public TetheringRequest(@NonNull final TetheringRequestParcel request) { 870 mRequestParcel = request; 871 } 872 873 private TetheringRequest(@NonNull Parcel in) { 874 mRequestParcel = in.readParcelable(TetheringRequestParcel.class.getClassLoader()); 875 } 876 877 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 878 @NonNull 879 public static final Creator<TetheringRequest> CREATOR = new Creator<>() { 880 @Override 881 public TetheringRequest createFromParcel(@NonNull Parcel in) { 882 return new TetheringRequest(in); 883 } 884 885 @Override 886 public TetheringRequest[] newArray(int size) { 887 return new TetheringRequest[size]; 888 } 889 }; 890 891 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 892 @Override 893 public int describeContents() { 894 return 0; 895 } 896 897 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 898 @Override 899 public void writeToParcel(@NonNull Parcel dest, int flags) { 900 dest.writeParcelable(mRequestParcel, flags); 901 } 902 903 /** Builder used to create TetheringRequest. */ 904 @SuppressLint({"UnflaggedApi", "StaticFinalBuilder"}) 905 public static class Builder { 906 private final TetheringRequestParcel mBuilderParcel; 907 908 /** Default constructor of Builder. */ 909 @SuppressLint("UnflaggedApi") 910 public Builder(@TetheringType final int type) { 911 mBuilderParcel = new TetheringRequestParcel(); 912 mBuilderParcel.tetheringType = type; 913 mBuilderParcel.localIPv4Address = null; 914 mBuilderParcel.staticClientAddress = null; 915 mBuilderParcel.exemptFromEntitlementCheck = false; 916 mBuilderParcel.showProvisioningUi = true; 917 mBuilderParcel.connectivityScope = getDefaultConnectivityScope(type); 918 mBuilderParcel.uid = Process.INVALID_UID; 919 mBuilderParcel.softApConfig = null; 920 mBuilderParcel.interfaceName = null; 921 mBuilderParcel.requestType = REQUEST_TYPE_EXPLICIT; 922 } 923 924 /** 925 * Configure tethering with static IPv4 assignment. 926 * 927 * A DHCP server will be started, but will only be able to offer the client address. 928 * The two addresses must be in the same prefix. 929 * 930 * @param localIPv4Address The preferred local IPv4 link address to use. 931 * @param clientAddress The static client address. 932 * @hide 933 */ 934 @SystemApi 935 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 936 @NonNull 937 public Builder setStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address, 938 @NonNull final LinkAddress clientAddress) { 939 Objects.requireNonNull(localIPv4Address); 940 Objects.requireNonNull(clientAddress); 941 if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) { 942 throw new IllegalArgumentException("Invalid server or client addresses"); 943 } 944 945 mBuilderParcel.localIPv4Address = localIPv4Address; 946 mBuilderParcel.staticClientAddress = clientAddress; 947 return this; 948 } 949 950 /** 951 * Start tethering without entitlement checks. 952 * @hide 953 */ 954 @SystemApi 955 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 956 @NonNull 957 public Builder setExemptFromEntitlementCheck(boolean exempt) { 958 mBuilderParcel.exemptFromEntitlementCheck = exempt; 959 return this; 960 } 961 962 /** 963 * If an entitlement check is needed, sets whether to show the entitlement UI or to 964 * perform a silent entitlement check. By default, the entitlement UI is shown. 965 * @hide 966 */ 967 @SystemApi 968 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 969 @NonNull 970 public Builder setShouldShowEntitlementUi(boolean showUi) { 971 mBuilderParcel.showProvisioningUi = showUi; 972 return this; 973 } 974 975 /** 976 * Sets the name of the interface. Currently supported only for 977 * - {@link #TETHERING_VIRTUAL}. 978 * - {@link #TETHERING_WIFI} (for Local-only Hotspot) 979 * - {@link #TETHERING_WIFI_P2P} 980 * @hide 981 */ 982 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 983 @RequiresPermission(anyOf = { 984 android.Manifest.permission.NETWORK_SETTINGS, 985 android.Manifest.permission.NETWORK_STACK, 986 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 987 }) 988 @NonNull 989 @SystemApi(client = MODULE_LIBRARIES) 990 public Builder setInterfaceName(@Nullable final String interfaceName) { 991 switch (mBuilderParcel.tetheringType) { 992 case TETHERING_VIRTUAL: 993 case TETHERING_WIFI_P2P: 994 case TETHERING_WIFI: 995 break; 996 default: 997 throw new IllegalArgumentException("Interface name cannot be set for" 998 + " tethering type " + interfaceName); 999 } 1000 mBuilderParcel.interfaceName = interfaceName; 1001 return this; 1002 } 1003 1004 /** 1005 * Sets the connectivity scope to be provided by this tethering downstream. 1006 * @hide 1007 */ 1008 @SystemApi 1009 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 1010 @NonNull 1011 public Builder setConnectivityScope(@ConnectivityScope int scope) { 1012 if (!checkConnectivityScope(mBuilderParcel.tetheringType, scope)) { 1013 throw new IllegalArgumentException("Invalid connectivity scope " + scope); 1014 } 1015 1016 mBuilderParcel.connectivityScope = scope; 1017 return this; 1018 } 1019 1020 /** 1021 * Set the desired SoftApConfiguration for {@link #TETHERING_WIFI}. If this is null or 1022 * not set, then the persistent tethering SoftApConfiguration from 1023 * {@link WifiManager#getSoftApConfiguration()} will be used. 1024 * </p> 1025 * If TETHERING_WIFI is already enabled and a new request is made with a different 1026 * SoftApConfiguration, the request will be accepted if the device can support an 1027 * additional tethering Wi-Fi AP interface. Otherwise, the request will be rejected. 1028 * </p> 1029 * Non-system callers using TETHERING_WIFI must specify a SoftApConfiguration. 1030 * 1031 * @param softApConfig SoftApConfiguration to use. 1032 * @throws IllegalArgumentException if the tethering type isn't TETHERING_WIFI. 1033 */ 1034 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1035 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 1036 @NonNull 1037 public Builder setSoftApConfiguration(@Nullable SoftApConfiguration softApConfig) { 1038 if (mBuilderParcel.tetheringType != TETHERING_WIFI) { 1039 throw new IllegalArgumentException( 1040 "SoftApConfiguration can only be set for TETHERING_WIFI"); 1041 } 1042 mBuilderParcel.softApConfig = softApConfig; 1043 return this; 1044 } 1045 1046 /** Build {@link TetheringRequest} with the currently set configuration. */ 1047 @NonNull 1048 @SuppressLint("UnflaggedApi") 1049 public TetheringRequest build() { 1050 return new TetheringRequest(mBuilderParcel); 1051 } 1052 } 1053 1054 /** 1055 * Get the local IPv4 address, if one was configured with 1056 * {@link Builder#setStaticIpv4Addresses}. 1057 * @hide 1058 */ 1059 @SystemApi 1060 @Nullable 1061 public LinkAddress getLocalIpv4Address() { 1062 return mRequestParcel.localIPv4Address; 1063 } 1064 1065 /** 1066 * Get the static IPv4 address of the client, if one was configured with 1067 * {@link Builder#setStaticIpv4Addresses}. 1068 * @hide 1069 */ 1070 @SystemApi 1071 @Nullable 1072 public LinkAddress getClientStaticIpv4Address() { 1073 return mRequestParcel.staticClientAddress; 1074 } 1075 1076 /** 1077 * Get tethering type. 1078 * @hide 1079 */ 1080 @SystemApi 1081 @TetheringType 1082 public int getTetheringType() { 1083 return mRequestParcel.tetheringType; 1084 } 1085 1086 /** 1087 * Get connectivity type 1088 * @hide 1089 */ 1090 @SystemApi 1091 @ConnectivityScope 1092 public int getConnectivityScope() { 1093 return mRequestParcel.connectivityScope; 1094 } 1095 1096 /** 1097 * Check if exempt from entitlement check. 1098 * @hide 1099 */ 1100 @SystemApi 1101 public boolean isExemptFromEntitlementCheck() { 1102 return mRequestParcel.exemptFromEntitlementCheck; 1103 } 1104 1105 /** 1106 * Check if show entitlement ui. 1107 * @hide 1108 */ 1109 @SystemApi 1110 public boolean getShouldShowEntitlementUi() { 1111 return mRequestParcel.showProvisioningUi; 1112 } 1113 1114 /** 1115 * Get interface name. 1116 * @hide 1117 */ 1118 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1119 @Nullable 1120 @SystemApi(client = MODULE_LIBRARIES) 1121 public String getInterfaceName() { 1122 return mRequestParcel.interfaceName; 1123 } 1124 1125 /** 1126 * Check whether the two addresses are ipv4 and in the same prefix. 1127 * @hide 1128 */ 1129 public static boolean checkStaticAddressConfiguration( 1130 @NonNull final LinkAddress localIPv4Address, 1131 @NonNull final LinkAddress clientAddress) { 1132 return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength() 1133 && localIPv4Address.isIpv4() && clientAddress.isIpv4() 1134 && new IpPrefix(localIPv4Address.toString()).equals( 1135 new IpPrefix(clientAddress.toString())); 1136 } 1137 1138 /** 1139 * Returns the default connectivity scope for the given tethering type. Usually this is 1140 * CONNECTIVITY_SCOPE_GLOBAL, except for NCM which for historical reasons defaults to local. 1141 * @hide 1142 */ 1143 public static @ConnectivityScope int getDefaultConnectivityScope(int tetheringType) { 1144 return tetheringType != TETHERING_NCM 1145 ? CONNECTIVITY_SCOPE_GLOBAL 1146 : CONNECTIVITY_SCOPE_LOCAL; 1147 } 1148 1149 /** 1150 * Checks whether the requested connectivity scope is allowed. 1151 * @hide 1152 */ 1153 private static boolean checkConnectivityScope(int type, int scope) { 1154 if (scope == CONNECTIVITY_SCOPE_GLOBAL) return true; 1155 return type == TETHERING_USB || type == TETHERING_ETHERNET || type == TETHERING_NCM; 1156 } 1157 1158 /** 1159 * Get the desired SoftApConfiguration of the request, if one was specified. 1160 */ 1161 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1162 @Nullable 1163 public SoftApConfiguration getSoftApConfiguration() { 1164 return mRequestParcel.softApConfig; 1165 } 1166 1167 /** 1168 * Sets the UID of the app that sent this request. This should always be overridden when 1169 * receiving TetheringRequest from an external source. 1170 * @hide 1171 */ 1172 public void setUid(int uid) { 1173 mRequestParcel.uid = uid; 1174 } 1175 1176 /** 1177 * Sets the package name of the app that sent this request. This should always be overridden 1178 * when receiving a TetheringRequest from an external source. 1179 * @hide 1180 */ 1181 public void setPackageName(String packageName) { 1182 mRequestParcel.packageName = packageName; 1183 } 1184 1185 /** 1186 * Gets the UID of the app that sent this request. This defaults to 1187 * {@link Process#INVALID_UID} if unset. 1188 * @hide 1189 */ 1190 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1191 @SystemApi(client = MODULE_LIBRARIES) 1192 public int getUid() { 1193 return mRequestParcel.uid; 1194 } 1195 1196 /** 1197 * Gets the package name of the app that sent this request. This defaults to {@code null} if 1198 * unset. 1199 * @hide 1200 */ 1201 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1202 @SystemApi(client = MODULE_LIBRARIES) 1203 @Nullable 1204 public String getPackageName() { 1205 return mRequestParcel.packageName; 1206 } 1207 1208 /** 1209 * Get a TetheringRequestParcel from the configuration 1210 * @hide 1211 */ 1212 public TetheringRequestParcel getParcel() { 1213 return mRequestParcel; 1214 } 1215 1216 /** 1217 * Get the type of the request. 1218 * @hide 1219 */ 1220 public @RequestType int getRequestType() { 1221 return mRequestParcel.requestType; 1222 } 1223 1224 /** 1225 * String of TetheringRequest detail. 1226 * @hide 1227 */ 1228 @SystemApi 1229 public String toString() { 1230 StringJoiner sj = new StringJoiner(", ", "TetheringRequest[ ", " ]"); 1231 sj.add(typeToString(mRequestParcel.tetheringType)); 1232 if (mRequestParcel.requestType == REQUEST_TYPE_IMPLICIT) { 1233 sj.add("IMPLICIT"); 1234 } else if (mRequestParcel.requestType == REQUEST_TYPE_LEGACY) { 1235 sj.add("LEGACY"); 1236 } else if (mRequestParcel.requestType == REQUEST_TYPE_PLACEHOLDER) { 1237 sj.add("PLACEHOLDER"); 1238 } 1239 if (mRequestParcel.localIPv4Address != null) { 1240 sj.add("localIpv4Address=" + mRequestParcel.localIPv4Address); 1241 } 1242 if (mRequestParcel.staticClientAddress != null) { 1243 sj.add("staticClientAddress=" + mRequestParcel.staticClientAddress); 1244 } 1245 if (mRequestParcel.exemptFromEntitlementCheck) { 1246 sj.add("exemptFromEntitlementCheck"); 1247 } 1248 if (mRequestParcel.showProvisioningUi) { 1249 sj.add("showProvisioningUi"); 1250 } 1251 sj.add(connectivityScopeToString(mRequestParcel.connectivityScope)); 1252 if (mRequestParcel.softApConfig != null) { 1253 sj.add("softApConfig=" + mRequestParcel.softApConfig); 1254 } 1255 if (mRequestParcel.uid != Process.INVALID_UID) { 1256 sj.add("uid=" + mRequestParcel.uid); 1257 } 1258 if (mRequestParcel.packageName != null) { 1259 sj.add("packageName=" + mRequestParcel.packageName); 1260 } 1261 if (mRequestParcel.interfaceName != null) { 1262 sj.add("interfaceName=" + mRequestParcel.interfaceName); 1263 } 1264 return sj.toString(); 1265 } 1266 1267 @SuppressLint("UnflaggedApi") 1268 private static boolean supportsInterfaceName(int tetheringType) { 1269 // TODO: Check the interface name for TETHERING_WIFI and TETHERING_WIFI_P2P once 1270 // they're actually used. 1271 // Suppress lint for TETHERING_VIRTUAL since this method is only used internally. 1272 return tetheringType == TETHERING_VIRTUAL; 1273 } 1274 1275 private static boolean supportsConcurrentConnectivityScopes(int tetheringType) { 1276 // Currently, only WIFI supports simultaneous local and global connectivity. 1277 // This can't happen for REQUEST_TYPE_EXPLICIT requests, because 1278 // TetheringRequest.Builder will not allow building an explicit TetheringRequest 1279 // with TETHERING_WIFI and CONNECTIVITY_SCOPE_LOCAL, but when local-only hotspot 1280 // is running, there is a REQUEST_TYPE_IMPLICIT request in the serving request list. 1281 return tetheringType == TETHERING_WIFI; 1282 } 1283 1284 /** 1285 * Returns true if the other TetheringRequest "fuzzy" matches this one. This is used 1286 * internally to match tracked requests with external requests from API calls, and to reject 1287 * additional requests that the link layer has no capacity for. 1288 * @hide 1289 */ 1290 public boolean fuzzyMatches(final TetheringRequest other) { 1291 if (other == null) return false; 1292 final int type = getTetheringType(); 1293 if (type != other.getTetheringType()) return false; 1294 if (supportsInterfaceName(type) 1295 && !TextUtils.equals(getInterfaceName(), other.getInterfaceName())) { 1296 return false; 1297 } 1298 if (supportsConcurrentConnectivityScopes(type) 1299 && getConnectivityScope() != other.getConnectivityScope()) { 1300 return false; 1301 } 1302 return true; 1303 } 1304 1305 /** 1306 * @hide 1307 */ 1308 @SystemApi 1309 @Override 1310 public boolean equals(Object obj) { 1311 if (this == obj) return true; 1312 if (!(obj instanceof TetheringRequest otherRequest)) return false; 1313 if (!equalsIgnoreUidPackage(otherRequest)) return false; 1314 TetheringRequestParcel parcel = getParcel(); 1315 TetheringRequestParcel otherParcel = otherRequest.getParcel(); 1316 return parcel.uid == otherParcel.uid 1317 && Objects.equals(parcel.packageName, otherParcel.packageName); 1318 } 1319 1320 /** 1321 * @hide 1322 */ 1323 public boolean equalsIgnoreUidPackage(TetheringRequest otherRequest) { 1324 TetheringRequestParcel parcel = getParcel(); 1325 TetheringRequestParcel otherParcel = otherRequest.getParcel(); 1326 // Note: Changes here should also be reflected in fuzzyMatches(TetheringRequest) when 1327 // appropriate. 1328 return parcel.requestType == otherParcel.requestType 1329 && parcel.tetheringType == otherParcel.tetheringType 1330 && Objects.equals(parcel.localIPv4Address, otherParcel.localIPv4Address) 1331 && Objects.equals(parcel.staticClientAddress, otherParcel.staticClientAddress) 1332 && parcel.exemptFromEntitlementCheck == otherParcel.exemptFromEntitlementCheck 1333 && parcel.showProvisioningUi == otherParcel.showProvisioningUi 1334 && parcel.connectivityScope == otherParcel.connectivityScope 1335 && Objects.equals(parcel.softApConfig, otherParcel.softApConfig) 1336 && Objects.equals(parcel.interfaceName, otherParcel.interfaceName); 1337 } 1338 1339 /** 1340 * @hide 1341 */ 1342 @SystemApi 1343 @Override 1344 public int hashCode() { 1345 TetheringRequestParcel parcel = getParcel(); 1346 return Objects.hash(parcel.tetheringType, parcel.localIPv4Address, 1347 parcel.staticClientAddress, parcel.exemptFromEntitlementCheck, 1348 parcel.showProvisioningUi, parcel.connectivityScope, parcel.softApConfig, 1349 parcel.uid, parcel.packageName, parcel.interfaceName); 1350 } 1351 } 1352 1353 /** 1354 * Callback for use with {@link #startTethering} to find out whether tethering succeeded. 1355 */ 1356 @SuppressLint("UnflaggedApi") 1357 public interface StartTetheringCallback { 1358 /** 1359 * Called when tethering has been successfully started. 1360 */ 1361 @SuppressLint("UnflaggedApi") 1362 default void onTetheringStarted() {} 1363 1364 /** 1365 * Called when starting tethering failed. 1366 * 1367 * @param error The error that caused the failure. 1368 */ 1369 @SuppressLint("UnflaggedApi") 1370 default void onTetheringFailed(@StartTetheringError final int error) {} 1371 } 1372 1373 /** 1374 * Callback for use with {@link #stopTethering} to find out whether stop tethering succeeded. 1375 */ 1376 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1377 public interface StopTetheringCallback { 1378 /** 1379 * Called when tethering has been successfully stopped. 1380 */ 1381 default void onStopTetheringSucceeded() {} 1382 1383 /** 1384 * Called when starting tethering failed. 1385 * 1386 * @param error The error that caused the failure. 1387 */ 1388 default void onStopTetheringFailed(@StopTetheringError final int error) {} 1389 } 1390 1391 /** 1392 * Starts tethering and runs tether provisioning for the given type if needed. If provisioning 1393 * fails, stopTethering will be called automatically. 1394 * 1395 * @param request a {@link TetheringRequest} which can specify the preferred configuration. 1396 * @param executor {@link Executor} to specify the thread upon which the callback of 1397 * TetheringRequest will be invoked. 1398 * @param callback A callback that will be called to indicate the success status of the 1399 * tethering start request. 1400 */ 1401 @RequiresPermission(value = android.Manifest.permission.TETHER_PRIVILEGED, conditional = true) 1402 @SuppressLint("UnflaggedApi") 1403 public void startTethering(@NonNull final TetheringRequest request, 1404 @NonNull final Executor executor, @NonNull final StartTetheringCallback callback) { 1405 final String callerPkg = mContext.getOpPackageName(); 1406 Log.i(TAG, "startTethering caller:" + callerPkg); 1407 1408 final IIntResultListener listener = new IIntResultListener.Stub() { 1409 @Override 1410 public void onResult(final int resultCode) { 1411 executor.execute(() -> { 1412 if (resultCode == TETHER_ERROR_NO_ERROR) { 1413 callback.onTetheringStarted(); 1414 } else { 1415 callback.onTetheringFailed(resultCode); 1416 } 1417 }); 1418 } 1419 }; 1420 getConnector(c -> c.startTethering(request.getParcel(), callerPkg, 1421 getAttributionTag(), listener)); 1422 } 1423 1424 /** 1425 * Starts tethering and runs tether provisioning for the given type if needed. If provisioning 1426 * fails, stopTethering will be called automatically. 1427 * 1428 * @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants. 1429 * @param executor {@link Executor} to specify the thread upon which the callback of 1430 * TetheringRequest will be invoked. 1431 * @hide 1432 */ 1433 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 1434 @SystemApi(client = MODULE_LIBRARIES) 1435 public void startTethering(int type, @NonNull final Executor executor, 1436 @NonNull final StartTetheringCallback callback) { 1437 startTethering(new TetheringRequest.Builder(type).build(), executor, callback); 1438 } 1439 1440 /** 1441 * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if 1442 * applicable. 1443 * 1444 * @hide 1445 */ 1446 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 1447 @SystemApi 1448 public void stopTethering(@TetheringType final int type) { 1449 final String callerPkg = mContext.getOpPackageName(); 1450 Log.i(TAG, "stopTethering caller:" + callerPkg); 1451 1452 getConnector(c -> c.stopTethering(type, callerPkg, getAttributionTag(), 1453 new IIntResultListener.Stub() { 1454 @Override 1455 public void onResult(int resultCode) { 1456 // TODO: provide an API to obtain result 1457 // This has never been possible as stopTethering has always been void and never 1458 // taken a callback object. The only indication that callers have is if the call 1459 // results in a TETHER_STATE_CHANGE broadcast. 1460 } 1461 })); 1462 } 1463 1464 /** 1465 * Stops tethering for the given request. Operation will fail with 1466 * {@link #TETHER_ERROR_UNKNOWN_REQUEST} if there is no request that matches it. 1467 */ 1468 @RequiresPermission(value = android.Manifest.permission.TETHER_PRIVILEGED, conditional = true) 1469 @FlaggedApi(Flags.FLAG_TETHERING_WITH_SOFT_AP_CONFIG) 1470 public void stopTethering(@NonNull TetheringRequest request, 1471 @NonNull final Executor executor, @NonNull final StopTetheringCallback callback) { 1472 Objects.requireNonNull(request); 1473 Objects.requireNonNull(executor); 1474 Objects.requireNonNull(callback); 1475 1476 final String callerPkg = mContext.getOpPackageName(); 1477 Log.i(TAG, "stopTethering: request=" + request + ", caller=" + callerPkg); 1478 getConnector(c -> c.stopTetheringRequest(request, callerPkg, getAttributionTag(), 1479 new IIntResultListener.Stub() { 1480 @Override 1481 public void onResult(final int resultCode) { 1482 executor.execute(() -> { 1483 if (resultCode == TETHER_ERROR_NO_ERROR) { 1484 callback.onStopTetheringSucceeded(); 1485 } else { 1486 callback.onStopTetheringFailed(resultCode); 1487 } 1488 }); 1489 } 1490 })); 1491 } 1492 1493 /** 1494 * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether 1495 * entitlement succeeded. 1496 * @hide 1497 */ 1498 @SystemApi 1499 public interface OnTetheringEntitlementResultListener { 1500 /** 1501 * Called to notify entitlement result. 1502 * 1503 * @param resultCode an int value of entitlement result. It may be one of 1504 * {@link #TETHER_ERROR_NO_ERROR}, 1505 * {@link #TETHER_ERROR_PROVISIONING_FAILED}, or 1506 * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN}. 1507 */ 1508 void onTetheringEntitlementResult(@EntitlementResult int result); 1509 } 1510 1511 /** 1512 * Request the latest value of the tethering entitlement check. 1513 * 1514 * <p>This method will only return the latest entitlement result if it is available. If no 1515 * cached entitlement result is available, and {@code showEntitlementUi} is false, 1516 * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN} will be returned. If {@code showEntitlementUi} is 1517 * true, entitlement will be run. 1518 * 1519 * @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants. 1520 * @param showEntitlementUi a boolean indicating whether to check result for the UI-based 1521 * entitlement check or the silent entitlement check. 1522 * @param executor the executor on which callback will be invoked. 1523 * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to 1524 * notify the caller of the result of entitlement check. The listener may be called zero 1525 * or one time. 1526 * @hide 1527 */ 1528 @SystemApi 1529 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 1530 public void requestLatestTetheringEntitlementResult(@TetheringType int type, 1531 boolean showEntitlementUi, 1532 @NonNull Executor executor, 1533 @NonNull final OnTetheringEntitlementResultListener listener) { 1534 if (listener == null) { 1535 throw new IllegalArgumentException( 1536 "OnTetheringEntitlementResultListener cannot be null."); 1537 } 1538 1539 ResultReceiver wrappedListener = new ResultReceiver(null /* handler */) { 1540 @Override 1541 protected void onReceiveResult(int resultCode, Bundle resultData) { 1542 executor.execute(() -> { 1543 listener.onTetheringEntitlementResult(resultCode); 1544 }); 1545 } 1546 }; 1547 1548 requestLatestTetheringEntitlementResult(type, wrappedListener, 1549 showEntitlementUi); 1550 } 1551 1552 /** 1553 * Helper function of #requestLatestTetheringEntitlementResult to remain backwards compatible 1554 * with ConnectivityManager#getLatestTetheringEntitlementResult 1555 * 1556 * {@hide} 1557 */ 1558 // TODO: improve the usage of ResultReceiver, b/145096122 1559 @SystemApi(client = MODULE_LIBRARIES) 1560 public void requestLatestTetheringEntitlementResult(@TetheringType final int type, 1561 @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) { 1562 final String callerPkg = mContext.getOpPackageName(); 1563 Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); 1564 1565 getConnector(c -> c.requestLatestTetheringEntitlementResult( 1566 type, receiver, showEntitlementUi, callerPkg, getAttributionTag())); 1567 } 1568 1569 /** 1570 * Callback for use with {@link registerTetheringEventCallback} to find out tethering 1571 * upstream status. 1572 */ 1573 @SuppressLint("UnflaggedApi") 1574 public interface TetheringEventCallback { 1575 /** 1576 * Called when tethering supported status changed. 1577 * 1578 * <p>This callback will be called immediately after the callback is 1579 * registered, and never be called if there is changes afterward. 1580 * 1581 * <p>Tethering may be disabled via system properties, device configuration, or device 1582 * policy restrictions. 1583 * 1584 * @param supported whether any tethering type is supported. 1585 * @hide 1586 */ 1587 @SystemApi 1588 default void onTetheringSupported(boolean supported) {} 1589 1590 /** 1591 * Called when tethering supported status changed. 1592 * 1593 * <p>This will be called immediately after the callback is registered, and may be called 1594 * multiple times later upon changes. 1595 * 1596 * <p>Tethering may be disabled via system properties, device configuration, or device 1597 * policy restrictions. 1598 * 1599 * @param supportedTypes a set of @TetheringType which is supported. 1600 * @hide 1601 */ 1602 default void onSupportedTetheringTypes(@NonNull Set<Integer> supportedTypes) {} 1603 1604 /** 1605 * Called when tethering upstream changed. 1606 * 1607 * <p>This will be called immediately after the callback is registered, and may be called 1608 * multiple times later upon changes. 1609 * 1610 * @param network the {@link Network} of tethering upstream. Null means tethering doesn't 1611 * have any upstream. 1612 * @hide 1613 */ 1614 @SystemApi 1615 default void onUpstreamChanged(@Nullable Network network) {} 1616 1617 /** 1618 * Called when there was a change in tethering interface regular expressions. 1619 * 1620 * <p>This will be called immediately after the callback is registered, and may be called 1621 * multiple times later upon changes. 1622 * @param reg The new regular expressions. 1623 * 1624 * @deprecated New clients should use the callbacks with {@link TetheringInterface} which 1625 * has the mapping between tethering type and interface. InterfaceRegex is no longer needed 1626 * to determine the mapping of tethering type and interface. 1627 * 1628 * @hide 1629 */ 1630 @Deprecated 1631 @SystemApi(client = MODULE_LIBRARIES) 1632 default void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {} 1633 1634 /** 1635 * Called when there was a change in the list of tetherable interfaces. Tetherable 1636 * interface means this interface is available and can be used for tethering. 1637 * 1638 * <p>This will be called immediately after the callback is registered, and may be called 1639 * multiple times later upon changes. 1640 * @param interfaces The list of tetherable interface names. 1641 * @hide 1642 */ 1643 @SystemApi 1644 default void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {} 1645 1646 /** 1647 * Called when there was a change in the list of tetherable interfaces. Tetherable 1648 * interface means this interface is available and can be used for tethering. 1649 * 1650 * <p>This will be called immediately after the callback is registered, and may be called 1651 * multiple times later upon changes. 1652 * @param interfaces The set of TetheringInterface of currently tetherable interface. 1653 * @hide 1654 */ 1655 @SystemApi 1656 default void onTetherableInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1657 // By default, the new callback calls the old callback, so apps 1658 // implementing the old callback just work. 1659 onTetherableInterfacesChanged(toIfaces(interfaces)); 1660 } 1661 1662 /** 1663 * Called when there was a change in the list of tethered interfaces. 1664 * 1665 * <p>This will be called immediately after the callback is registered, and may be called 1666 * multiple times later upon changes. 1667 * @param interfaces The lit of 0 or more String of currently tethered interface names. 1668 * @hide 1669 */ 1670 @SystemApi 1671 default void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {} 1672 1673 /** 1674 * Called when there was a change in the list of tethered interfaces. 1675 * 1676 * <p>This will be called immediately after the callback is registered, and may be called 1677 * multiple times later upon changes. 1678 * @param interfaces The set of 0 or more TetheringInterface of currently tethered 1679 * interface. 1680 */ 1681 @SuppressLint("UnflaggedApi") 1682 default void onTetheredInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1683 // By default, the new callback calls the old callback, so apps 1684 // implementing the old callback just work. 1685 onTetheredInterfacesChanged(toIfaces(interfaces)); 1686 } 1687 1688 /** 1689 * Called when there was a change in the list of local-only interfaces. 1690 * 1691 * <p>This will be called immediately after the callback is registered, and may be called 1692 * multiple times later upon changes. 1693 * @param interfaces The list of 0 or more String of active local-only interface names. 1694 * @hide 1695 */ 1696 @SystemApi 1697 default void onLocalOnlyInterfacesChanged(@NonNull List<String> interfaces) {} 1698 1699 /** 1700 * Called when there was a change in the list of local-only interfaces. 1701 * 1702 * <p>This will be called immediately after the callback is registered, and may be called 1703 * multiple times later upon changes. 1704 * @param interfaces The set of 0 or more TetheringInterface of active local-only 1705 * interface. 1706 * @hide 1707 */ 1708 @SystemApi 1709 default void onLocalOnlyInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1710 // By default, the new callback calls the old callback, so apps 1711 // implementing the old callback just work. 1712 onLocalOnlyInterfacesChanged(toIfaces(interfaces)); 1713 } 1714 1715 /** 1716 * Called when an error occurred configuring tethering. 1717 * 1718 * <p>This will be called immediately after the callback is registered if the latest status 1719 * on the interface is an error, and may be called multiple times later upon changes. 1720 * @param ifName Name of the interface. 1721 * @param error One of {@code TetheringManager#TETHER_ERROR_*}. 1722 * @hide 1723 */ 1724 @SystemApi 1725 default void onError(@NonNull String ifName, @TetheringIfaceError int error) {} 1726 1727 /** 1728 * Called when an error occurred configuring tethering. 1729 * 1730 * <p>This will be called immediately after the callback is registered if the latest status 1731 * on the interface is an error, and may be called multiple times later upon changes. 1732 * @param iface The interface that experienced the error. 1733 * @param error One of {@code TetheringManager#TETHER_ERROR_*}. 1734 * @hide 1735 */ 1736 @SystemApi 1737 default void onError(@NonNull TetheringInterface iface, @TetheringIfaceError int error) { 1738 // By default, the new callback calls the old callback, so apps 1739 // implementing the old callback just work. 1740 onError(iface.getInterface(), error); 1741 } 1742 1743 /** 1744 * Called when the list of tethered clients changes. 1745 * 1746 * <p>This callback provides best-effort information on connected clients based on state 1747 * known to the system, however the list cannot be completely accurate (and should not be 1748 * used for security purposes). For example, clients behind a bridge and using static IP 1749 * assignments are not visible to the tethering device; or even when using DHCP, such 1750 * clients may still be reported by this callback after disconnection as the system cannot 1751 * determine if they are still connected. 1752 * @param clients The new set of tethered clients; the collection is not ordered. 1753 * @hide 1754 */ 1755 @SystemApi 1756 default void onClientsChanged(@NonNull Collection<TetheredClient> clients) {} 1757 1758 /** 1759 * Called when tethering offload status changes. 1760 * 1761 * <p>This will be called immediately after the callback is registered. 1762 * @param status The offload status. 1763 * @hide 1764 */ 1765 @SystemApi 1766 default void onOffloadStatusChanged(@TetherOffloadStatus int status) {} 1767 } 1768 1769 /** 1770 * Covert DownStreamInterface collection to interface String array list. Internal use only. 1771 * 1772 * @hide 1773 */ 1774 public static ArrayList<String> toIfaces(Collection<TetheringInterface> tetherIfaces) { 1775 final ArrayList<String> ifaces = new ArrayList<>(); 1776 for (TetheringInterface tether : tetherIfaces) { 1777 ifaces.add(tether.getInterface()); 1778 } 1779 1780 return ifaces; 1781 } 1782 1783 private static String[] toIfaces(TetheringInterface[] tetherIfaces) { 1784 final String[] ifaces = new String[tetherIfaces.length]; 1785 for (int i = 0; i < tetherIfaces.length; i++) { 1786 ifaces[i] = tetherIfaces[i].getInterface(); 1787 } 1788 1789 return ifaces; 1790 } 1791 1792 1793 /** 1794 * Regular expressions used to identify tethering interfaces. 1795 * 1796 * @deprecated Instead of using regex to determine tethering type. New client could use the 1797 * callbacks with {@link TetheringInterface} which has the mapping of type and interface. 1798 * @hide 1799 */ 1800 @Deprecated 1801 @SystemApi(client = MODULE_LIBRARIES) 1802 public static class TetheringInterfaceRegexps { 1803 private final String[] mTetherableBluetoothRegexs; 1804 private final String[] mTetherableUsbRegexs; 1805 private final String[] mTetherableWifiRegexs; 1806 1807 /** @hide */ 1808 public TetheringInterfaceRegexps(@NonNull String[] tetherableBluetoothRegexs, 1809 @NonNull String[] tetherableUsbRegexs, @NonNull String[] tetherableWifiRegexs) { 1810 mTetherableBluetoothRegexs = tetherableBluetoothRegexs.clone(); 1811 mTetherableUsbRegexs = tetherableUsbRegexs.clone(); 1812 mTetherableWifiRegexs = tetherableWifiRegexs.clone(); 1813 } 1814 1815 @NonNull 1816 public List<String> getTetherableBluetoothRegexs() { 1817 return Collections.unmodifiableList(Arrays.asList(mTetherableBluetoothRegexs)); 1818 } 1819 1820 @NonNull 1821 public List<String> getTetherableUsbRegexs() { 1822 return Collections.unmodifiableList(Arrays.asList(mTetherableUsbRegexs)); 1823 } 1824 1825 @NonNull 1826 public List<String> getTetherableWifiRegexs() { 1827 return Collections.unmodifiableList(Arrays.asList(mTetherableWifiRegexs)); 1828 } 1829 1830 @Override 1831 public int hashCode() { 1832 return Objects.hash( 1833 Arrays.hashCode(mTetherableBluetoothRegexs), 1834 Arrays.hashCode(mTetherableUsbRegexs), 1835 Arrays.hashCode(mTetherableWifiRegexs)); 1836 } 1837 1838 @Override 1839 public boolean equals(@Nullable Object obj) { 1840 if (!(obj instanceof TetheringInterfaceRegexps)) return false; 1841 final TetheringInterfaceRegexps other = (TetheringInterfaceRegexps) obj; 1842 return Arrays.equals(mTetherableBluetoothRegexs, other.mTetherableBluetoothRegexs) 1843 && Arrays.equals(mTetherableUsbRegexs, other.mTetherableUsbRegexs) 1844 && Arrays.equals(mTetherableWifiRegexs, other.mTetherableWifiRegexs); 1845 } 1846 } 1847 1848 /** 1849 * Start listening to tethering change events. Any new added callback will receive the last 1850 * tethering status right away. If callback is registered, 1851 * {@link TetheringEventCallback#onUpstreamChanged} will immediately be called. If tethering 1852 * has no upstream or disabled, the argument of callback will be null. The same callback object 1853 * cannot be registered twice. 1854 * 1855 * @param executor the executor on which callback will be invoked. 1856 * @param callback the callback to be called when tethering has change events. 1857 */ 1858 @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE) 1859 @SuppressLint("UnflaggedApi") 1860 public void registerTetheringEventCallback(@NonNull Executor executor, 1861 @NonNull TetheringEventCallback callback) { 1862 Objects.requireNonNull(executor); 1863 Objects.requireNonNull(callback); 1864 1865 final String callerPkg = mContext.getOpPackageName(); 1866 Log.i(TAG, "registerTetheringEventCallback caller:" + callerPkg); 1867 1868 synchronized (mTetheringEventCallbacks) { 1869 if (mTetheringEventCallbacks.containsKey(callback)) { 1870 throw new IllegalArgumentException("callback was already registered."); 1871 } 1872 final ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() { 1873 // Only accessed with a lock on this object 1874 private final HashMap<TetheringInterface, Integer> mErrorStates = new HashMap<>(); 1875 private TetheringInterface[] mLastTetherableInterfaces = null; 1876 private TetheringInterface[] mLastTetheredInterfaces = null; 1877 private TetheringInterface[] mLastLocalOnlyInterfaces = null; 1878 1879 @Override 1880 public void onUpstreamChanged(Network network) throws RemoteException { 1881 executor.execute(() -> { 1882 callback.onUpstreamChanged(network); 1883 }); 1884 } 1885 1886 private synchronized void sendErrorCallbacks(final TetherStatesParcel newStates) { 1887 for (int i = 0; i < newStates.erroredIfaceList.length; i++) { 1888 final TetheringInterface tetherIface = newStates.erroredIfaceList[i]; 1889 final Integer lastError = mErrorStates.get(tetherIface); 1890 final int newError = newStates.lastErrorList[i]; 1891 if (newError != TETHER_ERROR_NO_ERROR 1892 && !Objects.equals(lastError, newError)) { 1893 callback.onError(tetherIface, newError); 1894 } 1895 mErrorStates.put(tetherIface, newError); 1896 } 1897 } 1898 1899 private synchronized void maybeSendTetherableIfacesChangedCallback( 1900 final TetherStatesParcel newStates) { 1901 if (Arrays.equals(mLastTetherableInterfaces, newStates.availableList)) return; 1902 mLastTetherableInterfaces = newStates.availableList.clone(); 1903 callback.onTetherableInterfacesChanged( 1904 Collections.unmodifiableSet((new ArraySet(mLastTetherableInterfaces)))); 1905 } 1906 1907 private synchronized void maybeSendTetheredIfacesChangedCallback( 1908 final TetherStatesParcel newStates) { 1909 if (Arrays.equals(mLastTetheredInterfaces, newStates.tetheredList)) return; 1910 mLastTetheredInterfaces = newStates.tetheredList.clone(); 1911 callback.onTetheredInterfacesChanged( 1912 Collections.unmodifiableSet((new ArraySet(mLastTetheredInterfaces)))); 1913 } 1914 1915 private synchronized void maybeSendLocalOnlyIfacesChangedCallback( 1916 final TetherStatesParcel newStates) { 1917 if (Arrays.equals(mLastLocalOnlyInterfaces, newStates.localOnlyList)) return; 1918 mLastLocalOnlyInterfaces = newStates.localOnlyList.clone(); 1919 callback.onLocalOnlyInterfacesChanged( 1920 Collections.unmodifiableSet((new ArraySet(mLastLocalOnlyInterfaces)))); 1921 } 1922 1923 // Called immediately after the callbacks are registered. 1924 @Override 1925 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 1926 executor.execute(() -> { 1927 callback.onSupportedTetheringTypes(unpackBits(parcel.supportedTypes)); 1928 callback.onTetheringSupported(parcel.supportedTypes != 0); 1929 callback.onUpstreamChanged(parcel.upstreamNetwork); 1930 sendErrorCallbacks(parcel.states); 1931 sendRegexpsChanged(parcel.config); 1932 maybeSendTetherableIfacesChangedCallback(parcel.states); 1933 maybeSendTetheredIfacesChangedCallback(parcel.states); 1934 maybeSendLocalOnlyIfacesChangedCallback(parcel.states); 1935 callback.onClientsChanged(parcel.tetheredClients); 1936 callback.onOffloadStatusChanged(parcel.offloadStatus); 1937 }); 1938 } 1939 1940 @Override 1941 public void onCallbackStopped(int errorCode) { 1942 executor.execute(() -> { 1943 throwIfPermissionFailure(errorCode); 1944 }); 1945 } 1946 1947 @Override 1948 public void onSupportedTetheringTypes(long supportedBitmap) { 1949 executor.execute(() -> { 1950 callback.onSupportedTetheringTypes(unpackBits(supportedBitmap)); 1951 }); 1952 } 1953 1954 private void sendRegexpsChanged(TetheringConfigurationParcel parcel) { 1955 callback.onTetherableInterfaceRegexpsChanged(new TetheringInterfaceRegexps( 1956 parcel.tetherableBluetoothRegexs, 1957 parcel.tetherableUsbRegexs, 1958 parcel.tetherableWifiRegexs)); 1959 } 1960 1961 @Override 1962 public void onConfigurationChanged(TetheringConfigurationParcel config) { 1963 executor.execute(() -> sendRegexpsChanged(config)); 1964 } 1965 1966 @Override 1967 public void onTetherStatesChanged(TetherStatesParcel states) { 1968 executor.execute(() -> { 1969 sendErrorCallbacks(states); 1970 maybeSendTetherableIfacesChangedCallback(states); 1971 maybeSendTetheredIfacesChangedCallback(states); 1972 maybeSendLocalOnlyIfacesChangedCallback(states); 1973 }); 1974 } 1975 1976 @Override 1977 public void onTetherClientsChanged(final List<TetheredClient> clients) { 1978 executor.execute(() -> callback.onClientsChanged(clients)); 1979 } 1980 1981 @Override 1982 public void onOffloadStatusChanged(final int status) { 1983 executor.execute(() -> callback.onOffloadStatusChanged(status)); 1984 } 1985 }; 1986 getConnector(c -> c.registerTetheringEventCallback(remoteCallback, callerPkg)); 1987 mTetheringEventCallbacks.put(callback, remoteCallback); 1988 } 1989 } 1990 1991 /** 1992 * Unpack bitmap to a set of bit position intergers. 1993 * @hide 1994 */ 1995 public static ArraySet<Integer> unpackBits(long val) { 1996 final ArraySet<Integer> result = new ArraySet<>(Long.bitCount(val)); 1997 int bitPos = 0; 1998 while (val != 0) { 1999 if ((val & 1) == 1) result.add(bitPos); 2000 2001 val = val >>> 1; 2002 bitPos++; 2003 } 2004 2005 return result; 2006 } 2007 2008 /** 2009 * Remove tethering event callback previously registered with 2010 * {@link #registerTetheringEventCallback}. 2011 * 2012 * @param callback previously registered callback. 2013 */ 2014 @RequiresPermission(anyOf = { 2015 Manifest.permission.TETHER_PRIVILEGED, 2016 Manifest.permission.ACCESS_NETWORK_STATE 2017 }) 2018 @SuppressLint("UnflaggedApi") 2019 public void unregisterTetheringEventCallback(@NonNull final TetheringEventCallback callback) { 2020 Objects.requireNonNull(callback); 2021 2022 final String callerPkg = mContext.getOpPackageName(); 2023 Log.i(TAG, "unregisterTetheringEventCallback caller:" + callerPkg); 2024 2025 synchronized (mTetheringEventCallbacks) { 2026 ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback); 2027 if (remoteCallback == null) { 2028 throw new IllegalArgumentException("callback was not registered."); 2029 } 2030 2031 getConnector(c -> c.unregisterTetheringEventCallback(remoteCallback, callerPkg)); 2032 } 2033 } 2034 2035 /** 2036 * Get a more detailed error code after a Tethering or Untethering 2037 * request asynchronously failed. 2038 * 2039 * @param iface The name of the interface of interest 2040 * @return error The error code of the last error tethering or untethering the named 2041 * interface 2042 * @hide 2043 */ 2044 @SystemApi(client = MODULE_LIBRARIES) 2045 public int getLastTetherError(@NonNull final String iface) { 2046 mCallback.waitForStarted(); 2047 if (mTetherStatesParcel == null) return TETHER_ERROR_NO_ERROR; 2048 2049 int i = 0; 2050 for (TetheringInterface errored : mTetherStatesParcel.erroredIfaceList) { 2051 if (iface.equals(errored.getInterface())) return mTetherStatesParcel.lastErrorList[i]; 2052 2053 i++; 2054 } 2055 return TETHER_ERROR_NO_ERROR; 2056 } 2057 2058 /** 2059 * Get the list of regular expressions that define any tetherable 2060 * USB network interfaces. If USB tethering is not supported by the 2061 * device, this list should be empty. 2062 * 2063 * @return an array of 0 or more regular expression Strings defining 2064 * what interfaces are considered tetherable usb interfaces. 2065 * @hide 2066 */ 2067 @SystemApi(client = MODULE_LIBRARIES) 2068 public @NonNull String[] getTetherableUsbRegexs() { 2069 mCallback.waitForStarted(); 2070 return mTetheringConfiguration.tetherableUsbRegexs; 2071 } 2072 2073 /** 2074 * Get the list of regular expressions that define any tetherable 2075 * Wifi network interfaces. If Wifi tethering is not supported by the 2076 * device, this list should be empty. 2077 * 2078 * @return an array of 0 or more regular expression Strings defining 2079 * what interfaces are considered tetherable wifi interfaces. 2080 * @hide 2081 */ 2082 @SystemApi(client = MODULE_LIBRARIES) 2083 public @NonNull String[] getTetherableWifiRegexs() { 2084 mCallback.waitForStarted(); 2085 return mTetheringConfiguration.tetherableWifiRegexs; 2086 } 2087 2088 /** 2089 * Get the list of regular expressions that define any tetherable 2090 * Bluetooth network interfaces. If Bluetooth tethering is not supported by the 2091 * device, this list should be empty. 2092 * 2093 * @return an array of 0 or more regular expression Strings defining 2094 * what interfaces are considered tetherable bluetooth interfaces. 2095 * @hide 2096 */ 2097 @SystemApi(client = MODULE_LIBRARIES) 2098 public @NonNull String[] getTetherableBluetoothRegexs() { 2099 mCallback.waitForStarted(); 2100 return mTetheringConfiguration.tetherableBluetoothRegexs; 2101 } 2102 2103 /** 2104 * Get the set of tetherable, available interfaces. This list is limited by 2105 * device configuration and current interface existence. 2106 * 2107 * @return an array of 0 or more Strings of tetherable interface names. 2108 * @hide 2109 */ 2110 @SystemApi(client = MODULE_LIBRARIES) 2111 public @NonNull String[] getTetherableIfaces() { 2112 mCallback.waitForStarted(); 2113 if (mTetherStatesParcel == null) return new String[0]; 2114 2115 return toIfaces(mTetherStatesParcel.availableList); 2116 } 2117 2118 /** 2119 * Get the set of tethered interfaces. 2120 * 2121 * @return an array of 0 or more String of currently tethered interface names. 2122 * @hide 2123 */ 2124 @SystemApi(client = MODULE_LIBRARIES) 2125 public @NonNull String[] getTetheredIfaces() { 2126 mCallback.waitForStarted(); 2127 if (mTetherStatesParcel == null) return new String[0]; 2128 2129 return toIfaces(mTetherStatesParcel.tetheredList); 2130 } 2131 2132 /** 2133 * Get the set of interface names which attempted to tether but 2134 * failed. Re-attempting to tether may cause them to reset to the Tethered 2135 * state. Alternatively, causing the interface to be destroyed and recreated 2136 * may cause them to reset to the available state. 2137 * {@link TetheringManager#getLastTetherError} can be used to get more 2138 * information on the cause of the errors. 2139 * 2140 * @return an array of 0 or more String indicating the interface names 2141 * which failed to tether. 2142 * @hide 2143 */ 2144 @SystemApi(client = MODULE_LIBRARIES) 2145 public @NonNull String[] getTetheringErroredIfaces() { 2146 mCallback.waitForStarted(); 2147 if (mTetherStatesParcel == null) return new String[0]; 2148 2149 return toIfaces(mTetherStatesParcel.erroredIfaceList); 2150 } 2151 2152 /** 2153 * Get the set of tethered dhcp ranges. 2154 * 2155 * @deprecated This API just return the default value which is not used in DhcpServer. 2156 * @hide 2157 */ 2158 @Deprecated 2159 public @NonNull String[] getTetheredDhcpRanges() { 2160 mCallback.waitForStarted(); 2161 return mTetheringConfiguration.legacyDhcpRanges; 2162 } 2163 2164 /** 2165 * Check if the device allows for tethering. It may be disabled via 2166 * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or 2167 * due to device configuration. 2168 * 2169 * @return a boolean - {@code true} indicating Tethering is supported. 2170 * @hide 2171 */ 2172 @SystemApi(client = MODULE_LIBRARIES) 2173 public boolean isTetheringSupported() { 2174 final String callerPkg = mContext.getOpPackageName(); 2175 2176 return isTetheringSupported(callerPkg); 2177 } 2178 2179 /** 2180 * Check if the device allows for tethering. It may be disabled via {@code ro.tether.denied} 2181 * system property, Settings.TETHER_SUPPORTED or due to device configuration. This is useful 2182 * for system components that query this API on behalf of an app. In particular, Bluetooth 2183 * has @UnsupportedAppUsage calls that will let apps turn on bluetooth tethering if they have 2184 * the right permissions, but such an app needs to know whether it can (permissions as well 2185 * as support from the device) turn on tethering in the first place to show the appropriate UI. 2186 * 2187 * @param callerPkg The caller package name, if it is not matching the calling uid, 2188 * SecurityException would be thrown. 2189 * @return a boolean - {@code true} indicating Tethering is supported. 2190 * @hide 2191 */ 2192 @SystemApi(client = MODULE_LIBRARIES) 2193 public boolean isTetheringSupported(@NonNull final String callerPkg) { 2194 2195 final RequestDispatcher dispatcher = new RequestDispatcher(); 2196 final int ret = dispatcher.waitForResult((connector, listener) -> { 2197 try { 2198 connector.isTetheringSupported(callerPkg, getAttributionTag(), listener); 2199 } catch (RemoteException e) { 2200 throw new IllegalStateException(e); 2201 } 2202 }, this); 2203 2204 return ret == TETHER_ERROR_NO_ERROR; 2205 } 2206 2207 /** 2208 * Stop all active tethering. 2209 * @hide 2210 */ 2211 @SystemApi 2212 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 2213 public void stopAllTethering() { 2214 final String callerPkg = mContext.getOpPackageName(); 2215 Log.i(TAG, "stopAllTethering caller:" + callerPkg); 2216 2217 getConnector(c -> c.stopAllTethering(callerPkg, getAttributionTag(), 2218 new IIntResultListener.Stub() { 2219 @Override 2220 public void onResult(int resultCode) { 2221 // TODO: add an API parameter to send result to caller. 2222 // This has never been possible as stopAllTethering has always been void 2223 // and never taken a callback object. The only indication that callers have 2224 // is if the call results in a TETHER_STATE_CHANGE broadcast. 2225 } 2226 })); 2227 } 2228 2229 /** 2230 * Whether to treat networks that have TRANSPORT_TEST as Tethering upstreams. The effects of 2231 * this method apply to any test networks that are already present on the system. 2232 * 2233 * @throws SecurityException If the caller doesn't have the NETWORK_SETTINGS permission. 2234 * @hide 2235 */ 2236 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) 2237 public void setPreferTestNetworks(final boolean prefer) { 2238 Log.i(TAG, "setPreferTestNetworks caller: " + mContext.getOpPackageName()); 2239 2240 final RequestDispatcher dispatcher = new RequestDispatcher(); 2241 final int ret = dispatcher.waitForResult((connector, listener) -> { 2242 try { 2243 connector.setPreferTestNetworks(prefer, listener); 2244 } catch (RemoteException e) { 2245 throw new IllegalStateException(e); 2246 } 2247 }, this); 2248 } 2249 } 2250