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