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