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