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