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