• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 package com.android.networkstack.tethering;
18 
19 import static android.Manifest.permission.NETWORK_SETTINGS;
20 import static android.Manifest.permission.NETWORK_STACK;
21 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
22 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
23 import static android.hardware.usb.UsbManager.USB_CONNECTED;
24 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
25 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
26 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
27 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
28 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
29 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
30 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
31 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
32 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
33 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
34 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
35 import static android.net.TetheringManager.EXTRA_ERRORED_TETHER;
36 import static android.net.TetheringManager.TETHERING_BLUETOOTH;
37 import static android.net.TetheringManager.TETHERING_ETHERNET;
38 import static android.net.TetheringManager.TETHERING_INVALID;
39 import static android.net.TetheringManager.TETHERING_NCM;
40 import static android.net.TetheringManager.TETHERING_USB;
41 import static android.net.TetheringManager.TETHERING_VIRTUAL;
42 import static android.net.TetheringManager.TETHERING_WIFI;
43 import static android.net.TetheringManager.TETHERING_WIFI_P2P;
44 import static android.net.TetheringManager.TETHERING_WIGIG;
45 import static android.net.TetheringManager.TETHER_ERROR_BLUETOOTH_SERVICE_PENDING;
46 import static android.net.TetheringManager.TETHER_ERROR_DUPLICATE_REQUEST;
47 import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
48 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
49 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
50 import static android.net.TetheringManager.TETHER_ERROR_SOFT_AP_CALLBACK_PENDING;
51 import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
52 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
53 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
54 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
55 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
56 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
57 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
58 import static android.net.TetheringManager.TetheringRequest.REQUEST_TYPE_PLACEHOLDER;
59 import static android.net.TetheringManager.toIfaces;
60 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
61 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
62 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
63 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
64 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
65 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
66 import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
67 import static android.net.wifi.WifiManager.SoftApCallback;
68 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
69 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
70 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
71 
72 import static com.android.networkstack.tethering.RequestTracker.AddResult.FAILURE_DUPLICATE_REQUEST_ERROR;
73 import static com.android.networkstack.tethering.RequestTracker.AddResult.FAILURE_DUPLICATE_REQUEST_RESTART;
74 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS;
75 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
76 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.isCellular;
77 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED;
78 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI;
79 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P;
80 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS;
81 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS;
82 import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WITH_PLACEHOLDER_REQUEST;
83 import static com.android.networkstack.tethering.util.TetheringMessageBase.BASE_MAIN_SM;
84 import static com.android.networkstack.tethering.util.TetheringUtils.createImplicitLocalOnlyTetheringRequest;
85 import static com.android.networkstack.tethering.util.TetheringUtils.createLegacyGlobalScopeTetheringRequest;
86 import static com.android.networkstack.tethering.util.TetheringUtils.createPlaceholderRequest;
87 
88 import android.app.usage.NetworkStatsManager;
89 import android.bluetooth.BluetoothAdapter;
90 import android.bluetooth.BluetoothPan;
91 import android.bluetooth.BluetoothProfile;
92 import android.bluetooth.BluetoothProfile.ServiceListener;
93 import android.content.BroadcastReceiver;
94 import android.content.Context;
95 import android.content.Intent;
96 import android.content.IntentFilter;
97 import android.content.pm.PackageManager;
98 import android.database.ContentObserver;
99 import android.hardware.usb.UsbManager;
100 import android.net.ConnectivityManager;
101 import android.net.EthernetManager;
102 import android.net.IIntResultListener;
103 import android.net.INetd;
104 import android.net.ITetheringEventCallback;
105 import android.net.IpPrefix;
106 import android.net.LinkAddress;
107 import android.net.LinkProperties;
108 import android.net.Network;
109 import android.net.NetworkInfo;
110 import android.net.TetherStatesParcel;
111 import android.net.TetheredClient;
112 import android.net.TetheringCallbackStartedParcel;
113 import android.net.TetheringConfigurationParcel;
114 import android.net.TetheringInterface;
115 import android.net.TetheringManager.TetheringRequest;
116 import android.net.Uri;
117 import android.net.ip.IpServer;
118 import android.net.wifi.SoftApState;
119 import android.net.wifi.WifiClient;
120 import android.net.wifi.WifiManager;
121 import android.net.wifi.p2p.WifiP2pGroup;
122 import android.net.wifi.p2p.WifiP2pInfo;
123 import android.net.wifi.p2p.WifiP2pManager;
124 import android.os.Binder;
125 import android.os.Bundle;
126 import android.os.Handler;
127 import android.os.Looper;
128 import android.os.Message;
129 import android.os.Process;
130 import android.os.RemoteCallbackList;
131 import android.os.RemoteException;
132 import android.os.ResultReceiver;
133 import android.os.ServiceSpecificException;
134 import android.os.UserHandle;
135 import android.os.UserManager;
136 import android.provider.Settings;
137 import android.telephony.PhoneStateListener;
138 import android.telephony.TelephonyManager;
139 import android.text.TextUtils;
140 import android.util.ArrayMap;
141 import android.util.Log;
142 import android.util.SparseArray;
143 
144 import androidx.annotation.NonNull;
145 import androidx.annotation.Nullable;
146 
147 import com.android.internal.annotations.VisibleForTesting;
148 import com.android.internal.util.IndentingPrintWriter;
149 import com.android.internal.util.MessageUtils;
150 import com.android.internal.util.State;
151 import com.android.internal.util.StateMachine;
152 import com.android.modules.utils.build.SdkLevel;
153 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
154 import com.android.net.module.util.CollectionUtils;
155 import com.android.net.module.util.HandlerUtils;
156 import com.android.net.module.util.NetdUtils;
157 import com.android.net.module.util.RoutingCoordinatorManager;
158 import com.android.net.module.util.SharedLog;
159 import com.android.net.module.util.TerribleErrorLog;
160 import com.android.networkstack.apishim.common.BluetoothPanShim;
161 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
162 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
163 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
164 import com.android.networkstack.tethering.metrics.TetheringMetrics;
165 import com.android.networkstack.tethering.metrics.TetheringStatsLog;
166 import com.android.networkstack.tethering.util.InterfaceSet;
167 import com.android.networkstack.tethering.util.PrefixUtils;
168 import com.android.networkstack.tethering.util.VersionedBroadcastListener;
169 import com.android.networkstack.tethering.wear.WearableConnectionManager;
170 
171 import java.io.FileDescriptor;
172 import java.io.PrintWriter;
173 import java.net.InetAddress;
174 import java.util.ArrayList;
175 import java.util.Arrays;
176 import java.util.Collection;
177 import java.util.Collections;
178 import java.util.HashSet;
179 import java.util.List;
180 import java.util.Objects;
181 import java.util.Set;
182 import java.util.concurrent.Executor;
183 import java.util.concurrent.RejectedExecutionException;
184 
185 /**
186  *
187  * This class holds much of the business logic to allow Android devices
188  * to act as IP gateways via USB, BT, and WiFi interfaces.
189  */
190 public class Tethering {
191 
192     private static final String TAG = Tethering.class.getSimpleName();
193     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
194     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
195 
196     private static final Class[] sMessageClasses = {
197             Tethering.class, TetherMainSM.class, IpServer.class
198     };
199     private static final SparseArray<String> sMagicDecoderRing =
200             MessageUtils.findMessageNames(sMessageClasses);
201 
202     private static final int DUMP_TIMEOUT_MS = 10_000;
203 
204     // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
205     private static final int NETID_UNSET = 0;
206 
207     private static class TetherState {
208         public final IpServer ipServer;
209         public int lastState;
210         public int lastError;
211         // This field only valid for TETHERING_USB and TETHERING_NCM.
212         // TODO: Change this from boolean to int for extension.
213         public final boolean isNcm;
214 
TetherState(IpServer ipServer, boolean isNcm)215         TetherState(IpServer ipServer, boolean isNcm) {
216             this.ipServer = ipServer;
217             // Assume all state machines start out available and with no errors.
218             lastState = IpServer.STATE_AVAILABLE;
219             lastError = TETHER_ERROR_NO_ERROR;
220             this.isNcm = isNcm;
221         }
222 
isCurrentlyServing()223         public boolean isCurrentlyServing() {
224             switch (lastState) {
225                 case IpServer.STATE_TETHERED:
226                 case IpServer.STATE_LOCAL_ONLY:
227                     return true;
228                 default:
229                     return false;
230             }
231         }
232     }
233 
234     /**
235      * Cookie added when registering {@link android.net.TetheringManager.TetheringEventCallback}.
236      */
237     private static class CallbackCookie {
238         public final int uid;
239         public final boolean hasSystemPrivilege;
240 
CallbackCookie(int uid, boolean hasSystemPrivilege)241         private CallbackCookie(int uid, boolean hasSystemPrivilege) {
242             this.uid = uid;
243             this.hasSystemPrivilege = hasSystemPrivilege;
244         }
245     }
246 
247     private final SharedLog mLog = new SharedLog(TAG);
248     private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
249             new RemoteCallbackList<>();
250     private final RequestTracker mRequestTracker;
251 
252     private final Context mContext;
253     private final ArrayMap<String, TetherState> mTetherStates;
254     private final BroadcastReceiver mStateReceiver;
255     private final Looper mLooper;
256     private final TetherMainSM mTetherMainSM;
257     private final OffloadController mOffloadController;
258     private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
259     private final VersionedBroadcastListener mCarrierConfigChange;
260     private final TetheringDependencies mDeps;
261     private final EntitlementManager mEntitlementMgr;
262     private final Handler mHandler;
263     private final INetd mNetd;
264     private final NetdCallback mNetdCallback;
265     private final RoutingCoordinatorManager mRoutingCoordinator;
266     private final UserRestrictionActionListener mTetheringRestriction;
267     private final ActiveDataSubIdListener mActiveDataSubIdListener;
268     private final ConnectedClientsTracker mConnectedClientsTracker;
269     private final TetheringThreadExecutor mExecutor;
270     private final TetheringNotificationUpdater mNotificationUpdater;
271     private final UserManager mUserManager;
272     private final BpfCoordinator mBpfCoordinator;
273     private final TetheringMetrics mTetheringMetrics;
274     private final WearableConnectionManager mWearableConnectionManager;
275     private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
276 
277     private volatile TetheringConfiguration mConfig;
278     private InterfaceSet mCurrentUpstreamIfaceSet;
279 
280     private boolean mRndisEnabled;       // track the RNDIS function enabled state
281     private boolean mNcmEnabled;         // track the NCM function enabled state
282     private Network mTetherUpstream;
283     private boolean mDataSaverEnabled = false;
284     private String mWifiP2pTetherInterface = null;
285     private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED;
286 
287     private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest;
288     private TetheredInterfaceRequestShim mBluetoothIfaceRequest;
289     private String mConfiguredEthernetIface;
290     private String mConfiguredBluetoothIface;
291     private String mConfiguredVirtualIface;
292     private EthernetCallback mEthernetCallback;
293     private TetheredInterfaceCallbackShim mBluetoothCallback;
294     private SettingsObserver mSettingsObserver;
295     private BluetoothPan mBluetoothPan;
296     private PanServiceListener mBluetoothPanListener;
297     // Pending listener for starting Bluetooth tethering before the PAN service is connected. Once
298     // the service is connected, the bluetooth iface will be requested and the listener will be
299     // called.
300     private IIntResultListener mPendingPanRequestListener;
301     // AIDL doesn't support Set<Integer>. Maintain a int bitmap here. When the bitmap is passed to
302     // TetheringManager, TetheringManager would convert it to a set of Integer types.
303     // mSupportedTypeBitmap should always be updated inside tethering internal thread but it may be
304     // read from binder thread which called TetheringService directly.
305     private volatile long mSupportedTypeBitmap;
306 
Tethering(TetheringDependencies deps)307     public Tethering(TetheringDependencies deps) {
308         mLog.mark("Tethering.constructed");
309         mDeps = deps;
310         mContext = mDeps.getContext();
311         mNetd = mDeps.getINetd(mContext, mLog);
312         mRoutingCoordinator = mDeps.getRoutingCoordinator(mContext, mLog);
313         mLooper = mDeps.makeTetheringLooper();
314         mNotificationUpdater = mDeps.makeNotificationUpdater(mContext, mLooper);
315         mTetheringMetrics = mDeps.makeTetheringMetrics(mContext);
316         mRequestTracker = new RequestTracker(isTetheringWithSoftApConfigEnabled());
317 
318         mTetherStates = new ArrayMap<>();
319         mConnectedClientsTracker = new ConnectedClientsTracker();
320 
321         mTetherMainSM = new TetherMainSM("TetherMain", mLooper, deps);
322         mTetherMainSM.start();
323 
324         mHandler = mTetherMainSM.getHandler();
325         mOffloadController = mDeps.makeOffloadController(mHandler, mLog,
326                 new OffloadController.Dependencies() {
327 
328                     @Override
329                     public TetheringConfiguration getTetherConfig() {
330                         return mConfig;
331                     }
332                 });
333         mUpstreamNetworkMonitor = mDeps.makeUpstreamNetworkMonitor(mContext, mHandler, mLog,
334                 (what, obj) -> {
335                     mTetherMainSM.sendMessage(TetherMainSM.EVENT_UPSTREAM_CALLBACK, what, 0, obj);
336                 });
337 
338         IntentFilter filter = new IntentFilter();
339         filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
340         // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
341         // permission is changed according to entitlement check result.
342         mEntitlementMgr = mDeps.makeEntitlementManager(mContext, mHandler, mLog,
343                 () -> mTetherMainSM.sendMessage(
344                 TetherMainSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
345         mEntitlementMgr.setOnTetherProvisioningFailedListener((downstream, reason) -> {
346             mLog.log("OBSERVED OnTetherProvisioningFailed : " + reason);
347             stopTethering(downstream);
348         });
349         mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
350             return mConfig;
351         });
352 
353         mCarrierConfigChange = new VersionedBroadcastListener(
354                 "CarrierConfigChangeListener", mContext, mHandler, filter,
355                 (Intent ignored) -> {
356                     mLog.log("OBSERVED carrier config change");
357                     updateConfiguration();
358                     mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
359                 });
360 
361         mSettingsObserver = new SettingsObserver(mContext, mHandler);
362         mSettingsObserver.startObserve();
363 
364         mStateReceiver = new StateReceiver();
365 
366         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
367         mTetheringRestriction = new UserRestrictionActionListener(
368                 mUserManager, this, mNotificationUpdater);
369         mExecutor = new TetheringThreadExecutor(mHandler);
370         mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
371         mNetdCallback = new NetdCallback();
372 
373         // Load tethering configuration.
374         updateConfiguration();
375         mConfig.readEnableSyncSM(mContext);
376 
377         // Must be initialized after tethering configuration is loaded because BpfCoordinator
378         // constructor needs to use the configuration.
379         mBpfCoordinator = mDeps.makeBpfCoordinator(
380                 new BpfCoordinator.Dependencies() {
381                     @NonNull
382                     public Handler getHandler() {
383                         return mHandler;
384                     }
385 
386                     @NonNull
387                     public Context getContext() {
388                         return mContext;
389                     }
390 
391                     @NonNull
392                     public INetd getNetd() {
393                         return mNetd;
394                     }
395 
396                     @NonNull
397                     public NetworkStatsManager getNetworkStatsManager() {
398                         return mContext.getSystemService(NetworkStatsManager.class);
399                     }
400 
401                     @NonNull
402                     public SharedLog getSharedLog() {
403                         return mLog;
404                     }
405 
406                     @Nullable
407                     public TetheringConfiguration getTetherConfig() {
408                         return mConfig;
409                     }
410                 });
411 
412         if (SdkLevel.isAtLeastT() && mConfig.isWearTetheringEnabled()) {
413             mWearableConnectionManager = mDeps.makeWearableConnectionManager(mContext);
414         } else {
415             mWearableConnectionManager = null;
416         }
417 
418         startStateMachineUpdaters();
419     }
420 
421     private class SettingsObserver extends ContentObserver {
422         private final Uri mForceUsbFunctions;
423         private final Uri mTetherSupported;
424         private final Context mContext;
425 
SettingsObserver(Context ctx, Handler handler)426         SettingsObserver(Context ctx, Handler handler) {
427             super(handler);
428             mContext = ctx;
429             mForceUsbFunctions = Settings.Global.getUriFor(TETHER_FORCE_USB_FUNCTIONS);
430             mTetherSupported = Settings.Global.getUriFor(Settings.Global.TETHER_SUPPORTED);
431         }
432 
startObserve()433         public void startObserve() {
434             mContext.getContentResolver().registerContentObserver(mForceUsbFunctions, false, this);
435             mContext.getContentResolver().registerContentObserver(mTetherSupported, false, this);
436         }
437 
438         @Override
onChange(boolean selfChange)439         public void onChange(boolean selfChange) {
440             Log.wtf(TAG, "Should never be reached.");
441         }
442 
443         @Override
onChange(boolean selfChange, Uri uri)444         public void onChange(boolean selfChange, Uri uri) {
445             if (mForceUsbFunctions.equals(uri)) {
446                 mLog.i("OBSERVED TETHER_FORCE_USB_FUNCTIONS settings change");
447                 final boolean isUsingNcm = mConfig.isUsingNcm();
448                 updateConfiguration();
449                 if (isUsingNcm != mConfig.isUsingNcm()) {
450                     stopTetheringInternal(TETHERING_USB);
451                     stopTetheringInternal(TETHERING_NCM);
452                 }
453             } else if (mTetherSupported.equals(uri)) {
454                 mLog.i("OBSERVED TETHER_SUPPORTED settings change");
455                 updateSupportedDownstreams(mConfig);
456             } else {
457                 mLog.e("Unexpected settings change: " + uri);
458             }
459         }
460     }
461 
462     @VisibleForTesting
getSettingsObserverForTest()463     ContentObserver getSettingsObserverForTest() {
464         return mSettingsObserver;
465     }
466 
isTetheringWithSoftApConfigEnabled()467     boolean isTetheringWithSoftApConfigEnabled() {
468         return mDeps.isTetheringWithSoftApConfigEnabled();
469     }
470 
471     /**
472      * Start to register callbacks.
473      * Call this function when tethering is ready to handle callback events.
474      */
startStateMachineUpdaters()475     private void startStateMachineUpdaters() {
476         try {
477             mNetd.registerUnsolicitedEventListener(mNetdCallback);
478         } catch (RemoteException e) {
479             mLog.e("Unable to register netd UnsolicitedEventListener");
480         }
481         mCarrierConfigChange.startListening();
482         mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
483                 PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
484 
485         IntentFilter filter = new IntentFilter();
486         filter.addAction(UsbManager.ACTION_USB_STATE);
487         filter.addAction(CONNECTIVITY_ACTION);
488         filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
489         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
490         filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
491         filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
492         filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
493         mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
494 
495         final IntentFilter noUpstreamFilter = new IntentFilter();
496         noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING);
497         mContext.registerReceiver(
498                 mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler);
499 
500         final WifiManager wifiManager = getWifiManager();
501         if (wifiManager != null) {
502             wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
503             if (SdkLevel.isAtLeastT()) {
504                 // Although WifiManager#registerLocalOnlyHotspotSoftApCallback document that it need
505                 // NEARBY_WIFI_DEVICES permission, but actually a caller who have NETWORK_STACK
506                 // or MAINLINE_NETWORK_STACK permission can also use this API.
507                 wifiManager.registerLocalOnlyHotspotSoftApCallback(mExecutor,
508                         new LocalOnlyHotspotCallback());
509             }
510         }
511 
512         startTrackDefaultNetwork();
513     }
514 
515     private class TetheringThreadExecutor implements Executor {
516         private final Handler mTetherHandler;
TetheringThreadExecutor(Handler handler)517         TetheringThreadExecutor(Handler handler) {
518             mTetherHandler = handler;
519         }
520         @Override
execute(Runnable command)521         public void execute(Runnable command) {
522             if (!mTetherHandler.post(command)) {
523                 throw new RejectedExecutionException(mTetherHandler + " is shutting down");
524             }
525         }
526     }
527 
528     private class ActiveDataSubIdListener extends PhoneStateListener {
ActiveDataSubIdListener(Executor executor)529         ActiveDataSubIdListener(Executor executor) {
530             super(executor);
531         }
532 
533         @Override
onActiveDataSubscriptionIdChanged(int subId)534         public void onActiveDataSubscriptionIdChanged(int subId) {
535             mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
536                     + " to " + subId);
537             if (subId == mActiveDataSubId) return;
538 
539             mActiveDataSubId = subId;
540             updateConfiguration();
541             mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
542             // To avoid launching unexpected provisioning checks, ignore re-provisioning
543             // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
544             // will be triggered again when CarrierConfig is loaded.
545             if (TetheringConfiguration.getCarrierConfig(mContext, subId) != null) {
546                 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
547             } else {
548                 mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
549             }
550         }
551     }
552 
getWifiManager()553     private WifiManager getWifiManager() {
554         return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
555     }
556 
557     // NOTE: This is always invoked on the mLooper thread.
updateConfiguration()558     private void updateConfiguration() {
559         mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
560         mUpstreamNetworkMonitor.setUpstreamConfig(mConfig.chooseUpstreamAutomatically,
561                 mConfig.isDunRequired);
562         reportConfigurationChanged(mConfig.toStableParcelable());
563 
564         updateSupportedDownstreams(mConfig);
565     }
566 
maybeDunSettingChanged()567     private void maybeDunSettingChanged() {
568         final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
569         if (isDunRequired == mConfig.isDunRequired) return;
570         updateConfiguration();
571     }
572 
573     private class NetdCallback extends BaseNetdUnsolicitedEventListener {
574         @Override
onInterfaceChanged(String ifName, boolean up)575         public void onInterfaceChanged(String ifName, boolean up) {
576             mHandler.post(() -> interfaceStatusChanged(ifName, up));
577         }
578 
579         @Override
onInterfaceLinkStateChanged(String ifName, boolean up)580         public void onInterfaceLinkStateChanged(String ifName, boolean up) {
581             mHandler.post(() -> interfaceLinkStateChanged(ifName, up));
582         }
583 
584         @Override
onInterfaceAdded(String ifName)585         public void onInterfaceAdded(String ifName) {
586             mHandler.post(() -> interfaceAdded(ifName));
587         }
588 
589         @Override
onInterfaceRemoved(String ifName)590         public void onInterfaceRemoved(String ifName) {
591             mHandler.post(() -> interfaceRemoved(ifName));
592         }
593     }
594 
595     private class TetheringSoftApCallback implements SoftApCallback {
596         @Override
onConnectedClientsChanged(final List<WifiClient> clients)597         public void onConnectedClientsChanged(final List<WifiClient> clients) {
598             updateConnectedClients(clients, null);
599         }
600     }
601 
602     private class LocalOnlyHotspotCallback implements SoftApCallback {
603         @Override
onConnectedClientsChanged(final List<WifiClient> clients)604         public void onConnectedClientsChanged(final List<WifiClient> clients) {
605             updateConnectedClients(null, clients);
606         }
607     }
608 
609     // This method needs to exist because TETHERING_BLUETOOTH before Android T and TETHERING_WIGIG
610     // can't use enableIpServing.
processInterfaceStateChange(final String iface, boolean enabled)611     private void processInterfaceStateChange(final String iface, boolean enabled) {
612         final int type = ifaceNameToType(iface);
613         // Do not listen to USB interface state changes or USB interface add/removes. USB tethering
614         // is driven only by USB_ACTION broadcasts.
615         if (type == TETHERING_USB || type == TETHERING_NCM) return;
616 
617         // On T+, BLUETOOTH uses enableIpServing.
618         if (type == TETHERING_BLUETOOTH && SdkLevel.isAtLeastT()) return;
619 
620         // Cannot happen: on S+, tetherableWigigRegexps is always empty.
621         if (type == TETHERING_WIGIG && SdkLevel.isAtLeastS()) return;
622 
623         // After V, disallow this legacy codepath from starting tethering of any type:
624         // everything must call ensureIpServerStarted directly.
625         //
626         // Don't touch the teardown path for now. It's more complicated because:
627         // - ensureIpServerStarted and ensureIpServerStopped act on different
628         //   tethering types.
629         // - Depending on the type, ensureIpServerStopped is either called twice (once
630         //   on interface down and once on interface removed) or just once (on
631         //   interface removed).
632         //
633         // Note that this only affects WIFI and WIFI_P2P. The other types are either
634         // ignored above, or ignored by ensureIpServerStarted. Note that even for WIFI
635         // and WIFI_P2P, this code should not ever run in normal use, because the
636         // hotspot and p2p code do not call tether(). It's possible that this could
637         // happen in the field due to unforeseen OEM modifications. If it does happen,
638         // a terrible error is logged in tether().
639         // TODO: fix the teardown path to stop depending on interface state notifications.
640         // These are not necessary since most/all link layers have their own teardown
641         // notifications, and can race with those notifications.
642         if (enabled && SdkLevel.isAtLeastB()) {
643             return;
644         }
645 
646         if (enabled) {
647             ensureIpServerStartedForInterface(iface);
648         } else {
649             ensureIpServerStopped(iface);
650         }
651     }
652 
interfaceStatusChanged(String iface, boolean up)653     void interfaceStatusChanged(String iface, boolean up) {
654         // Never called directly: only called from interfaceLinkStateChanged.
655         // See NetlinkHandler.cpp: notifyInterfaceChanged.
656         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
657 
658         final int type = ifaceNameToType(iface);
659         if (!up && type != TETHERING_BLUETOOTH && type != TETHERING_WIGIG) {
660             // Ignore usb interface down after enabling RNDIS.
661             // We will handle disconnect in interfaceRemoved.
662             // Similarly, ignore interface down for WiFi.  We monitor WiFi AP status
663             // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
664             if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
665             return;
666         }
667 
668         processInterfaceStateChange(iface, up);
669     }
670 
interfaceLinkStateChanged(String iface, boolean up)671     void interfaceLinkStateChanged(String iface, boolean up) {
672         interfaceStatusChanged(iface, up);
673     }
674 
ifaceNameToType(String iface)675     private int ifaceNameToType(String iface) {
676         final TetheringConfiguration cfg = mConfig;
677 
678         if (cfg.isWifi(iface)) {
679             return TETHERING_WIFI;
680         } else if (cfg.isWigig(iface)) {
681             return TETHERING_WIGIG;
682         } else if (cfg.isWifiP2p(iface)) {
683             return TETHERING_WIFI_P2P;
684         } else if (cfg.isUsb(iface)) {
685             return TETHERING_USB;
686         } else if (cfg.isBluetooth(iface)) {
687             return TETHERING_BLUETOOTH;
688         } else if (cfg.isNcm(iface)) {
689             return TETHERING_NCM;
690         }
691         return TETHERING_INVALID;
692     }
693 
interfaceAdded(String iface)694     void interfaceAdded(String iface) {
695         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
696         processInterfaceStateChange(iface, true /* enabled */);
697     }
698 
interfaceRemoved(String iface)699     void interfaceRemoved(String iface) {
700         if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
701         processInterfaceStateChange(iface, false /* enabled */);
702     }
703 
startTethering(final TetheringRequest request, final String callerPkg, final IIntResultListener listener)704     void startTethering(final TetheringRequest request, final String callerPkg,
705             final IIntResultListener listener) {
706         mHandler.post(() -> {
707             final int type = request.getTetheringType();
708             RequestTracker.AddResult result = mRequestTracker.addPendingRequest(request);
709             // If tethering is already pending with a conflicting request, stop tethering before
710             // starting.
711             if (result == FAILURE_DUPLICATE_REQUEST_RESTART) {
712                 stopTetheringInternal(type); // Also removes the request from the tracker.
713                 mRequestTracker.addPendingRequest(request);
714             } else if (result == FAILURE_DUPLICATE_REQUEST_ERROR) {
715                 // Reject any fuzzy matched request.
716                 // TODO: Add a CTS test to verify back-to-back start/stop calls succeed. This must
717                 // be for a non-Wifi type, since Wifi will reject the start calls if it hasn't
718                 // brought down the SoftAP yet.
719                 sendTetherResult(listener, TETHER_ERROR_DUPLICATE_REQUEST);
720                 return;
721             }
722 
723             if (request.isExemptFromEntitlementCheck()) {
724                 mEntitlementMgr.setExemptedDownstreamType(type);
725             } else {
726                 mEntitlementMgr.startProvisioningIfNeeded(type,
727                         request.getShouldShowEntitlementUi());
728             }
729             enableTetheringInternal(true /* enabled */, request, listener);
730             mTetheringMetrics.createBuilder(type, callerPkg);
731         });
732     }
733 
stopTethering(int type)734     void stopTethering(int type) {
735         mHandler.post(() -> {
736             stopTetheringInternal(type);
737         });
738     }
739 
stopTetheringRequest(@onNull final TetheringRequest request, @NonNull final IIntResultListener listener)740     void stopTetheringRequest(@NonNull final TetheringRequest request,
741             @NonNull final IIntResultListener listener) {
742         if (!isTetheringWithSoftApConfigEnabled()) return;
743         final boolean hasNetworkSettings = hasCallingPermission(NETWORK_SETTINGS);
744         mHandler.post(() -> {
745             if (mRequestTracker.findFuzzyMatchedRequest(request, !hasNetworkSettings) != null) {
746                 final int type = request.getTetheringType();
747                 stopTetheringInternal(type);
748                 // TODO: We should send the success result after the waiting for tethering to
749                 //       actually stop.
750                 sendTetherResult(listener, TETHER_ERROR_NO_ERROR);
751                 return;
752             }
753 
754             // Request doesn't match any active requests, ignore.
755             sendTetherResult(listener, TETHER_ERROR_UNKNOWN_REQUEST);
756         });
757     }
758 
stopTetheringInternal(int type)759     void stopTetheringInternal(int type) {
760         mRequestTracker.removeAllPendingRequests(type);
761         mRequestTracker.removeAllServingRequests(type);
762 
763         // Using a placeholder here is ok since none of the disable APIs use the request for
764         // anything. We simply need the tethering type to know which link layer to poke for removal.
765         // TODO: Remove the placeholder here and loop through each pending/serving request.
766         enableTetheringInternal(false /* disabled */, createPlaceholderRequest(type), null);
767         mEntitlementMgr.stopProvisioningIfNeeded(type);
768     }
769 
770     /**
771      * Enables or disables tethering for the given type. If provisioning is required, it will
772      * schedule provisioning rechecks for the specified interface.
773      */
enableTetheringInternal(boolean enable, @NonNull final TetheringRequest request, final IIntResultListener listener)774     private void enableTetheringInternal(boolean enable, @NonNull final TetheringRequest request,
775             final IIntResultListener listener) {
776         final int type = request.getTetheringType();
777         final int result;
778         switch (type) {
779             case TETHERING_WIFI:
780                 result = setWifiTethering(enable, request, listener);
781                 break;
782             case TETHERING_USB:
783                 result = setUsbTethering(enable);
784                 break;
785             case TETHERING_BLUETOOTH:
786                 result = setBluetoothTethering(enable, listener);
787                 break;
788             case TETHERING_NCM:
789                 result = setNcmTethering(enable);
790                 break;
791             case TETHERING_ETHERNET:
792                 result = setEthernetTethering(enable);
793                 break;
794             case TETHERING_VIRTUAL:
795                 result = setVirtualMachineTethering(enable, request);
796                 break;
797             default:
798                 Log.w(TAG, "Invalid tether type.");
799                 result = TETHER_ERROR_UNKNOWN_TYPE;
800         }
801 
802         // The result of Bluetooth tethering will be sent after the pan service connects.
803         if (result == TETHER_ERROR_BLUETOOTH_SERVICE_PENDING) return;
804 
805         // The result of Wifi tethering will be sent after the SoftApCallback result.
806         if (result == TETHER_ERROR_SOFT_AP_CALLBACK_PENDING) return;
807 
808         sendTetherResultAndRemoveOnError(request, listener, result);
809     }
810 
sendTetherResult(final IIntResultListener listener, final int result)811     private void sendTetherResult(final IIntResultListener listener, final int result) {
812         if (listener != null) {
813             try {
814                 listener.onResult(result);
815             } catch (RemoteException e) {
816             }
817         }
818     }
819 
sendTetherResultAndRemoveOnError(TetheringRequest request, final IIntResultListener listener, final int result)820     private void sendTetherResultAndRemoveOnError(TetheringRequest request,
821             final IIntResultListener listener, final int result) {
822         sendTetherResult(listener, result);
823 
824         if (result != TETHER_ERROR_NO_ERROR) {
825             mRequestTracker.removePendingRequest(request);
826             final int type = request.getTetheringType();
827             mTetheringMetrics.updateErrorCode(type, result);
828             mTetheringMetrics.sendReport(type);
829         }
830     }
831 
setWifiTethering(final boolean enable, TetheringRequest request, IIntResultListener listener)832     private int setWifiTethering(final boolean enable, TetheringRequest request,
833             IIntResultListener listener) {
834         final long ident = Binder.clearCallingIdentity();
835         try {
836             final WifiManager mgr = getWifiManager();
837             if (mgr == null) {
838                 mLog.e("setWifiTethering: failed to get WifiManager!");
839                 return TETHER_ERROR_SERVICE_UNAVAIL;
840             }
841             final boolean success;
842             if (enable) {
843                 if (isTetheringWithSoftApConfigEnabled()) {
844                     // Notes:
845                     // - A call to startTetheredHotspot can only succeed if the SoftAp is idle. If
846                     //   the SoftAp is running or is being disabled, the call will fail.
847                     // - If a call to startTetheredHotspot fails, the callback is immediately called
848                     //   with WIFI_AP_STATE_FAILED and a null interface.
849                     // - If a call to startTetheredHotspot succeeds, the passed-in callback is the
850                     //   only callback that will receive future WIFI_AP_STATE_ENABLED and
851                     //   WIFI_AP_STATE_DISABLED events in the future, until another call to
852                     //   startTetheredHotspot succeeds, at which point the old callback will stop
853                     //   receiving any events.
854                     // - Wifi may decide to restart the hotspot at any time (such as for a CC
855                     //   change), and if it does so, it will send WIFI_AP_STATE_DISABLED and then
856                     //   either WIFI_AP_STATE_ENABLED or (if restarting fails) WIFI_AP_STATE_FAILED.
857                     mgr.startTetheredHotspot(request, mExecutor,
858                             new StartTetheringSoftApCallback(listener));
859                     // Result isn't used since we get the real result via
860                     // StartTetheringSoftApCallback.
861                     return TETHER_ERROR_SOFT_AP_CALLBACK_PENDING;
862                 }
863                 success = mgr.startTetheredHotspot(null);
864             } else {
865                 success = mgr.stopSoftAp();
866             }
867 
868             if (success) {
869                 return TETHER_ERROR_NO_ERROR;
870             }
871         } finally {
872             Binder.restoreCallingIdentity(ident);
873         }
874 
875         return TETHER_ERROR_INTERNAL_ERROR;
876     }
877 
setBluetoothTethering(final boolean enable, final IIntResultListener listener)878     private int setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
879         final BluetoothAdapter adapter = mDeps.getBluetoothAdapter();
880         if (adapter == null || !adapter.isEnabled()) {
881             Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
882                     + (adapter == null));
883             return TETHER_ERROR_SERVICE_UNAVAIL;
884         }
885 
886         if (mBluetoothPanListener != null && mBluetoothPanListener.isConnected()) {
887             // The PAN service is connected. Enable or disable bluetooth tethering.
888             // When bluetooth tethering is enabled, any time a PAN client pairs with this
889             // host, bluetooth will bring up a bt-pan interface and notify tethering to
890             // enable IP serving.
891             return setBluetoothTetheringSettings(mBluetoothPan, enable);
892         }
893 
894         if (!enable) {
895             // The service is not connected. If disabling tethering, there's no point starting
896             // the service just to stop tethering since tethering is not started. Just remove
897             // any pending request to enable tethering, and notify them that they have failed.
898             if (mPendingPanRequestListener != null) {
899                 sendTetherResult(mPendingPanRequestListener, TETHER_ERROR_SERVICE_UNAVAIL);
900             }
901             mPendingPanRequestListener = null;
902             return TETHER_ERROR_NO_ERROR;
903         }
904 
905         // Only allow one pending request at a time.
906         if (mPendingPanRequestListener != null) {
907             return TETHER_ERROR_SERVICE_UNAVAIL;
908         }
909 
910         mPendingPanRequestListener = listener;
911 
912         // Bluetooth tethering is not a popular feature. To avoid bind to bluetooth pan service all
913         // the time but user never use bluetooth tethering. mBluetoothPanListener is created first
914         // time someone calls a bluetooth tethering method (even if it's just to disable tethering
915         // when it's already disabled) and never unset after that.
916         if (mBluetoothPanListener == null) {
917             mBluetoothPanListener = new PanServiceListener();
918             adapter.getProfileProxy(mContext, mBluetoothPanListener, BluetoothProfile.PAN);
919         }
920         return TETHER_ERROR_BLUETOOTH_SERVICE_PENDING;
921     }
922 
923     private class PanServiceListener implements ServiceListener {
924         private boolean mIsConnected = false;
925 
926         @Override
onServiceConnected(int profile, BluetoothProfile proxy)927         public void onServiceConnected(int profile, BluetoothProfile proxy) {
928             // Posting this to handling onServiceConnected in tethering handler thread may have
929             // race condition that bluetooth service may disconnected when tethering thread
930             // actaully handle onServiceconnected. If this race happen, calling
931             // BluetoothPan#setBluetoothTethering would silently fail. It is fine because pan
932             // service is unreachable and both bluetooth and bluetooth tethering settings are off.
933             mHandler.post(() -> {
934                 mBluetoothPan = (BluetoothPan) proxy;
935                 mIsConnected = true;
936 
937                 if (mPendingPanRequestListener != null) {
938                     final int result = setBluetoothTetheringSettings(mBluetoothPan,
939                             true /* enable */);
940                     sendTetherResultAndRemoveOnError(
941                             mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH),
942                             mPendingPanRequestListener,
943                             result);
944                 }
945                 mPendingPanRequestListener = null;
946             });
947         }
948 
949         @Override
onServiceDisconnected(int profile)950         public void onServiceDisconnected(int profile) {
951             mHandler.post(() -> {
952                 // onServiceDisconnected means Bluetooth is off (or crashed) and is not
953                 // reachable before next onServiceConnected.
954                 mIsConnected = false;
955 
956                 if (mPendingPanRequestListener != null) {
957                     sendTetherResultAndRemoveOnError(
958                             mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH),
959                             mPendingPanRequestListener,
960                             TETHER_ERROR_SERVICE_UNAVAIL);
961                 }
962                 mPendingPanRequestListener = null;
963                 mBluetoothIfaceRequest = null;
964                 mBluetoothCallback = null;
965                 maybeDisableBluetoothIpServing();
966             });
967         }
968 
isConnected()969         public boolean isConnected() {
970             return mIsConnected;
971         }
972     }
973 
setBluetoothTetheringSettings(@onNull final BluetoothPan bluetoothPan, final boolean enable)974     private int setBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
975             final boolean enable) {
976         if (SdkLevel.isAtLeastT()) {
977             changeBluetoothTetheringSettings(bluetoothPan, enable);
978         } else {
979             changeBluetoothTetheringSettingsPreT(bluetoothPan, enable);
980         }
981 
982         // Enabling bluetooth tethering settings can silently fail. Send internal error if the
983         // result is not expected.
984         return bluetoothPan.isTetheringOn() == enable
985                 ? TETHER_ERROR_NO_ERROR : TETHER_ERROR_INTERNAL_ERROR;
986     }
987 
changeBluetoothTetheringSettingsPreT(@onNull final BluetoothPan bluetoothPan, final boolean enable)988     private void changeBluetoothTetheringSettingsPreT(@NonNull final BluetoothPan bluetoothPan,
989             final boolean enable) {
990         bluetoothPan.setBluetoothTethering(enable);
991     }
992 
changeBluetoothTetheringSettings(@onNull final BluetoothPan bluetoothPan, final boolean enable)993     private void changeBluetoothTetheringSettings(@NonNull final BluetoothPan bluetoothPan,
994             final boolean enable) {
995         final BluetoothPanShim panShim = mDeps.makeBluetoothPanShim(bluetoothPan);
996         if (enable) {
997             if (mBluetoothIfaceRequest != null) {
998                 Log.d(TAG, "Bluetooth tethering settings already enabled");
999                 return;
1000             }
1001 
1002             mBluetoothCallback = new BluetoothCallback();
1003             try {
1004                 mBluetoothIfaceRequest = panShim.requestTetheredInterface(mExecutor,
1005                         mBluetoothCallback);
1006             } catch (UnsupportedApiLevelException e) {
1007                 Log.wtf(TAG, "Use unsupported API, " + e);
1008             }
1009         } else {
1010             if (mBluetoothIfaceRequest == null) {
1011                 Log.d(TAG, "Bluetooth tethering settings already disabled");
1012                 return;
1013             }
1014 
1015             mBluetoothIfaceRequest.release();
1016             mBluetoothIfaceRequest = null;
1017             mBluetoothCallback = null;
1018             // If bluetooth request is released, tethering won't able to receive
1019             // onUnavailable callback, explicitly disable bluetooth IpServer manually.
1020             maybeDisableBluetoothIpServing();
1021         }
1022     }
1023 
1024     // BluetoothCallback is only called after T. Before T, PanService would call tether/untether to
1025     // notify bluetooth interface status.
1026     private class BluetoothCallback implements TetheredInterfaceCallbackShim {
1027         @Override
onAvailable(String iface)1028         public void onAvailable(String iface) {
1029             if (this != mBluetoothCallback) return;
1030 
1031             final TetheringRequest request =
1032                     mRequestTracker.getOrCreatePendingRequest(TETHERING_BLUETOOTH);
1033             enableIpServing(request, iface);
1034             mConfiguredBluetoothIface = iface;
1035         }
1036 
1037         @Override
onUnavailable()1038         public void onUnavailable() {
1039             if (this != mBluetoothCallback) return;
1040 
1041             maybeDisableBluetoothIpServing();
1042         }
1043     }
1044 
maybeDisableBluetoothIpServing()1045     private void maybeDisableBluetoothIpServing() {
1046         if (mConfiguredBluetoothIface == null) return;
1047 
1048         ensureIpServerStopped(mConfiguredBluetoothIface);
1049         mConfiguredBluetoothIface = null;
1050     }
1051 
setEthernetTethering(final boolean enable)1052     private int setEthernetTethering(final boolean enable) {
1053         final EthernetManager em = (EthernetManager) mContext.getSystemService(
1054                 Context.ETHERNET_SERVICE);
1055         if (enable) {
1056             if (mEthernetCallback != null) {
1057                 Log.d(TAG, "Ethernet tethering already started");
1058                 return TETHER_ERROR_NO_ERROR;
1059             }
1060 
1061             mEthernetCallback = new EthernetCallback();
1062             mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
1063         } else {
1064             stopEthernetTethering();
1065         }
1066         return TETHER_ERROR_NO_ERROR;
1067     }
1068 
stopEthernetTethering()1069     private void stopEthernetTethering() {
1070         if (mConfiguredEthernetIface != null) {
1071             ensureIpServerStopped(mConfiguredEthernetIface);
1072             mConfiguredEthernetIface = null;
1073         }
1074         if (mEthernetCallback != null) {
1075             mEthernetIfaceRequest.release();
1076             mEthernetCallback = null;
1077             mEthernetIfaceRequest = null;
1078         }
1079     }
1080 
1081     private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback {
1082         @Override
onAvailable(String iface)1083         public void onAvailable(String iface) {
1084             if (this != mEthernetCallback) {
1085                 // Ethernet callback arrived after Ethernet tethering stopped. Ignore.
1086                 return;
1087             }
1088 
1089             final TetheringRequest request = mRequestTracker.getOrCreatePendingRequest(
1090                     TETHERING_ETHERNET);
1091             enableIpServing(request, iface);
1092             mConfiguredEthernetIface = iface;
1093         }
1094 
1095         @Override
onUnavailable()1096         public void onUnavailable() {
1097             if (this != mEthernetCallback) {
1098                 // onAvailable called after stopping Ethernet tethering.
1099                 return;
1100             }
1101             stopEthernetTethering();
1102         }
1103     }
1104 
setVirtualMachineTethering(final boolean enable, @NonNull final TetheringRequest request)1105     private int setVirtualMachineTethering(final boolean enable,
1106             @NonNull final TetheringRequest request) {
1107         final String iface = request.getInterfaceName();
1108         if (enable) {
1109             if (TextUtils.isEmpty(iface)) {
1110                 mConfiguredVirtualIface = "avf_tap_fixed";
1111             } else {
1112                 mConfiguredVirtualIface = iface;
1113             }
1114             enableIpServing(request, mConfiguredVirtualIface);
1115         } else if (mConfiguredVirtualIface != null) {
1116             ensureIpServerStopped(mConfiguredVirtualIface);
1117             mConfiguredVirtualIface = null;
1118         }
1119         return TETHER_ERROR_NO_ERROR;
1120     }
1121 
handleLegacyTether(String iface, final IIntResultListener listener)1122     private void handleLegacyTether(String iface, final IIntResultListener listener) {
1123         if (SdkLevel.isAtLeastB()) {
1124             // After V, the TetheringManager and ConnectivityManager tether and untether methods
1125             // throw UnsupportedOperationException, so this cannot happen in normal use. Ensure
1126             // that this code cannot run even if callers use raw binder calls or other
1127             // unsupported methods.
1128             return;
1129         }
1130 
1131         final int type = ifaceNameToType(iface);
1132         if (type == TETHERING_INVALID) {
1133             Log.e(TAG, "Ignoring call to legacy tether for unknown iface " + iface);
1134             sendTetherResult(listener, TETHER_ERROR_UNKNOWN_IFACE);
1135         }
1136 
1137         TetheringRequest request = mRequestTracker.getNextPendingRequest(type);
1138         if (request == null) {
1139             request = createLegacyGlobalScopeTetheringRequest(type);
1140         }
1141         int result = tetherInternal(request, iface);
1142         switch (type) {
1143             case TETHERING_WIFI:
1144                 TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
1145                         "Legacy tether API called on Wifi iface " + iface,
1146                         CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
1147                         CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI);
1148                 if (result == TETHER_ERROR_NO_ERROR) {
1149                     TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
1150                             "Legacy tether API succeeded on Wifi iface " + iface,
1151                             CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
1152                             CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS);
1153                 }
1154                 break;
1155             case TETHERING_WIFI_P2P:
1156                 TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
1157                         "Legacy tether API called on Wifi P2P iface " + iface,
1158                         CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
1159                         CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P);
1160                 if (result == TETHER_ERROR_NO_ERROR) {
1161                     TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
1162                             "Legacy tether API succeeded on Wifi P2P iface " + iface,
1163                             CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
1164                             CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS);
1165                 }
1166                 break;
1167             default:
1168                 // Do nothing
1169                 break;
1170         }
1171         sendTetherResult(listener, result);
1172     }
1173 
1174     /**
1175      * Legacy tether API that starts tethering with CONNECTIVITY_SCOPE_GLOBAL on the given iface.
1176      *
1177      * This API relies on the IpServer having been started for the interface by
1178      * processInterfaceStateChanged beforehand, which is only possible for
1179      *     - WIGIG Pre-S
1180      *     - BLUETOOTH Pre-T
1181      *     - WIFI
1182      *     - WIFI_P2P.
1183      * Note that WIFI and WIFI_P2P already start tethering on their respective ifaces via
1184      * WIFI_(AP/P2P_STATE_CHANGED broadcasts, which makes this API redundant for those types unless
1185      * those broadcasts are disabled by OEM.
1186      */
legacyTether(String iface, final IIntResultListener listener)1187     void legacyTether(String iface, final IIntResultListener listener) {
1188         mHandler.post(() -> handleLegacyTether(iface, listener));
1189     }
1190 
tetherInternal(@onNull TetheringRequest request, String iface)1191     private int tetherInternal(@NonNull TetheringRequest request, String iface) {
1192         if (DBG) Log.d(TAG, "Tethering " + iface);
1193         TetherState tetherState = mTetherStates.get(iface);
1194         if (tetherState == null) {
1195             Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
1196             return TETHER_ERROR_UNKNOWN_IFACE;
1197         }
1198         // Ignore the error status of the interface.  If the interface is available,
1199         // the errors are referring to past tethering attempts anyway.
1200         if (tetherState.lastState != IpServer.STATE_AVAILABLE) {
1201             Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
1202             return TETHER_ERROR_UNAVAIL_IFACE;
1203         }
1204         mRequestTracker.promoteRequestToServing(tetherState.ipServer, request);
1205         // NOTE: If a CMD_TETHER_REQUESTED message is already in the IpServer's queue but not yet
1206         // processed, this will be a no-op and it will not return an error.
1207         tetherState.ipServer.enable(request);
1208         if (request.getRequestType() == REQUEST_TYPE_PLACEHOLDER) {
1209             TerribleErrorLog.logTerribleError(TetheringStatsLog::write,
1210                     "Started tethering with placeholder request: " + request,
1211                     CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
1212                     CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WITH_PLACEHOLDER_REQUEST);
1213         }
1214         return TETHER_ERROR_NO_ERROR;
1215     }
1216 
legacyUntether(String iface, final IIntResultListener listener)1217     void legacyUntether(String iface, final IIntResultListener listener) {
1218         if (SdkLevel.isAtLeastB()) {
1219             // After V, the TetheringManager and ConnectivityManager tether and untether methods
1220             // throw UnsupportedOperationException, so this cannot happen in normal use. Ensure
1221             // that this code cannot run even if callers use raw binder calls or other
1222             // unsupported methods.
1223             return;
1224         }
1225         mHandler.post(() -> {
1226             sendTetherResult(listener, legacyUntetherInternal(iface));
1227         });
1228     }
1229 
legacyUntetherInternal(String iface)1230     int legacyUntetherInternal(String iface) {
1231         if (DBG) Log.d(TAG, "Untethering " + iface);
1232         TetherState tetherState = mTetherStates.get(iface);
1233         if (tetherState == null) {
1234             Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
1235             return TETHER_ERROR_UNKNOWN_IFACE;
1236         }
1237         if (!tetherState.isCurrentlyServing()) {
1238             Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
1239             return TETHER_ERROR_UNAVAIL_IFACE;
1240         }
1241         ensureIpServerUnwanted(tetherState.ipServer);
1242         return TETHER_ERROR_NO_ERROR;
1243     }
1244 
stopAllTethering()1245     void stopAllTethering() {
1246         stopTethering(TETHERING_WIFI);
1247         stopTethering(TETHERING_WIFI_P2P);
1248         stopTethering(TETHERING_USB);
1249         stopTethering(TETHERING_BLUETOOTH);
1250         stopTethering(TETHERING_ETHERNET);
1251     }
1252 
1253     @VisibleForTesting
getLastErrorForTest(String iface)1254     int getLastErrorForTest(String iface) {
1255         TetherState tetherState = mTetherStates.get(iface);
1256         if (tetherState == null) {
1257             Log.e(TAG, "Tried to getLastErrorForTest on an unknown iface :" + iface
1258                     + ", ignoring");
1259             return TETHER_ERROR_UNKNOWN_IFACE;
1260         }
1261         return tetherState.lastError;
1262     }
1263 
isTetherProvisioningRequired()1264     boolean isTetherProvisioningRequired() {
1265         final TetheringConfiguration cfg = mConfig;
1266         return mEntitlementMgr.isTetherProvisioningRequired(cfg);
1267     }
1268 
getServedUsbType(boolean forNcmFunction)1269     private int getServedUsbType(boolean forNcmFunction) {
1270         // TETHERING_NCM is only used if the device does not use NCM for regular USB tethering.
1271         if (forNcmFunction && !mConfig.isUsingNcm()) return TETHERING_NCM;
1272 
1273         return TETHERING_USB;
1274     }
1275 
1276     // TODO: Figure out how to update for local hotspot mode interfaces.
notifyTetherStatesChanged()1277     private void notifyTetherStatesChanged() {
1278         if (!isTetheringSupported()) return;
1279 
1280         sendTetherStatesChangedCallback();
1281         sendTetherStatesChangedBroadcast();
1282 
1283         int downstreamTypesMask = DOWNSTREAM_NONE;
1284         for (int i = 0; i < mTetherStates.size(); i++) {
1285             final TetherState tetherState = mTetherStates.valueAt(i);
1286             final int type = tetherState.ipServer.interfaceType();
1287             if (tetherState.lastState != IpServer.STATE_TETHERED) continue;
1288             switch (type) {
1289                 case TETHERING_USB:
1290                 case TETHERING_WIFI:
1291                 case TETHERING_BLUETOOTH:
1292                     downstreamTypesMask |= (1 << type);
1293                     break;
1294                 default:
1295                     // Do nothing.
1296                     break;
1297             }
1298         }
1299         mNotificationUpdater.onDownstreamChanged(downstreamTypesMask);
1300     }
1301 
1302     /**
1303      * Builds a TetherStatesParcel for the specified CallbackCookie. SoftApConfiguration will only
1304      * be included if the cookie has the same uid as the app that specified the configuration, or
1305      * if the cookie has system privilege.
1306      *
1307      * @param cookie CallbackCookie of the receiving app.
1308      * @return TetherStatesParcel with information redacted for the specified cookie.
1309      */
buildTetherStatesParcel(CallbackCookie cookie)1310     private TetherStatesParcel buildTetherStatesParcel(CallbackCookie cookie) {
1311         final ArrayList<TetheringInterface> available = new ArrayList<>();
1312         final ArrayList<TetheringInterface> tethered = new ArrayList<>();
1313         final ArrayList<TetheringInterface> localOnly = new ArrayList<>();
1314         final ArrayList<TetheringInterface> errored = new ArrayList<>();
1315         final ArrayList<Integer> lastErrors = new ArrayList<>();
1316 
1317         for (int i = 0; i < mTetherStates.size(); i++) {
1318             final TetherState tetherState = mTetherStates.valueAt(i);
1319             final int type = tetherState.ipServer.interfaceType();
1320             final String iface = mTetherStates.keyAt(i);
1321             // Note: serving requests are only populated on B+. B+ also uses the sync state
1322             // machine by default. This ensures that the serving request is (correctly) populated
1323             // after the IpServer enters the available state and before it enters the serving
1324             // state.
1325             final TetheringRequest request =
1326                     mRequestTracker.getServingRequest(tetherState.ipServer);
1327             final boolean includeSoftApConfig = request != null && cookie != null
1328                     && (cookie.uid == request.getUid() || cookie.hasSystemPrivilege);
1329             final TetheringInterface tetheringIface = new TetheringInterface(type, iface,
1330                     includeSoftApConfig ? request.getSoftApConfiguration() : null);
1331             if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
1332                 errored.add(tetheringIface);
1333                 lastErrors.add(tetherState.lastError);
1334             } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
1335                 available.add(tetheringIface);
1336             } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) {
1337                 localOnly.add(tetheringIface);
1338             } else if (tetherState.lastState == IpServer.STATE_TETHERED) {
1339                 switch (type) {
1340                     case TETHERING_USB:
1341                     case TETHERING_WIFI:
1342                     case TETHERING_BLUETOOTH:
1343                         break;
1344                     default:
1345                         // Do nothing.
1346                         break;
1347                 }
1348                 tethered.add(tetheringIface);
1349             }
1350         }
1351 
1352         final TetherStatesParcel parcel = new TetherStatesParcel();
1353         parcel.availableList = available.toArray(new TetheringInterface[0]);
1354         parcel.tetheredList = tethered.toArray(new TetheringInterface[0]);
1355         parcel.localOnlyList = localOnly.toArray(new TetheringInterface[0]);
1356         parcel.erroredIfaceList = errored.toArray(new TetheringInterface[0]);
1357         parcel.lastErrorList = new int[lastErrors.size()];
1358         for (int i = 0; i < lastErrors.size(); i++) {
1359             parcel.lastErrorList[i] = lastErrors.get(i);
1360         }
1361         return parcel;
1362     }
1363 
sendTetherStatesChangedBroadcast()1364     private void sendTetherStatesChangedBroadcast() {
1365         final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED);
1366         bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1367 
1368         TetherStatesParcel parcel = buildTetherStatesParcel(null /* cookie */);
1369         bcast.putStringArrayListExtra(
1370                 EXTRA_AVAILABLE_TETHER, toIfaces(Arrays.asList(parcel.availableList)));
1371         bcast.putStringArrayListExtra(
1372                 EXTRA_ACTIVE_LOCAL_ONLY, toIfaces(Arrays.asList(parcel.localOnlyList)));
1373         bcast.putStringArrayListExtra(
1374                 EXTRA_ACTIVE_TETHER, toIfaces(Arrays.asList(parcel.tetheredList)));
1375         bcast.putStringArrayListExtra(
1376                 EXTRA_ERRORED_TETHER, toIfaces(Arrays.asList(parcel.erroredIfaceList)));
1377         mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
1378     }
1379 
1380     private class StateReceiver extends BroadcastReceiver {
1381         @Override
onReceive(Context content, Intent intent)1382         public void onReceive(Context content, Intent intent) {
1383             final String action = intent.getAction();
1384             if (action == null) return;
1385 
1386             if (action.equals(UsbManager.ACTION_USB_STATE)) {
1387                 handleUsbAction(intent);
1388             } else if (action.equals(CONNECTIVITY_ACTION)) {
1389                 handleConnectivityAction(intent);
1390             } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
1391                 handleWifiApAction(intent);
1392             } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
1393                 handleWifiP2pAction(intent);
1394             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
1395                 mLog.log("OBSERVED configuration changed");
1396                 updateConfiguration();
1397             } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) {
1398                 mLog.log("OBSERVED user restrictions changed");
1399                 handleUserRestrictionAction();
1400             } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) {
1401                 mLog.log("OBSERVED data saver changed");
1402                 handleDataSaverChanged();
1403             } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) {
1404                 stopAllTethering();
1405             }
1406         }
1407 
handleConnectivityAction(Intent intent)1408         private void handleConnectivityAction(Intent intent) {
1409             // CONNECTIVITY_ACTION is not handled since U+ device.
1410             if (SdkLevel.isAtLeastU()) return;
1411 
1412             final NetworkInfo networkInfo =
1413                     (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO);
1414             if (networkInfo == null
1415                     || networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
1416                 return;
1417             }
1418 
1419             if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
1420             mTetherMainSM.sendMessage(TetherMainSM.CMD_UPSTREAM_CHANGED);
1421         }
1422 
handleUsbAction(Intent intent)1423         private void handleUsbAction(Intent intent) {
1424             final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
1425             final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
1426             final boolean usbRndis = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
1427             final boolean usbNcm = intent.getBooleanExtra(USB_FUNCTION_NCM, false);
1428 
1429             mLog.i(String.format("USB bcast connected:%s configured:%s rndis:%s ncm:%s",
1430                     usbConnected, usbConfigured, usbRndis, usbNcm));
1431 
1432             // There are three types of ACTION_USB_STATE:
1433             //
1434             //     - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
1435             //       Meaning: USB connection has ended either because of
1436             //       software reset or hard unplug.
1437             //
1438             //     - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
1439             //       Meaning: the first stage of USB protocol handshake has
1440             //       occurred but it is not complete.
1441             //
1442             //     - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
1443             //       Meaning: the USB handshake is completely done and all the
1444             //       functions are ready to use.
1445             //
1446             // For more explanation, see b/62552150 .
1447             boolean rndisEnabled = usbConfigured && usbRndis;
1448             boolean ncmEnabled = usbConfigured && usbNcm;
1449             if (!usbConnected) {
1450                 // Don't stop provisioning if function is disabled but usb is still connected. The
1451                 // function may be disable/enable to handle ip conflict condition (disabling the
1452                 // function is necessary to ensure the connected device sees a disconnect).
1453                 // Normally the provisioning should be stopped by stopTethering(int)
1454                 maybeStopUsbProvisioning();
1455                 rndisEnabled = false;
1456                 ncmEnabled = false;
1457             }
1458 
1459             if (mRndisEnabled != rndisEnabled) {
1460                 changeUsbIpServing(rndisEnabled, false /* forNcmFunction */);
1461                 mRndisEnabled = rndisEnabled;
1462             }
1463 
1464             if (mNcmEnabled != ncmEnabled) {
1465                 changeUsbIpServing(ncmEnabled, true /* forNcmFunction */);
1466                 mNcmEnabled = ncmEnabled;
1467             }
1468         }
1469 
changeUsbIpServing(boolean enable, boolean forNcmFunction)1470         private void changeUsbIpServing(boolean enable, boolean forNcmFunction) {
1471             if (enable) {
1472                 // enable ip serving if function is enabled and usb is configured.
1473                 enableUsbIpServing(forNcmFunction);
1474             } else {
1475                 disableUsbIpServing(forNcmFunction);
1476             }
1477         }
1478 
maybeStopUsbProvisioning()1479         private void maybeStopUsbProvisioning() {
1480             for (int i = 0; i < mTetherStates.size(); i++) {
1481                 final int type = mTetherStates.valueAt(i).ipServer.interfaceType();
1482                 if (type == TETHERING_USB || type == TETHERING_NCM) {
1483                     mEntitlementMgr.stopProvisioningIfNeeded(type);
1484                 }
1485             }
1486         }
1487 
handleWifiApAction(Intent intent)1488         private void handleWifiApAction(Intent intent) {
1489             final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
1490             final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
1491             final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
1492 
1493             // In B+, Tethered AP is handled by StartTetheringSoftApCallback.
1494             if (isTetheringWithSoftApConfigEnabled() && ipmode == IFACE_IP_MODE_TETHERED) return;
1495 
1496             switch (curState) {
1497                 case WifiManager.WIFI_AP_STATE_ENABLING:
1498                     // We can see this state on the way to both enabled and failure states.
1499                     break;
1500                 case WifiManager.WIFI_AP_STATE_ENABLED:
1501                     enableWifiIpServing(ifname, ipmode);
1502                     break;
1503                 case WifiManager.WIFI_AP_STATE_DISABLING:
1504                     // We can see this state on the way to disabled.
1505                     break;
1506                 case WifiManager.WIFI_AP_STATE_DISABLED:
1507                 case WifiManager.WIFI_AP_STATE_FAILED:
1508                 default:
1509                     disableWifiIpServing(ifname, curState);
1510                     break;
1511             }
1512         }
1513 
isGroupOwner(WifiP2pGroup group)1514         private boolean isGroupOwner(WifiP2pGroup group) {
1515             return group != null && group.isGroupOwner()
1516                     && !TextUtils.isEmpty(group.getInterface());
1517         }
1518 
handleWifiP2pAction(Intent intent)1519         private void handleWifiP2pAction(Intent intent) {
1520             if (mConfig.isWifiP2pLegacyTetheringMode()) return;
1521 
1522             final WifiP2pInfo p2pInfo =
1523                     (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
1524             final WifiP2pGroup group =
1525                     (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
1526 
1527             mLog.i("WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
1528 
1529             // if no group is formed, bring it down if needed.
1530             if (p2pInfo == null || !p2pInfo.groupFormed) {
1531                 disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface);
1532                 mWifiP2pTetherInterface = null;
1533                 return;
1534             }
1535 
1536             // If there is a group but the device is not the owner, bail out.
1537             if (!isGroupOwner(group)) return;
1538 
1539             // If already serving from the correct interface, nothing to do.
1540             if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
1541 
1542             // If already serving from another interface, turn it down first.
1543             if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
1544                 mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
1545                         + "is different from current interface "
1546                         + group.getInterface() + ", re-tether it");
1547                 disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface);
1548             }
1549 
1550             // Finally bring up serving on the new interface
1551             mWifiP2pTetherInterface = group.getInterface();
1552             enableWifiP2pIpServing(mWifiP2pTetherInterface);
1553         }
1554 
handleUserRestrictionAction()1555         private void handleUserRestrictionAction() {
1556             if (mTetheringRestriction.onUserRestrictionsChanged()) {
1557                 updateSupportedDownstreams(mConfig);
1558             }
1559         }
1560 
handleDataSaverChanged()1561         private void handleDataSaverChanged() {
1562             final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(
1563                     Context.CONNECTIVITY_SERVICE);
1564             final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus()
1565                     != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
1566 
1567             if (mDataSaverEnabled == isDataSaverEnabled) return;
1568 
1569             mDataSaverEnabled = isDataSaverEnabled;
1570             if (mDataSaverEnabled) {
1571                 stopAllTethering();
1572             }
1573         }
1574     }
1575 
1576     class StartTetheringSoftApCallback implements SoftApCallback {
1577 
1578         @Nullable
1579         IIntResultListener mPendingListener;
1580 
StartTetheringSoftApCallback(IIntResultListener pendingListener)1581         StartTetheringSoftApCallback(IIntResultListener pendingListener) {
1582             mPendingListener = pendingListener;
1583         }
1584 
1585         @Override
onStateChanged(SoftApState softApState)1586         public void onStateChanged(SoftApState softApState) {
1587             final int state = softApState.getState();
1588             final String iface = softApState.getIface();
1589             final TetheringRequest request = softApState.getTetheringRequest();
1590             switch (softApState.getState()) {
1591                 case WifiManager.WIFI_AP_STATE_ENABLED:
1592                     enableIpServing(request, iface);
1593                     // If stopTethering has already been called, IP serving will still be started,
1594                     // but as soon as the wifi code processes the stop, WIFI_AP_STATE_DISABLED will
1595                     // be sent and tethering will be stopped again.
1596                     sendTetherResultAndRemoveOnError(request, mPendingListener,
1597                             TETHER_ERROR_NO_ERROR);
1598                     mPendingListener = null;
1599                     break;
1600                 case WifiManager.WIFI_AP_STATE_FAILED:
1601                     // TODO: if a call to startTethering happens just after a call to stopTethering,
1602                     // the start will fail because hotspot is still being disabled. This likely
1603                     // cannot be fixed in tethering code but must be fixed in WiFi.
1604                     sendTetherResultAndRemoveOnError(request, mPendingListener,
1605                             TETHER_ERROR_INTERNAL_ERROR);
1606                     mPendingListener = null;
1607                     break;
1608                 case WifiManager.WIFI_AP_STATE_DISABLED:
1609                     // TODO(b/403164072): SoftAP may restart due to CC change, in which we'll get
1610                     // DISABLED -> ENABLED (or FAILED). Before the transition back to ENABLED is
1611                     // complete, it is possible that a new Wifi request is accepted since there's no
1612                     // active request to fuzzy-match it, which will unexpectedly cause Wifi to
1613                     // overwrite this SoftApCallback. This should be fixed in Wifi to disallow any
1614                     // new calls to startTetheredHotspot while SoftAP is restarting.
1615                     disableWifiIpServing(iface, state);
1616                     break;
1617                 default:
1618                     break;
1619             }
1620         }
1621     }
1622 
1623     @VisibleForTesting
getPendingTetheringRequests()1624     List<TetheringRequest> getPendingTetheringRequests() {
1625         return mRequestTracker.getPendingTetheringRequests();
1626     }
1627 
1628     @VisibleForTesting
getServingTetheringRequests()1629     List<TetheringRequest> getServingTetheringRequests() {
1630         return mRequestTracker.getServingTetheringRequests();
1631     }
1632 
1633     @VisibleForTesting
isTetheringActive()1634     boolean isTetheringActive() {
1635         return getTetheredIfaces().length > 0;
1636     }
1637 
1638     // TODO: Refine TetheringTest then remove UserRestrictionActionListener class and handle
1639     // onUserRestrictionsChanged inside Tethering#handleUserRestrictionAction directly.
1640     @VisibleForTesting
1641     protected static class UserRestrictionActionListener {
1642         private final UserManager mUserMgr;
1643         private final Tethering mTethering;
1644         private final TetheringNotificationUpdater mNotificationUpdater;
1645         public boolean mDisallowTethering;
1646 
UserRestrictionActionListener(@onNull UserManager um, @NonNull Tethering tethering, @NonNull TetheringNotificationUpdater updater)1647         public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering tethering,
1648                 @NonNull TetheringNotificationUpdater updater) {
1649             mUserMgr = um;
1650             mTethering = tethering;
1651             mNotificationUpdater = updater;
1652             mDisallowTethering = false;
1653         }
1654 
1655         // return whether tethering disallowed is changed.
onUserRestrictionsChanged()1656         public boolean onUserRestrictionsChanged() {
1657             // getUserRestrictions gets restriction for this process' user, which is the primary
1658             // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
1659             // user. See UserManager.DISALLOW_CONFIG_TETHERING.
1660             final Bundle restrictions = mUserMgr.getUserRestrictions();
1661             final boolean newlyDisallowed =
1662                     restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
1663             final boolean prevDisallowed = mDisallowTethering;
1664             mDisallowTethering = newlyDisallowed;
1665 
1666             final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed);
1667             if (!tetheringDisallowedChanged) return false;
1668 
1669             if (!newlyDisallowed) {
1670                 // Clear the restricted notification when user is allowed to have tethering
1671                 // function.
1672                 mNotificationUpdater.tetheringRestrictionLifted();
1673                 return true;
1674             }
1675 
1676             if (mTethering.isTetheringActive()) {
1677                 // Restricted notification is shown when tethering function is disallowed on
1678                 // user's device.
1679                 mNotificationUpdater.notifyTetheringDisabledByRestriction();
1680 
1681                 // Untether from all downstreams since tethering is disallowed.
1682                 mTethering.stopAllTethering();
1683             }
1684 
1685             return true;
1686             // TODO(b/148139325): send tetheringSupported on restriction change
1687         }
1688     }
1689 
enableIpServing(@onNull TetheringRequest request, String ifname)1690     private void enableIpServing(@NonNull TetheringRequest request, String ifname) {
1691         enableIpServing(request, ifname, false /* isNcm */);
1692     }
1693 
enableIpServing(@onNull TetheringRequest request, String ifname, boolean isNcm)1694     private void enableIpServing(@NonNull TetheringRequest request, String ifname, boolean isNcm) {
1695         ensureIpServerStartedForType(ifname, request.getTetheringType(), isNcm);
1696         if (tetherInternal(request, ifname) != TETHER_ERROR_NO_ERROR) {
1697             Log.e(TAG, "unable start tethering on iface " + ifname);
1698         }
1699     }
1700 
disableWifiIpServingCommon(int tetheringType, String ifname)1701     private void disableWifiIpServingCommon(int tetheringType, String ifname) {
1702         if (!TextUtils.isEmpty(ifname) && mTetherStates.containsKey(ifname)) {
1703             ensureIpServerUnwanted(mTetherStates.get(ifname).ipServer);
1704             return;
1705         }
1706 
1707         if (SdkLevel.isAtLeastT()) {
1708             mLog.e("Tethering no longer handle untracked interface after T: " + ifname);
1709             return;
1710         }
1711 
1712         // Attempt to guess the interface name before T. Pure AOSP code should never enter here
1713         // because WIFI_AP_STATE_CHANGED intent always include ifname and it should be tracked
1714         // by mTetherStates. In case OEMs have some modification in wifi side which pass null
1715         // or empty ifname. Before T, tethering allow to disable the first wifi ipServer if
1716         // given ifname don't match any tracking ipServer.
1717         for (int i = 0; i < mTetherStates.size(); i++) {
1718             final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
1719             if (ipServer.interfaceType() == tetheringType) {
1720                 ensureIpServerUnwanted(ipServer);
1721                 return;
1722             }
1723         }
1724         mLog.log("Error disabling Wi-Fi IP serving; "
1725                 + (TextUtils.isEmpty(ifname) ? "no interface name specified"
1726                                            : "specified interface: " + ifname));
1727     }
1728 
disableWifiIpServing(String ifname, int apState)1729     private void disableWifiIpServing(String ifname, int apState) {
1730         mLog.log("Canceling WiFi tethering request - interface=" + ifname + " state=" + apState);
1731 
1732         disableWifiIpServingCommon(TETHERING_WIFI, ifname);
1733     }
1734 
enableWifiP2pIpServing(String ifname)1735     private void enableWifiP2pIpServing(String ifname) {
1736         if (TextUtils.isEmpty(ifname)) {
1737             mLog.e("Cannot enable P2P IP serving with invalid interface");
1738             return;
1739         }
1740 
1741         // After T, tethering always trust the iface pass by state change intent. This allow
1742         // tethering to deprecate tetherable p2p regexs after T.
1743         final int type = SdkLevel.isAtLeastT() ? TETHERING_WIFI_P2P : ifaceNameToType(ifname);
1744         if (!checkTetherableType(type)) {
1745             mLog.e(ifname + " is not a tetherable iface, ignoring");
1746             return;
1747         }
1748         // No need to call getOrCreatePendingRequest. There can never be explicit requests for
1749         // TETHERING_WIFI_P2P because enableTetheringInternal ignores that type.
1750         final TetheringRequest request = createImplicitLocalOnlyTetheringRequest(type);
1751         enableIpServing(request, ifname);
1752     }
1753 
disableWifiP2pIpServingIfNeeded(String ifname)1754     private void disableWifiP2pIpServingIfNeeded(String ifname) {
1755         if (TextUtils.isEmpty(ifname)) return;
1756 
1757         mLog.log("Canceling P2P tethering request - interface=" + ifname);
1758         disableWifiIpServingCommon(TETHERING_WIFI_P2P, ifname);
1759     }
1760 
1761     // TODO: fold this in to enableWifiIpServing.  We cannot do this at the moment because there
1762     // are tests that send wifi AP broadcasts with a null interface. But if this can't happen on
1763     // real devices, we should fix those tests to always pass in an interface.
maybeInferWifiTetheringType(String ifname)1764     private int maybeInferWifiTetheringType(String ifname) {
1765         return SdkLevel.isAtLeastT() ? TETHERING_WIFI : ifaceNameToType(ifname);
1766     }
1767 
enableWifiIpServing(String ifname, int wifiIpMode)1768     private void enableWifiIpServing(String ifname, int wifiIpMode) {
1769         mLog.log("request WiFi tethering - interface=" + ifname + " state=" + wifiIpMode);
1770 
1771         // Map wifiIpMode values to IpServer.Callback serving states.
1772         TetheringRequest request;
1773         final int type;
1774         switch (wifiIpMode) {
1775             case IFACE_IP_MODE_TETHERED:
1776                 type = maybeInferWifiTetheringType(ifname);
1777                 request = mRequestTracker.getOrCreatePendingRequest(type);
1778                 // Wifi requests will always have CONNECTIVITY_SCOPE_GLOBAL, because
1779                 // TetheringRequest.Builder will not allow callers to set CONNECTIVITY_SCOPE_LOCAL
1780                 // for TETHERING_WIFI. However, if maybeInferWifiTetheringType returns a non-Wifi
1781                 // type (which could happen on a pre-T implementation of Wi-Fi if the regexps are
1782                 // misconfigured), then force the connectivity scope to global in order to match the
1783                 // historical behavior.
1784                 request.getParcel().connectivityScope = CONNECTIVITY_SCOPE_GLOBAL;
1785                 break;
1786             case IFACE_IP_MODE_LOCAL_ONLY:
1787                 type = maybeInferWifiTetheringType(ifname);
1788                 request = createImplicitLocalOnlyTetheringRequest(type);
1789                 break;
1790             default:
1791                 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
1792                 return;
1793         }
1794 
1795         // After T, tethering always trust the iface pass by state change intent. This allow
1796         // tethering to deprecate tetherable wifi regexs after T.
1797         if (!checkTetherableType(type)) {
1798             mLog.e(ifname + " is not a tetherable iface, ignoring");
1799             return;
1800         }
1801 
1802         if (!TextUtils.isEmpty(ifname)) {
1803             enableIpServing(request, ifname);
1804         } else {
1805             mLog.e("Cannot enable IP serving on missing interface name");
1806         }
1807     }
1808 
1809     // TODO: Pass TetheringRequest into this method. The code can look at the existing requests
1810     // to see which one matches the function that was enabled. That will tell the code what
1811     // tethering type was requested, without having to guess it from the configuration.
1812     // This method:
1813     //     - allows requesting either tethering or local hotspot serving states
1814     //     - only tethers the first matching interface in listInterfaces()
1815     //       order of a given type
enableUsbIpServing(boolean forNcmFunction)1816     private void enableUsbIpServing(boolean forNcmFunction) {
1817         // Note: TetheringConfiguration#isUsingNcm can change between the call to
1818         // startTethering(TETHERING_USB) and the ACTION_USB_STATE broadcast. If the USB tethering
1819         // function changes from NCM to RNDIS, this can lead to Tethering starting NCM tethering
1820         // as local-only. But if this happens, the SettingsObserver will call stopTetheringInternal
1821         // for both TETHERING_USB and TETHERING_NCM, so the local-only NCM interface will be
1822         // stopped immediately.
1823         final int tetheringType = getServedUsbType(forNcmFunction);
1824         String[] ifaces = null;
1825         try {
1826             ifaces = mNetd.interfaceGetList();
1827         } catch (RemoteException | ServiceSpecificException e) {
1828             mLog.e("Cannot enableUsbIpServing due to error listing Interfaces" + e);
1829             return;
1830         }
1831 
1832         final TetheringRequest request = mRequestTracker.getOrCreatePendingRequest(tetheringType);
1833         if (ifaces != null) {
1834             for (String iface : ifaces) {
1835                 if (ifaceNameToType(iface) == tetheringType) {
1836                     enableIpServing(request, iface, forNcmFunction);
1837                     return;
1838                 }
1839             }
1840         }
1841 
1842         mLog.e("could not enable IpServer for function " + (forNcmFunction ? "NCM" : "RNDIS"));
1843     }
1844 
disableUsbIpServing(boolean forNcmFunction)1845     private void disableUsbIpServing(boolean forNcmFunction) {
1846         for (int i = 0; i < mTetherStates.size(); i++) {
1847             final TetherState state = mTetherStates.valueAt(i);
1848             final int type = state.ipServer.interfaceType();
1849             if (type != TETHERING_USB && type != TETHERING_NCM) continue;
1850 
1851             if (state.isNcm == forNcmFunction) {
1852                 ensureIpServerStopped(state.ipServer.interfaceName());
1853             }
1854         }
1855     }
1856 
getTetheringConfiguration()1857     TetheringConfiguration getTetheringConfiguration() {
1858         return mConfig;
1859     }
1860 
isEthernetSupported()1861     private boolean isEthernetSupported() {
1862         return mContext.getSystemService(Context.ETHERNET_SERVICE) != null;
1863     }
1864 
setUsbTethering(boolean enable, IIntResultListener listener)1865     void setUsbTethering(boolean enable, IIntResultListener listener) {
1866         mHandler.post(() -> {
1867             sendTetherResult(listener, setUsbTethering(enable));
1868         });
1869     }
1870 
setUsbTethering(boolean enable)1871     private int setUsbTethering(boolean enable) {
1872         if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
1873         UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
1874         if (usbManager == null) {
1875             mLog.e("setUsbTethering: failed to get UsbManager!");
1876             return TETHER_ERROR_SERVICE_UNAVAIL;
1877         }
1878 
1879         final long usbFunction = mConfig.isUsingNcm()
1880                 ? UsbManager.FUNCTION_NCM : UsbManager.FUNCTION_RNDIS;
1881         usbManager.setCurrentFunctions(enable ? usbFunction : UsbManager.FUNCTION_NONE);
1882 
1883         return TETHER_ERROR_NO_ERROR;
1884     }
1885 
setNcmTethering(boolean enable)1886     private int setNcmTethering(boolean enable) {
1887         if (VDBG) Log.d(TAG, "setNcmTethering(" + enable + ")");
1888 
1889         // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be
1890         // available.
1891         if (mConfig.isUsingNcm() && enable) return TETHER_ERROR_SERVICE_UNAVAIL;
1892 
1893         UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
1894         usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_NCM : UsbManager.FUNCTION_NONE);
1895         return TETHER_ERROR_NO_ERROR;
1896     }
1897 
1898     // TODO review API - figure out how to delete these entirely.
getTetheredIfaces()1899     String[] getTetheredIfaces() {
1900         ArrayList<String> list = new ArrayList<String>();
1901         for (int i = 0; i < mTetherStates.size(); i++) {
1902             TetherState tetherState = mTetherStates.valueAt(i);
1903             if (tetherState.lastState == IpServer.STATE_TETHERED) {
1904                 list.add(mTetherStates.keyAt(i));
1905             }
1906         }
1907         return list.toArray(new String[list.size()]);
1908     }
1909 
getTetherableIfacesForTest()1910     String[] getTetherableIfacesForTest() {
1911         ArrayList<String> list = new ArrayList<String>();
1912         for (int i = 0; i < mTetherStates.size(); i++) {
1913             TetherState tetherState = mTetherStates.valueAt(i);
1914             if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
1915                 list.add(mTetherStates.keyAt(i));
1916             }
1917         }
1918         return list.toArray(new String[list.size()]);
1919     }
1920 
logMessage(State state, int what)1921     private void logMessage(State state, int what) {
1922         mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
1923     }
1924 
1925     // Needed because the canonical source of upstream truth is just the
1926     // upstream interface set, |mCurrentUpstreamIfaceSet|.
pertainsToCurrentUpstream(UpstreamNetworkState ns)1927     private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) {
1928         if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
1929             for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
1930                 if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
1931                     return true;
1932                 }
1933             }
1934         }
1935         return false;
1936     }
1937 
1938     class TetherMainSM extends StateMachine {
1939         // an interface SM has requested Tethering/Local Hotspot
1940         static final int EVENT_IFACE_SERVING_STATE_ACTIVE       = BASE_MAIN_SM + 1;
1941         // an interface SM has unrequested Tethering/Local Hotspot
1942         static final int EVENT_IFACE_SERVING_STATE_INACTIVE     = BASE_MAIN_SM + 2;
1943         // upstream connection change - do the right thing
1944         static final int CMD_UPSTREAM_CHANGED                   = BASE_MAIN_SM + 3;
1945         // we don't have a valid upstream conn, check again after a delay
1946         static final int CMD_RETRY_UPSTREAM                     = BASE_MAIN_SM + 4;
1947         // Events from NetworkCallbacks that we process on the main state
1948         // machine thread on behalf of the UpstreamNetworkMonitor.
1949         static final int EVENT_UPSTREAM_CALLBACK                = BASE_MAIN_SM + 5;
1950         // we treated the error and want now to clear it
1951         static final int CMD_CLEAR_ERROR                        = BASE_MAIN_SM + 6;
1952         static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MAIN_SM + 7;
1953         // Events from EntitlementManager to choose upstream again.
1954         static final int EVENT_UPSTREAM_PERMISSION_CHANGED      = BASE_MAIN_SM + 8;
1955         // Internal request from IpServer to enable or disable downstream.
1956         static final int EVENT_REQUEST_CHANGE_DOWNSTREAM        = BASE_MAIN_SM + 9;
1957         private final State mInitialState;
1958         private final State mTetherModeAliveState;
1959 
1960         private final State mSetIpForwardingEnabledErrorState;
1961         private final State mSetIpForwardingDisabledErrorState;
1962         private final State mStartTetheringErrorState;
1963         private final State mStopTetheringErrorState;
1964         private final State mSetDnsForwardersErrorState;
1965 
1966         // This list is a little subtle.  It contains all the interfaces that currently are
1967         // requesting tethering, regardless of whether these interfaces are still members of
1968         // mTetherStates.  This allows us to maintain the following predicates:
1969         //
1970         // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1971         //    interfaces.
1972         // 2) mNotifyList contains all state machines that may have outstanding tethering state
1973         //    that needs to be torn down.
1974         // 3) Use mNotifyList for predictable ordering order for ConnectedClientsTracker.
1975         //
1976         // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1977         // so that the garbage collector does not clean up the state machine before it has a chance
1978         // to tear itself down.
1979         private final ArrayList<IpServer> mNotifyList;
1980         private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
1981         private final OffloadWrapper mOffload;
1982         // TODO: Figure out how to merge this and other downstream-tracking objects
1983         // into a single coherent structure.
1984         private final HashSet<IpServer> mForwardedDownstreams;
1985 
1986         private static final int UPSTREAM_SETTLE_TIME_MS     = 10000;
1987 
TetherMainSM(String name, Looper looper, TetheringDependencies deps)1988         TetherMainSM(String name, Looper looper, TetheringDependencies deps) {
1989             super(name, looper);
1990 
1991             mForwardedDownstreams = new HashSet<>();
1992             mInitialState = new InitialState();
1993             mTetherModeAliveState = new TetherModeAliveState();
1994             mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
1995             mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
1996             mStartTetheringErrorState = new StartTetheringErrorState();
1997             mStopTetheringErrorState = new StopTetheringErrorState();
1998             mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
1999 
2000             addState(mInitialState);
2001             addState(mTetherModeAliveState);
2002             addState(mSetIpForwardingEnabledErrorState);
2003             addState(mSetIpForwardingDisabledErrorState);
2004             addState(mStartTetheringErrorState);
2005             addState(mStopTetheringErrorState);
2006             addState(mSetDnsForwardersErrorState);
2007 
2008             mNotifyList = new ArrayList<>();
2009             mIPv6TetheringCoordinator = deps.makeIPv6TetheringCoordinator(mNotifyList, mLog);
2010             mOffload = new OffloadWrapper();
2011 
2012             setInitialState(mInitialState);
2013         }
2014 
2015         /**
2016          * Returns all downstreams that are serving clients, regardless of they are actually
2017          * tethered or localOnly. This must be called on the tethering thread (not thread-safe).
2018          */
2019         @NonNull
getAllDownstreams()2020         public List<IpServer> getAllDownstreams() {
2021             return mNotifyList;
2022         }
2023 
2024         class InitialState extends State {
2025             @Override
processMessage(Message message)2026             public boolean processMessage(Message message) {
2027                 logMessage(this, message.what);
2028                 switch (message.what) {
2029                     case EVENT_IFACE_SERVING_STATE_ACTIVE: {
2030                         final IpServer who = (IpServer) message.obj;
2031                         if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
2032                         handleInterfaceServingStateActive(message.arg1, who);
2033                         transitionTo(mTetherModeAliveState);
2034                         break;
2035                     }
2036                     case EVENT_IFACE_SERVING_STATE_INACTIVE: {
2037                         final IpServer who = (IpServer) message.obj;
2038                         if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
2039                         handleInterfaceServingStateInactive(who);
2040                         break;
2041                     }
2042                     case EVENT_IFACE_UPDATE_LINKPROPERTIES:
2043                         // Silently ignore these for now.
2044                         break;
2045                     default:
2046                         return NOT_HANDLED;
2047                 }
2048                 return HANDLED;
2049             }
2050         }
2051 
turnOnMainTetherSettings()2052         protected boolean turnOnMainTetherSettings() {
2053             final TetheringConfiguration cfg = mConfig;
2054             try {
2055                 mNetd.ipfwdEnableForwarding(TAG);
2056             } catch (RemoteException | ServiceSpecificException e) {
2057                 mLog.e(e);
2058                 transitionTo(mSetIpForwardingEnabledErrorState);
2059                 return false;
2060             }
2061 
2062             // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
2063             // Legacy DHCP server is disabled if passed an empty ranges array
2064             final String[] dhcpRanges = cfg.useLegacyDhcpServer()
2065                     ? cfg.legacyDhcpRanges : new String[0];
2066             try {
2067                 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
2068             } catch (RemoteException | ServiceSpecificException e) {
2069                 try {
2070                     // Stop and retry.
2071                     mNetd.tetherStop();
2072                     NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
2073                 } catch (RemoteException | ServiceSpecificException ee) {
2074                     mLog.e(ee);
2075                     transitionTo(mStartTetheringErrorState);
2076                     return false;
2077                 }
2078             }
2079             mLog.log("SET main tether settings: ON");
2080             return true;
2081         }
2082 
turnOffMainTetherSettings()2083         protected boolean turnOffMainTetherSettings() {
2084             try {
2085                 mNetd.tetherStop();
2086             } catch (RemoteException | ServiceSpecificException e) {
2087                 mLog.e(e);
2088                 transitionTo(mStopTetheringErrorState);
2089                 return false;
2090             }
2091             try {
2092                 mNetd.ipfwdDisableForwarding(TAG);
2093             } catch (RemoteException | ServiceSpecificException e) {
2094                 mLog.e(e);
2095                 transitionTo(mSetIpForwardingDisabledErrorState);
2096                 return false;
2097             }
2098             transitionTo(mInitialState);
2099             mLog.log("SET main tether settings: OFF");
2100             return true;
2101         }
2102 
chooseUpstreamType(boolean tryCell)2103         protected void chooseUpstreamType(boolean tryCell) {
2104             // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
2105             // do not currently know how to watch for changes in DUN settings.
2106             maybeDunSettingChanged();
2107 
2108             final TetheringConfiguration config = mConfig;
2109             final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically)
2110                     ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
2111                     : mUpstreamNetworkMonitor.selectPreferredUpstreamType(
2112                             config.preferredUpstreamIfaceTypes);
2113 
2114             if (ns == null) {
2115                 if (tryCell) {
2116                     mUpstreamNetworkMonitor.setTryCell(true);
2117                     // We think mobile should be coming up; don't set a retry.
2118                 } else {
2119                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
2120                 }
2121             } else if (!isCellular(ns)) {
2122                 mUpstreamNetworkMonitor.setTryCell(false);
2123             }
2124 
2125             setUpstreamNetwork(ns);
2126             final Network newUpstream = (ns != null) ? ns.network : null;
2127             if (!Objects.equals(mTetherUpstream, newUpstream)) {
2128                 mTetherUpstream = newUpstream;
2129                 reportUpstreamChanged(mTetherUpstream);
2130                 // Need to notify capabilities change after upstream network changed because
2131                 // upstream may switch to existing network which don't have
2132                 // UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES callback.
2133                 mNotificationUpdater.onUpstreamCapabilitiesChanged(
2134                         (ns != null) ? ns.networkCapabilities : null);
2135             }
2136             mTetheringMetrics.maybeUpdateUpstreamType(ns);
2137         }
2138 
setUpstreamNetwork(UpstreamNetworkState ns)2139         protected void setUpstreamNetwork(UpstreamNetworkState ns) {
2140             InterfaceSet ifaces = null;
2141             if (ns != null) {
2142                 // Find the interface with the default IPv4 route. It may be the
2143                 // interface described by linkProperties, or one of the interfaces
2144                 // stacked on top of it.
2145                 mLog.i("Looking for default routes on: " + ns.linkProperties);
2146                 ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns);
2147                 mLog.i("Found upstream interface(s): " + ifaces);
2148             }
2149 
2150             if (ifaces != null) {
2151                 setDnsForwarders(ns.network, ns.linkProperties);
2152             }
2153             notifyDownstreamsOfNewUpstreamIface(ifaces);
2154             if (ns != null && pertainsToCurrentUpstream(ns)) {
2155                 // If we already have UpstreamNetworkState for this network update it immediately.
2156                 handleNewUpstreamNetworkState(ns);
2157             } else if (mCurrentUpstreamIfaceSet == null) {
2158                 // There are no available upstream networks.
2159                 handleNewUpstreamNetworkState(null);
2160             }
2161         }
2162 
setDnsForwarders(final Network network, final LinkProperties lp)2163         protected void setDnsForwarders(final Network network, final LinkProperties lp) {
2164             // TODO: Set v4 and/or v6 DNS per available connectivity.
2165             final Collection<InetAddress> dnses = lp.getDnsServers();
2166             // TODO: Properly support the absence of DNS servers.
2167             final String[] dnsServers;
2168             if (dnses != null && !dnses.isEmpty()) {
2169                 dnsServers = new String[dnses.size()];
2170                 int i = 0;
2171                 for (InetAddress dns : dnses) {
2172                     dnsServers[i++] = dns.getHostAddress();
2173                 }
2174             } else {
2175                 dnsServers = mConfig.defaultIPv4DNS;
2176             }
2177             final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
2178             try {
2179                 mNetd.tetherDnsSet(netId, dnsServers);
2180                 mLog.log(String.format(
2181                         "SET DNS forwarders: network=%s dnsServers=%s",
2182                         network, Arrays.toString(dnsServers)));
2183             } catch (RemoteException | ServiceSpecificException e) {
2184                 // TODO: Investigate how this can fail and what exactly
2185                 // happens if/when such failures occur.
2186                 mLog.e("setting DNS forwarders failed, " + e);
2187                 transitionTo(mSetDnsForwardersErrorState);
2188             }
2189         }
2190 
notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces)2191         protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
2192             mCurrentUpstreamIfaceSet = ifaces;
2193             for (IpServer ipServer : mNotifyList) {
2194                 ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
2195             }
2196         }
2197 
handleNewUpstreamNetworkState(UpstreamNetworkState ns)2198         protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
2199             mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
2200             mOffload.updateUpstreamNetworkState(ns);
2201             mBpfCoordinator.updateUpstreamNetworkState(ns);
2202         }
2203 
handleInterfaceServingStateActive(int mode, IpServer who)2204         private void handleInterfaceServingStateActive(int mode, IpServer who) {
2205             if (mNotifyList.indexOf(who) < 0) {
2206                 mNotifyList.add(who);
2207                 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
2208             }
2209 
2210             if (mode == IpServer.STATE_TETHERED) {
2211                 // No need to notify OffloadController just yet as there are no
2212                 // "offload-able" prefixes to pass along. This will handled
2213                 // when the TISM informs Tethering of its LinkProperties.
2214                 mForwardedDownstreams.add(who);
2215             } else {
2216                 mOffload.excludeDownstreamInterface(who.interfaceName());
2217                 mForwardedDownstreams.remove(who);
2218             }
2219 
2220             // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
2221             if (who.interfaceType() == TETHERING_WIFI) {
2222                 final WifiManager mgr = getWifiManager();
2223                 final String iface = who.interfaceName();
2224                 switch (mode) {
2225                     case IpServer.STATE_TETHERED:
2226                         mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
2227                         break;
2228                     case IpServer.STATE_LOCAL_ONLY:
2229                         mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
2230                         break;
2231                     default:
2232                         Log.wtf(TAG, "Unknown active serving mode: " + mode);
2233                         break;
2234                 }
2235             }
2236         }
2237 
handleInterfaceServingStateInactive(IpServer who)2238         private void handleInterfaceServingStateInactive(IpServer who) {
2239             mNotifyList.remove(who);
2240             mIPv6TetheringCoordinator.removeActiveDownstream(who);
2241             mOffload.excludeDownstreamInterface(who.interfaceName());
2242             mForwardedDownstreams.remove(who);
2243             maybeDhcpLeasesChanged();
2244 
2245             // If this is a Wi-Fi interface, tell WifiManager of any errors
2246             // or the inactive serving state.
2247             if (who.interfaceType() == TETHERING_WIFI) {
2248                 final WifiManager mgr = getWifiManager();
2249                 final String iface = who.interfaceName();
2250                 if (mgr == null) {
2251                     Log.wtf(TAG, "Skipping WifiManager notification about inactive tethering");
2252                 } else if (who.lastError() != TETHER_ERROR_NO_ERROR) {
2253                     mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_CONFIGURATION_ERROR);
2254                 } else {
2255                     mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_UNSPECIFIED);
2256                 }
2257             }
2258         }
2259 
2260         @VisibleForTesting
handleUpstreamNetworkMonitorCallback(int arg1, Object o)2261         void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
2262             if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
2263                 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
2264                 return;
2265             }
2266 
2267             final UpstreamNetworkState ns = (UpstreamNetworkState) o;
2268             switch (arg1) {
2269                 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
2270                     mRoutingCoordinator.updateUpstreamPrefix(
2271                             ns.linkProperties, ns.networkCapabilities, ns.network);
2272                     break;
2273                 case UpstreamNetworkMonitor.EVENT_ON_LOST:
2274                     mRoutingCoordinator.removeUpstreamPrefix(ns.network);
2275                     break;
2276             }
2277 
2278             if (mConfig.chooseUpstreamAutomatically
2279                     && arg1 == UpstreamNetworkMonitor.EVENT_DEFAULT_SWITCHED) {
2280                 chooseUpstreamType(true);
2281                 return;
2282             }
2283 
2284             if (ns == null || !pertainsToCurrentUpstream(ns)) {
2285                 // TODO: In future, this is where upstream evaluation and selection
2286                 // could be handled for notifications which include sufficient data.
2287                 // For example, after CONNECTIVITY_ACTION listening is removed, here
2288                 // is where we could observe a Wi-Fi network becoming available and
2289                 // passing validation.
2290                 if (mCurrentUpstreamIfaceSet == null) {
2291                     // If we have no upstream interface, try to run through upstream
2292                     // selection again.  If, for example, IPv4 connectivity has shown up
2293                     // after IPv6 (e.g., 464xlat became available) we want the chance to
2294                     // notice and act accordingly.
2295                     chooseUpstreamType(false);
2296                 }
2297                 return;
2298             }
2299 
2300             switch (arg1) {
2301                 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
2302                     if (ns.network.equals(mTetherUpstream)) {
2303                         mNotificationUpdater.onUpstreamCapabilitiesChanged(ns.networkCapabilities);
2304                     }
2305                     handleNewUpstreamNetworkState(ns);
2306                     break;
2307                 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
2308                     chooseUpstreamType(false);
2309                     break;
2310                 case UpstreamNetworkMonitor.EVENT_ON_LOST:
2311                     // TODO: Re-evaluate possible upstreams. Currently upstream
2312                     // reevaluation is triggered via received CONNECTIVITY_ACTION
2313                     // broadcasts that result in being passed a
2314                     // TetherMainSM.CMD_UPSTREAM_CHANGED.
2315                     handleNewUpstreamNetworkState(null);
2316 
2317                     if (SdkLevel.isAtLeastU()) {
2318                         // Need to try DUN immediately if Wi-Fi goes down.
2319                         chooseUpstreamType(true);
2320                     }
2321                     break;
2322                 default:
2323                     mLog.e("Unknown arg1 value: " + arg1);
2324                     break;
2325             }
2326         }
2327 
upstreamWanted()2328         private boolean upstreamWanted() {
2329             return !mForwardedDownstreams.isEmpty();
2330         }
2331 
2332         class TetherModeAliveState extends State {
2333             boolean mUpstreamWanted = false;
2334             boolean mTryCell = true;
2335 
2336             @Override
enter()2337             public void enter() {
2338                 // If turning on main tether settings fails, we have already
2339                 // transitioned to an error state; exit early.
2340                 if (!turnOnMainTetherSettings()) {
2341                     return;
2342                 }
2343 
2344                 mRoutingCoordinator.maybeRemoveDeprecatedUpstreams();
2345                 mUpstreamNetworkMonitor.startObserveUpstreamNetworks();
2346 
2347                 // TODO: De-duplicate with updateUpstreamWanted() below.
2348                 if (upstreamWanted()) {
2349                     mUpstreamWanted = true;
2350                     mOffload.start();
2351                     chooseUpstreamType(true);
2352                     mTryCell = false;
2353                 }
2354                 mTetheringMetrics.initUpstreamUsageBaseline();
2355             }
2356 
2357             @Override
exit()2358             public void exit() {
2359                 mOffload.stop();
2360                 mUpstreamNetworkMonitor.stop();
2361                 notifyDownstreamsOfNewUpstreamIface(null);
2362                 handleNewUpstreamNetworkState(null);
2363                 if (mTetherUpstream != null) {
2364                     mTetherUpstream = null;
2365                     reportUpstreamChanged(null);
2366                     mNotificationUpdater.onUpstreamCapabilitiesChanged(null);
2367                 }
2368                 mTetheringMetrics.cleanup();
2369             }
2370 
updateUpstreamWanted()2371             private boolean updateUpstreamWanted() {
2372                 final boolean previousUpstreamWanted = mUpstreamWanted;
2373                 mUpstreamWanted = upstreamWanted();
2374                 if (mUpstreamWanted != previousUpstreamWanted) {
2375                     if (mUpstreamWanted) {
2376                         mOffload.start();
2377                     } else {
2378                         mOffload.stop();
2379                     }
2380                 }
2381                 return previousUpstreamWanted;
2382             }
2383 
2384             @Override
processMessage(Message message)2385             public boolean processMessage(Message message) {
2386                 logMessage(this, message.what);
2387                 boolean retValue = true;
2388                 switch (message.what) {
2389                     case EVENT_IFACE_SERVING_STATE_ACTIVE: {
2390                         IpServer who = (IpServer) message.obj;
2391                         if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
2392                         handleInterfaceServingStateActive(message.arg1, who);
2393                         who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED,
2394                                 mCurrentUpstreamIfaceSet);
2395                         // If there has been a change and an upstream is now
2396                         // desired, kick off the selection process.
2397                         final boolean previousUpstreamWanted = updateUpstreamWanted();
2398                         if (!previousUpstreamWanted && mUpstreamWanted) {
2399                             chooseUpstreamType(true);
2400                         }
2401                         break;
2402                     }
2403                     case EVENT_IFACE_SERVING_STATE_INACTIVE: {
2404                         IpServer who = (IpServer) message.obj;
2405                         if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
2406                         handleInterfaceServingStateInactive(who);
2407 
2408                         if (mNotifyList.isEmpty()) {
2409                             // This transitions us out of TetherModeAliveState,
2410                             // either to InitialState or an error state.
2411                             turnOffMainTetherSettings();
2412                             break;
2413                         }
2414 
2415                         if (DBG) {
2416                             Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size()
2417                                     + " live requests:");
2418                             for (IpServer o : mNotifyList) {
2419                                 Log.d(TAG, "  " + o);
2420                             }
2421                         }
2422                         // If there has been a change and an upstream is no
2423                         // longer desired, release any mobile requests.
2424                         final boolean previousUpstreamWanted = updateUpstreamWanted();
2425                         if (previousUpstreamWanted && !mUpstreamWanted) {
2426                             mUpstreamNetworkMonitor.setTryCell(false);
2427                         }
2428                         break;
2429                     }
2430                     case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
2431                         final LinkProperties newLp = (LinkProperties) message.obj;
2432                         if (message.arg1 == IpServer.STATE_TETHERED) {
2433                             mOffload.updateDownstreamLinkProperties(newLp);
2434                         } else {
2435                             mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
2436                         }
2437                         break;
2438                     }
2439                     case EVENT_UPSTREAM_PERMISSION_CHANGED:
2440                     case CMD_UPSTREAM_CHANGED:
2441                         updateUpstreamWanted();
2442                         if (!mUpstreamWanted) break;
2443 
2444                         // Need to try DUN immediately if Wi-Fi goes down.
2445                         chooseUpstreamType(true);
2446                         mTryCell = false;
2447                         break;
2448                     case CMD_RETRY_UPSTREAM:
2449                         updateUpstreamWanted();
2450                         if (!mUpstreamWanted) break;
2451 
2452                         chooseUpstreamType(mTryCell);
2453                         mTryCell = !mTryCell;
2454                         break;
2455                     case EVENT_UPSTREAM_CALLBACK: {
2456                         updateUpstreamWanted();
2457                         if (mUpstreamWanted) {
2458                             handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
2459                         }
2460                         break;
2461                     }
2462                     case EVENT_REQUEST_CHANGE_DOWNSTREAM: {
2463                         final int type = message.arg1;
2464                         final Boolean enabled = (Boolean) message.obj;
2465                         // Using a placeholder here is ok since we just need to the type of
2466                         // tethering to poke the link layer. When the link layer comes up, we won't
2467                         // have a pending request to use, but this matches the historical behavior.
2468                         // TODO: Get the TetheringRequest from IpServer and make sure to put it in
2469                         //       the pending list too.
2470                         enableTetheringInternal(enabled, createPlaceholderRequest(type), null);
2471                         break;
2472                     }
2473                     default:
2474                         retValue = false;
2475                         break;
2476                 }
2477                 return retValue;
2478             }
2479         }
2480 
2481         class ErrorState extends State {
2482             private int mErrorNotification;
2483 
2484             @Override
processMessage(Message message)2485             public boolean processMessage(Message message) {
2486                 boolean retValue = true;
2487                 switch (message.what) {
2488                     case EVENT_IFACE_SERVING_STATE_ACTIVE:
2489                         IpServer who = (IpServer) message.obj;
2490                         who.sendMessage(mErrorNotification);
2491                         break;
2492                     case CMD_CLEAR_ERROR:
2493                         mErrorNotification = TETHER_ERROR_NO_ERROR;
2494                         transitionTo(mInitialState);
2495                         break;
2496                     default:
2497                         retValue = false;
2498                 }
2499                 return retValue;
2500             }
2501 
notify(int msgType)2502             void notify(int msgType) {
2503                 mErrorNotification = msgType;
2504                 for (IpServer ipServer : mNotifyList) {
2505                     ipServer.sendMessage(msgType);
2506                 }
2507             }
2508 
2509         }
2510 
2511         class SetIpForwardingEnabledErrorState extends ErrorState {
2512             @Override
enter()2513             public void enter() {
2514                 Log.e(TAG, "Error in setIpForwardingEnabled");
2515                 notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR);
2516             }
2517         }
2518 
2519         class SetIpForwardingDisabledErrorState extends ErrorState {
2520             @Override
enter()2521             public void enter() {
2522                 Log.e(TAG, "Error in setIpForwardingDisabled");
2523                 notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR);
2524             }
2525         }
2526 
2527         class StartTetheringErrorState extends ErrorState {
2528             @Override
enter()2529             public void enter() {
2530                 Log.e(TAG, "Error in startTethering");
2531                 notify(IpServer.CMD_START_TETHERING_ERROR);
2532                 try {
2533                     mNetd.ipfwdDisableForwarding(TAG);
2534                 } catch (RemoteException | ServiceSpecificException e) { }
2535             }
2536         }
2537 
2538         class StopTetheringErrorState extends ErrorState {
2539             @Override
enter()2540             public void enter() {
2541                 Log.e(TAG, "Error in stopTethering");
2542                 notify(IpServer.CMD_STOP_TETHERING_ERROR);
2543                 try {
2544                     mNetd.ipfwdDisableForwarding(TAG);
2545                 } catch (RemoteException | ServiceSpecificException e) { }
2546             }
2547         }
2548 
2549         class SetDnsForwardersErrorState extends ErrorState {
2550             @Override
enter()2551             public void enter() {
2552                 Log.e(TAG, "Error in setDnsForwarders");
2553                 notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
2554                 try {
2555                     mNetd.tetherStop();
2556                 } catch (RemoteException | ServiceSpecificException e) { }
2557                 try {
2558                     mNetd.ipfwdDisableForwarding(TAG);
2559                 } catch (RemoteException | ServiceSpecificException e) { }
2560             }
2561         }
2562 
2563         // A wrapper class to handle multiple situations where several calls to
2564         // the OffloadController need to happen together.
2565         //
2566         // TODO: This suggests that the interface between OffloadController and
2567         // Tethering is in need of improvement. Refactor these calls into the
2568         // OffloadController implementation.
2569         class OffloadWrapper {
start()2570             public void start() {
2571                 final int status = mOffloadController.start() ? TETHER_HARDWARE_OFFLOAD_STARTED
2572                         : TETHER_HARDWARE_OFFLOAD_FAILED;
2573                 updateOffloadStatus(status);
2574                 sendOffloadExemptPrefixes();
2575             }
2576 
stop()2577             public void stop() {
2578                 mOffloadController.stop();
2579                 updateOffloadStatus(TETHER_HARDWARE_OFFLOAD_STOPPED);
2580             }
2581 
updateUpstreamNetworkState(UpstreamNetworkState ns)2582             public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
2583                 mOffloadController.setUpstreamLinkProperties(
2584                         (ns != null) ? ns.linkProperties : null);
2585             }
2586 
updateDownstreamLinkProperties(LinkProperties newLp)2587             public void updateDownstreamLinkProperties(LinkProperties newLp) {
2588                 // Update the list of offload-exempt prefixes before adding
2589                 // new prefixes on downstream interfaces to the offload HAL.
2590                 sendOffloadExemptPrefixes();
2591                 mOffloadController.notifyDownstreamLinkProperties(newLp);
2592             }
2593 
excludeDownstreamInterface(String ifname)2594             public void excludeDownstreamInterface(String ifname) {
2595                 // This and other interfaces may be in local-only hotspot mode;
2596                 // resend all local prefixes to the OffloadController.
2597                 sendOffloadExemptPrefixes();
2598                 mOffloadController.removeDownstreamInterface(ifname);
2599             }
2600 
sendOffloadExemptPrefixes()2601             public void sendOffloadExemptPrefixes() {
2602                 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
2603             }
2604 
sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes)2605             public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
2606                 // Add in well-known minimum set.
2607                 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
2608                 // Add tragically hardcoded prefixes.
2609                 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
2610 
2611                 // Maybe add prefixes or addresses for downstreams, depending on
2612                 // the IP serving mode of each.
2613                 for (IpServer ipServer : mNotifyList) {
2614                     final LinkProperties lp = ipServer.linkProperties();
2615 
2616                     switch (ipServer.servingMode()) {
2617                         case IpServer.STATE_UNAVAILABLE:
2618                         case IpServer.STATE_AVAILABLE:
2619                             // No usable LinkProperties in these states.
2620                             continue;
2621                         case IpServer.STATE_TETHERED:
2622                             // Only add IPv4 /32 and IPv6 /128 prefixes. The
2623                             // directly-connected prefixes will be sent as
2624                             // downstream "offload-able" prefixes.
2625                             for (LinkAddress addr : lp.getAllLinkAddresses()) {
2626                                 final InetAddress ip = addr.getAddress();
2627                                 if (ip.isLinkLocalAddress()) continue;
2628                                 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
2629                             }
2630                             break;
2631                         case IpServer.STATE_LOCAL_ONLY:
2632                             // Add prefixes covering all local IPs.
2633                             localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
2634                             break;
2635                     }
2636                 }
2637 
2638                 mOffloadController.setLocalPrefixes(localPrefixes);
2639             }
2640 
updateOffloadStatus(final int newStatus)2641             private void updateOffloadStatus(final int newStatus) {
2642                 if (newStatus == mOffloadStatus) return;
2643 
2644                 mOffloadStatus = newStatus;
2645                 reportOffloadStatusChanged(mOffloadStatus);
2646             }
2647         }
2648     }
2649 
startTrackDefaultNetwork()2650     private void startTrackDefaultNetwork() {
2651         mUpstreamNetworkMonitor.startTrackDefaultNetwork(mEntitlementMgr);
2652     }
2653 
2654     /** Get the latest value of the tethering entitlement check. */
requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi)2655     void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
2656             boolean showEntitlementUi) {
2657         if (receiver == null) return;
2658 
2659         mHandler.post(() -> {
2660             mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver,
2661                     showEntitlementUi);
2662         });
2663     }
2664 
2665     /** Register tethering event callback */
registerTetheringEventCallback(ITetheringEventCallback callback)2666     void registerTetheringEventCallback(ITetheringEventCallback callback) {
2667         final int uid = mDeps.getBinderCallingUid();
2668         final boolean hasSystemPrivilege = hasCallingPermission(NETWORK_SETTINGS)
2669                 || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
2670                 || hasCallingPermission(NETWORK_STACK);
2671         mHandler.post(() -> {
2672             CallbackCookie cookie = new CallbackCookie(uid, hasSystemPrivilege);
2673             mTetheringEventCallbacks.register(callback, cookie);
2674             final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
2675             parcel.supportedTypes = mSupportedTypeBitmap;
2676             parcel.upstreamNetwork = mTetherUpstream;
2677             parcel.config = mConfig.toStableParcelable();
2678             parcel.states = buildTetherStatesParcel(cookie);
2679             parcel.tetheredClients = hasSystemPrivilege
2680                     ? mConnectedClientsTracker.getLastTetheredClients()
2681                     : Collections.emptyList();
2682             parcel.offloadStatus = mOffloadStatus;
2683             try {
2684                 callback.onCallbackStarted(parcel);
2685             } catch (RemoteException e) {
2686                 // Not really very much to do here.
2687             }
2688         });
2689     }
2690 
hasCallingPermission(@onNull String permission)2691     private boolean hasCallingPermission(@NonNull String permission) {
2692         return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
2693     }
2694 
2695     /** Unregister tethering event callback */
unregisterTetheringEventCallback(ITetheringEventCallback callback)2696     void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
2697         mHandler.post(() -> {
2698             mTetheringEventCallbacks.unregister(callback);
2699         });
2700     }
2701 
reportTetheringSupportedChange(final long supportedBitmap)2702     private void reportTetheringSupportedChange(final long supportedBitmap) {
2703         final int length = mTetheringEventCallbacks.beginBroadcast();
2704         try {
2705             for (int i = 0; i < length; i++) {
2706                 try {
2707                     mTetheringEventCallbacks.getBroadcastItem(i).onSupportedTetheringTypes(
2708                             supportedBitmap);
2709                 } catch (RemoteException e) {
2710                     // Not really very much to do here.
2711                 }
2712             }
2713         } finally {
2714             mTetheringEventCallbacks.finishBroadcast();
2715         }
2716     }
2717 
reportUpstreamChanged(final Network network)2718     private void reportUpstreamChanged(final Network network) {
2719         final int length = mTetheringEventCallbacks.beginBroadcast();
2720         try {
2721             for (int i = 0; i < length; i++) {
2722                 try {
2723                     mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
2724                 } catch (RemoteException e) {
2725                     // Not really very much to do here.
2726                 }
2727             }
2728         } finally {
2729             mTetheringEventCallbacks.finishBroadcast();
2730         }
2731     }
2732 
reportConfigurationChanged(TetheringConfigurationParcel config)2733     private void reportConfigurationChanged(TetheringConfigurationParcel config) {
2734         final int length = mTetheringEventCallbacks.beginBroadcast();
2735         try {
2736             for (int i = 0; i < length; i++) {
2737                 try {
2738                     mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config);
2739                     // TODO(b/148139325): send tetheringSupported on configuration change
2740                 } catch (RemoteException e) {
2741                     // Not really very much to do here.
2742                 }
2743             }
2744         } finally {
2745             mTetheringEventCallbacks.finishBroadcast();
2746         }
2747     }
2748 
sendTetherStatesChangedCallback()2749     private void sendTetherStatesChangedCallback() {
2750         final int length = mTetheringEventCallbacks.beginBroadcast();
2751         try {
2752             for (int i = 0; i < length; i++) {
2753                 try {
2754                     TetherStatesParcel parcel = buildTetherStatesParcel(
2755                             (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i));
2756                     mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(parcel);
2757                 } catch (RemoteException e) {
2758                     // Not really very much to do here.
2759                 }
2760             }
2761         } finally {
2762             mTetheringEventCallbacks.finishBroadcast();
2763         }
2764 
2765         if (DBG) {
2766             // Use a CallbackCookie with system privilege so nothing is redacted.
2767             TetherStatesParcel parcel = buildTetherStatesParcel(
2768                     new CallbackCookie(Process.SYSTEM_UID, true /* hasSystemPrivilege */));
2769             Log.d(TAG, String.format(
2770                     "sendTetherStatesChangedCallback %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
2771                     "avail", TextUtils.join(",", Arrays.asList(parcel.availableList)),
2772                     "local_only", TextUtils.join(",", Arrays.asList(parcel.localOnlyList)),
2773                     "tether", TextUtils.join(",", Arrays.asList(parcel.tetheredList)),
2774                     "error", TextUtils.join(",", Arrays.asList(parcel.erroredIfaceList))));
2775         }
2776     }
2777 
reportTetherClientsChanged(List<TetheredClient> clients)2778     private void reportTetherClientsChanged(List<TetheredClient> clients) {
2779         final int length = mTetheringEventCallbacks.beginBroadcast();
2780         try {
2781             for (int i = 0; i < length; i++) {
2782                 try {
2783                     final CallbackCookie cookie =
2784                             (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i);
2785                     if (!cookie.hasSystemPrivilege) continue;
2786                     mTetheringEventCallbacks.getBroadcastItem(i).onTetherClientsChanged(clients);
2787                 } catch (RemoteException e) {
2788                     // Not really very much to do here.
2789                 }
2790             }
2791         } finally {
2792             mTetheringEventCallbacks.finishBroadcast();
2793         }
2794     }
2795 
reportOffloadStatusChanged(final int status)2796     private void reportOffloadStatusChanged(final int status) {
2797         final int length = mTetheringEventCallbacks.beginBroadcast();
2798         try {
2799             for (int i = 0; i < length; i++) {
2800                 try {
2801                     mTetheringEventCallbacks.getBroadcastItem(i).onOffloadStatusChanged(status);
2802                 } catch (RemoteException e) {
2803                     // Not really very much to do here.
2804                 }
2805             }
2806         } finally {
2807             mTetheringEventCallbacks.finishBroadcast();
2808         }
2809     }
2810 
updateSupportedDownstreams(final TetheringConfiguration config)2811     private void updateSupportedDownstreams(final TetheringConfiguration config) {
2812         final long preSupportedBitmap = mSupportedTypeBitmap;
2813 
2814         if (!isTetheringAllowed() || mEntitlementMgr.isProvisioningNeededButUnavailable()) {
2815             mSupportedTypeBitmap = 0;
2816         } else {
2817             mSupportedTypeBitmap = makeSupportedDownstreams(config);
2818         }
2819 
2820         if (preSupportedBitmap != mSupportedTypeBitmap) {
2821             reportTetheringSupportedChange(mSupportedTypeBitmap);
2822         }
2823     }
2824 
makeSupportedDownstreams(final TetheringConfiguration config)2825     private long makeSupportedDownstreams(final TetheringConfiguration config) {
2826         long types = 0;
2827         if (config.tetherableUsbRegexs.length != 0) types |= (1 << TETHERING_USB);
2828 
2829         if (config.tetherableWifiRegexs.length != 0) types |= (1 << TETHERING_WIFI);
2830 
2831         if (config.tetherableBluetoothRegexs.length != 0) types |= (1 << TETHERING_BLUETOOTH);
2832 
2833         // Before T, isTetheringSupported would return true if wifi, usb and bluetooth tethering are
2834         // disabled (whole tethering settings would be hidden). This means tethering would also not
2835         // support wifi p2p, ethernet tethering and mirrorlink. This is wrong but probably there are
2836         // some devices in the field rely on this to disable tethering entirely.
2837         if (!SdkLevel.isAtLeastT() && types == 0) return types;
2838 
2839         if (config.tetherableNcmRegexs.length != 0) types |= (1 << TETHERING_NCM);
2840 
2841         if (config.tetherableWifiP2pRegexs.length != 0) types |= (1 << TETHERING_WIFI_P2P);
2842 
2843         if (isEthernetSupported()) types |= (1 << TETHERING_ETHERNET);
2844 
2845         return types;
2846     }
2847 
2848     // if ro.tether.denied = true we default to no tethering
2849     // gservices could set the secure setting to 1 though to enable it on a build where it
2850     // had previously been turned off.
isTetheringAllowed()2851     boolean isTetheringAllowed() {
2852         final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
2853         final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
2854                 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
2855         return tetherSupported
2856                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
2857     }
2858 
isTetheringSupported()2859     boolean isTetheringSupported() {
2860         return mSupportedTypeBitmap > 0;
2861     }
2862 
dumpBpf(IndentingPrintWriter pw)2863     private void dumpBpf(IndentingPrintWriter pw) {
2864         pw.println("BPF offload:");
2865         pw.increaseIndent();
2866         mBpfCoordinator.dump(pw);
2867         pw.decreaseIndent();
2868     }
2869 
doDump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2870     void doDump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
2871         // Binder.java closes the resource for us.
2872         @SuppressWarnings("resource") final IndentingPrintWriter pw = new IndentingPrintWriter(
2873                 writer, "  ");
2874 
2875         // Used for testing instead of human debug.
2876         if (CollectionUtils.contains(args, "bpfRawMap")) {
2877             mBpfCoordinator.dumpRawMap(pw, args);
2878             return;
2879         }
2880 
2881         if (CollectionUtils.contains(args, "bpf")) {
2882             dumpBpf(pw);
2883             return;
2884         }
2885 
2886         pw.println("Tethering:");
2887         pw.increaseIndent();
2888 
2889         pw.println("Callbacks registered: "
2890                 + mTetheringEventCallbacks.getRegisteredCallbackCount());
2891 
2892         pw.println("Configuration:");
2893         pw.increaseIndent();
2894         final TetheringConfiguration cfg = mConfig;
2895         cfg.dump(pw);
2896         pw.decreaseIndent();
2897 
2898         pw.println("Entitlement:");
2899         pw.increaseIndent();
2900         mEntitlementMgr.dump(pw);
2901         pw.decreaseIndent();
2902 
2903         pw.println("Tether state:");
2904         pw.increaseIndent();
2905         for (int i = 0; i < mTetherStates.size(); i++) {
2906             final String iface = mTetherStates.keyAt(i);
2907             final TetherState tetherState = mTetherStates.valueAt(i);
2908             pw.print(iface + " - ");
2909 
2910             switch (tetherState.lastState) {
2911                 case IpServer.STATE_UNAVAILABLE:
2912                     pw.print("UnavailableState");
2913                     break;
2914                 case IpServer.STATE_AVAILABLE:
2915                     pw.print("AvailableState");
2916                     break;
2917                 case IpServer.STATE_TETHERED:
2918                     pw.print("TetheredState");
2919                     break;
2920                 case IpServer.STATE_LOCAL_ONLY:
2921                     pw.print("LocalHotspotState");
2922                     break;
2923                 default:
2924                     pw.print("UnknownState");
2925                     break;
2926             }
2927             pw.println(" - lastError = " + tetherState.lastError);
2928         }
2929         pw.println("Upstream wanted: " + mTetherMainSM.upstreamWanted());
2930         pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet);
2931         pw.decreaseIndent();
2932 
2933         pw.println("Hardware offload:");
2934         pw.increaseIndent();
2935         mOffloadController.dump(pw);
2936         pw.decreaseIndent();
2937 
2938         dumpBpf(pw);
2939 
2940         if (mWearableConnectionManager != null) {
2941             pw.println("WearableConnectionManager:");
2942             pw.increaseIndent();
2943             mWearableConnectionManager.dump(pw);
2944             pw.decreaseIndent();
2945         }
2946 
2947         pw.println("Log:");
2948         pw.increaseIndent();
2949         if (CollectionUtils.contains(args, "--short")) {
2950             pw.println("<log removed for brevity>");
2951         } else {
2952             mLog.dump(fd, pw, args);
2953         }
2954         pw.decreaseIndent();
2955 
2956         pw.decreaseIndent();
2957     }
2958 
dump(@onNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args)2959     void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
2960         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2961                 != PERMISSION_GRANTED) {
2962             writer.println("Permission Denial: can't dump.");
2963             return;
2964         }
2965 
2966         if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> doDump(fd, writer, args),
2967                 DUMP_TIMEOUT_MS)) {
2968             writer.println("Dump timeout after " + DUMP_TIMEOUT_MS + "ms");
2969         }
2970     }
2971 
maybeDhcpLeasesChanged()2972     private void maybeDhcpLeasesChanged() {
2973         // null means wifi clients did not change.
2974         updateConnectedClients(null, null);
2975     }
2976 
updateConnectedClients(final List<WifiClient> wifiClients, final List<WifiClient> localOnlyClients)2977     private void updateConnectedClients(final List<WifiClient> wifiClients,
2978             final List<WifiClient> localOnlyClients) {
2979         if (mConnectedClientsTracker.updateConnectedClients(mTetherMainSM.getAllDownstreams(),
2980                 wifiClients, localOnlyClients)) {
2981             reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
2982         }
2983     }
2984 
2985     private class ControlCallback extends IpServer.Callback {
2986         @Override
updateInterfaceState(IpServer who, int state, int lastError)2987         public void updateInterfaceState(IpServer who, int state, int lastError) {
2988             final String iface = who.interfaceName();
2989             final TetherState tetherState = mTetherStates.get(iface);
2990             if (tetherState != null && tetherState.ipServer.equals(who)) {
2991                 tetherState.lastState = state;
2992                 tetherState.lastError = lastError;
2993             } else {
2994                 // Note: Even if an IpServer exists for this iface, it may be different from "who"
2995                 // if a new IpServer fills the gap before the IpServer.STATE_UNAVAILABLE transition.
2996                 // TODO: remove this comment once the sync state machine is enabled everywhere.
2997                 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
2998             }
2999 
3000             mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, lastError));
3001 
3002             // If TetherMainSM is in ErrorState, TetherMainSM stays there.
3003             // Thus we give a chance for TetherMainSM to recover to InitialState
3004             // by sending CMD_CLEAR_ERROR
3005             if (lastError == TETHER_ERROR_INTERNAL_ERROR) {
3006                 mTetherMainSM.sendMessage(TetherMainSM.CMD_CLEAR_ERROR, who);
3007             }
3008             int which;
3009             switch (state) {
3010                 case IpServer.STATE_UNAVAILABLE:
3011                     which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
3012                     break;
3013                 case IpServer.STATE_AVAILABLE:
3014                     if (lastError != TETHER_ERROR_NO_ERROR) {
3015                         // IpServer transitioned from an enabled state (STATE_TETHERED or
3016                         // STATE_LOCAL_ONLY) back to STATE_AVAILABLE due to an error, so make sure
3017                         // we remove the serving request from RequestTracker.
3018                         // TODO: don't continue to use IpServers after they have hit an error, and
3019                         // instead move them to STATE_UNAVAILABLE. This code can then
3020                         // unconditionally remove the serving request whenever the IpServer enters
3021                         // STATE_UNAVAILABLE.
3022                         mRequestTracker.removeServingRequest(who);
3023                     }
3024                     which = TetherMainSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
3025                     break;
3026                 case IpServer.STATE_TETHERED:
3027                 case IpServer.STATE_LOCAL_ONLY:
3028                     which = TetherMainSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
3029                     break;
3030                 default:
3031                     Log.wtf(TAG, "Unknown interface state: " + state);
3032                     return;
3033             }
3034             mTetherMainSM.sendMessage(which, state, 0, who);
3035             notifyTetherStatesChanged();
3036         }
3037 
3038         @Override
updateLinkProperties(IpServer who, LinkProperties newLp)3039         public void updateLinkProperties(IpServer who, LinkProperties newLp) {
3040             final String iface = who.interfaceName();
3041             final int state;
3042             final TetherState tetherState = mTetherStates.get(iface);
3043             if (tetherState != null && tetherState.ipServer.equals(who)) {
3044                 state = tetherState.lastState;
3045             } else {
3046                 mLog.log("got notification from stale iface " + iface);
3047                 return;
3048             }
3049 
3050             mLog.log(String.format(
3051                     "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
3052                     iface, IpServer.getStateString(state), newLp));
3053             final int which = TetherMainSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
3054             mTetherMainSM.sendMessage(which, state, 0, newLp);
3055         }
3056 
3057         @Override
dhcpLeasesChanged()3058         public void dhcpLeasesChanged() {
3059             maybeDhcpLeasesChanged();
3060         }
3061 
3062         @Override
requestEnableTethering(int tetheringType, boolean enabled)3063         public void requestEnableTethering(int tetheringType, boolean enabled) {
3064             mTetherMainSM.sendMessage(TetherMainSM.EVENT_REQUEST_CHANGE_DOWNSTREAM,
3065                     tetheringType, 0, enabled ? Boolean.TRUE : Boolean.FALSE);
3066         }
3067     }
3068 
hasSystemFeature(final String feature)3069     private boolean hasSystemFeature(final String feature) {
3070         return mContext.getPackageManager().hasSystemFeature(feature);
3071     }
3072 
checkTetherableType(int type)3073     private boolean checkTetherableType(int type) {
3074         if ((type == TETHERING_WIFI || type == TETHERING_WIGIG)
3075                 && !hasSystemFeature(PackageManager.FEATURE_WIFI)) {
3076             return false;
3077         }
3078 
3079         if (type == TETHERING_WIFI_P2P && !hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
3080             return false;
3081         }
3082 
3083         return type != TETHERING_INVALID;
3084     }
3085 
ensureIpServerStartedForInterface(final String iface)3086     private void ensureIpServerStartedForInterface(final String iface) {
3087         // If we don't care about this type of interface, ignore.
3088         final int interfaceType = ifaceNameToType(iface);
3089         if (!checkTetherableType(interfaceType)) {
3090             mLog.log(iface + " is used for " + interfaceType + " which is not tetherable"
3091                      + " (-1 == INVALID is expected on upstream interface)");
3092             return;
3093         }
3094 
3095         ensureIpServerStartedForType(iface, interfaceType, false /* isNcm */);
3096     }
3097 
ensureIpServerStartedForType(final String iface, int interfaceType, boolean isNcm)3098     private void ensureIpServerStartedForType(final String iface, int interfaceType,
3099             boolean isNcm) {
3100         // If we have already started a TISM for this interface, skip.
3101         if (mTetherStates.containsKey(iface)) {
3102             mLog.log("active iface (" + iface + ") reported as added, ignoring");
3103             return;
3104         }
3105 
3106         mLog.i("adding IpServer for: " + iface);
3107         final TetherState tetherState = new TetherState(
3108                 new IpServer(iface, mContext, mHandler, interfaceType, mLog, mNetd, mBpfCoordinator,
3109                         mRoutingCoordinator, new ControlCallback(), mConfig, mTetheringMetrics,
3110                         mDeps.makeIpServerDependencies()), isNcm);
3111         mTetherStates.put(iface, tetherState);
3112         tetherState.ipServer.start();
3113     }
3114 
ensureIpServerStopped(final String iface)3115     private void ensureIpServerStopped(final String iface) {
3116         final TetherState tetherState = mTetherStates.get(iface);
3117         if (tetherState == null) return;
3118 
3119         mRequestTracker.removeServingRequest(tetherState.ipServer);
3120         tetherState.ipServer.stop();
3121         mLog.i("removing IpServer for: " + iface);
3122         mTetherStates.remove(iface);
3123     }
3124 
ensureIpServerUnwanted(final IpServer ipServer)3125     private void ensureIpServerUnwanted(final IpServer ipServer) {
3126         mLog.i("unrequesting IpServer: " + ipServer);
3127         mRequestTracker.removeServingRequest(ipServer);
3128         ipServer.unwanted();
3129     }
3130 
copy(String[] strarray)3131     private static String[] copy(String[] strarray) {
3132         return Arrays.copyOf(strarray, strarray.length);
3133     }
3134 
setPreferTestNetworks(final boolean prefer, IIntResultListener listener)3135     void setPreferTestNetworks(final boolean prefer, IIntResultListener listener) {
3136         mHandler.post(() -> {
3137             mUpstreamNetworkMonitor.setPreferTestNetworks(prefer);
3138             sendTetherResult(listener, TETHER_ERROR_NO_ERROR);
3139         });
3140     }
3141 
3142     @VisibleForTesting
getTetherMainSMForTesting()3143     public TetherMainSM getTetherMainSMForTesting() {
3144         return mTetherMainSM;
3145     }
3146 }
3147