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.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SuppressLint; 26 import android.annotation.SystemApi; 27 import android.content.Context; 28 import android.os.Bundle; 29 import android.os.ConditionVariable; 30 import android.os.IBinder; 31 import android.os.RemoteException; 32 import android.os.ResultReceiver; 33 import android.util.ArrayMap; 34 import android.util.ArraySet; 35 import android.util.Log; 36 37 import com.android.internal.annotations.GuardedBy; 38 39 import java.lang.annotation.Retention; 40 import java.lang.annotation.RetentionPolicy; 41 import java.lang.ref.WeakReference; 42 import java.util.ArrayList; 43 import java.util.Arrays; 44 import java.util.Collection; 45 import java.util.Collections; 46 import java.util.HashMap; 47 import java.util.List; 48 import java.util.Objects; 49 import java.util.Set; 50 import java.util.concurrent.Executor; 51 import java.util.function.Supplier; 52 53 /** 54 * This class provides the APIs to control the tethering service. 55 * <p> The primary responsibilities of this class are to provide the APIs for applications to 56 * start tethering, stop tethering, query configuration and query status. 57 * 58 * @hide 59 */ 60 @SystemApi 61 public class TetheringManager { 62 private static final String TAG = TetheringManager.class.getSimpleName(); 63 private static final int DEFAULT_TIMEOUT_MS = 60_000; 64 private static final long CONNECTOR_POLL_INTERVAL_MILLIS = 200L; 65 66 @GuardedBy("mConnectorWaitQueue") 67 @Nullable 68 private ITetheringConnector mConnector; 69 @GuardedBy("mConnectorWaitQueue") 70 @NonNull 71 private final List<ConnectorConsumer> mConnectorWaitQueue = new ArrayList<>(); 72 private final Supplier<IBinder> mConnectorSupplier; 73 74 private final TetheringCallbackInternal mCallback; 75 private final Context mContext; 76 private final ArrayMap<TetheringEventCallback, ITetheringEventCallback> 77 mTetheringEventCallbacks = new ArrayMap<>(); 78 79 private volatile TetheringConfigurationParcel mTetheringConfiguration; 80 private volatile TetherStatesParcel mTetherStatesParcel; 81 82 /** 83 * Broadcast Action: A tetherable connection has come or gone. 84 * Uses {@code TetheringManager.EXTRA_AVAILABLE_TETHER}, 85 * {@code TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY}, 86 * {@code TetheringManager.EXTRA_ACTIVE_TETHER}, and 87 * {@code TetheringManager.EXTRA_ERRORED_TETHER} to indicate 88 * the current state of tethering. Each include a list of 89 * interface names in that state (may be empty). 90 * 91 * @deprecated New client should use TetheringEventCallback instead. 92 */ 93 @Deprecated 94 public static final String ACTION_TETHER_STATE_CHANGED = 95 "android.net.conn.TETHER_STATE_CHANGED"; 96 97 /** 98 * gives a String[] listing all the interfaces configured for 99 * tethering and currently available for tethering. 100 */ 101 public static final String EXTRA_AVAILABLE_TETHER = "availableArray"; 102 103 /** 104 * gives a String[] listing all the interfaces currently in local-only 105 * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding) 106 */ 107 public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY"; 108 109 /** 110 * gives a String[] listing all the interfaces currently tethered 111 * (ie, has DHCPv4 support and packets potentially forwarded/NATed) 112 */ 113 public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; 114 115 /** 116 * gives a String[] listing all the interfaces we tried to tether and 117 * failed. Use {@link #getLastTetherError} to find the error code 118 * for any interfaces listed here. 119 */ 120 public static final String EXTRA_ERRORED_TETHER = "erroredArray"; 121 122 /** @hide */ 123 @Retention(RetentionPolicy.SOURCE) 124 @IntDef(flag = false, value = { 125 TETHERING_WIFI, 126 TETHERING_USB, 127 TETHERING_BLUETOOTH, 128 TETHERING_WIFI_P2P, 129 TETHERING_NCM, 130 TETHERING_ETHERNET, 131 }) 132 public @interface TetheringType { 133 } 134 135 /** 136 * Invalid tethering type. 137 * @see #startTethering. 138 */ 139 public static final int TETHERING_INVALID = -1; 140 141 /** 142 * Wifi tethering type. 143 * @see #startTethering. 144 */ 145 public static final int TETHERING_WIFI = 0; 146 147 /** 148 * USB tethering type. 149 * @see #startTethering. 150 */ 151 public static final int TETHERING_USB = 1; 152 153 /** 154 * Bluetooth tethering type. 155 * @see #startTethering. 156 */ 157 public static final int TETHERING_BLUETOOTH = 2; 158 159 /** 160 * Wifi P2p tethering type. 161 * Wifi P2p tethering is set through events automatically, and don't 162 * need to start from #startTethering. 163 */ 164 public static final int TETHERING_WIFI_P2P = 3; 165 166 /** 167 * Ncm local tethering type. 168 * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback) 169 */ 170 public static final int TETHERING_NCM = 4; 171 172 /** 173 * Ethernet tethering type. 174 * @see #startTethering(TetheringRequest, Executor, StartTetheringCallback) 175 */ 176 public static final int TETHERING_ETHERNET = 5; 177 178 /** 179 * WIGIG tethering type. Use a separate type to prevent 180 * conflicts with TETHERING_WIFI 181 * This type is only used internally by the tethering module 182 * @hide 183 */ 184 public static final int TETHERING_WIGIG = 6; 185 186 /** 187 * The int value of last tethering type. 188 * @hide 189 */ 190 public static final int MAX_TETHERING_TYPE = TETHERING_WIGIG; 191 192 /** @hide */ 193 @Retention(RetentionPolicy.SOURCE) 194 @IntDef(value = { 195 TETHER_ERROR_NO_ERROR, 196 TETHER_ERROR_PROVISIONING_FAILED, 197 TETHER_ERROR_ENTITLEMENT_UNKNOWN, 198 }) 199 public @interface EntitlementResult { 200 } 201 202 /** @hide */ 203 @Retention(RetentionPolicy.SOURCE) 204 @IntDef(value = { 205 TETHER_ERROR_NO_ERROR, 206 TETHER_ERROR_UNKNOWN_IFACE, 207 TETHER_ERROR_SERVICE_UNAVAIL, 208 TETHER_ERROR_INTERNAL_ERROR, 209 TETHER_ERROR_TETHER_IFACE_ERROR, 210 TETHER_ERROR_ENABLE_FORWARDING_ERROR, 211 TETHER_ERROR_DISABLE_FORWARDING_ERROR, 212 TETHER_ERROR_IFACE_CFG_ERROR, 213 TETHER_ERROR_DHCPSERVER_ERROR, 214 }) 215 public @interface TetheringIfaceError { 216 } 217 218 /** @hide */ 219 @Retention(RetentionPolicy.SOURCE) 220 @IntDef(value = { 221 TETHER_ERROR_SERVICE_UNAVAIL, 222 TETHER_ERROR_INTERNAL_ERROR, 223 TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, 224 TETHER_ERROR_UNKNOWN_TYPE, 225 }) 226 public @interface StartTetheringError { 227 } 228 229 public static final int TETHER_ERROR_NO_ERROR = 0; 230 public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; 231 public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; 232 public static final int TETHER_ERROR_UNSUPPORTED = 3; 233 public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; 234 public static final int TETHER_ERROR_INTERNAL_ERROR = 5; 235 public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; 236 public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; 237 public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; 238 public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; 239 public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; 240 public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; 241 public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; 242 public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; 243 public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; 244 public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; 245 public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; 246 247 /** @hide */ 248 @Retention(RetentionPolicy.SOURCE) 249 @IntDef(flag = false, value = { 250 TETHER_HARDWARE_OFFLOAD_STOPPED, 251 TETHER_HARDWARE_OFFLOAD_STARTED, 252 TETHER_HARDWARE_OFFLOAD_FAILED, 253 }) 254 public @interface TetherOffloadStatus { 255 } 256 257 /** Tethering offload status is stopped. */ 258 public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; 259 /** Tethering offload status is started. */ 260 public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; 261 /** Fail to start tethering offload. */ 262 public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; 263 264 /** 265 * Create a TetheringManager object for interacting with the tethering service. 266 * 267 * @param context Context for the manager. 268 * @param connectorSupplier Supplier for the manager connector; may return null while the 269 * service is not connected. 270 * {@hide} 271 */ 272 @SystemApi(client = MODULE_LIBRARIES) TetheringManager(@onNull final Context context, @NonNull Supplier<IBinder> connectorSupplier)273 public TetheringManager(@NonNull final Context context, 274 @NonNull Supplier<IBinder> connectorSupplier) { 275 mContext = context; 276 mCallback = new TetheringCallbackInternal(this); 277 mConnectorSupplier = connectorSupplier; 278 279 final String pkgName = mContext.getOpPackageName(); 280 281 final IBinder connector = mConnectorSupplier.get(); 282 // If the connector is available on start, do not start a polling thread. This introduces 283 // differences in the thread that sends the oneway binder calls to the service between the 284 // first few seconds after boot and later, but it avoids always having differences between 285 // the first usage of TetheringManager from a process and subsequent usages (so the 286 // difference is only on boot). On boot binder calls may be queued until the service comes 287 // up and be sent from a worker thread; later, they are always sent from the caller thread. 288 // Considering that it's just oneway binder calls, and ordering is preserved, this seems 289 // better than inconsistent behavior persisting after boot. 290 if (connector != null) { 291 mConnector = ITetheringConnector.Stub.asInterface(connector); 292 } else { 293 startPollingForConnector(); 294 } 295 296 Log.i(TAG, "registerTetheringEventCallback:" + pkgName); 297 getConnector(c -> c.registerTetheringEventCallback(mCallback, pkgName)); 298 } 299 300 /** @hide */ 301 @Override finalize()302 protected void finalize() throws Throwable { 303 final String pkgName = mContext.getOpPackageName(); 304 Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName); 305 // 1. It's generally not recommended to perform long operations in finalize, but while 306 // unregisterTetheringEventCallback does an IPC, it's a oneway IPC so should not block. 307 // 2. If the connector is not yet connected, TetheringManager is impossible to finalize 308 // because the connector polling thread strong reference the TetheringManager object. So 309 // it's guaranteed that registerTetheringEventCallback was already called before calling 310 // unregisterTetheringEventCallback in finalize. 311 if (mConnector == null) Log.wtf(TAG, "null connector in finalize!"); 312 getConnector(c -> c.unregisterTetheringEventCallback(mCallback, pkgName)); 313 314 super.finalize(); 315 } 316 startPollingForConnector()317 private void startPollingForConnector() { 318 new Thread(() -> { 319 while (true) { 320 try { 321 Thread.sleep(CONNECTOR_POLL_INTERVAL_MILLIS); 322 } catch (InterruptedException e) { 323 // Not much to do here, the system needs to wait for the connector 324 } 325 326 final IBinder connector = mConnectorSupplier.get(); 327 if (connector != null) { 328 onTetheringConnected(ITetheringConnector.Stub.asInterface(connector)); 329 return; 330 } 331 } 332 }).start(); 333 } 334 335 private interface ConnectorConsumer { onConnectorAvailable(ITetheringConnector connector)336 void onConnectorAvailable(ITetheringConnector connector) throws RemoteException; 337 } 338 onTetheringConnected(ITetheringConnector connector)339 private void onTetheringConnected(ITetheringConnector connector) { 340 // Process the connector wait queue in order, including any items that are added 341 // while processing. 342 // 343 // 1. Copy the queue to a local variable under lock. 344 // 2. Drain the local queue with the lock released (otherwise, enqueuing future commands 345 // would block on the lock). 346 // 3. Acquire the lock again. If any new tasks were queued during step 2, goto 1. 347 // If not, set mConnector to non-null so future tasks are run immediately, not queued. 348 // 349 // For this to work, all calls to the tethering service must use getConnector(), which 350 // ensures that tasks are added to the queue with the lock held. 351 // 352 // Once mConnector is set to non-null, it will never be null again. If the network stack 353 // process crashes, no recovery is possible. 354 // TODO: evaluate whether it is possible to recover from network stack process crashes 355 // (though in most cases the system will have crashed when the network stack process 356 // crashes). 357 do { 358 final List<ConnectorConsumer> localWaitQueue; 359 synchronized (mConnectorWaitQueue) { 360 localWaitQueue = new ArrayList<>(mConnectorWaitQueue); 361 mConnectorWaitQueue.clear(); 362 } 363 364 // Allow more tasks to be added at the end without blocking while draining the queue. 365 for (ConnectorConsumer task : localWaitQueue) { 366 try { 367 task.onConnectorAvailable(connector); 368 } catch (RemoteException e) { 369 // Most likely the network stack process crashed, which is likely to crash the 370 // system. Keep processing other requests but report the error loudly. 371 Log.wtf(TAG, "Error processing request for the tethering connector", e); 372 } 373 } 374 375 synchronized (mConnectorWaitQueue) { 376 if (mConnectorWaitQueue.size() == 0) { 377 mConnector = connector; 378 return; 379 } 380 } 381 } while (true); 382 } 383 384 /** 385 * Asynchronously get the ITetheringConnector to execute some operation. 386 * 387 * <p>If the connector is already available, the operation will be executed on the caller's 388 * thread. Otherwise it will be queued and executed on a worker thread. The operation should be 389 * limited to performing oneway binder calls to minimize differences due to threading. 390 */ getConnector(ConnectorConsumer consumer)391 private void getConnector(ConnectorConsumer consumer) { 392 final ITetheringConnector connector; 393 synchronized (mConnectorWaitQueue) { 394 connector = mConnector; 395 if (connector == null) { 396 mConnectorWaitQueue.add(consumer); 397 return; 398 } 399 } 400 401 try { 402 consumer.onConnectorAvailable(connector); 403 } catch (RemoteException e) { 404 throw new IllegalStateException(e); 405 } 406 } 407 408 private interface RequestHelper { runRequest(ITetheringConnector connector, IIntResultListener listener)409 void runRequest(ITetheringConnector connector, IIntResultListener listener); 410 } 411 412 // Used to dispatch legacy ConnectivityManager methods that expect tethering to be able to 413 // return results and perform operations synchronously. 414 // TODO: remove once there are no callers of these legacy methods. 415 private class RequestDispatcher { 416 private final ConditionVariable mWaiting; 417 public volatile int mRemoteResult; 418 419 private final IIntResultListener mListener = new IIntResultListener.Stub() { 420 @Override 421 public void onResult(final int resultCode) { 422 mRemoteResult = resultCode; 423 mWaiting.open(); 424 } 425 }; 426 RequestDispatcher()427 RequestDispatcher() { 428 mWaiting = new ConditionVariable(); 429 } 430 waitForResult(final RequestHelper request)431 int waitForResult(final RequestHelper request) { 432 getConnector(c -> request.runRequest(c, mListener)); 433 if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) { 434 throw new IllegalStateException("Callback timeout"); 435 } 436 437 throwIfPermissionFailure(mRemoteResult); 438 439 return mRemoteResult; 440 } 441 } 442 throwIfPermissionFailure(final int errorCode)443 private static void throwIfPermissionFailure(final int errorCode) { 444 switch (errorCode) { 445 case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION: 446 throw new SecurityException("No android.permission.TETHER_PRIVILEGED" 447 + " or android.permission.WRITE_SETTINGS permission"); 448 case TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION: 449 throw new SecurityException( 450 "No android.permission.ACCESS_NETWORK_STATE permission"); 451 } 452 } 453 454 /** 455 * A request for a tethered interface. 456 * 457 * There are two reasons why this doesn't implement CLoseable: 458 * 1. To consistency with the existing EthernetManager.TetheredInterfaceRequest, which is 459 * already released. 460 * 2. This is not synchronous, so it's not useful to use try-with-resources. 461 * 462 * {@hide} 463 */ 464 @SystemApi(client = MODULE_LIBRARIES) 465 @SuppressLint("NotCloseable") 466 public interface TetheredInterfaceRequest { 467 /** 468 * Release the request to tear down tethered interface. 469 */ release()470 void release(); 471 } 472 473 /** 474 * Callback for requestTetheredInterface. 475 * 476 * {@hide} 477 */ 478 @SystemApi(client = MODULE_LIBRARIES) 479 public interface TetheredInterfaceCallback { 480 /** 481 * Called when the tethered interface is available. 482 * @param iface The name of the interface. 483 */ onAvailable(@onNull String iface)484 void onAvailable(@NonNull String iface); 485 486 /** 487 * Called when the tethered interface is now unavailable. 488 */ onUnavailable()489 void onUnavailable(); 490 } 491 492 private static class TetheringCallbackInternal extends ITetheringEventCallback.Stub { 493 private volatile int mError = TETHER_ERROR_NO_ERROR; 494 private final ConditionVariable mWaitForCallback = new ConditionVariable(); 495 // This object is never garbage collected because the Tethering code running in 496 // the system server always maintains a reference to it for as long as 497 // mCallback is registered. 498 // 499 // Don't keep a strong reference to TetheringManager because otherwise 500 // TetheringManager cannot be garbage collected, and because TetheringManager 501 // stores the Context that it was created from, this will prevent the calling 502 // Activity from being garbage collected as well. 503 private final WeakReference<TetheringManager> mTetheringMgrRef; 504 TetheringCallbackInternal(final TetheringManager tm)505 TetheringCallbackInternal(final TetheringManager tm) { 506 mTetheringMgrRef = new WeakReference<>(tm); 507 } 508 509 @Override onCallbackStarted(TetheringCallbackStartedParcel parcel)510 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 511 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 512 if (tetheringMgr != null) { 513 tetheringMgr.mTetheringConfiguration = parcel.config; 514 tetheringMgr.mTetherStatesParcel = parcel.states; 515 mWaitForCallback.open(); 516 } 517 } 518 519 @Override onCallbackStopped(int errorCode)520 public void onCallbackStopped(int errorCode) { 521 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 522 if (tetheringMgr != null) { 523 mError = errorCode; 524 mWaitForCallback.open(); 525 } 526 } 527 528 @Override onSupportedTetheringTypes(long supportedBitmap)529 public void onSupportedTetheringTypes(long supportedBitmap) { } 530 531 @Override onUpstreamChanged(Network network)532 public void onUpstreamChanged(Network network) { } 533 534 @Override onConfigurationChanged(TetheringConfigurationParcel config)535 public void onConfigurationChanged(TetheringConfigurationParcel config) { 536 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 537 if (tetheringMgr != null) tetheringMgr.mTetheringConfiguration = config; 538 } 539 540 @Override onTetherStatesChanged(TetherStatesParcel states)541 public void onTetherStatesChanged(TetherStatesParcel states) { 542 TetheringManager tetheringMgr = mTetheringMgrRef.get(); 543 if (tetheringMgr != null) tetheringMgr.mTetherStatesParcel = states; 544 } 545 546 @Override onTetherClientsChanged(List<TetheredClient> clients)547 public void onTetherClientsChanged(List<TetheredClient> clients) { } 548 549 @Override onOffloadStatusChanged(int status)550 public void onOffloadStatusChanged(int status) { } 551 waitForStarted()552 public void waitForStarted() { 553 mWaitForCallback.block(DEFAULT_TIMEOUT_MS); 554 throwIfPermissionFailure(mError); 555 } 556 } 557 558 /** 559 * Attempt to tether the named interface. This will setup a dhcp server 560 * on the interface, forward and NAT IP v4 packets and forward DNS requests 561 * to the best active upstream network interface. Note that if no upstream 562 * IP network interface is available, dhcp will still run and traffic will be 563 * allowed between the tethered devices and this device, though upstream net 564 * access will of course fail until an upstream network interface becomes 565 * active. 566 * 567 * @deprecated The only usages is PanService. It uses this for legacy reasons 568 * and will migrate away as soon as possible. 569 * 570 * @param iface the interface name to tether. 571 * @return error a {@code TETHER_ERROR} value indicating success or failure type 572 * 573 * {@hide} 574 */ 575 @Deprecated 576 @SystemApi(client = MODULE_LIBRARIES) tether(@onNull final String iface)577 public int tether(@NonNull final String iface) { 578 final String callerPkg = mContext.getOpPackageName(); 579 Log.i(TAG, "tether caller:" + callerPkg); 580 final RequestDispatcher dispatcher = new RequestDispatcher(); 581 582 return dispatcher.waitForResult((connector, listener) -> { 583 try { 584 connector.tether(iface, callerPkg, getAttributionTag(), listener); 585 } catch (RemoteException e) { 586 throw new IllegalStateException(e); 587 } 588 }); 589 } 590 591 /** 592 * @return the context's attribution tag 593 */ 594 private @Nullable String getAttributionTag() { 595 return mContext.getAttributionTag(); 596 } 597 598 /** 599 * Stop tethering the named interface. 600 * 601 * @deprecated The only usages is PanService. It uses this for legacy reasons 602 * and will migrate away as soon as possible. 603 * 604 * {@hide} 605 */ 606 @Deprecated 607 @SystemApi(client = MODULE_LIBRARIES) 608 public int untether(@NonNull final String iface) { 609 final String callerPkg = mContext.getOpPackageName(); 610 Log.i(TAG, "untether caller:" + callerPkg); 611 612 final RequestDispatcher dispatcher = new RequestDispatcher(); 613 614 return dispatcher.waitForResult((connector, listener) -> { 615 try { 616 connector.untether(iface, callerPkg, getAttributionTag(), listener); 617 } catch (RemoteException e) { 618 throw new IllegalStateException(e); 619 } 620 }); 621 } 622 623 /** 624 * Attempt to both alter the mode of USB and Tethering of USB. 625 * 626 * @deprecated New clients should not use this API anymore. All clients should use 627 * #startTethering or #stopTethering which encapsulate proper entitlement logic. If the API is 628 * used and an entitlement check is needed, downstream USB tethering will be enabled but will 629 * not have any upstream. 630 * 631 * {@hide} 632 */ 633 @Deprecated 634 @SystemApi(client = MODULE_LIBRARIES) 635 public int setUsbTethering(final boolean enable) { 636 final String callerPkg = mContext.getOpPackageName(); 637 Log.i(TAG, "setUsbTethering caller:" + callerPkg); 638 639 final RequestDispatcher dispatcher = new RequestDispatcher(); 640 641 return dispatcher.waitForResult((connector, listener) -> { 642 try { 643 connector.setUsbTethering(enable, callerPkg, getAttributionTag(), 644 listener); 645 } catch (RemoteException e) { 646 throw new IllegalStateException(e); 647 } 648 }); 649 } 650 651 /** 652 * Indicates that this tethering connection will provide connectivity beyond this device (e.g., 653 * global Internet access). 654 */ 655 public static final int CONNECTIVITY_SCOPE_GLOBAL = 1; 656 657 /** 658 * Indicates that this tethering connection will only provide local connectivity. 659 */ 660 public static final int CONNECTIVITY_SCOPE_LOCAL = 2; 661 662 /** 663 * Connectivity scopes for {@link TetheringRequest.Builder#setConnectivityScope}. 664 * @hide 665 */ 666 @Retention(RetentionPolicy.SOURCE) 667 @IntDef(prefix = "CONNECTIVITY_SCOPE_", value = { 668 CONNECTIVITY_SCOPE_GLOBAL, 669 CONNECTIVITY_SCOPE_LOCAL, 670 }) 671 public @interface ConnectivityScope {} 672 673 /** 674 * Use with {@link #startTethering} to specify additional parameters when starting tethering. 675 */ 676 public static class TetheringRequest { 677 /** A configuration set for TetheringRequest. */ 678 private final TetheringRequestParcel mRequestParcel; 679 680 private TetheringRequest(final TetheringRequestParcel request) { 681 mRequestParcel = request; 682 } 683 684 /** Builder used to create TetheringRequest. */ 685 public static class Builder { 686 private final TetheringRequestParcel mBuilderParcel; 687 688 /** Default constructor of Builder. */ 689 public Builder(@TetheringType final int type) { 690 mBuilderParcel = new TetheringRequestParcel(); 691 mBuilderParcel.tetheringType = type; 692 mBuilderParcel.localIPv4Address = null; 693 mBuilderParcel.staticClientAddress = null; 694 mBuilderParcel.exemptFromEntitlementCheck = false; 695 mBuilderParcel.showProvisioningUi = true; 696 mBuilderParcel.connectivityScope = getDefaultConnectivityScope(type); 697 } 698 699 /** 700 * Configure tethering with static IPv4 assignment. 701 * 702 * A DHCP server will be started, but will only be able to offer the client address. 703 * The two addresses must be in the same prefix. 704 * 705 * @param localIPv4Address The preferred local IPv4 link address to use. 706 * @param clientAddress The static client address. 707 */ 708 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 709 @NonNull 710 public Builder setStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address, 711 @NonNull final LinkAddress clientAddress) { 712 Objects.requireNonNull(localIPv4Address); 713 Objects.requireNonNull(clientAddress); 714 if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) { 715 throw new IllegalArgumentException("Invalid server or client addresses"); 716 } 717 718 mBuilderParcel.localIPv4Address = localIPv4Address; 719 mBuilderParcel.staticClientAddress = clientAddress; 720 return this; 721 } 722 723 /** Start tethering without entitlement checks. */ 724 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 725 @NonNull 726 public Builder setExemptFromEntitlementCheck(boolean exempt) { 727 mBuilderParcel.exemptFromEntitlementCheck = exempt; 728 return this; 729 } 730 731 /** 732 * If an entitlement check is needed, sets whether to show the entitlement UI or to 733 * perform a silent entitlement check. By default, the entitlement UI is shown. 734 */ 735 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 736 @NonNull 737 public Builder setShouldShowEntitlementUi(boolean showUi) { 738 mBuilderParcel.showProvisioningUi = showUi; 739 return this; 740 } 741 742 /** 743 * Sets the connectivity scope to be provided by this tethering downstream. 744 */ 745 @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) 746 @NonNull 747 public Builder setConnectivityScope(@ConnectivityScope int scope) { 748 if (!checkConnectivityScope(mBuilderParcel.tetheringType, scope)) { 749 throw new IllegalArgumentException("Invalid connectivity scope " + scope); 750 } 751 752 mBuilderParcel.connectivityScope = scope; 753 return this; 754 } 755 756 /** Build {@link TetheringRequest} with the currently set configuration. */ 757 @NonNull 758 public TetheringRequest build() { 759 return new TetheringRequest(mBuilderParcel); 760 } 761 } 762 763 /** 764 * Get the local IPv4 address, if one was configured with 765 * {@link Builder#setStaticIpv4Addresses}. 766 */ 767 @Nullable 768 public LinkAddress getLocalIpv4Address() { 769 return mRequestParcel.localIPv4Address; 770 } 771 772 /** 773 * Get the static IPv4 address of the client, if one was configured with 774 * {@link Builder#setStaticIpv4Addresses}. 775 */ 776 @Nullable 777 public LinkAddress getClientStaticIpv4Address() { 778 return mRequestParcel.staticClientAddress; 779 } 780 781 /** Get tethering type. */ 782 @TetheringType 783 public int getTetheringType() { 784 return mRequestParcel.tetheringType; 785 } 786 787 /** Get connectivity type */ 788 @ConnectivityScope 789 public int getConnectivityScope() { 790 return mRequestParcel.connectivityScope; 791 } 792 793 /** Check if exempt from entitlement check. */ 794 public boolean isExemptFromEntitlementCheck() { 795 return mRequestParcel.exemptFromEntitlementCheck; 796 } 797 798 /** Check if show entitlement ui. */ 799 public boolean getShouldShowEntitlementUi() { 800 return mRequestParcel.showProvisioningUi; 801 } 802 803 /** 804 * Check whether the two addresses are ipv4 and in the same prefix. 805 * @hide 806 */ 807 public static boolean checkStaticAddressConfiguration( 808 @NonNull final LinkAddress localIPv4Address, 809 @NonNull final LinkAddress clientAddress) { 810 return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength() 811 && localIPv4Address.isIpv4() && clientAddress.isIpv4() 812 && new IpPrefix(localIPv4Address.toString()).equals( 813 new IpPrefix(clientAddress.toString())); 814 } 815 816 /** 817 * Returns the default connectivity scope for the given tethering type. Usually this is 818 * CONNECTIVITY_SCOPE_GLOBAL, except for NCM which for historical reasons defaults to local. 819 * @hide 820 */ 821 public static @ConnectivityScope int getDefaultConnectivityScope(int tetheringType) { 822 return tetheringType != TETHERING_NCM 823 ? CONNECTIVITY_SCOPE_GLOBAL 824 : CONNECTIVITY_SCOPE_LOCAL; 825 } 826 827 /** 828 * Checks whether the requested connectivity scope is allowed. 829 * @hide 830 */ 831 private static boolean checkConnectivityScope(int type, int scope) { 832 if (scope == CONNECTIVITY_SCOPE_GLOBAL) return true; 833 return type == TETHERING_USB || type == TETHERING_ETHERNET || type == TETHERING_NCM; 834 } 835 836 /** 837 * Get a TetheringRequestParcel from the configuration 838 * @hide 839 */ 840 public TetheringRequestParcel getParcel() { 841 return mRequestParcel; 842 } 843 844 /** String of TetheringRequest detail. */ 845 public String toString() { 846 return "TetheringRequest [ type= " + mRequestParcel.tetheringType 847 + ", localIPv4Address= " + mRequestParcel.localIPv4Address 848 + ", staticClientAddress= " + mRequestParcel.staticClientAddress 849 + ", exemptFromEntitlementCheck= " 850 + mRequestParcel.exemptFromEntitlementCheck + ", showProvisioningUi= " 851 + mRequestParcel.showProvisioningUi + " ]"; 852 } 853 } 854 855 /** 856 * Callback for use with {@link #startTethering} to find out whether tethering succeeded. 857 */ 858 public interface StartTetheringCallback { 859 /** 860 * Called when tethering has been successfully started. 861 */ 862 default void onTetheringStarted() {} 863 864 /** 865 * Called when starting tethering failed. 866 * 867 * @param error The error that caused the failure. 868 */ 869 default void onTetheringFailed(@StartTetheringError final int error) {} 870 } 871 872 /** 873 * Starts tethering and runs tether provisioning for the given type if needed. If provisioning 874 * fails, stopTethering will be called automatically. 875 * 876 * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will 877 * fail if a tethering entitlement check is required. 878 * 879 * @param request a {@link TetheringRequest} which can specify the preferred configuration. 880 * @param executor {@link Executor} to specify the thread upon which the callback of 881 * TetheringRequest will be invoked. 882 * @param callback A callback that will be called to indicate the success status of the 883 * tethering start request. 884 */ 885 @RequiresPermission(anyOf = { 886 android.Manifest.permission.TETHER_PRIVILEGED, 887 android.Manifest.permission.WRITE_SETTINGS 888 }) 889 public void startTethering(@NonNull final TetheringRequest request, 890 @NonNull final Executor executor, @NonNull final StartTetheringCallback callback) { 891 final String callerPkg = mContext.getOpPackageName(); 892 Log.i(TAG, "startTethering caller:" + callerPkg); 893 894 final IIntResultListener listener = new IIntResultListener.Stub() { 895 @Override 896 public void onResult(final int resultCode) { 897 executor.execute(() -> { 898 if (resultCode == TETHER_ERROR_NO_ERROR) { 899 callback.onTetheringStarted(); 900 } else { 901 callback.onTetheringFailed(resultCode); 902 } 903 }); 904 } 905 }; 906 getConnector(c -> c.startTethering(request.getParcel(), callerPkg, 907 getAttributionTag(), listener)); 908 } 909 910 /** 911 * Starts tethering and runs tether provisioning for the given type if needed. If provisioning 912 * fails, stopTethering will be called automatically. 913 * 914 * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will 915 * fail if a tethering entitlement check is required. 916 * 917 * @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants. 918 * @param executor {@link Executor} to specify the thread upon which the callback of 919 * TetheringRequest will be invoked. 920 * @hide 921 */ 922 @RequiresPermission(anyOf = { 923 android.Manifest.permission.TETHER_PRIVILEGED, 924 android.Manifest.permission.WRITE_SETTINGS 925 }) 926 @SystemApi(client = MODULE_LIBRARIES) 927 public void startTethering(int type, @NonNull final Executor executor, 928 @NonNull final StartTetheringCallback callback) { 929 startTethering(new TetheringRequest.Builder(type).build(), executor, callback); 930 } 931 932 /** 933 * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if 934 * applicable. 935 * 936 * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will 937 * fail if a tethering entitlement check is required. 938 */ 939 @RequiresPermission(anyOf = { 940 android.Manifest.permission.TETHER_PRIVILEGED, 941 android.Manifest.permission.WRITE_SETTINGS 942 }) 943 public void stopTethering(@TetheringType final int type) { 944 final String callerPkg = mContext.getOpPackageName(); 945 Log.i(TAG, "stopTethering caller:" + callerPkg); 946 947 getConnector(c -> c.stopTethering(type, callerPkg, getAttributionTag(), 948 new IIntResultListener.Stub() { 949 @Override 950 public void onResult(int resultCode) { 951 // TODO: provide an API to obtain result 952 // This has never been possible as stopTethering has always been void and never 953 // taken a callback object. The only indication that callers have is if the call 954 // results in a TETHER_STATE_CHANGE broadcast. 955 } 956 })); 957 } 958 959 /** 960 * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether 961 * entitlement succeeded. 962 */ 963 public interface OnTetheringEntitlementResultListener { 964 /** 965 * Called to notify entitlement result. 966 * 967 * @param resultCode an int value of entitlement result. It may be one of 968 * {@link #TETHER_ERROR_NO_ERROR}, 969 * {@link #TETHER_ERROR_PROVISIONING_FAILED}, or 970 * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN}. 971 */ 972 void onTetheringEntitlementResult(@EntitlementResult int result); 973 } 974 975 /** 976 * Request the latest value of the tethering entitlement check. 977 * 978 * <p>This method will only return the latest entitlement result if it is available. If no 979 * cached entitlement result is available, and {@code showEntitlementUi} is false, 980 * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN} will be returned. If {@code showEntitlementUi} is 981 * true, entitlement will be run. 982 * 983 * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will 984 * fail if a tethering entitlement check is required. 985 * 986 * @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants. 987 * @param showEntitlementUi a boolean indicating whether to check result for the UI-based 988 * entitlement check or the silent entitlement check. 989 * @param executor the executor on which callback will be invoked. 990 * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to 991 * notify the caller of the result of entitlement check. The listener may be called zero 992 * or one time. 993 */ 994 @RequiresPermission(anyOf = { 995 android.Manifest.permission.TETHER_PRIVILEGED, 996 android.Manifest.permission.WRITE_SETTINGS 997 }) 998 public void requestLatestTetheringEntitlementResult(@TetheringType int type, 999 boolean showEntitlementUi, 1000 @NonNull Executor executor, 1001 @NonNull final OnTetheringEntitlementResultListener listener) { 1002 if (listener == null) { 1003 throw new IllegalArgumentException( 1004 "OnTetheringEntitlementResultListener cannot be null."); 1005 } 1006 1007 ResultReceiver wrappedListener = new ResultReceiver(null /* handler */) { 1008 @Override 1009 protected void onReceiveResult(int resultCode, Bundle resultData) { 1010 executor.execute(() -> { 1011 listener.onTetheringEntitlementResult(resultCode); 1012 }); 1013 } 1014 }; 1015 1016 requestLatestTetheringEntitlementResult(type, wrappedListener, 1017 showEntitlementUi); 1018 } 1019 1020 /** 1021 * Helper function of #requestLatestTetheringEntitlementResult to remain backwards compatible 1022 * with ConnectivityManager#getLatestTetheringEntitlementResult 1023 * 1024 * {@hide} 1025 */ 1026 // TODO: improve the usage of ResultReceiver, b/145096122 1027 @SystemApi(client = MODULE_LIBRARIES) 1028 public void requestLatestTetheringEntitlementResult(@TetheringType final int type, 1029 @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) { 1030 final String callerPkg = mContext.getOpPackageName(); 1031 Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); 1032 1033 getConnector(c -> c.requestLatestTetheringEntitlementResult( 1034 type, receiver, showEntitlementUi, callerPkg, getAttributionTag())); 1035 } 1036 1037 /** 1038 * Callback for use with {@link registerTetheringEventCallback} to find out tethering 1039 * upstream status. 1040 */ 1041 public interface TetheringEventCallback { 1042 /** 1043 * Called when tethering supported status changed. 1044 * 1045 * <p>This callback will be called immediately after the callback is 1046 * registered, and never be called if there is changes afterward. 1047 * 1048 * <p>Tethering may be disabled via system properties, device configuration, or device 1049 * policy restrictions. 1050 * 1051 * @param supported whether any tethering type is supported. 1052 */ 1053 default void onTetheringSupported(boolean supported) {} 1054 1055 /** 1056 * Called when tethering supported status changed. 1057 * 1058 * <p>This will be called immediately after the callback is registered, and may be called 1059 * multiple times later upon changes. 1060 * 1061 * <p>Tethering may be disabled via system properties, device configuration, or device 1062 * policy restrictions. 1063 * 1064 * @param supportedTypes a set of @TetheringType which is supported. 1065 * @hide 1066 */ 1067 default void onSupportedTetheringTypes(@NonNull Set<Integer> supportedTypes) {} 1068 1069 /** 1070 * Called when tethering upstream changed. 1071 * 1072 * <p>This will be called immediately after the callback is registered, and may be called 1073 * multiple times later upon changes. 1074 * 1075 * @param network the {@link Network} of tethering upstream. Null means tethering doesn't 1076 * have any upstream. 1077 */ 1078 default void onUpstreamChanged(@Nullable Network network) {} 1079 1080 /** 1081 * Called when there was a change in tethering interface regular expressions. 1082 * 1083 * <p>This will be called immediately after the callback is registered, and may be called 1084 * multiple times later upon changes. 1085 * @param reg The new regular expressions. 1086 * 1087 * @deprecated New clients should use the callbacks with {@link TetheringInterface} which 1088 * has the mapping between tethering type and interface. InterfaceRegex is no longer needed 1089 * to determine the mapping of tethering type and interface. 1090 * 1091 * @hide 1092 */ 1093 @Deprecated 1094 @SystemApi(client = MODULE_LIBRARIES) 1095 default void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {} 1096 1097 /** 1098 * Called when there was a change in the list of tetherable interfaces. Tetherable 1099 * interface means this interface is available and can be used for tethering. 1100 * 1101 * <p>This will be called immediately after the callback is registered, and may be called 1102 * multiple times later upon changes. 1103 * @param interfaces The list of tetherable interface names. 1104 */ 1105 default void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {} 1106 1107 /** 1108 * Called when there was a change in the list of tetherable interfaces. Tetherable 1109 * interface means this interface is available and can be used for tethering. 1110 * 1111 * <p>This will be called immediately after the callback is registered, and may be called 1112 * multiple times later upon changes. 1113 * @param interfaces The set of TetheringInterface of currently tetherable interface. 1114 */ 1115 default void onTetherableInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1116 // By default, the new callback calls the old callback, so apps 1117 // implementing the old callback just work. 1118 onTetherableInterfacesChanged(toIfaces(interfaces)); 1119 } 1120 1121 /** 1122 * Called when there was a change in the list of tethered interfaces. 1123 * 1124 * <p>This will be called immediately after the callback is registered, and may be called 1125 * multiple times later upon changes. 1126 * @param interfaces The lit of 0 or more String of currently tethered interface names. 1127 */ 1128 default void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {} 1129 1130 /** 1131 * Called when there was a change in the list of tethered interfaces. 1132 * 1133 * <p>This will be called immediately after the callback is registered, and may be called 1134 * multiple times later upon changes. 1135 * @param interfaces The set of 0 or more TetheringInterface of currently tethered 1136 * interface. 1137 */ 1138 default void onTetheredInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1139 // By default, the new callback calls the old callback, so apps 1140 // implementing the old callback just work. 1141 onTetheredInterfacesChanged(toIfaces(interfaces)); 1142 } 1143 1144 /** 1145 * Called when there was a change in the list of local-only interfaces. 1146 * 1147 * <p>This will be called immediately after the callback is registered, and may be called 1148 * multiple times later upon changes. 1149 * @param interfaces The list of 0 or more String of active local-only interface names. 1150 */ 1151 default void onLocalOnlyInterfacesChanged(@NonNull List<String> interfaces) {} 1152 1153 /** 1154 * Called when there was a change in the list of local-only interfaces. 1155 * 1156 * <p>This will be called immediately after the callback is registered, and may be called 1157 * multiple times later upon changes. 1158 * @param interfaces The set of 0 or more TetheringInterface of active local-only 1159 * interface. 1160 */ 1161 default void onLocalOnlyInterfacesChanged(@NonNull Set<TetheringInterface> interfaces) { 1162 // By default, the new callback calls the old callback, so apps 1163 // implementing the old callback just work. 1164 onLocalOnlyInterfacesChanged(toIfaces(interfaces)); 1165 } 1166 1167 /** 1168 * Called when an error occurred configuring tethering. 1169 * 1170 * <p>This will be called immediately after the callback is registered if the latest status 1171 * on the interface is an error, and may be called multiple times later upon changes. 1172 * @param ifName Name of the interface. 1173 * @param error One of {@code TetheringManager#TETHER_ERROR_*}. 1174 */ 1175 default void onError(@NonNull String ifName, @TetheringIfaceError int error) {} 1176 1177 /** 1178 * Called when an error occurred configuring tethering. 1179 * 1180 * <p>This will be called immediately after the callback is registered if the latest status 1181 * on the interface is an error, and may be called multiple times later upon changes. 1182 * @param iface The interface that experienced the error. 1183 * @param error One of {@code TetheringManager#TETHER_ERROR_*}. 1184 */ 1185 default void onError(@NonNull TetheringInterface iface, @TetheringIfaceError int error) { 1186 // By default, the new callback calls the old callback, so apps 1187 // implementing the old callback just work. 1188 onError(iface.getInterface(), error); 1189 } 1190 1191 /** 1192 * Called when the list of tethered clients changes. 1193 * 1194 * <p>This callback provides best-effort information on connected clients based on state 1195 * known to the system, however the list cannot be completely accurate (and should not be 1196 * used for security purposes). For example, clients behind a bridge and using static IP 1197 * assignments are not visible to the tethering device; or even when using DHCP, such 1198 * clients may still be reported by this callback after disconnection as the system cannot 1199 * determine if they are still connected. 1200 * @param clients The new set of tethered clients; the collection is not ordered. 1201 */ 1202 default void onClientsChanged(@NonNull Collection<TetheredClient> clients) {} 1203 1204 /** 1205 * Called when tethering offload status changes. 1206 * 1207 * <p>This will be called immediately after the callback is registered. 1208 * @param status The offload status. 1209 */ 1210 default void onOffloadStatusChanged(@TetherOffloadStatus int status) {} 1211 } 1212 1213 /** 1214 * Covert DownStreamInterface collection to interface String array list. Internal use only. 1215 * 1216 * @hide 1217 */ 1218 public static ArrayList<String> toIfaces(Collection<TetheringInterface> tetherIfaces) { 1219 final ArrayList<String> ifaces = new ArrayList<>(); 1220 for (TetheringInterface tether : tetherIfaces) { 1221 ifaces.add(tether.getInterface()); 1222 } 1223 1224 return ifaces; 1225 } 1226 1227 private static String[] toIfaces(TetheringInterface[] tetherIfaces) { 1228 final String[] ifaces = new String[tetherIfaces.length]; 1229 for (int i = 0; i < tetherIfaces.length; i++) { 1230 ifaces[i] = tetherIfaces[i].getInterface(); 1231 } 1232 1233 return ifaces; 1234 } 1235 1236 1237 /** 1238 * Regular expressions used to identify tethering interfaces. 1239 * 1240 * @deprecated Instead of using regex to determine tethering type. New client could use the 1241 * callbacks with {@link TetheringInterface} which has the mapping of type and interface. 1242 * @hide 1243 */ 1244 @Deprecated 1245 @SystemApi(client = MODULE_LIBRARIES) 1246 public static class TetheringInterfaceRegexps { 1247 private final String[] mTetherableBluetoothRegexs; 1248 private final String[] mTetherableUsbRegexs; 1249 private final String[] mTetherableWifiRegexs; 1250 1251 /** @hide */ 1252 public TetheringInterfaceRegexps(@NonNull String[] tetherableBluetoothRegexs, 1253 @NonNull String[] tetherableUsbRegexs, @NonNull String[] tetherableWifiRegexs) { 1254 mTetherableBluetoothRegexs = tetherableBluetoothRegexs.clone(); 1255 mTetherableUsbRegexs = tetherableUsbRegexs.clone(); 1256 mTetherableWifiRegexs = tetherableWifiRegexs.clone(); 1257 } 1258 1259 @NonNull 1260 public List<String> getTetherableBluetoothRegexs() { 1261 return Collections.unmodifiableList(Arrays.asList(mTetherableBluetoothRegexs)); 1262 } 1263 1264 @NonNull 1265 public List<String> getTetherableUsbRegexs() { 1266 return Collections.unmodifiableList(Arrays.asList(mTetherableUsbRegexs)); 1267 } 1268 1269 @NonNull 1270 public List<String> getTetherableWifiRegexs() { 1271 return Collections.unmodifiableList(Arrays.asList(mTetherableWifiRegexs)); 1272 } 1273 1274 @Override 1275 public int hashCode() { 1276 return Objects.hash(mTetherableBluetoothRegexs, mTetherableUsbRegexs, 1277 mTetherableWifiRegexs); 1278 } 1279 1280 @Override 1281 public boolean equals(@Nullable Object obj) { 1282 if (!(obj instanceof TetheringInterfaceRegexps)) return false; 1283 final TetheringInterfaceRegexps other = (TetheringInterfaceRegexps) obj; 1284 return Arrays.equals(mTetherableBluetoothRegexs, other.mTetherableBluetoothRegexs) 1285 && Arrays.equals(mTetherableUsbRegexs, other.mTetherableUsbRegexs) 1286 && Arrays.equals(mTetherableWifiRegexs, other.mTetherableWifiRegexs); 1287 } 1288 } 1289 1290 /** 1291 * Start listening to tethering change events. Any new added callback will receive the last 1292 * tethering status right away. If callback is registered, 1293 * {@link TetheringEventCallback#onUpstreamChanged} will immediately be called. If tethering 1294 * has no upstream or disabled, the argument of callback will be null. The same callback object 1295 * cannot be registered twice. 1296 * 1297 * @param executor the executor on which callback will be invoked. 1298 * @param callback the callback to be called when tethering has change events. 1299 */ 1300 @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE) 1301 public void registerTetheringEventCallback(@NonNull Executor executor, 1302 @NonNull TetheringEventCallback callback) { 1303 final String callerPkg = mContext.getOpPackageName(); 1304 Log.i(TAG, "registerTetheringEventCallback caller:" + callerPkg); 1305 1306 synchronized (mTetheringEventCallbacks) { 1307 if (mTetheringEventCallbacks.containsKey(callback)) { 1308 throw new IllegalArgumentException("callback was already registered."); 1309 } 1310 final ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() { 1311 // Only accessed with a lock on this object 1312 private final HashMap<TetheringInterface, Integer> mErrorStates = new HashMap<>(); 1313 private TetheringInterface[] mLastTetherableInterfaces = null; 1314 private TetheringInterface[] mLastTetheredInterfaces = null; 1315 private TetheringInterface[] mLastLocalOnlyInterfaces = null; 1316 1317 @Override 1318 public void onUpstreamChanged(Network network) throws RemoteException { 1319 executor.execute(() -> { 1320 callback.onUpstreamChanged(network); 1321 }); 1322 } 1323 1324 private synchronized void sendErrorCallbacks(final TetherStatesParcel newStates) { 1325 for (int i = 0; i < newStates.erroredIfaceList.length; i++) { 1326 final TetheringInterface tetherIface = newStates.erroredIfaceList[i]; 1327 final Integer lastError = mErrorStates.get(tetherIface); 1328 final int newError = newStates.lastErrorList[i]; 1329 if (newError != TETHER_ERROR_NO_ERROR 1330 && !Objects.equals(lastError, newError)) { 1331 callback.onError(tetherIface, newError); 1332 } 1333 mErrorStates.put(tetherIface, newError); 1334 } 1335 } 1336 1337 private synchronized void maybeSendTetherableIfacesChangedCallback( 1338 final TetherStatesParcel newStates) { 1339 if (Arrays.equals(mLastTetherableInterfaces, newStates.availableList)) return; 1340 mLastTetherableInterfaces = newStates.availableList.clone(); 1341 callback.onTetherableInterfacesChanged( 1342 Collections.unmodifiableSet((new ArraySet(mLastTetherableInterfaces)))); 1343 } 1344 1345 private synchronized void maybeSendTetheredIfacesChangedCallback( 1346 final TetherStatesParcel newStates) { 1347 if (Arrays.equals(mLastTetheredInterfaces, newStates.tetheredList)) return; 1348 mLastTetheredInterfaces = newStates.tetheredList.clone(); 1349 callback.onTetheredInterfacesChanged( 1350 Collections.unmodifiableSet((new ArraySet(mLastTetheredInterfaces)))); 1351 } 1352 1353 private synchronized void maybeSendLocalOnlyIfacesChangedCallback( 1354 final TetherStatesParcel newStates) { 1355 if (Arrays.equals(mLastLocalOnlyInterfaces, newStates.localOnlyList)) return; 1356 mLastLocalOnlyInterfaces = newStates.localOnlyList.clone(); 1357 callback.onLocalOnlyInterfacesChanged( 1358 Collections.unmodifiableSet((new ArraySet(mLastLocalOnlyInterfaces)))); 1359 } 1360 1361 // Called immediately after the callbacks are registered. 1362 @Override 1363 public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { 1364 executor.execute(() -> { 1365 callback.onSupportedTetheringTypes(unpackBits(parcel.supportedTypes)); 1366 callback.onTetheringSupported(parcel.supportedTypes != 0); 1367 callback.onUpstreamChanged(parcel.upstreamNetwork); 1368 sendErrorCallbacks(parcel.states); 1369 sendRegexpsChanged(parcel.config); 1370 maybeSendTetherableIfacesChangedCallback(parcel.states); 1371 maybeSendTetheredIfacesChangedCallback(parcel.states); 1372 maybeSendLocalOnlyIfacesChangedCallback(parcel.states); 1373 callback.onClientsChanged(parcel.tetheredClients); 1374 callback.onOffloadStatusChanged(parcel.offloadStatus); 1375 }); 1376 } 1377 1378 @Override 1379 public void onCallbackStopped(int errorCode) { 1380 executor.execute(() -> { 1381 throwIfPermissionFailure(errorCode); 1382 }); 1383 } 1384 1385 @Override 1386 public void onSupportedTetheringTypes(long supportedBitmap) { 1387 executor.execute(() -> { 1388 callback.onSupportedTetheringTypes(unpackBits(supportedBitmap)); 1389 }); 1390 } 1391 1392 private void sendRegexpsChanged(TetheringConfigurationParcel parcel) { 1393 callback.onTetherableInterfaceRegexpsChanged(new TetheringInterfaceRegexps( 1394 parcel.tetherableBluetoothRegexs, 1395 parcel.tetherableUsbRegexs, 1396 parcel.tetherableWifiRegexs)); 1397 } 1398 1399 @Override 1400 public void onConfigurationChanged(TetheringConfigurationParcel config) { 1401 executor.execute(() -> sendRegexpsChanged(config)); 1402 } 1403 1404 @Override 1405 public void onTetherStatesChanged(TetherStatesParcel states) { 1406 executor.execute(() -> { 1407 sendErrorCallbacks(states); 1408 maybeSendTetherableIfacesChangedCallback(states); 1409 maybeSendTetheredIfacesChangedCallback(states); 1410 maybeSendLocalOnlyIfacesChangedCallback(states); 1411 }); 1412 } 1413 1414 @Override 1415 public void onTetherClientsChanged(final List<TetheredClient> clients) { 1416 executor.execute(() -> callback.onClientsChanged(clients)); 1417 } 1418 1419 @Override 1420 public void onOffloadStatusChanged(final int status) { 1421 executor.execute(() -> callback.onOffloadStatusChanged(status)); 1422 } 1423 }; 1424 getConnector(c -> c.registerTetheringEventCallback(remoteCallback, callerPkg)); 1425 mTetheringEventCallbacks.put(callback, remoteCallback); 1426 } 1427 } 1428 1429 /** 1430 * Unpack bitmap to a set of bit position intergers. 1431 * @hide 1432 */ 1433 public static ArraySet<Integer> unpackBits(long val) { 1434 final ArraySet<Integer> result = new ArraySet<>(Long.bitCount(val)); 1435 int bitPos = 0; 1436 while (val != 0) { 1437 if ((val & 1) == 1) result.add(bitPos); 1438 1439 val = val >>> 1; 1440 bitPos++; 1441 } 1442 1443 return result; 1444 } 1445 1446 /** 1447 * Remove tethering event callback previously registered with 1448 * {@link #registerTetheringEventCallback}. 1449 * 1450 * @param callback previously registered callback. 1451 */ 1452 @RequiresPermission(anyOf = { 1453 Manifest.permission.TETHER_PRIVILEGED, 1454 Manifest.permission.ACCESS_NETWORK_STATE 1455 }) 1456 public void unregisterTetheringEventCallback(@NonNull final TetheringEventCallback callback) { 1457 final String callerPkg = mContext.getOpPackageName(); 1458 Log.i(TAG, "unregisterTetheringEventCallback caller:" + callerPkg); 1459 1460 synchronized (mTetheringEventCallbacks) { 1461 ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback); 1462 if (remoteCallback == null) { 1463 throw new IllegalArgumentException("callback was not registered."); 1464 } 1465 1466 getConnector(c -> c.unregisterTetheringEventCallback(remoteCallback, callerPkg)); 1467 } 1468 } 1469 1470 /** 1471 * Get a more detailed error code after a Tethering or Untethering 1472 * request asynchronously failed. 1473 * 1474 * @param iface The name of the interface of interest 1475 * @return error The error code of the last error tethering or untethering the named 1476 * interface 1477 * @hide 1478 */ 1479 @SystemApi(client = MODULE_LIBRARIES) 1480 public int getLastTetherError(@NonNull final String iface) { 1481 mCallback.waitForStarted(); 1482 if (mTetherStatesParcel == null) return TETHER_ERROR_NO_ERROR; 1483 1484 int i = 0; 1485 for (TetheringInterface errored : mTetherStatesParcel.erroredIfaceList) { 1486 if (iface.equals(errored.getInterface())) return mTetherStatesParcel.lastErrorList[i]; 1487 1488 i++; 1489 } 1490 return TETHER_ERROR_NO_ERROR; 1491 } 1492 1493 /** 1494 * Get the list of regular expressions that define any tetherable 1495 * USB network interfaces. If USB tethering is not supported by the 1496 * device, this list should be empty. 1497 * 1498 * @return an array of 0 or more regular expression Strings defining 1499 * what interfaces are considered tetherable usb interfaces. 1500 * @hide 1501 */ 1502 @SystemApi(client = MODULE_LIBRARIES) 1503 public @NonNull String[] getTetherableUsbRegexs() { 1504 mCallback.waitForStarted(); 1505 return mTetheringConfiguration.tetherableUsbRegexs; 1506 } 1507 1508 /** 1509 * Get the list of regular expressions that define any tetherable 1510 * Wifi network interfaces. If Wifi tethering is not supported by the 1511 * device, this list should be empty. 1512 * 1513 * @return an array of 0 or more regular expression Strings defining 1514 * what interfaces are considered tetherable wifi interfaces. 1515 * @hide 1516 */ 1517 @SystemApi(client = MODULE_LIBRARIES) 1518 public @NonNull String[] getTetherableWifiRegexs() { 1519 mCallback.waitForStarted(); 1520 return mTetheringConfiguration.tetherableWifiRegexs; 1521 } 1522 1523 /** 1524 * Get the list of regular expressions that define any tetherable 1525 * Bluetooth network interfaces. If Bluetooth tethering is not supported by the 1526 * device, this list should be empty. 1527 * 1528 * @return an array of 0 or more regular expression Strings defining 1529 * what interfaces are considered tetherable bluetooth interfaces. 1530 * @hide 1531 */ 1532 @SystemApi(client = MODULE_LIBRARIES) 1533 public @NonNull String[] getTetherableBluetoothRegexs() { 1534 mCallback.waitForStarted(); 1535 return mTetheringConfiguration.tetherableBluetoothRegexs; 1536 } 1537 1538 /** 1539 * Get the set of tetherable, available interfaces. This list is limited by 1540 * device configuration and current interface existence. 1541 * 1542 * @return an array of 0 or more Strings of tetherable interface names. 1543 * @hide 1544 */ 1545 @SystemApi(client = MODULE_LIBRARIES) 1546 public @NonNull String[] getTetherableIfaces() { 1547 mCallback.waitForStarted(); 1548 if (mTetherStatesParcel == null) return new String[0]; 1549 1550 return toIfaces(mTetherStatesParcel.availableList); 1551 } 1552 1553 /** 1554 * Get the set of tethered interfaces. 1555 * 1556 * @return an array of 0 or more String of currently tethered interface names. 1557 * @hide 1558 */ 1559 @SystemApi(client = MODULE_LIBRARIES) 1560 public @NonNull String[] getTetheredIfaces() { 1561 mCallback.waitForStarted(); 1562 if (mTetherStatesParcel == null) return new String[0]; 1563 1564 return toIfaces(mTetherStatesParcel.tetheredList); 1565 } 1566 1567 /** 1568 * Get the set of interface names which attempted to tether but 1569 * failed. Re-attempting to tether may cause them to reset to the Tethered 1570 * state. Alternatively, causing the interface to be destroyed and recreated 1571 * may cause them to reset to the available state. 1572 * {@link TetheringManager#getLastTetherError} can be used to get more 1573 * information on the cause of the errors. 1574 * 1575 * @return an array of 0 or more String indicating the interface names 1576 * which failed to tether. 1577 * @hide 1578 */ 1579 @SystemApi(client = MODULE_LIBRARIES) 1580 public @NonNull String[] getTetheringErroredIfaces() { 1581 mCallback.waitForStarted(); 1582 if (mTetherStatesParcel == null) return new String[0]; 1583 1584 return toIfaces(mTetherStatesParcel.erroredIfaceList); 1585 } 1586 1587 /** 1588 * Get the set of tethered dhcp ranges. 1589 * 1590 * @deprecated This API just return the default value which is not used in DhcpServer. 1591 * @hide 1592 */ 1593 @Deprecated 1594 public @NonNull String[] getTetheredDhcpRanges() { 1595 mCallback.waitForStarted(); 1596 return mTetheringConfiguration.legacyDhcpRanges; 1597 } 1598 1599 /** 1600 * Check if the device allows for tethering. It may be disabled via 1601 * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or 1602 * due to device configuration. 1603 * 1604 * @return a boolean - {@code true} indicating Tethering is supported. 1605 * @hide 1606 */ 1607 @SystemApi(client = MODULE_LIBRARIES) 1608 public boolean isTetheringSupported() { 1609 final String callerPkg = mContext.getOpPackageName(); 1610 1611 return isTetheringSupported(callerPkg); 1612 } 1613 1614 /** 1615 * Check if the device allows for tethering. It may be disabled via {@code ro.tether.denied} 1616 * system property, Settings.TETHER_SUPPORTED or due to device configuration. This is useful 1617 * for system components that query this API on behalf of an app. In particular, Bluetooth 1618 * has @UnsupportedAppUsage calls that will let apps turn on bluetooth tethering if they have 1619 * the right permissions, but such an app needs to know whether it can (permissions as well 1620 * as support from the device) turn on tethering in the first place to show the appropriate UI. 1621 * 1622 * @param callerPkg The caller package name, if it is not matching the calling uid, 1623 * SecurityException would be thrown. 1624 * @return a boolean - {@code true} indicating Tethering is supported. 1625 * @hide 1626 */ 1627 @SystemApi(client = MODULE_LIBRARIES) 1628 public boolean isTetheringSupported(@NonNull final String callerPkg) { 1629 1630 final RequestDispatcher dispatcher = new RequestDispatcher(); 1631 final int ret = dispatcher.waitForResult((connector, listener) -> { 1632 try { 1633 connector.isTetheringSupported(callerPkg, getAttributionTag(), listener); 1634 } catch (RemoteException e) { 1635 throw new IllegalStateException(e); 1636 } 1637 }); 1638 1639 return ret == TETHER_ERROR_NO_ERROR; 1640 } 1641 1642 /** 1643 * Stop all active tethering. 1644 * 1645 * <p>Without {@link android.Manifest.permission.TETHER_PRIVILEGED} permission, the call will 1646 * fail if a tethering entitlement check is required. 1647 */ 1648 @RequiresPermission(anyOf = { 1649 android.Manifest.permission.TETHER_PRIVILEGED, 1650 android.Manifest.permission.WRITE_SETTINGS 1651 }) 1652 public void stopAllTethering() { 1653 final String callerPkg = mContext.getOpPackageName(); 1654 Log.i(TAG, "stopAllTethering caller:" + callerPkg); 1655 1656 getConnector(c -> c.stopAllTethering(callerPkg, getAttributionTag(), 1657 new IIntResultListener.Stub() { 1658 @Override 1659 public void onResult(int resultCode) { 1660 // TODO: add an API parameter to send result to caller. 1661 // This has never been possible as stopAllTethering has always been void 1662 // and never taken a callback object. The only indication that callers have 1663 // is if the call results in a TETHER_STATE_CHANGE broadcast. 1664 } 1665 })); 1666 } 1667 1668 /** 1669 * Whether to treat networks that have TRANSPORT_TEST as Tethering upstreams. The effects of 1670 * this method apply to any test networks that are already present on the system. 1671 * 1672 * @throws SecurityException If the caller doesn't have the NETWORK_SETTINGS permission. 1673 * @hide 1674 */ 1675 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) 1676 public void setPreferTestNetworks(final boolean prefer) { 1677 Log.i(TAG, "setPreferTestNetworks caller: " + mContext.getOpPackageName()); 1678 1679 final RequestDispatcher dispatcher = new RequestDispatcher(); 1680 final int ret = dispatcher.waitForResult((connector, listener) -> { 1681 try { 1682 connector.setPreferTestNetworks(prefer, listener); 1683 } catch (RemoteException e) { 1684 throw new IllegalStateException(e); 1685 } 1686 }); 1687 } 1688 } 1689