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