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