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