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