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