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