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