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.server.connectivity;
18 
19 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
20 import static android.hardware.usb.UsbManager.USB_CONNECTED;
21 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
22 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
23 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
24 import static android.net.ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY;
25 import static android.net.ConnectivityManager.EXTRA_ACTIVE_TETHER;
26 import static android.net.ConnectivityManager.EXTRA_AVAILABLE_TETHER;
27 import static android.net.ConnectivityManager.EXTRA_ERRORED_TETHER;
28 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
29 import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
30 import static android.net.ConnectivityManager.TETHERING_INVALID;
31 import static android.net.ConnectivityManager.TETHERING_USB;
32 import static android.net.ConnectivityManager.TETHERING_WIFI;
33 import static android.net.ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
34 import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
35 import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL;
36 import static android.net.ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
37 import static android.net.ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
38 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
39 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
40 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
41 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
42 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
43 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
44 import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
45 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
46 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
47 
48 import static com.android.server.ConnectivityService.SHORT_ARG;
49 
50 import android.app.Notification;
51 import android.app.NotificationManager;
52 import android.app.PendingIntent;
53 import android.bluetooth.BluetoothAdapter;
54 import android.bluetooth.BluetoothPan;
55 import android.bluetooth.BluetoothProfile;
56 import android.bluetooth.BluetoothProfile.ServiceListener;
57 import android.content.BroadcastReceiver;
58 import android.content.Context;
59 import android.content.Intent;
60 import android.content.IntentFilter;
61 import android.content.res.Resources;
62 import android.hardware.usb.UsbManager;
63 import android.net.INetworkPolicyManager;
64 import android.net.INetworkStatsService;
65 import android.net.ITetheringEventCallback;
66 import android.net.IpPrefix;
67 import android.net.LinkAddress;
68 import android.net.LinkProperties;
69 import android.net.Network;
70 import android.net.NetworkInfo;
71 import android.net.NetworkState;
72 import android.net.NetworkUtils;
73 import android.net.ip.IpServer;
74 import android.net.util.InterfaceSet;
75 import android.net.util.PrefixUtils;
76 import android.net.util.SharedLog;
77 import android.net.util.VersionedBroadcastListener;
78 import android.net.wifi.WifiManager;
79 import android.os.Binder;
80 import android.os.Bundle;
81 import android.os.Handler;
82 import android.os.INetworkManagementService;
83 import android.os.Looper;
84 import android.os.Message;
85 import android.os.RemoteCallbackList;
86 import android.os.RemoteException;
87 import android.os.ResultReceiver;
88 import android.os.UserHandle;
89 import android.os.UserManager;
90 import android.os.UserManagerInternal;
91 import android.os.UserManagerInternal.UserRestrictionsListener;
92 import android.text.TextUtils;
93 import android.util.ArrayMap;
94 import android.util.Log;
95 import android.util.SparseArray;
96 
97 import com.android.internal.annotations.VisibleForTesting;
98 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
99 import com.android.internal.notification.SystemNotificationChannels;
100 import com.android.internal.telephony.TelephonyIntents;
101 import com.android.internal.util.DumpUtils;
102 import com.android.internal.util.IndentingPrintWriter;
103 import com.android.internal.util.MessageUtils;
104 import com.android.internal.util.Protocol;
105 import com.android.internal.util.State;
106 import com.android.internal.util.StateMachine;
107 import com.android.server.LocalServices;
108 import com.android.server.connectivity.tethering.EntitlementManager;
109 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
110 import com.android.server.connectivity.tethering.OffloadController;
111 import com.android.server.connectivity.tethering.TetheringConfiguration;
112 import com.android.server.connectivity.tethering.TetheringDependencies;
113 import com.android.server.connectivity.tethering.TetheringInterfaceUtils;
114 import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
115 import com.android.server.net.BaseNetworkObserver;
116 
117 import java.io.FileDescriptor;
118 import java.io.PrintWriter;
119 import java.net.InetAddress;
120 import java.util.ArrayList;
121 import java.util.Arrays;
122 import java.util.Collection;
123 import java.util.HashSet;
124 import java.util.Set;
125 
126 /**
127  * @hide
128  *
129  * This class holds much of the business logic to allow Android devices
130  * to act as IP gateways via USB, BT, and WiFi interfaces.
131  */
132 public class Tethering extends BaseNetworkObserver {
133 
134     private final static String TAG = Tethering.class.getSimpleName();
135     private final static boolean DBG = false;
136     private final static boolean VDBG = false;
137 
138     private static final Class[] messageClasses = {
139             Tethering.class, TetherMasterSM.class, IpServer.class
140     };
141     private static final SparseArray<String> sMagicDecoderRing =
142             MessageUtils.findMessageNames(messageClasses);
143 
144     private static class TetherState {
145         public final IpServer ipServer;
146         public int lastState;
147         public int lastError;
148 
TetherState(IpServer ipServer)149         public TetherState(IpServer ipServer) {
150             this.ipServer = ipServer;
151             // Assume all state machines start out available and with no errors.
152             lastState = IpServer.STATE_AVAILABLE;
153             lastError = TETHER_ERROR_NO_ERROR;
154         }
155 
isCurrentlyServing()156         public boolean isCurrentlyServing() {
157             switch (lastState) {
158                 case IpServer.STATE_TETHERED:
159                 case IpServer.STATE_LOCAL_ONLY:
160                     return true;
161                 default:
162                     return false;
163             }
164         }
165     }
166 
167     private final SharedLog mLog = new SharedLog(TAG);
168 
169     // used to synchronize public access to members
170     private final Object mPublicSync;
171     private final Context mContext;
172     private final ArrayMap<String, TetherState> mTetherStates;
173     private final BroadcastReceiver mStateReceiver;
174     private final INetworkManagementService mNMService;
175     private final INetworkStatsService mStatsService;
176     private final INetworkPolicyManager mPolicyManager;
177     private final Looper mLooper;
178     private final StateMachine mTetherMasterSM;
179     private final OffloadController mOffloadController;
180     private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
181     // TODO: Figure out how to merge this and other downstream-tracking objects
182     // into a single coherent structure.
183     private final HashSet<IpServer> mForwardedDownstreams;
184     private final VersionedBroadcastListener mCarrierConfigChange;
185     private final VersionedBroadcastListener mDefaultSubscriptionChange;
186     private final TetheringDependencies mDeps;
187     private final EntitlementManager mEntitlementMgr;
188     private final Handler mHandler;
189     private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
190             new RemoteCallbackList<>();
191 
192     private volatile TetheringConfiguration mConfig;
193     private InterfaceSet mCurrentUpstreamIfaceSet;
194     private Notification.Builder mTetheredNotificationBuilder;
195     private int mLastNotificationId;
196 
197     private boolean mRndisEnabled;       // track the RNDIS function enabled state
198     // True iff. WiFi tethering should be started when soft AP is ready.
199     private boolean mWifiTetherRequested;
200     private Network mTetherUpstream;
201 
Tethering(Context context, INetworkManagementService nmService, INetworkStatsService statsService, INetworkPolicyManager policyManager, Looper looper, MockableSystemProperties systemProperties, TetheringDependencies deps)202     public Tethering(Context context, INetworkManagementService nmService,
203             INetworkStatsService statsService, INetworkPolicyManager policyManager,
204             Looper looper, MockableSystemProperties systemProperties,
205             TetheringDependencies deps) {
206         mLog.mark("constructed");
207         mContext = context;
208         mNMService = nmService;
209         mStatsService = statsService;
210         mPolicyManager = policyManager;
211         mLooper = looper;
212         mDeps = deps;
213 
214         mPublicSync = new Object();
215 
216         mTetherStates = new ArrayMap<>();
217 
218         mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
219         mTetherMasterSM.start();
220 
221         mHandler = mTetherMasterSM.getHandler();
222         mOffloadController = new OffloadController(mHandler,
223                 mDeps.getOffloadHardwareInterface(mHandler, mLog),
224                 mContext.getContentResolver(), mNMService,
225                 mLog);
226         mUpstreamNetworkMonitor = deps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
227                 TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
228         mForwardedDownstreams = new HashSet<>();
229 
230         IntentFilter filter = new IntentFilter();
231         filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
232         // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
233         // permission is changed according to entitlement check result.
234         mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog,
235                 TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED, systemProperties);
236         mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
237             mLog.log("OBSERVED UiEnitlementFailed");
238             stopTethering(downstream);
239         });
240         mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
241             maybeDefaultDataSubChanged();
242             return mConfig;
243         });
244 
245         mCarrierConfigChange = new VersionedBroadcastListener(
246                 "CarrierConfigChangeListener", mContext, mHandler, filter,
247                 (Intent ignored) -> {
248                     mLog.log("OBSERVED carrier config change");
249                     updateConfiguration();
250                     mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
251                 });
252 
253         filter = new IntentFilter();
254         filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
255         mDefaultSubscriptionChange = new VersionedBroadcastListener(
256                 "DefaultSubscriptionChangeListener", mContext, mHandler, filter,
257                 (Intent ignored) -> {
258                     mLog.log("OBSERVED default data subscription change");
259                     maybeDefaultDataSubChanged();
260                     // To avoid launch unexpected provisioning checks, ignore re-provisioning when
261                     // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
262                     // triggered again when CarrierConfig is loaded.
263                     if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
264                         mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
265                     } else {
266                         mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
267                     }
268                 });
269         mStateReceiver = new StateReceiver();
270 
271         // Load tethering configuration.
272         updateConfiguration();
273 
274         startStateMachineUpdaters(mHandler);
275     }
276 
startStateMachineUpdaters(Handler handler)277     private void startStateMachineUpdaters(Handler handler) {
278         mCarrierConfigChange.startListening();
279         mDefaultSubscriptionChange.startListening();
280 
281         IntentFilter filter = new IntentFilter();
282         filter.addAction(UsbManager.ACTION_USB_STATE);
283         filter.addAction(CONNECTIVITY_ACTION);
284         filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
285         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
286         mContext.registerReceiver(mStateReceiver, filter, null, handler);
287 
288         filter = new IntentFilter();
289         filter.addAction(Intent.ACTION_MEDIA_SHARED);
290         filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
291         filter.addDataScheme("file");
292         mContext.registerReceiver(mStateReceiver, filter, null, handler);
293 
294         final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
295         // This check is useful only for some unit tests; example: ConnectivityServiceTest.
296         if (umi != null) {
297             umi.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
298         }
299     }
300 
getWifiManager()301     private WifiManager getWifiManager() {
302         return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
303     }
304 
305     // NOTE: This is always invoked on the mLooper thread.
updateConfiguration()306     private void updateConfiguration() {
307         final int subId = mDeps.getDefaultDataSubscriptionId();
308         updateConfiguration(subId);
309     }
310 
updateConfiguration(final int subId)311     private void updateConfiguration(final int subId) {
312         mConfig = new TetheringConfiguration(mContext, mLog, subId);
313         mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
314     }
315 
maybeDunSettingChanged()316     private void maybeDunSettingChanged() {
317         final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
318         if (isDunRequired == mConfig.isDunRequired) return;
319         updateConfiguration();
320     }
321 
maybeDefaultDataSubChanged()322     private void maybeDefaultDataSubChanged() {
323         final int subId = mDeps.getDefaultDataSubscriptionId();
324         if (subId == mConfig.subId) return;
325         updateConfiguration(subId);
326     }
327 
328     @Override
interfaceStatusChanged(String iface, boolean up)329     public void interfaceStatusChanged(String iface, boolean up) {
330         // Never called directly: only called from interfaceLinkStateChanged.
331         // See NetlinkHandler.cpp:71.
332         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
333         synchronized (mPublicSync) {
334             if (up) {
335                 maybeTrackNewInterfaceLocked(iface);
336             } else {
337                 if (ifaceNameToType(iface) == TETHERING_BLUETOOTH) {
338                     stopTrackingInterfaceLocked(iface);
339                 } else {
340                     // Ignore usb0 down after enabling RNDIS.
341                     // We will handle disconnect in interfaceRemoved.
342                     // Similarly, ignore interface down for WiFi.  We monitor WiFi AP status
343                     // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
344                     if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
345                 }
346             }
347         }
348     }
349 
350     @Override
interfaceLinkStateChanged(String iface, boolean up)351     public void interfaceLinkStateChanged(String iface, boolean up) {
352         interfaceStatusChanged(iface, up);
353     }
354 
ifaceNameToType(String iface)355     private int ifaceNameToType(String iface) {
356         final TetheringConfiguration cfg = mConfig;
357 
358         if (cfg.isWifi(iface)) {
359             return TETHERING_WIFI;
360         } else if (cfg.isUsb(iface)) {
361             return TETHERING_USB;
362         } else if (cfg.isBluetooth(iface)) {
363             return TETHERING_BLUETOOTH;
364         }
365         return TETHERING_INVALID;
366     }
367 
368     @Override
interfaceAdded(String iface)369     public void interfaceAdded(String iface) {
370         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
371         synchronized (mPublicSync) {
372             maybeTrackNewInterfaceLocked(iface);
373         }
374     }
375 
376     @Override
interfaceRemoved(String iface)377     public void interfaceRemoved(String iface) {
378         if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
379         synchronized (mPublicSync) {
380             stopTrackingInterfaceLocked(iface);
381         }
382     }
383 
startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi)384     public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
385         mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi);
386         enableTetheringInternal(type, true /* enabled */, receiver);
387     }
388 
stopTethering(int type)389     public void stopTethering(int type) {
390         enableTetheringInternal(type, false /* disabled */, null);
391         mEntitlementMgr.stopProvisioningIfNeeded(type);
392     }
393 
394     /**
395      * Enables or disables tethering for the given type. If provisioning is required, it will
396      * schedule provisioning rechecks for the specified interface.
397      */
enableTetheringInternal(int type, boolean enable, ResultReceiver receiver)398     private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
399         int result;
400         switch (type) {
401             case TETHERING_WIFI:
402                 result = setWifiTethering(enable);
403                 sendTetherResult(receiver, result);
404                 break;
405             case TETHERING_USB:
406                 result = setUsbTethering(enable);
407                 sendTetherResult(receiver, result);
408                 break;
409             case TETHERING_BLUETOOTH:
410                 setBluetoothTethering(enable, receiver);
411                 break;
412             default:
413                 Log.w(TAG, "Invalid tether type.");
414                 sendTetherResult(receiver, TETHER_ERROR_UNKNOWN_IFACE);
415         }
416     }
417 
sendTetherResult(ResultReceiver receiver, int result)418     private void sendTetherResult(ResultReceiver receiver, int result) {
419         if (receiver != null) {
420             receiver.send(result, null);
421         }
422     }
423 
setWifiTethering(final boolean enable)424     private int setWifiTethering(final boolean enable) {
425         final long ident = Binder.clearCallingIdentity();
426         try {
427             synchronized (mPublicSync) {
428                 final WifiManager mgr = getWifiManager();
429                 if (mgr == null) {
430                     mLog.e("setWifiTethering: failed to get WifiManager!");
431                     return TETHER_ERROR_SERVICE_UNAVAIL;
432                 }
433                 if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||
434                     (!enable && mgr.stopSoftAp())) {
435                     mWifiTetherRequested = enable;
436                     return TETHER_ERROR_NO_ERROR;
437                 }
438             }
439         } finally {
440             Binder.restoreCallingIdentity(ident);
441         }
442 
443         return TETHER_ERROR_MASTER_ERROR;
444     }
445 
setBluetoothTethering(final boolean enable, final ResultReceiver receiver)446     private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
447         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
448         if (adapter == null || !adapter.isEnabled()) {
449             Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " +
450                     (adapter == null));
451             sendTetherResult(receiver, TETHER_ERROR_SERVICE_UNAVAIL);
452             return;
453         }
454 
455         adapter.getProfileProxy(mContext, new ServiceListener() {
456             @Override
457             public void onServiceDisconnected(int profile) { }
458 
459             @Override
460             public void onServiceConnected(int profile, BluetoothProfile proxy) {
461                 ((BluetoothPan) proxy).setBluetoothTethering(enable);
462                 // TODO: Enabling bluetooth tethering can fail asynchronously here.
463                 // We should figure out a way to bubble up that failure instead of sending success.
464                 final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
465                         ? TETHER_ERROR_NO_ERROR
466                         : TETHER_ERROR_MASTER_ERROR;
467                 sendTetherResult(receiver, result);
468                 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
469             }
470         }, BluetoothProfile.PAN);
471     }
472 
tether(String iface)473     public int tether(String iface) {
474         return tether(iface, IpServer.STATE_TETHERED);
475     }
476 
tether(String iface, int requestedState)477     private int tether(String iface, int requestedState) {
478         if (DBG) Log.d(TAG, "Tethering " + iface);
479         synchronized (mPublicSync) {
480             TetherState tetherState = mTetherStates.get(iface);
481             if (tetherState == null) {
482                 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
483                 return TETHER_ERROR_UNKNOWN_IFACE;
484             }
485             // Ignore the error status of the interface.  If the interface is available,
486             // the errors are referring to past tethering attempts anyway.
487             if (tetherState.lastState != IpServer.STATE_AVAILABLE) {
488                 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
489                 return TETHER_ERROR_UNAVAIL_IFACE;
490             }
491             // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's
492             // queue but not yet processed, this will be a no-op and it will not
493             // return an error.
494             //
495             // TODO: reexamine the threading and messaging model.
496             tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState);
497             return TETHER_ERROR_NO_ERROR;
498         }
499     }
500 
untether(String iface)501     public int untether(String iface) {
502         if (DBG) Log.d(TAG, "Untethering " + iface);
503         synchronized (mPublicSync) {
504             TetherState tetherState = mTetherStates.get(iface);
505             if (tetherState == null) {
506                 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
507                 return TETHER_ERROR_UNKNOWN_IFACE;
508             }
509             if (!tetherState.isCurrentlyServing()) {
510                 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
511                 return TETHER_ERROR_UNAVAIL_IFACE;
512             }
513             tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED);
514             return TETHER_ERROR_NO_ERROR;
515         }
516     }
517 
untetherAll()518     public void untetherAll() {
519         stopTethering(TETHERING_WIFI);
520         stopTethering(TETHERING_USB);
521         stopTethering(TETHERING_BLUETOOTH);
522     }
523 
getLastTetherError(String iface)524     public int getLastTetherError(String iface) {
525         synchronized (mPublicSync) {
526             TetherState tetherState = mTetherStates.get(iface);
527             if (tetherState == null) {
528                 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
529                         ", ignoring");
530                 return TETHER_ERROR_UNKNOWN_IFACE;
531             }
532             return tetherState.lastError;
533         }
534     }
535 
536     // TODO: Figure out how to update for local hotspot mode interfaces.
sendTetherStateChangedBroadcast()537     private void sendTetherStateChangedBroadcast() {
538         if (!mDeps.isTetheringSupported()) return;
539 
540         final ArrayList<String> availableList = new ArrayList<>();
541         final ArrayList<String> tetherList = new ArrayList<>();
542         final ArrayList<String> localOnlyList = new ArrayList<>();
543         final ArrayList<String> erroredList = new ArrayList<>();
544 
545         boolean wifiTethered = false;
546         boolean usbTethered = false;
547         boolean bluetoothTethered = false;
548 
549         final TetheringConfiguration cfg = mConfig;
550 
551         synchronized (mPublicSync) {
552             for (int i = 0; i < mTetherStates.size(); i++) {
553                 TetherState tetherState = mTetherStates.valueAt(i);
554                 String iface = mTetherStates.keyAt(i);
555                 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
556                     erroredList.add(iface);
557                 } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
558                     availableList.add(iface);
559                 } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) {
560                     localOnlyList.add(iface);
561                 } else if (tetherState.lastState == IpServer.STATE_TETHERED) {
562                     if (cfg.isUsb(iface)) {
563                         usbTethered = true;
564                     } else if (cfg.isWifi(iface)) {
565                         wifiTethered = true;
566                     } else if (cfg.isBluetooth(iface)) {
567                         bluetoothTethered = true;
568                     }
569                     tetherList.add(iface);
570                 }
571             }
572         }
573         final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED);
574         bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
575                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
576         bcast.putStringArrayListExtra(EXTRA_AVAILABLE_TETHER, availableList);
577         bcast.putStringArrayListExtra(EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
578         bcast.putStringArrayListExtra(EXTRA_ACTIVE_TETHER, tetherList);
579         bcast.putStringArrayListExtra(EXTRA_ERRORED_TETHER, erroredList);
580         mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
581         if (DBG) {
582             Log.d(TAG, String.format(
583                     "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
584                     "avail", TextUtils.join(",", availableList),
585                     "local_only", TextUtils.join(",", localOnlyList),
586                     "tether", TextUtils.join(",", tetherList),
587                     "error", TextUtils.join(",", erroredList)));
588         }
589 
590         if (usbTethered) {
591             if (wifiTethered || bluetoothTethered) {
592                 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
593             } else {
594                 showTetheredNotification(SystemMessage.NOTE_TETHER_USB);
595             }
596         } else if (wifiTethered) {
597             if (bluetoothTethered) {
598                 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
599             } else {
600                 /* We now have a status bar icon for WifiTethering, so drop the notification */
601                 clearTetheredNotification();
602             }
603         } else if (bluetoothTethered) {
604             showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH);
605         } else {
606             clearTetheredNotification();
607         }
608     }
609 
showTetheredNotification(int id)610     private void showTetheredNotification(int id) {
611         showTetheredNotification(id, true);
612     }
613 
614     @VisibleForTesting
showTetheredNotification(int id, boolean tetheringOn)615     protected void showTetheredNotification(int id, boolean tetheringOn) {
616         NotificationManager notificationManager =
617                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
618         if (notificationManager == null) {
619             return;
620         }
621         int icon = 0;
622         switch(id) {
623           case SystemMessage.NOTE_TETHER_USB:
624             icon = com.android.internal.R.drawable.stat_sys_tether_usb;
625             break;
626           case SystemMessage.NOTE_TETHER_BLUETOOTH:
627             icon = com.android.internal.R.drawable.stat_sys_tether_bluetooth;
628             break;
629           case SystemMessage.NOTE_TETHER_GENERAL:
630           default:
631             icon = com.android.internal.R.drawable.stat_sys_tether_general;
632             break;
633         }
634 
635         if (mLastNotificationId != 0) {
636             if (mLastNotificationId == icon) {
637                 return;
638             }
639             notificationManager.cancelAsUser(null, mLastNotificationId,
640                     UserHandle.ALL);
641             mLastNotificationId = 0;
642         }
643 
644         Intent intent = new Intent();
645         intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
646         intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
647 
648         PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0,
649                 null, UserHandle.CURRENT);
650 
651         Resources r = Resources.getSystem();
652         final CharSequence title;
653         final CharSequence message;
654 
655         if (tetheringOn) {
656             title = r.getText(com.android.internal.R.string.tethered_notification_title);
657             message = r.getText(com.android.internal.R.string.tethered_notification_message);
658         } else {
659             title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
660             message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
661         }
662 
663         if (mTetheredNotificationBuilder == null) {
664             mTetheredNotificationBuilder =
665                     new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
666             mTetheredNotificationBuilder.setWhen(0)
667                     .setOngoing(true)
668                     .setColor(mContext.getColor(
669                             com.android.internal.R.color.system_notification_accent_color))
670                     .setVisibility(Notification.VISIBILITY_PUBLIC)
671                     .setCategory(Notification.CATEGORY_STATUS);
672         }
673         mTetheredNotificationBuilder.setSmallIcon(icon)
674                 .setContentTitle(title)
675                 .setContentText(message)
676                 .setContentIntent(pi);
677         mLastNotificationId = id;
678 
679         notificationManager.notifyAsUser(null, mLastNotificationId,
680                 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
681     }
682 
683     @VisibleForTesting
clearTetheredNotification()684     protected void clearTetheredNotification() {
685         NotificationManager notificationManager =
686             (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
687         if (notificationManager != null && mLastNotificationId != 0) {
688             notificationManager.cancelAsUser(null, mLastNotificationId,
689                     UserHandle.ALL);
690             mLastNotificationId = 0;
691         }
692     }
693 
694     private class StateReceiver extends BroadcastReceiver {
695         @Override
onReceive(Context content, Intent intent)696         public void onReceive(Context content, Intent intent) {
697             final String action = intent.getAction();
698             if (action == null) return;
699 
700             if (action.equals(UsbManager.ACTION_USB_STATE)) {
701                 handleUsbAction(intent);
702             } else if (action.equals(CONNECTIVITY_ACTION)) {
703                 handleConnectivityAction(intent);
704             } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
705                 handleWifiApAction(intent);
706             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
707                 mLog.log("OBSERVED configuration changed");
708                 updateConfiguration();
709             }
710         }
711 
handleConnectivityAction(Intent intent)712         private void handleConnectivityAction(Intent intent) {
713             final NetworkInfo networkInfo =
714                     (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO);
715             if (networkInfo == null ||
716                     networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
717                 return;
718             }
719 
720             if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
721             mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
722         }
723 
handleUsbAction(Intent intent)724         private void handleUsbAction(Intent intent) {
725             final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
726             final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
727             final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
728 
729             mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
730                     usbConnected, usbConfigured, rndisEnabled));
731 
732             // There are three types of ACTION_USB_STATE:
733             //
734             //     - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
735             //       Meaning: USB connection has ended either because of
736             //       software reset or hard unplug.
737             //
738             //     - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
739             //       Meaning: the first stage of USB protocol handshake has
740             //       occurred but it is not complete.
741             //
742             //     - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
743             //       Meaning: the USB handshake is completely done and all the
744             //       functions are ready to use.
745             //
746             // For more explanation, see b/62552150 .
747             synchronized (Tethering.this.mPublicSync) {
748                 if (!usbConnected && mRndisEnabled) {
749                     // Turn off tethering if it was enabled and there is a disconnect.
750                     tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
751                     mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
752                 } else if (usbConfigured && rndisEnabled) {
753                     // Tether if rndis is enabled and usb is configured.
754                     tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
755                 }
756                 mRndisEnabled = usbConfigured && rndisEnabled;
757             }
758         }
759 
handleWifiApAction(Intent intent)760         private void handleWifiApAction(Intent intent) {
761             final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
762             final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
763             final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
764 
765             synchronized (Tethering.this.mPublicSync) {
766                 switch (curState) {
767                     case WifiManager.WIFI_AP_STATE_ENABLING:
768                         // We can see this state on the way to both enabled and failure states.
769                         break;
770                     case WifiManager.WIFI_AP_STATE_ENABLED:
771                         enableWifiIpServingLocked(ifname, ipmode);
772                         break;
773                     case WifiManager.WIFI_AP_STATE_DISABLED:
774                     case WifiManager.WIFI_AP_STATE_DISABLING:
775                     case WifiManager.WIFI_AP_STATE_FAILED:
776                     default:
777                         disableWifiIpServingLocked(ifname, curState);
778                         mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
779                         break;
780                 }
781             }
782         }
783     }
784 
785     @VisibleForTesting
786     protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
787         private final Tethering mWrapper;
788 
TetheringUserRestrictionListener(Tethering wrapper)789         public TetheringUserRestrictionListener(Tethering wrapper) {
790             mWrapper = wrapper;
791         }
792 
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)793         public void onUserRestrictionsChanged(int userId,
794                                               Bundle newRestrictions,
795                                               Bundle prevRestrictions) {
796             final boolean newlyDisallowed =
797                     newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
798             final boolean previouslyDisallowed =
799                     prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
800             final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);
801 
802             if (!tetheringDisallowedChanged) {
803                 return;
804             }
805 
806             mWrapper.clearTetheredNotification();
807             final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
808 
809             if (newlyDisallowed && isTetheringActiveOnDevice) {
810                 mWrapper.showTetheredNotification(
811                         com.android.internal.R.drawable.stat_sys_tether_general, false);
812                 mWrapper.untetherAll();
813             }
814         }
815     }
816 
disableWifiIpServingLocked(String ifname, int apState)817     private void disableWifiIpServingLocked(String ifname, int apState) {
818         mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
819 
820         // Regardless of whether we requested this transition, the AP has gone
821         // down.  Don't try to tether again unless we're requested to do so.
822         // TODO: Remove this altogether, once Wi-Fi reliably gives us an
823         // interface name with every broadcast.
824         mWifiTetherRequested = false;
825 
826         if (!TextUtils.isEmpty(ifname)) {
827             final TetherState ts = mTetherStates.get(ifname);
828             if (ts != null) {
829                 ts.ipServer.unwanted();
830                 return;
831             }
832         }
833 
834         for (int i = 0; i < mTetherStates.size(); i++) {
835             final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
836             if (ipServer.interfaceType() == TETHERING_WIFI) {
837                 ipServer.unwanted();
838                 return;
839             }
840         }
841 
842         mLog.log("Error disabling Wi-Fi IP serving; " +
843                 (TextUtils.isEmpty(ifname) ? "no interface name specified"
844                                            : "specified interface: " + ifname));
845     }
846 
enableWifiIpServingLocked(String ifname, int wifiIpMode)847     private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
848         // Map wifiIpMode values to IpServer.Callback serving states, inferring
849         // from mWifiTetherRequested as a final "best guess".
850         final int ipServingMode;
851         switch (wifiIpMode) {
852             case IFACE_IP_MODE_TETHERED:
853                 ipServingMode = IpServer.STATE_TETHERED;
854                 break;
855             case IFACE_IP_MODE_LOCAL_ONLY:
856                 ipServingMode = IpServer.STATE_LOCAL_ONLY;
857                 break;
858             default:
859                 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
860                 return;
861         }
862 
863         if (!TextUtils.isEmpty(ifname)) {
864             maybeTrackNewInterfaceLocked(ifname, TETHERING_WIFI);
865             changeInterfaceState(ifname, ipServingMode);
866         } else {
867             mLog.e(String.format(
868                    "Cannot enable IP serving in mode %s on missing interface name",
869                    ipServingMode));
870         }
871     }
872 
873     // TODO: Consider renaming to something more accurate in its description.
874     // This method:
875     //     - allows requesting either tethering or local hotspot serving states
876     //     - handles both enabling and disabling serving states
877     //     - only tethers the first matching interface in listInterfaces()
878     //       order of a given type
tetherMatchingInterfaces(int requestedState, int interfaceType)879     private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
880         if (VDBG) {
881             Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
882         }
883 
884         String[] ifaces = null;
885         try {
886             ifaces = mNMService.listInterfaces();
887         } catch (Exception e) {
888             Log.e(TAG, "Error listing Interfaces", e);
889             return;
890         }
891         String chosenIface = null;
892         if (ifaces != null) {
893             for (String iface : ifaces) {
894                 if (ifaceNameToType(iface) == interfaceType) {
895                     chosenIface = iface;
896                     break;
897                 }
898             }
899         }
900         if (chosenIface == null) {
901             Log.e(TAG, "could not find iface of type " + interfaceType);
902             return;
903         }
904 
905         changeInterfaceState(chosenIface, requestedState);
906     }
907 
changeInterfaceState(String ifname, int requestedState)908     private void changeInterfaceState(String ifname, int requestedState) {
909         final int result;
910         switch (requestedState) {
911             case IpServer.STATE_UNAVAILABLE:
912             case IpServer.STATE_AVAILABLE:
913                 result = untether(ifname);
914                 break;
915             case IpServer.STATE_TETHERED:
916             case IpServer.STATE_LOCAL_ONLY:
917                 result = tether(ifname, requestedState);
918                 break;
919             default:
920                 Log.wtf(TAG, "Unknown interface state: " + requestedState);
921                 return;
922         }
923         if (result != TETHER_ERROR_NO_ERROR) {
924             Log.e(TAG, "unable start or stop tethering on iface " + ifname);
925             return;
926         }
927     }
928 
getTetheringConfiguration()929     public TetheringConfiguration getTetheringConfiguration() {
930         return mConfig;
931     }
932 
hasTetherableConfiguration()933     public boolean hasTetherableConfiguration() {
934         final TetheringConfiguration cfg = mConfig;
935         final boolean hasDownstreamConfiguration =
936                 (cfg.tetherableUsbRegexs.length != 0)
937                 || (cfg.tetherableWifiRegexs.length != 0)
938                 || (cfg.tetherableBluetoothRegexs.length != 0);
939         final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
940                 || cfg.chooseUpstreamAutomatically;
941 
942         return hasDownstreamConfiguration && hasUpstreamConfiguration;
943     }
944 
945     // TODO - update callers to use getTetheringConfiguration(),
946     // which has only final members.
getTetherableUsbRegexs()947     public String[] getTetherableUsbRegexs() {
948         return copy(mConfig.tetherableUsbRegexs);
949     }
950 
getTetherableWifiRegexs()951     public String[] getTetherableWifiRegexs() {
952         return copy(mConfig.tetherableWifiRegexs);
953     }
954 
getTetherableBluetoothRegexs()955     public String[] getTetherableBluetoothRegexs() {
956         return copy(mConfig.tetherableBluetoothRegexs);
957     }
958 
setUsbTethering(boolean enable)959     public int setUsbTethering(boolean enable) {
960         if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
961         UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
962         if (usbManager == null) {
963             mLog.e("setUsbTethering: failed to get UsbManager!");
964             return TETHER_ERROR_SERVICE_UNAVAIL;
965         }
966 
967         synchronized (mPublicSync) {
968             usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
969                     : UsbManager.FUNCTION_NONE);
970         }
971         return TETHER_ERROR_NO_ERROR;
972     }
973 
974     // TODO review API - figure out how to delete these entirely.
getTetheredIfaces()975     public String[] getTetheredIfaces() {
976         ArrayList<String> list = new ArrayList<String>();
977         synchronized (mPublicSync) {
978             for (int i = 0; i < mTetherStates.size(); i++) {
979                 TetherState tetherState = mTetherStates.valueAt(i);
980                 if (tetherState.lastState == IpServer.STATE_TETHERED) {
981                     list.add(mTetherStates.keyAt(i));
982                 }
983             }
984         }
985         return list.toArray(new String[list.size()]);
986     }
987 
getTetherableIfaces()988     public String[] getTetherableIfaces() {
989         ArrayList<String> list = new ArrayList<String>();
990         synchronized (mPublicSync) {
991             for (int i = 0; i < mTetherStates.size(); i++) {
992                 TetherState tetherState = mTetherStates.valueAt(i);
993                 if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
994                     list.add(mTetherStates.keyAt(i));
995                 }
996             }
997         }
998         return list.toArray(new String[list.size()]);
999     }
1000 
getTetheredDhcpRanges()1001     public String[] getTetheredDhcpRanges() {
1002         // TODO: this is only valid for the old DHCP server. Latest search suggests it is only used
1003         // by WifiP2pServiceImpl to start dnsmasq: remove/deprecate after migrating callers.
1004         return mConfig.legacyDhcpRanges;
1005     }
1006 
getErroredIfaces()1007     public String[] getErroredIfaces() {
1008         ArrayList<String> list = new ArrayList<String>();
1009         synchronized (mPublicSync) {
1010             for (int i = 0; i < mTetherStates.size(); i++) {
1011                 TetherState tetherState = mTetherStates.valueAt(i);
1012                 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
1013                     list.add(mTetherStates.keyAt(i));
1014                 }
1015             }
1016         }
1017         return list.toArray(new String[list.size()]);
1018     }
1019 
logMessage(State state, int what)1020     private void logMessage(State state, int what) {
1021         mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
1022     }
1023 
upstreamWanted()1024     private boolean upstreamWanted() {
1025         if (!mForwardedDownstreams.isEmpty()) return true;
1026 
1027         synchronized (mPublicSync) {
1028             return mWifiTetherRequested;
1029         }
1030     }
1031 
1032     // Needed because the canonical source of upstream truth is just the
1033     // upstream interface set, |mCurrentUpstreamIfaceSet|.
pertainsToCurrentUpstream(NetworkState ns)1034     private boolean pertainsToCurrentUpstream(NetworkState ns) {
1035         if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
1036             for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
1037                 if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
1038                     return true;
1039                 }
1040             }
1041         }
1042         return false;
1043     }
1044 
1045     class TetherMasterSM extends StateMachine {
1046         private static final int BASE_MASTER                    = Protocol.BASE_TETHERING;
1047         // an interface SM has requested Tethering/Local Hotspot
1048         static final int EVENT_IFACE_SERVING_STATE_ACTIVE       = BASE_MASTER + 1;
1049         // an interface SM has unrequested Tethering/Local Hotspot
1050         static final int EVENT_IFACE_SERVING_STATE_INACTIVE     = BASE_MASTER + 2;
1051         // upstream connection change - do the right thing
1052         static final int CMD_UPSTREAM_CHANGED                   = BASE_MASTER + 3;
1053         // we don't have a valid upstream conn, check again after a delay
1054         static final int CMD_RETRY_UPSTREAM                     = BASE_MASTER + 4;
1055         // Events from NetworkCallbacks that we process on the master state
1056         // machine thread on behalf of the UpstreamNetworkMonitor.
1057         static final int EVENT_UPSTREAM_CALLBACK                = BASE_MASTER + 5;
1058         // we treated the error and want now to clear it
1059         static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
1060         static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MASTER + 7;
1061         // Events from EntitlementManager to choose upstream again.
1062         static final int EVENT_UPSTREAM_PERMISSION_CHANGED      = BASE_MASTER + 8;
1063 
1064         private final State mInitialState;
1065         private final State mTetherModeAliveState;
1066 
1067         private final State mSetIpForwardingEnabledErrorState;
1068         private final State mSetIpForwardingDisabledErrorState;
1069         private final State mStartTetheringErrorState;
1070         private final State mStopTetheringErrorState;
1071         private final State mSetDnsForwardersErrorState;
1072 
1073         // This list is a little subtle.  It contains all the interfaces that currently are
1074         // requesting tethering, regardless of whether these interfaces are still members of
1075         // mTetherStates.  This allows us to maintain the following predicates:
1076         //
1077         // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1078         //    interfaces.
1079         // 2) mNotifyList contains all state machines that may have outstanding tethering state
1080         //    that needs to be torn down.
1081         //
1082         // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1083         // so that the garbage collector does not clean up the state machine before it has a chance
1084         // to tear itself down.
1085         private final ArrayList<IpServer> mNotifyList;
1086         private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
1087         private final OffloadWrapper mOffload;
1088 
1089         private static final int UPSTREAM_SETTLE_TIME_MS     = 10000;
1090 
TetherMasterSM(String name, Looper looper, TetheringDependencies deps)1091         TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
1092             super(name, looper);
1093 
1094             mInitialState = new InitialState();
1095             mTetherModeAliveState = new TetherModeAliveState();
1096             mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
1097             mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
1098             mStartTetheringErrorState = new StartTetheringErrorState();
1099             mStopTetheringErrorState = new StopTetheringErrorState();
1100             mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
1101 
1102             addState(mInitialState);
1103             addState(mTetherModeAliveState);
1104             addState(mSetIpForwardingEnabledErrorState);
1105             addState(mSetIpForwardingDisabledErrorState);
1106             addState(mStartTetheringErrorState);
1107             addState(mStopTetheringErrorState);
1108             addState(mSetDnsForwardersErrorState);
1109 
1110             mNotifyList = new ArrayList<>();
1111             mIPv6TetheringCoordinator = deps.getIPv6TetheringCoordinator(mNotifyList, mLog);
1112             mOffload = new OffloadWrapper();
1113 
1114             setInitialState(mInitialState);
1115         }
1116 
1117         class InitialState extends State {
1118             @Override
processMessage(Message message)1119             public boolean processMessage(Message message) {
1120                 logMessage(this, message.what);
1121                 switch (message.what) {
1122                     case EVENT_IFACE_SERVING_STATE_ACTIVE: {
1123                         final IpServer who = (IpServer) message.obj;
1124                         if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1125                         handleInterfaceServingStateActive(message.arg1, who);
1126                         transitionTo(mTetherModeAliveState);
1127                         break;
1128                     }
1129                     case EVENT_IFACE_SERVING_STATE_INACTIVE: {
1130                         final IpServer who = (IpServer) message.obj;
1131                         if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1132                         handleInterfaceServingStateInactive(who);
1133                         break;
1134                     }
1135                     case EVENT_IFACE_UPDATE_LINKPROPERTIES:
1136                         // Silently ignore these for now.
1137                         break;
1138                     default:
1139                         return NOT_HANDLED;
1140                 }
1141                 return HANDLED;
1142             }
1143         }
1144 
turnOnMasterTetherSettings()1145         protected boolean turnOnMasterTetherSettings() {
1146             final TetheringConfiguration cfg = mConfig;
1147             try {
1148                 mNMService.setIpForwardingEnabled(true);
1149             } catch (Exception e) {
1150                 mLog.e(e);
1151                 transitionTo(mSetIpForwardingEnabledErrorState);
1152                 return false;
1153             }
1154             // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
1155             // Legacy DHCP server is disabled if passed an empty ranges array
1156             final String[] dhcpRanges = cfg.enableLegacyDhcpServer
1157                     ? cfg.legacyDhcpRanges
1158                     : new String[0];
1159             try {
1160                 // TODO: Find a more accurate method name (startDHCPv4()?).
1161                 mNMService.startTethering(dhcpRanges);
1162             } catch (Exception e) {
1163                 try {
1164                     mNMService.stopTethering();
1165                     mNMService.startTethering(dhcpRanges);
1166                 } catch (Exception ee) {
1167                     mLog.e(ee);
1168                     transitionTo(mStartTetheringErrorState);
1169                     return false;
1170                 }
1171             }
1172             mLog.log("SET master tether settings: ON");
1173             return true;
1174         }
1175 
turnOffMasterTetherSettings()1176         protected boolean turnOffMasterTetherSettings() {
1177             try {
1178                 mNMService.stopTethering();
1179             } catch (Exception e) {
1180                 mLog.e(e);
1181                 transitionTo(mStopTetheringErrorState);
1182                 return false;
1183             }
1184             try {
1185                 mNMService.setIpForwardingEnabled(false);
1186             } catch (Exception e) {
1187                 mLog.e(e);
1188                 transitionTo(mSetIpForwardingDisabledErrorState);
1189                 return false;
1190             }
1191             transitionTo(mInitialState);
1192             mLog.log("SET master tether settings: OFF");
1193             return true;
1194         }
1195 
chooseUpstreamType(boolean tryCell)1196         protected void chooseUpstreamType(boolean tryCell) {
1197             // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
1198             // do not currently know how to watch for changes in DUN settings.
1199             maybeDunSettingChanged();
1200 
1201             final TetheringConfiguration config = mConfig;
1202             final NetworkState ns = (config.chooseUpstreamAutomatically)
1203                     ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
1204                     : mUpstreamNetworkMonitor.selectPreferredUpstreamType(
1205                             config.preferredUpstreamIfaceTypes);
1206             if (ns == null) {
1207                 if (tryCell) {
1208                     mUpstreamNetworkMonitor.registerMobileNetworkRequest();
1209                     // We think mobile should be coming up; don't set a retry.
1210                 } else {
1211                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
1212                 }
1213             }
1214             setUpstreamNetwork(ns);
1215             final Network newUpstream = (ns != null) ? ns.network : null;
1216             if (mTetherUpstream != newUpstream) {
1217                 mTetherUpstream = newUpstream;
1218                 mUpstreamNetworkMonitor.setCurrentUpstream(mTetherUpstream);
1219                 reportUpstreamChanged(mTetherUpstream);
1220             }
1221         }
1222 
setUpstreamNetwork(NetworkState ns)1223         protected void setUpstreamNetwork(NetworkState ns) {
1224             InterfaceSet ifaces = null;
1225             if (ns != null) {
1226                 // Find the interface with the default IPv4 route. It may be the
1227                 // interface described by linkProperties, or one of the interfaces
1228                 // stacked on top of it.
1229                 mLog.i("Looking for default routes on: " + ns.linkProperties);
1230                 ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns);
1231                 mLog.i("Found upstream interface(s): " + ifaces);
1232             }
1233 
1234             if (ifaces != null) {
1235                 setDnsForwarders(ns.network, ns.linkProperties);
1236             }
1237             notifyDownstreamsOfNewUpstreamIface(ifaces);
1238             if (ns != null && pertainsToCurrentUpstream(ns)) {
1239                 // If we already have NetworkState for this network update it immediately.
1240                 handleNewUpstreamNetworkState(ns);
1241             } else if (mCurrentUpstreamIfaceSet == null) {
1242                 // There are no available upstream networks.
1243                 handleNewUpstreamNetworkState(null);
1244             }
1245         }
1246 
setDnsForwarders(final Network network, final LinkProperties lp)1247         protected void setDnsForwarders(final Network network, final LinkProperties lp) {
1248             // TODO: Set v4 and/or v6 DNS per available connectivity.
1249             String[] dnsServers = mConfig.defaultIPv4DNS;
1250             final Collection<InetAddress> dnses = lp.getDnsServers();
1251             // TODO: Properly support the absence of DNS servers.
1252             if (dnses != null && !dnses.isEmpty()) {
1253                 // TODO: remove this invocation of NetworkUtils.makeStrings().
1254                 dnsServers = NetworkUtils.makeStrings(dnses);
1255             }
1256             try {
1257                 mNMService.setDnsForwarders(network, dnsServers);
1258                 mLog.log(String.format(
1259                         "SET DNS forwarders: network=%s dnsServers=%s",
1260                         network, Arrays.toString(dnsServers)));
1261             } catch (Exception e) {
1262                 // TODO: Investigate how this can fail and what exactly
1263                 // happens if/when such failures occur.
1264                 mLog.e("setting DNS forwarders failed, " + e);
1265                 transitionTo(mSetDnsForwardersErrorState);
1266             }
1267         }
1268 
notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces)1269         protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
1270             mCurrentUpstreamIfaceSet = ifaces;
1271             for (IpServer ipServer : mNotifyList) {
1272                 ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
1273             }
1274         }
1275 
handleNewUpstreamNetworkState(NetworkState ns)1276         protected void handleNewUpstreamNetworkState(NetworkState ns) {
1277             mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
1278             mOffload.updateUpstreamNetworkState(ns);
1279         }
1280 
handleInterfaceServingStateActive(int mode, IpServer who)1281         private void handleInterfaceServingStateActive(int mode, IpServer who) {
1282             if (mNotifyList.indexOf(who) < 0) {
1283                 mNotifyList.add(who);
1284                 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
1285             }
1286 
1287             if (mode == IpServer.STATE_TETHERED) {
1288                 // No need to notify OffloadController just yet as there are no
1289                 // "offload-able" prefixes to pass along. This will handled
1290                 // when the TISM informs Tethering of its LinkProperties.
1291                 mForwardedDownstreams.add(who);
1292             } else {
1293                 mOffload.excludeDownstreamInterface(who.interfaceName());
1294                 mForwardedDownstreams.remove(who);
1295             }
1296 
1297             // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
1298             if (who.interfaceType() == TETHERING_WIFI) {
1299                 final WifiManager mgr = getWifiManager();
1300                 final String iface = who.interfaceName();
1301                 switch (mode) {
1302                     case IpServer.STATE_TETHERED:
1303                         mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
1304                         break;
1305                     case IpServer.STATE_LOCAL_ONLY:
1306                         mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
1307                         break;
1308                     default:
1309                         Log.wtf(TAG, "Unknown active serving mode: " + mode);
1310                         break;
1311                 }
1312             }
1313         }
1314 
handleInterfaceServingStateInactive(IpServer who)1315         private void handleInterfaceServingStateInactive(IpServer who) {
1316             mNotifyList.remove(who);
1317             mIPv6TetheringCoordinator.removeActiveDownstream(who);
1318             mOffload.excludeDownstreamInterface(who.interfaceName());
1319             mForwardedDownstreams.remove(who);
1320 
1321             // If this is a Wi-Fi interface, tell WifiManager of any errors.
1322             if (who.interfaceType() == TETHERING_WIFI) {
1323                 if (who.lastError() != TETHER_ERROR_NO_ERROR) {
1324                     getWifiManager().updateInterfaceIpState(
1325                             who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
1326                 }
1327             }
1328         }
1329 
handleUpstreamNetworkMonitorCallback(int arg1, Object o)1330         private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
1331             if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
1332                 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
1333                 return;
1334             }
1335 
1336             final NetworkState ns = (NetworkState) o;
1337 
1338             if (ns == null || !pertainsToCurrentUpstream(ns)) {
1339                 // TODO: In future, this is where upstream evaluation and selection
1340                 // could be handled for notifications which include sufficient data.
1341                 // For example, after CONNECTIVITY_ACTION listening is removed, here
1342                 // is where we could observe a Wi-Fi network becoming available and
1343                 // passing validation.
1344                 if (mCurrentUpstreamIfaceSet == null) {
1345                     // If we have no upstream interface, try to run through upstream
1346                     // selection again.  If, for example, IPv4 connectivity has shown up
1347                     // after IPv6 (e.g., 464xlat became available) we want the chance to
1348                     // notice and act accordingly.
1349                     chooseUpstreamType(false);
1350                 }
1351                 return;
1352             }
1353 
1354             switch (arg1) {
1355                 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
1356                     handleNewUpstreamNetworkState(ns);
1357                     break;
1358                 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
1359                     chooseUpstreamType(false);
1360                     break;
1361                 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1362                     // TODO: Re-evaluate possible upstreams. Currently upstream
1363                     // reevaluation is triggered via received CONNECTIVITY_ACTION
1364                     // broadcasts that result in being passed a
1365                     // TetherMasterSM.CMD_UPSTREAM_CHANGED.
1366                     handleNewUpstreamNetworkState(null);
1367                     break;
1368                 default:
1369                     mLog.e("Unknown arg1 value: " + arg1);
1370                     break;
1371             }
1372         }
1373 
1374         class TetherModeAliveState extends State {
1375             boolean mUpstreamWanted = false;
1376             boolean mTryCell = true;
1377 
1378             @Override
enter()1379             public void enter() {
1380                 // If turning on master tether settings fails, we have already
1381                 // transitioned to an error state; exit early.
1382                 if (!turnOnMasterTetherSettings()) {
1383                     return;
1384                 }
1385 
1386                 mUpstreamNetworkMonitor.startObserveAllNetworks();
1387 
1388                 // TODO: De-duplicate with updateUpstreamWanted() below.
1389                 if (upstreamWanted()) {
1390                     mUpstreamWanted = true;
1391                     mOffload.start();
1392                     chooseUpstreamType(true);
1393                     mTryCell = false;
1394                 }
1395             }
1396 
1397             @Override
exit()1398             public void exit() {
1399                 mOffload.stop();
1400                 mUpstreamNetworkMonitor.stop();
1401                 notifyDownstreamsOfNewUpstreamIface(null);
1402                 handleNewUpstreamNetworkState(null);
1403                 if (mTetherUpstream != null) {
1404                     mTetherUpstream = null;
1405                     reportUpstreamChanged(null);
1406                 }
1407             }
1408 
updateUpstreamWanted()1409             private boolean updateUpstreamWanted() {
1410                 final boolean previousUpstreamWanted = mUpstreamWanted;
1411                 mUpstreamWanted = upstreamWanted();
1412                 if (mUpstreamWanted != previousUpstreamWanted) {
1413                     if (mUpstreamWanted) {
1414                         mOffload.start();
1415                     } else {
1416                         mOffload.stop();
1417                     }
1418                 }
1419                 return previousUpstreamWanted;
1420             }
1421 
1422             @Override
processMessage(Message message)1423             public boolean processMessage(Message message) {
1424                 logMessage(this, message.what);
1425                 boolean retValue = true;
1426                 switch (message.what) {
1427                     case EVENT_IFACE_SERVING_STATE_ACTIVE: {
1428                         IpServer who = (IpServer) message.obj;
1429                         if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1430                         handleInterfaceServingStateActive(message.arg1, who);
1431                         who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED,
1432                                 mCurrentUpstreamIfaceSet);
1433                         // If there has been a change and an upstream is now
1434                         // desired, kick off the selection process.
1435                         final boolean previousUpstreamWanted = updateUpstreamWanted();
1436                         if (!previousUpstreamWanted && mUpstreamWanted) {
1437                             chooseUpstreamType(true);
1438                         }
1439                         break;
1440                     }
1441                     case EVENT_IFACE_SERVING_STATE_INACTIVE: {
1442                         IpServer who = (IpServer) message.obj;
1443                         if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1444                         handleInterfaceServingStateInactive(who);
1445 
1446                         if (mNotifyList.isEmpty()) {
1447                             // This transitions us out of TetherModeAliveState,
1448                             // either to InitialState or an error state.
1449                             turnOffMasterTetherSettings();
1450                             break;
1451                         }
1452 
1453                         if (DBG) {
1454                             Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
1455                                     " live requests:");
1456                             for (IpServer o : mNotifyList) {
1457                                 Log.d(TAG, "  " + o);
1458                             }
1459                         }
1460                         // If there has been a change and an upstream is no
1461                         // longer desired, release any mobile requests.
1462                         final boolean previousUpstreamWanted = updateUpstreamWanted();
1463                         if (previousUpstreamWanted && !mUpstreamWanted) {
1464                             mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
1465                         }
1466                         break;
1467                     }
1468                     case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
1469                         final LinkProperties newLp = (LinkProperties) message.obj;
1470                         if (message.arg1 == IpServer.STATE_TETHERED) {
1471                             mOffload.updateDownstreamLinkProperties(newLp);
1472                         } else {
1473                             mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
1474                         }
1475                         break;
1476                     }
1477                     case EVENT_UPSTREAM_PERMISSION_CHANGED:
1478                     case CMD_UPSTREAM_CHANGED:
1479                         updateUpstreamWanted();
1480                         if (!mUpstreamWanted) break;
1481 
1482                         // Need to try DUN immediately if Wi-Fi goes down.
1483                         chooseUpstreamType(true);
1484                         mTryCell = false;
1485                         break;
1486                     case CMD_RETRY_UPSTREAM:
1487                         updateUpstreamWanted();
1488                         if (!mUpstreamWanted) break;
1489 
1490                         chooseUpstreamType(mTryCell);
1491                         mTryCell = !mTryCell;
1492                         break;
1493                     case EVENT_UPSTREAM_CALLBACK: {
1494                         updateUpstreamWanted();
1495                         if (mUpstreamWanted) {
1496                             handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
1497                         }
1498                         break;
1499                     }
1500                     default:
1501                         retValue = false;
1502                         break;
1503                 }
1504                 return retValue;
1505             }
1506         }
1507 
1508         class ErrorState extends State {
1509             private int mErrorNotification;
1510 
1511             @Override
processMessage(Message message)1512             public boolean processMessage(Message message) {
1513                 boolean retValue = true;
1514                 switch (message.what) {
1515                     case EVENT_IFACE_SERVING_STATE_ACTIVE:
1516                         IpServer who = (IpServer) message.obj;
1517                         who.sendMessage(mErrorNotification);
1518                         break;
1519                     case CMD_CLEAR_ERROR:
1520                         mErrorNotification = TETHER_ERROR_NO_ERROR;
1521                         transitionTo(mInitialState);
1522                         break;
1523                     default:
1524                        retValue = false;
1525                 }
1526                 return retValue;
1527             }
1528 
notify(int msgType)1529             void notify(int msgType) {
1530                 mErrorNotification = msgType;
1531                 for (IpServer ipServer : mNotifyList) {
1532                     ipServer.sendMessage(msgType);
1533                 }
1534             }
1535 
1536         }
1537 
1538         class SetIpForwardingEnabledErrorState extends ErrorState {
1539             @Override
enter()1540             public void enter() {
1541                 Log.e(TAG, "Error in setIpForwardingEnabled");
1542                 notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR);
1543             }
1544         }
1545 
1546         class SetIpForwardingDisabledErrorState extends ErrorState {
1547             @Override
enter()1548             public void enter() {
1549                 Log.e(TAG, "Error in setIpForwardingDisabled");
1550                 notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR);
1551             }
1552         }
1553 
1554         class StartTetheringErrorState extends ErrorState {
1555             @Override
enter()1556             public void enter() {
1557                 Log.e(TAG, "Error in startTethering");
1558                 notify(IpServer.CMD_START_TETHERING_ERROR);
1559                 try {
1560                     mNMService.setIpForwardingEnabled(false);
1561                 } catch (Exception e) {}
1562             }
1563         }
1564 
1565         class StopTetheringErrorState extends ErrorState {
1566             @Override
enter()1567             public void enter() {
1568                 Log.e(TAG, "Error in stopTethering");
1569                 notify(IpServer.CMD_STOP_TETHERING_ERROR);
1570                 try {
1571                     mNMService.setIpForwardingEnabled(false);
1572                 } catch (Exception e) {}
1573             }
1574         }
1575 
1576         class SetDnsForwardersErrorState extends ErrorState {
1577             @Override
enter()1578             public void enter() {
1579                 Log.e(TAG, "Error in setDnsForwarders");
1580                 notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
1581                 try {
1582                     mNMService.stopTethering();
1583                 } catch (Exception e) {}
1584                 try {
1585                     mNMService.setIpForwardingEnabled(false);
1586                 } catch (Exception e) {}
1587             }
1588         }
1589 
1590         // A wrapper class to handle multiple situations where several calls to
1591         // the OffloadController need to happen together.
1592         //
1593         // TODO: This suggests that the interface between OffloadController and
1594         // Tethering is in need of improvement. Refactor these calls into the
1595         // OffloadController implementation.
1596         class OffloadWrapper {
start()1597             public void start() {
1598                 mOffloadController.start();
1599                 sendOffloadExemptPrefixes();
1600             }
1601 
stop()1602             public void stop() {
1603                 mOffloadController.stop();
1604             }
1605 
updateUpstreamNetworkState(NetworkState ns)1606             public void updateUpstreamNetworkState(NetworkState ns) {
1607                 mOffloadController.setUpstreamLinkProperties(
1608                         (ns != null) ? ns.linkProperties : null);
1609             }
1610 
updateDownstreamLinkProperties(LinkProperties newLp)1611             public void updateDownstreamLinkProperties(LinkProperties newLp) {
1612                 // Update the list of offload-exempt prefixes before adding
1613                 // new prefixes on downstream interfaces to the offload HAL.
1614                 sendOffloadExemptPrefixes();
1615                 mOffloadController.notifyDownstreamLinkProperties(newLp);
1616             }
1617 
excludeDownstreamInterface(String ifname)1618             public void excludeDownstreamInterface(String ifname) {
1619                 // This and other interfaces may be in local-only hotspot mode;
1620                 // resend all local prefixes to the OffloadController.
1621                 sendOffloadExemptPrefixes();
1622                 mOffloadController.removeDownstreamInterface(ifname);
1623             }
1624 
sendOffloadExemptPrefixes()1625             public void sendOffloadExemptPrefixes() {
1626                 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
1627             }
1628 
sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes)1629             public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
1630                 // Add in well-known minimum set.
1631                 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
1632                 // Add tragically hardcoded prefixes.
1633                 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
1634 
1635                 // Maybe add prefixes or addresses for downstreams, depending on
1636                 // the IP serving mode of each.
1637                 for (IpServer ipServer : mNotifyList) {
1638                     final LinkProperties lp = ipServer.linkProperties();
1639 
1640                     switch (ipServer.servingMode()) {
1641                         case IpServer.STATE_UNAVAILABLE:
1642                         case IpServer.STATE_AVAILABLE:
1643                             // No usable LinkProperties in these states.
1644                             continue;
1645                         case IpServer.STATE_TETHERED:
1646                             // Only add IPv4 /32 and IPv6 /128 prefixes. The
1647                             // directly-connected prefixes will be sent as
1648                             // downstream "offload-able" prefixes.
1649                             for (LinkAddress addr : lp.getAllLinkAddresses()) {
1650                                 final InetAddress ip = addr.getAddress();
1651                                 if (ip.isLinkLocalAddress()) continue;
1652                                 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
1653                             }
1654                             break;
1655                         case IpServer.STATE_LOCAL_ONLY:
1656                             // Add prefixes covering all local IPs.
1657                             localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
1658                             break;
1659                     }
1660                 }
1661 
1662                 mOffloadController.setLocalPrefixes(localPrefixes);
1663             }
1664         }
1665     }
1666 
systemReady()1667     public void systemReady() {
1668         mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
1669                 mEntitlementMgr);
1670     }
1671 
1672     /** Get the latest value of the tethering entitlement check. */
getLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi)1673     public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
1674             boolean showEntitlementUi) {
1675         if (receiver != null) {
1676             mEntitlementMgr.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
1677         }
1678     }
1679 
1680     /** Register tethering event callback */
registerTetheringEventCallback(ITetheringEventCallback callback)1681     public void registerTetheringEventCallback(ITetheringEventCallback callback) {
1682         mHandler.post(() -> {
1683             try {
1684                 callback.onUpstreamChanged(mTetherUpstream);
1685             } catch (RemoteException e) {
1686                 // Not really very much to do here.
1687             }
1688             mTetheringEventCallbacks.register(callback);
1689         });
1690     }
1691 
1692     /** Unregister tethering event callback */
unregisterTetheringEventCallback(ITetheringEventCallback callback)1693     public void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
1694         mHandler.post(() -> {
1695             mTetheringEventCallbacks.unregister(callback);
1696         });
1697     }
1698 
reportUpstreamChanged(Network network)1699     private void reportUpstreamChanged(Network network) {
1700         final int length = mTetheringEventCallbacks.beginBroadcast();
1701         try {
1702             for (int i = 0; i < length; i++) {
1703                 try {
1704                     mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
1705                 } catch (RemoteException e) {
1706                     // Not really very much to do here.
1707                 }
1708             }
1709         } finally {
1710             mTetheringEventCallbacks.finishBroadcast();
1711         }
1712     }
1713 
1714     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)1715     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
1716         // Binder.java closes the resource for us.
1717         @SuppressWarnings("resource")
1718         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
1719         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
1720 
1721         pw.println("Tethering:");
1722         pw.increaseIndent();
1723 
1724         pw.println("Configuration:");
1725         pw.increaseIndent();
1726         final TetheringConfiguration cfg = mConfig;
1727         cfg.dump(pw);
1728         pw.decreaseIndent();
1729 
1730         pw.println("Entitlement:");
1731         pw.increaseIndent();
1732         mEntitlementMgr.dump(pw);
1733         pw.decreaseIndent();
1734 
1735         synchronized (mPublicSync) {
1736             pw.println("Tether state:");
1737             pw.increaseIndent();
1738             for (int i = 0; i < mTetherStates.size(); i++) {
1739                 final String iface = mTetherStates.keyAt(i);
1740                 final TetherState tetherState = mTetherStates.valueAt(i);
1741                 pw.print(iface + " - ");
1742 
1743                 switch (tetherState.lastState) {
1744                     case IpServer.STATE_UNAVAILABLE:
1745                         pw.print("UnavailableState");
1746                         break;
1747                     case IpServer.STATE_AVAILABLE:
1748                         pw.print("AvailableState");
1749                         break;
1750                     case IpServer.STATE_TETHERED:
1751                         pw.print("TetheredState");
1752                         break;
1753                     case IpServer.STATE_LOCAL_ONLY:
1754                         pw.print("LocalHotspotState");
1755                         break;
1756                     default:
1757                         pw.print("UnknownState");
1758                         break;
1759                 }
1760                 pw.println(" - lastError = " + tetherState.lastError);
1761             }
1762             pw.println("Upstream wanted: " + upstreamWanted());
1763             pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet);
1764             pw.decreaseIndent();
1765         }
1766 
1767         pw.println("Hardware offload:");
1768         pw.increaseIndent();
1769         mOffloadController.dump(pw);
1770         pw.decreaseIndent();
1771 
1772         pw.println("Log:");
1773         pw.increaseIndent();
1774         if (argsContain(args, SHORT_ARG)) {
1775             pw.println("<log removed for brevity>");
1776         } else {
1777             mLog.dump(fd, pw, args);
1778         }
1779         pw.decreaseIndent();
1780 
1781         pw.decreaseIndent();
1782     }
1783 
argsContain(String[] args, String target)1784     private static boolean argsContain(String[] args, String target) {
1785         for (String arg : args) {
1786             if (target.equals(arg)) return true;
1787         }
1788         return false;
1789     }
1790 
makeControlCallback()1791     private IpServer.Callback makeControlCallback() {
1792         return new IpServer.Callback() {
1793             @Override
1794             public void updateInterfaceState(IpServer who, int state, int lastError) {
1795                 notifyInterfaceStateChange(who, state, lastError);
1796             }
1797 
1798             @Override
1799             public void updateLinkProperties(IpServer who, LinkProperties newLp) {
1800                 notifyLinkPropertiesChanged(who, newLp);
1801             }
1802         };
1803     }
1804 
1805     // TODO: Move into TetherMasterSM.
1806     private void notifyInterfaceStateChange(IpServer who, int state, int error) {
1807         final String iface = who.interfaceName();
1808         synchronized (mPublicSync) {
1809             final TetherState tetherState = mTetherStates.get(iface);
1810             if (tetherState != null && tetherState.ipServer.equals(who)) {
1811                 tetherState.lastState = state;
1812                 tetherState.lastError = error;
1813             } else {
1814                 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
1815             }
1816         }
1817 
1818         mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
1819 
1820         try {
1821             // Notify that we're tethering (or not) this interface.
1822             // This is how data saver for instance knows if the user explicitly
1823             // turned on tethering (thus keeping us from being in data saver mode).
1824             mPolicyManager.onTetheringChanged(iface, state == IpServer.STATE_TETHERED);
1825         } catch (RemoteException e) {
1826             // Not really very much we can do here.
1827         }
1828 
1829         // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
1830         // Thus we give a chance for TetherMasterSM to recover to InitialState
1831         // by sending CMD_CLEAR_ERROR
1832         if (error == TETHER_ERROR_MASTER_ERROR) {
1833             mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
1834         }
1835         int which;
1836         switch (state) {
1837             case IpServer.STATE_UNAVAILABLE:
1838             case IpServer.STATE_AVAILABLE:
1839                 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
1840                 break;
1841             case IpServer.STATE_TETHERED:
1842             case IpServer.STATE_LOCAL_ONLY:
1843                 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
1844                 break;
1845             default:
1846                 Log.wtf(TAG, "Unknown interface state: " + state);
1847                 return;
1848         }
1849         mTetherMasterSM.sendMessage(which, state, 0, who);
1850         sendTetherStateChangedBroadcast();
1851     }
1852 
1853     private void notifyLinkPropertiesChanged(IpServer who, LinkProperties newLp) {
1854         final String iface = who.interfaceName();
1855         final int state;
1856         synchronized (mPublicSync) {
1857             final TetherState tetherState = mTetherStates.get(iface);
1858             if (tetherState != null && tetherState.ipServer.equals(who)) {
1859                 state = tetherState.lastState;
1860             } else {
1861                 mLog.log("got notification from stale iface " + iface);
1862                 return;
1863             }
1864         }
1865 
1866         mLog.log(String.format(
1867                 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
1868                 iface, IpServer.getStateString(state), newLp));
1869         final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
1870         mTetherMasterSM.sendMessage(which, state, 0, newLp);
1871     }
1872 
1873     private void maybeTrackNewInterfaceLocked(final String iface) {
1874         // If we don't care about this type of interface, ignore.
1875         final int interfaceType = ifaceNameToType(iface);
1876         if (interfaceType == TETHERING_INVALID) {
1877             mLog.log(iface + " is not a tetherable iface, ignoring");
1878             return;
1879         }
1880         maybeTrackNewInterfaceLocked(iface, interfaceType);
1881     }
1882 
1883     private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
1884         // If we have already started a TISM for this interface, skip.
1885         if (mTetherStates.containsKey(iface)) {
1886             mLog.log("active iface (" + iface + ") reported as added, ignoring");
1887             return;
1888         }
1889 
1890         mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
1891         final TetherState tetherState = new TetherState(
1892                 new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
1893                              makeControlCallback(), mConfig.enableLegacyDhcpServer,
1894                              mDeps.getIpServerDependencies()));
1895         mTetherStates.put(iface, tetherState);
1896         tetherState.ipServer.start();
1897     }
1898 
1899     private void stopTrackingInterfaceLocked(final String iface) {
1900         final TetherState tetherState = mTetherStates.get(iface);
1901         if (tetherState == null) {
1902             mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
1903             return;
1904         }
1905         tetherState.ipServer.stop();
1906         mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
1907         mTetherStates.remove(iface);
1908     }
1909 
1910     private static String[] copy(String[] strarray) {
1911         return Arrays.copyOf(strarray, strarray.length);
1912     }
1913 }
1914