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