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