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