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