blob: 5583e86cde705d889f69abc46caa0e3bcacb70cc [file] [log] [blame]
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.connectivity;
18
Erik Klinec438e302017-07-04 22:02:49 +090019import static android.hardware.usb.UsbManager.USB_CONFIGURED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090020import static android.hardware.usb.UsbManager.USB_CONNECTED;
21import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
Erik Kline93c4afa2017-06-04 11:36:01 +090022import static android.net.ConnectivityManager.getNetworkTypeName;
Erik Kline2efb8272017-05-31 15:53:53 +090023import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
24import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
Erik Kline2e88b5e2017-01-18 11:57:45 +090025import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
Erik Kline2efb8272017-05-31 15:53:53 +090026import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
27import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
28import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
29import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090030import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
Erik Kline7747fd42017-05-12 16:52:48 +090031import static com.android.server.ConnectivityService.SHORT_ARG;
Erik Kline2e88b5e2017-01-18 11:57:45 +090032
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080033import android.app.Notification;
34import android.app.NotificationManager;
35import android.app.PendingIntent;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080036import android.bluetooth.BluetoothAdapter;
37import android.bluetooth.BluetoothPan;
38import android.bluetooth.BluetoothProfile;
39import android.bluetooth.BluetoothProfile.ServiceListener;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080040import android.content.BroadcastReceiver;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -080041import android.content.ComponentName;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080042import android.content.Context;
43import android.content.Intent;
44import android.content.IntentFilter;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080045import android.content.pm.PackageManager;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080046import android.content.res.Resources;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080047import android.hardware.usb.UsbManager;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080048import android.net.ConnectivityManager;
Christopher Wileydeebfec2016-09-16 11:14:36 -070049import android.net.INetworkPolicyManager;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070050import android.net.INetworkStatsService;
Erik Kline3a5278f2017-06-24 19:29:10 +090051import android.net.IpPrefix;
Erik Klineed962a82017-07-06 19:49:35 +090052import android.net.LinkAddress;
Robert Greenwalt05d89362011-01-23 16:04:05 -080053import android.net.LinkProperties;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070054import android.net.Network;
Erik Kline0c9cb2b2015-11-20 17:47:08 +090055import android.net.NetworkCapabilities;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080056import android.net.NetworkInfo;
Erik Kline0c9cb2b2015-11-20 17:47:08 +090057import android.net.NetworkRequest;
Erik Kline6ff17f72015-12-10 20:42:12 +090058import android.net.NetworkState;
Robert Greenwalte5903732011-02-22 16:00:42 -080059import android.net.NetworkUtils;
Lorenzo Colitti13c9fde2013-03-15 04:22:37 +090060import android.net.RouteInfo;
Erik Kline32179ff2017-07-04 18:28:11 +090061import android.net.util.PrefixUtils;
Erik Kline7747fd42017-05-12 16:52:48 +090062import android.net.util.SharedLog;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080063import android.net.wifi.WifiManager;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080064import android.os.Binder;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080065import android.os.Bundle;
Erik Klinef4b6e342017-04-25 19:19:59 +090066import android.os.Handler;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080067import android.os.INetworkManagementService;
Robert Greenwaltdfadaea2010-03-11 15:03:08 -080068import android.os.Looper;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080069import android.os.Message;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080070import android.os.Parcel;
Christopher Wileydeebfec2016-09-16 11:14:36 -070071import android.os.RemoteException;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080072import android.os.ResultReceiver;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070073import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010074import android.os.UserManager;
75import android.os.UserManagerInternal;
76import android.os.UserManagerInternal.UserRestrictionsListener;
Jeremy Klein15f3d212016-01-24 17:01:09 -080077import android.provider.Settings;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080078import android.telephony.CarrierConfigManager;
Junda Liu38531582014-10-28 13:52:51 -070079import android.telephony.TelephonyManager;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090080import android.text.TextUtils;
Christopher Wileye9490392016-05-26 15:57:29 -070081import android.util.ArrayMap;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080082import android.util.Log;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090083import android.util.SparseArray;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080084
Christopher Wiley497c1472016-10-11 13:26:03 -070085import com.android.internal.annotations.VisibleForTesting;
Chris Wren282cfef2017-03-27 15:01:44 -040086import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -050087import com.android.internal.notification.SystemNotificationChannels;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -080088import com.android.internal.telephony.IccCardConstants;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -080089import com.android.internal.telephony.TelephonyIntents;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060090import com.android.internal.util.DumpUtils;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080091import com.android.internal.util.IndentingPrintWriter;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090092import com.android.internal.util.MessageUtils;
93import com.android.internal.util.Protocol;
Wink Saville64c42ca2011-04-18 14:55:10 -070094import com.android.internal.util.State;
95import com.android.internal.util.StateMachine;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010096import com.android.server.LocalServices;
Christopher Wileye03fb442016-05-18 13:45:20 -070097import com.android.server.connectivity.tethering.IControlsTethering;
Erik Kline1eb8c692016-07-08 17:21:26 +090098import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
Erik Klinee0cce212017-03-06 14:05:23 +090099import com.android.server.connectivity.tethering.OffloadController;
Erik Kline227648f2017-01-20 20:26:10 +0900100import com.android.server.connectivity.tethering.SimChangeListener;
Mitchell Wills7040b4e2016-05-23 16:40:10 -0700101import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
Hugo Benichib55fb222017-03-10 14:20:57 +0900102import com.android.server.connectivity.tethering.TetheringConfiguration;
Erik Kline47222fc2017-04-30 19:36:15 +0900103import com.android.server.connectivity.tethering.TetheringDependencies;
Erik Kline9bba3402017-01-13 16:46:52 +0900104import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
Lorenzo Colittif4e90ea2013-10-31 23:30:47 +0900105import com.android.server.net.BaseNetworkObserver;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800106
107import java.io.FileDescriptor;
108import java.io.PrintWriter;
Robert Greenwalt4f74d552011-12-19 16:59:31 -0800109import java.net.Inet4Address;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800110import java.net.InetAddress;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800111import java.util.ArrayList;
Lorenzo Colittib57edc52014-08-22 17:10:50 -0700112import java.util.Arrays;
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700113import java.util.Collection;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800114import java.util.HashMap;
Erik Klineea9cc482017-03-10 19:35:34 +0900115import java.util.HashSet;
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700116import java.util.Iterator;
Erik Klineea9cc482017-03-10 19:35:34 +0900117import java.util.Map;
Erik Kline3a5278f2017-06-24 19:29:10 +0900118import java.util.Set;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -0800119import java.util.concurrent.atomic.AtomicInteger;
120
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700121
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800122/**
123 * @hide
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800124 *
Christopher Wiley3b1d9222016-05-20 16:44:04 -0700125 * This class holds much of the business logic to allow Android devices
126 * to act as IP gateways via USB, BT, and WiFi interfaces.
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800127 */
Erik Kline6e9a1012017-06-06 19:24:21 +0900128public class Tethering extends BaseNetworkObserver {
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800129
Hugo Benichib55fb222017-03-10 14:20:57 +0900130 private final static String TAG = Tethering.class.getSimpleName();
Joe Onorato12acbd72016-02-01 17:49:31 -0800131 private final static boolean DBG = false;
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800132 private final static boolean VDBG = false;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800133
Christopher Wiley497c1472016-10-11 13:26:03 -0700134 protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
135
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900136 private static final Class[] messageClasses = {
Mitchell Wills7040b4e2016-05-23 16:40:10 -0700137 Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900138 };
139 private static final SparseArray<String> sMagicDecoderRing =
140 MessageUtils.findMessageNames(messageClasses);
141
Hugo Benichib55fb222017-03-10 14:20:57 +0900142 // {@link ComponentName} of the Service used to run tether provisioning.
143 private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
144 .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
145
146 private static class TetherState {
147 public final TetherInterfaceStateMachine stateMachine;
148 public int lastState;
149 public int lastError;
Erik Klineea9cc482017-03-10 19:35:34 +0900150
Hugo Benichib55fb222017-03-10 14:20:57 +0900151 public TetherState(TetherInterfaceStateMachine sm) {
152 stateMachine = sm;
153 // Assume all state machines start out available and with no errors.
154 lastState = IControlsTethering.STATE_AVAILABLE;
155 lastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
156 }
Erik Klineea9cc482017-03-10 19:35:34 +0900157
158 public boolean isCurrentlyServing() {
159 switch (lastState) {
160 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +0900161 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +0900162 return true;
163 default:
164 return false;
165 }
166 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900167 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700168
Erik Kline7747fd42017-05-12 16:52:48 +0900169 private final SharedLog mLog = new SharedLog(TAG);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900170
Robert Greenwaltb4453622011-11-03 16:01:40 -0700171 // used to synchronize public access to members
Erik Kline6ff17f72015-12-10 20:42:12 +0900172 private final Object mPublicSync;
Hugo Benichib55fb222017-03-10 14:20:57 +0900173 private final Context mContext;
174 private final ArrayMap<String, TetherState> mTetherStates;
175 private final BroadcastReceiver mStateReceiver;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700176 private final INetworkManagementService mNMService;
177 private final INetworkStatsService mStatsService;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700178 private final INetworkPolicyManager mPolicyManager;
Erik Kline6ff17f72015-12-10 20:42:12 +0900179 private final Looper mLooper;
Christopher Wiley497c1472016-10-11 13:26:03 -0700180 private final MockableSystemProperties mSystemProperties;
Erik Kline6ff17f72015-12-10 20:42:12 +0900181 private final StateMachine mTetherMasterSM;
Erik Klinee0cce212017-03-06 14:05:23 +0900182 private final OffloadController mOffloadController;
Erik Kline6ff17f72015-12-10 20:42:12 +0900183 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
Erik Kline6e9a1012017-06-06 19:24:21 +0900184 // TODO: Figure out how to merge this and other downstream-tracking objects
185 // into a single coherent structure.
Erik Klineea9cc482017-03-10 19:35:34 +0900186 private final HashSet<TetherInterfaceStateMachine> mForwardedDownstreams;
Erik Kline227648f2017-01-20 20:26:10 +0900187 private final SimChangeListener mSimChange;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800188
Hugo Benichib55fb222017-03-10 14:20:57 +0900189 private volatile TetheringConfiguration mConfig;
190 private String mCurrentUpstreamIface;
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400191 private Notification.Builder mTetheredNotificationBuilder;
192 private int mLastNotificationId;
Erik Klineea9cc482017-03-10 19:35:34 +0900193
Mike Lockwood6c2260b2011-07-19 13:04:47 -0700194 private boolean mRndisEnabled; // track the RNDIS function enabled state
195 private boolean mUsbTetherRequested; // true if USB tethering should be started
196 // when RNDIS is enabled
Erik Kline6e9a1012017-06-06 19:24:21 +0900197 // True iff. WiFi tethering should be started when soft AP is ready.
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700198 private boolean mWifiTetherRequested;
199
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700200 public Tethering(Context context, INetworkManagementService nmService,
Christopher Wiley497c1472016-10-11 13:26:03 -0700201 INetworkStatsService statsService, INetworkPolicyManager policyManager,
Erik Kline47222fc2017-04-30 19:36:15 +0900202 Looper looper, MockableSystemProperties systemProperties,
203 TetheringDependencies deps) {
Erik Kline7747fd42017-05-12 16:52:48 +0900204 mLog.mark("constructed");
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800205 mContext = context;
Chia-chi Yehc9338302011-05-11 16:35:13 -0700206 mNMService = nmService;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700207 mStatsService = statsService;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700208 mPolicyManager = policyManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700209 mLooper = looper;
210 mSystemProperties = systemProperties;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800211
Robert Greenwaltb4453622011-11-03 16:01:40 -0700212 mPublicSync = new Object();
213
Christopher Wileyd985dde2016-05-31 10:44:35 -0700214 mTetherStates = new ArrayMap<>();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800215
Robert Greenwaltdfadaea2010-03-11 15:03:08 -0800216 mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800217 mTetherMasterSM.start();
218
Erik Klinef4b6e342017-04-25 19:19:59 +0900219 final Handler smHandler = mTetherMasterSM.getHandler();
220 mOffloadController = new OffloadController(smHandler,
221 deps.getOffloadHardwareInterface(smHandler, mLog),
Lorenzo Colitti5a7dea12017-07-12 15:48:07 +0900222 mContext.getContentResolver(), mNMService,
Erik Klinef4b6e342017-04-25 19:19:59 +0900223 mLog);
Erik Klineebdb8c82017-01-10 17:37:54 +0900224 mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
Erik Kline32179ff2017-07-04 18:28:11 +0900225 mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
Erik Klineea9cc482017-03-10 19:35:34 +0900226 mForwardedDownstreams = new HashSet<>();
Erik Kline227648f2017-01-20 20:26:10 +0900227 mSimChange = new SimChangeListener(
Erik Kline32179ff2017-07-04 18:28:11 +0900228 mContext, smHandler, () -> reevaluateSimCardProvisioning());
Erik Kline6ff17f72015-12-10 20:42:12 +0900229
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800230 mStateReceiver = new StateReceiver();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800231 IntentFilter filter = new IntentFilter();
Mike Lockwood770126a2010-12-09 22:30:37 -0800232 filter.addAction(UsbManager.ACTION_USB_STATE);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800233 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700234 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700235 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
Erik Kline32179ff2017-07-04 18:28:11 +0900236 mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800237
238 filter = new IntentFilter();
Robert Greenwalt030f5e12010-03-10 16:41:03 -0800239 filter.addAction(Intent.ACTION_MEDIA_SHARED);
240 filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800241 filter.addDataScheme("file");
Erik Kline32179ff2017-07-04 18:28:11 +0900242 mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800243
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100244 UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
245
246 // this check is useful only for some unit tests; example: ConnectivityServiceTest
247 if (userManager != null) {
248 userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
249 }
250
Robert Greenwalt49348e72011-10-21 16:54:26 -0700251 // load device config info
252 updateConfiguration();
Robert Greenwalt49348e72011-10-21 16:54:26 -0700253 }
254
Sreeram Ramachandran62a61312014-07-24 16:05:17 -0700255 // We can't do this once in the Tethering() constructor and cache the value, because the
256 // CONNECTIVITY_SERVICE is registered only after the Tethering() constructor has completed.
257 private ConnectivityManager getConnectivityManager() {
258 return (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
259 }
260
Erik Kline216af6d2017-04-27 20:57:23 +0900261 private WifiManager getWifiManager() {
262 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
263 }
264
Erik Kline93c4afa2017-06-04 11:36:01 +0900265 // NOTE: This is always invoked on the mLooper thread.
Erik Klined781fba2017-01-23 13:01:58 +0900266 private void updateConfiguration() {
Erik Kline6bd74532017-05-19 10:10:41 +0900267 mConfig = new TetheringConfiguration(mContext, mLog);
Erik Kline93c4afa2017-06-04 11:36:01 +0900268 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800269 }
270
Erik Kline6ee73da2017-07-08 20:36:37 +0900271 private void maybeUpdateConfiguration() {
272 final int dunCheck = TetheringConfiguration.checkDunRequired(mContext);
273 if (dunCheck == mConfig.dunCheck) return;
274 updateConfiguration();
275 }
276
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900277 @Override
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700278 public void interfaceStatusChanged(String iface, boolean up) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900279 // Never called directly: only called from interfaceLinkStateChanged.
280 // See NetlinkHandler.cpp:71.
Wink Savillec9acde92011-09-21 11:05:43 -0700281 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700282 synchronized (mPublicSync) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700283 if (up) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900284 maybeTrackNewInterfaceLocked(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800285 } else {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900286 if (ifaceNameToType(iface) == ConnectivityManager.TETHERING_BLUETOOTH) {
287 stopTrackingInterfaceLocked(iface);
Christopher Wileyd30aaeb2016-07-08 09:33:50 -0700288 } else {
289 // Ignore usb0 down after enabling RNDIS.
290 // We will handle disconnect in interfaceRemoved.
291 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status
292 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
293 if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800294 }
295 }
296 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800297 }
298
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900299 @Override
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700300 public void interfaceLinkStateChanged(String iface, boolean up) {
Irfan Sheriff23eb2972011-07-22 15:21:10 -0700301 interfaceStatusChanged(iface, up);
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700302 }
303
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700304 private int ifaceNameToType(String iface) {
Erik Kline3e756652017-01-17 13:42:19 +0900305 final TetheringConfiguration cfg = mConfig;
306
307 if (cfg.isWifi(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700308 return ConnectivityManager.TETHERING_WIFI;
Erik Kline3e756652017-01-17 13:42:19 +0900309 } else if (cfg.isUsb(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700310 return ConnectivityManager.TETHERING_USB;
Erik Kline3e756652017-01-17 13:42:19 +0900311 } else if (cfg.isBluetooth(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700312 return ConnectivityManager.TETHERING_BLUETOOTH;
313 }
314 return ConnectivityManager.TETHERING_INVALID;
315 }
316
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900317 @Override
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800318 public void interfaceAdded(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700319 if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700320 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900321 maybeTrackNewInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800322 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800323 }
324
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900325 @Override
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800326 public void interfaceRemoved(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700327 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700328 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900329 stopTrackingInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800330 }
331 }
332
Hugo Benichib55fb222017-03-10 14:20:57 +0900333 public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800334 if (!isTetherProvisioningRequired()) {
335 enableTetheringInternal(type, true, receiver);
336 return;
337 }
338
339 if (showProvisioningUi) {
340 runUiTetherProvisioningAndEnable(type, receiver);
341 } else {
342 runSilentTetherProvisioningAndEnable(type, receiver);
343 }
344 }
345
346 public void stopTethering(int type) {
347 enableTetheringInternal(type, false, null);
348 if (isTetherProvisioningRequired()) {
349 cancelTetherProvisioningRechecks(type);
350 }
351 }
352
353 /**
354 * Check if the device requires a provisioning check in order to enable tethering.
355 *
356 * @return a boolean - {@code true} indicating tether provisioning is required by the carrier.
357 */
Christopher Wiley497c1472016-10-11 13:26:03 -0700358 @VisibleForTesting
359 protected boolean isTetherProvisioningRequired() {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800360 String[] provisionApp = mContext.getResources().getStringArray(
361 com.android.internal.R.array.config_mobile_hotspot_provision_app);
Christopher Wiley497c1472016-10-11 13:26:03 -0700362 if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800363 || provisionApp == null) {
364 return false;
365 }
366
367 // Check carrier config for entitlement checks
368 final CarrierConfigManager configManager = (CarrierConfigManager) mContext
369 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
Rebecca Silbersteinb07f1402016-10-04 13:53:33 -0700370 if (configManager != null && configManager.getConfig() != null) {
371 // we do have a CarrierConfigManager and it has a config.
372 boolean isEntitlementCheckRequired = configManager.getConfig().getBoolean(
373 CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
374 if (!isEntitlementCheckRequired) {
375 return false;
376 }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800377 }
378 return (provisionApp.length == 2);
379 }
380
Erik Kline227648f2017-01-20 20:26:10 +0900381 // Used by the SIM card change observation code.
382 // TODO: De-duplicate above code.
383 private boolean hasMobileHotspotProvisionApp() {
384 try {
385 if (!mContext.getResources().getString(com.android.internal.R.string.
386 config_mobile_hotspot_provision_app_no_ui).isEmpty()) {
387 Log.d(TAG, "re-evaluate provisioning");
388 return true;
389 }
390 } catch (Resources.NotFoundException e) {}
391 Log.d(TAG, "no prov-check needed for new SIM");
392 return false;
393 }
394
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800395 /**
396 * Enables or disables tethering for the given type. This should only be called once
397 * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
398 * for the specified interface.
399 */
400 private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700401 boolean isProvisioningRequired = enable && isTetherProvisioningRequired();
402 int result;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800403 switch (type) {
404 case ConnectivityManager.TETHERING_WIFI:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700405 result = setWifiTethering(enable);
406 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
407 scheduleProvisioningRechecks(type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800408 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700409 sendTetherResult(receiver, result);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800410 break;
411 case ConnectivityManager.TETHERING_USB:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700412 result = setUsbTethering(enable);
413 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800414 scheduleProvisioningRechecks(type);
415 }
416 sendTetherResult(receiver, result);
417 break;
418 case ConnectivityManager.TETHERING_BLUETOOTH:
419 setBluetoothTethering(enable, receiver);
420 break;
421 default:
422 Log.w(TAG, "Invalid tether type.");
423 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE);
424 }
425 }
426
427 private void sendTetherResult(ResultReceiver receiver, int result) {
428 if (receiver != null) {
429 receiver.send(result, null);
430 }
431 }
432
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700433 private int setWifiTethering(final boolean enable) {
Erik Kline256be782017-04-29 13:20:04 +0900434 int rval = ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
435 final long ident = Binder.clearCallingIdentity();
436 try {
437 synchronized (mPublicSync) {
438 mWifiTetherRequested = enable;
439 final WifiManager mgr = getWifiManager();
440 if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||
441 (!enable && mgr.stopSoftAp())) {
442 rval = ConnectivityManager.TETHER_ERROR_NO_ERROR;
443 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700444 }
Erik Kline256be782017-04-29 13:20:04 +0900445 } finally {
446 Binder.restoreCallingIdentity(ident);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700447 }
Erik Kline256be782017-04-29 13:20:04 +0900448 return rval;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700449 }
450
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800451 private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
452 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
453 if (adapter == null || !adapter.isEnabled()) {
454 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " +
455 (adapter == null));
456 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL);
457 return;
458 }
459
460 adapter.getProfileProxy(mContext, new ServiceListener() {
461 @Override
462 public void onServiceDisconnected(int profile) { }
463
464 @Override
465 public void onServiceConnected(int profile, BluetoothProfile proxy) {
466 ((BluetoothPan) proxy).setBluetoothTethering(enable);
467 // TODO: Enabling bluetooth tethering can fail asynchronously here.
468 // We should figure out a way to bubble up that failure instead of sending success.
Jeremy Klein45ae04a2016-02-05 10:37:32 -0800469 int result = ((BluetoothPan) proxy).isTetheringOn() == enable ?
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800470 ConnectivityManager.TETHER_ERROR_NO_ERROR :
471 ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
472 sendTetherResult(receiver, result);
473 if (enable && isTetherProvisioningRequired()) {
474 scheduleProvisioningRechecks(ConnectivityManager.TETHERING_BLUETOOTH);
475 }
476 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
477 }
478 }, BluetoothProfile.PAN);
479 }
480
481 private void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
Jeremy Klein15f3d212016-01-24 17:01:09 -0800482 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
483 sendUiTetherProvisionIntent(type, proxyReceiver);
484 }
485
486 private void sendUiTetherProvisionIntent(int type, ResultReceiver receiver) {
487 Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING);
488 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
489 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
490 final long ident = Binder.clearCallingIdentity();
491 try {
492 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
493 } finally {
494 Binder.restoreCallingIdentity(ident);
495 }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800496 }
497
498 /**
Erik Klinefdd41112017-01-12 17:02:51 +0900499 * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result
500 * is successful before firing back up to the wrapped receiver.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800501 *
502 * @param type The type of tethering being enabled.
503 * @param receiver A ResultReceiver which will be called back with an int resultCode.
504 * @return The proxy receiver.
505 */
506 private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) {
507 ResultReceiver rr = new ResultReceiver(null) {
508 @Override
509 protected void onReceiveResult(int resultCode, Bundle resultData) {
510 // If provisioning is successful, enable tethering, otherwise just send the error.
511 if (resultCode == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
512 enableTetheringInternal(type, true, receiver);
513 } else {
514 sendTetherResult(receiver, resultCode);
515 }
516 }
517 };
518
519 // The following is necessary to avoid unmarshalling issues when sending the receiver
Erik Kline6ff17f72015-12-10 20:42:12 +0900520 // across processes.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800521 Parcel parcel = Parcel.obtain();
522 rr.writeToParcel(parcel,0);
523 parcel.setDataPosition(0);
524 ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
525 parcel.recycle();
526 return receiverForSending;
527 }
528
529 private void scheduleProvisioningRechecks(int type) {
530 Intent intent = new Intent();
531 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
532 intent.putExtra(ConnectivityManager.EXTRA_SET_ALARM, true);
533 intent.setComponent(TETHER_SERVICE);
534 final long ident = Binder.clearCallingIdentity();
535 try {
536 mContext.startServiceAsUser(intent, UserHandle.CURRENT);
537 } finally {
538 Binder.restoreCallingIdentity(ident);
539 }
540 }
541
542 private void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
543 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
544 sendSilentTetherProvisionIntent(type, proxyReceiver);
545 }
546
547 private void sendSilentTetherProvisionIntent(int type, ResultReceiver receiver) {
548 Intent intent = new Intent();
549 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
550 intent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
551 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
552 intent.setComponent(TETHER_SERVICE);
553 final long ident = Binder.clearCallingIdentity();
554 try {
555 mContext.startServiceAsUser(intent, UserHandle.CURRENT);
556 } finally {
557 Binder.restoreCallingIdentity(ident);
558 }
559 }
560
561 private void cancelTetherProvisioningRechecks(int type) {
562 if (getConnectivityManager().isTetheringSupported()) {
563 Intent intent = new Intent();
564 intent.putExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE, type);
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 }
Erik Kline6ff17f72015-12-10 20:42:12 +0900574
Erik Kline227648f2017-01-20 20:26:10 +0900575 // Used by the SIM card change observation code.
576 // TODO: De-duplicate with above code, where possible.
577 private void startProvisionIntent(int tetherType) {
578 final Intent startProvIntent = new Intent();
579 startProvIntent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, tetherType);
580 startProvIntent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
581 startProvIntent.setComponent(TETHER_SERVICE);
582 mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT);
583 }
584
Robert Greenwalt5a735062010-03-02 17:25:02 -0800585 public int tether(String iface) {
Erik Klineea9cc482017-03-10 19:35:34 +0900586 return tether(iface, IControlsTethering.STATE_TETHERED);
587 }
588
589 private int tether(String iface, int requestedState) {
Wink Savillec9acde92011-09-21 11:05:43 -0700590 if (DBG) Log.d(TAG, "Tethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700591 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700592 TetherState tetherState = mTetherStates.get(iface);
593 if (tetherState == null) {
Erik Kline00019f42016-06-30 19:31:46 +0900594 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700595 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
596 }
597 // Ignore the error status of the interface. If the interface is available,
598 // the errors are referring to past tethering attempts anyway.
Hugo Benichib55fb222017-03-10 14:20:57 +0900599 if (tetherState.lastState != IControlsTethering.STATE_AVAILABLE) {
Erik Kline00019f42016-06-30 19:31:46 +0900600 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700601 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700602 }
Erik Klineea9cc482017-03-10 19:35:34 +0900603 // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's
604 // queue but not yet processed, this will be a no-op and it will not
605 // return an error.
606 //
607 // TODO: reexamine the threading and messaging model.
608 tetherState.stateMachine.sendMessage(
609 TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, requestedState);
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700610 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800611 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800612 }
613
Robert Greenwalt5a735062010-03-02 17:25:02 -0800614 public int untether(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700615 if (DBG) Log.d(TAG, "Untethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700616 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700617 TetherState tetherState = mTetherStates.get(iface);
618 if (tetherState == null) {
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700619 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
620 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
621 }
Erik Klineea9cc482017-03-10 19:35:34 +0900622 if (!tetherState.isCurrentlyServing()) {
623 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700624 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
625 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900626 tetherState.stateMachine.sendMessage(
Christopher Wileyd985dde2016-05-31 10:44:35 -0700627 TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700628 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800629 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800630 }
631
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700632 public void untetherAll() {
Christopher Wileyfa6a4862016-09-19 08:58:06 -0700633 stopTethering(ConnectivityManager.TETHERING_WIFI);
634 stopTethering(ConnectivityManager.TETHERING_USB);
635 stopTethering(ConnectivityManager.TETHERING_BLUETOOTH);
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700636 }
637
Robert Greenwalt5a735062010-03-02 17:25:02 -0800638 public int getLastTetherError(String iface) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700639 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700640 TetherState tetherState = mTetherStates.get(iface);
641 if (tetherState == null) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700642 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
643 ", ignoring");
644 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
645 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900646 return tetherState.lastError;
Robert Greenwalt5a735062010-03-02 17:25:02 -0800647 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800648 }
649
Erik Klineea9cc482017-03-10 19:35:34 +0900650 // TODO: Figure out how to update for local hotspot mode interfaces.
Christopher Wileyd985dde2016-05-31 10:44:35 -0700651 private void sendTetherStateChangedBroadcast() {
Sreeram Ramachandran62a61312014-07-24 16:05:17 -0700652 if (!getConnectivityManager().isTetheringSupported()) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800653
Erik Kline8351faa2017-04-17 16:47:23 +0900654 final ArrayList<String> availableList = new ArrayList<>();
655 final ArrayList<String> tetherList = new ArrayList<>();
656 final ArrayList<String> localOnlyList = new ArrayList<>();
657 final ArrayList<String> erroredList = new ArrayList<>();
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800658
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800659 boolean wifiTethered = false;
660 boolean usbTethered = false;
Danica Chang6fdd0c62010-08-11 14:54:43 -0700661 boolean bluetoothTethered = false;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800662
Erik Kline3e756652017-01-17 13:42:19 +0900663 final TetheringConfiguration cfg = mConfig;
664
Robert Greenwaltb4453622011-11-03 16:01:40 -0700665 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700666 for (int i = 0; i < mTetherStates.size(); i++) {
667 TetherState tetherState = mTetherStates.valueAt(i);
668 String iface = mTetherStates.keyAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +0900669 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700670 erroredList.add(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +0900671 } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700672 availableList.add(iface);
Erik Klineca41be72017-04-20 22:59:16 +0900673 } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_ONLY) {
Erik Kline8351faa2017-04-17 16:47:23 +0900674 localOnlyList.add(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +0900675 } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
Erik Kline3e756652017-01-17 13:42:19 +0900676 if (cfg.isUsb(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700677 usbTethered = true;
Erik Kline3e756652017-01-17 13:42:19 +0900678 } else if (cfg.isWifi(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700679 wifiTethered = true;
Erik Kline3e756652017-01-17 13:42:19 +0900680 } else if (cfg.isBluetooth(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700681 bluetoothTethered = true;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800682 }
Erik Kline8351faa2017-04-17 16:47:23 +0900683 tetherList.add(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800684 }
685 }
686 }
Erik Kline8351faa2017-04-17 16:47:23 +0900687 final Intent bcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
688 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
Robert Greenwalt98c79e52011-07-28 11:51:11 -0700689 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Erik Kline8351faa2017-04-17 16:47:23 +0900690 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, availableList);
691 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
692 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, tetherList);
693 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, erroredList);
694 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800695 if (DBG) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900696 Log.d(TAG, String.format(
Erik Kline8351faa2017-04-17 16:47:23 +0900697 "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
698 "avail", TextUtils.join(",", availableList),
699 "local_only", TextUtils.join(",", localOnlyList),
700 "tether", TextUtils.join(",", tetherList),
701 "error", TextUtils.join(",", erroredList)));
Robert Greenwalt924cc942010-06-28 10:26:19 -0700702 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800703
704 if (usbTethered) {
Danica Chang6fdd0c62010-08-11 14:54:43 -0700705 if (wifiTethered || bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400706 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800707 } else {
Chris Wren282cfef2017-03-27 15:01:44 -0400708 showTetheredNotification(SystemMessage.NOTE_TETHER_USB);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800709 }
710 } else if (wifiTethered) {
Danica Chang6fdd0c62010-08-11 14:54:43 -0700711 if (bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400712 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
Danica Chang6fdd0c62010-08-11 14:54:43 -0700713 } else {
Vinit Deshpande2576a802014-11-18 13:56:15 -0800714 /* We now have a status bar icon for WifiTethering, so drop the notification */
715 clearTetheredNotification();
Danica Chang6fdd0c62010-08-11 14:54:43 -0700716 }
717 } else if (bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400718 showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800719 } else {
720 clearTetheredNotification();
721 }
722 }
723
Chris Wren282cfef2017-03-27 15:01:44 -0400724 private void showTetheredNotification(int id) {
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100725 showTetheredNotification(id, true);
726 }
727
728 @VisibleForTesting
729 protected void showTetheredNotification(int id, boolean tetheringOn) {
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800730 NotificationManager notificationManager =
Erik Klinec438e302017-07-04 22:02:49 +0900731 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800732 if (notificationManager == null) {
733 return;
734 }
Chris Wren282cfef2017-03-27 15:01:44 -0400735 int icon = 0;
736 switch(id) {
737 case SystemMessage.NOTE_TETHER_USB:
738 icon = com.android.internal.R.drawable.stat_sys_tether_usb;
739 break;
740 case SystemMessage.NOTE_TETHER_BLUETOOTH:
741 icon = com.android.internal.R.drawable.stat_sys_tether_bluetooth;
742 break;
743 case SystemMessage.NOTE_TETHER_GENERAL:
744 default:
745 icon = com.android.internal.R.drawable.stat_sys_tether_general;
746 break;
747 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800748
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400749 if (mLastNotificationId != 0) {
750 if (mLastNotificationId == icon) {
Robert Greenwaltdb3fe9e2010-03-18 16:28:30 -0700751 return;
752 }
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400753 notificationManager.cancelAsUser(null, mLastNotificationId,
Robert Greenwalt3cab6b02012-10-04 16:44:26 -0700754 UserHandle.ALL);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400755 mLastNotificationId = 0;
Robert Greenwaltdb3fe9e2010-03-18 16:28:30 -0700756 }
757
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800758 Intent intent = new Intent();
759 intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
760 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
761
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700762 PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0,
763 null, UserHandle.CURRENT);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800764
765 Resources r = Resources.getSystem();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100766 final CharSequence title;
767 final CharSequence message;
768
769 if (tetheringOn) {
770 title = r.getText(com.android.internal.R.string.tethered_notification_title);
771 message = r.getText(com.android.internal.R.string.tethered_notification_message);
772 } else {
773 title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
774 message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
775 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800776
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400777 if (mTetheredNotificationBuilder == null) {
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500778 mTetheredNotificationBuilder =
779 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400780 mTetheredNotificationBuilder.setWhen(0)
781 .setOngoing(true)
782 .setColor(mContext.getColor(
783 com.android.internal.R.color.system_notification_accent_color))
784 .setVisibility(Notification.VISIBILITY_PUBLIC)
785 .setCategory(Notification.CATEGORY_STATUS);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800786 }
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400787 mTetheredNotificationBuilder.setSmallIcon(icon)
788 .setContentTitle(title)
789 .setContentText(message)
790 .setContentIntent(pi);
Chris Wren282cfef2017-03-27 15:01:44 -0400791 mLastNotificationId = id;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800792
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400793 notificationManager.notifyAsUser(null, mLastNotificationId,
zhouzhijie130d4592017-05-18 10:02:59 +0800794 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800795 }
796
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100797 @VisibleForTesting
798 protected void clearTetheredNotification() {
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800799 NotificationManager notificationManager =
Erik Klinec438e302017-07-04 22:02:49 +0900800 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400801 if (notificationManager != null && mLastNotificationId != 0) {
802 notificationManager.cancelAsUser(null, mLastNotificationId,
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700803 UserHandle.ALL);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400804 mLastNotificationId = 0;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800805 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800806 }
807
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800808 private class StateReceiver extends BroadcastReceiver {
Nick Kralevich70c117a2014-05-27 15:30:02 -0700809 @Override
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800810 public void onReceive(Context content, Intent intent) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900811 final String action = intent.getAction();
812 if (action == null) return;
813
Mike Lockwood770126a2010-12-09 22:30:37 -0800814 if (action.equals(UsbManager.ACTION_USB_STATE)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900815 handleUsbAction(intent);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800816 } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900817 handleConnectivityAction(intent);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700818 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900819 handleWifiApAction(intent);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700820 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
821 updateConfiguration();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800822 }
823 }
Erik Kline2e88b5e2017-01-18 11:57:45 +0900824
825 private void handleConnectivityAction(Intent intent) {
826 final NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(
827 ConnectivityManager.EXTRA_NETWORK_INFO);
828 if (networkInfo == null ||
829 networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
830 return;
831 }
832
833 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
834 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
835 }
836
837 private void handleUsbAction(Intent intent) {
838 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
Erik Klinec438e302017-07-04 22:02:49 +0900839 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900840 final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
Erik Klinec438e302017-07-04 22:02:49 +0900841
842 mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
843 usbConnected, usbConfigured, rndisEnabled));
844
845 // There are three types of ACTION_USB_STATE:
846 //
847 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
848 // Meaning: USB connection has ended either because of
849 // software reset or hard unplug.
850 //
851 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
852 // Meaning: the first stage of USB protocol handshake has
853 // occurred but it is not complete.
854 //
855 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
856 // Meaning: the USB handshake is completely done and all the
857 // functions are ready to use.
858 //
859 // For more explanation, see b/62552150 .
Erik Kline2e88b5e2017-01-18 11:57:45 +0900860 synchronized (Tethering.this.mPublicSync) {
Erik Kline3897dc12017-08-07 18:11:22 -0700861 // Always record the state of RNDIS.
Erik Kline12905682017-08-08 20:53:46 -0700862 // TODO: consider:
863 // final boolean disconnected = !usbConnected;
864 // if (disconnected) {
865 // mRndisEnabled = false;
866 // mUsbTetherRequested = false;
867 // return;
868 // }
869 // final boolean configured = usbConnected && usbConfigured;
870 // mRndisEnabled = configured ? rndisEnabled : false;
871 // if (!configured) return;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900872 mRndisEnabled = rndisEnabled;
Erik Kline3897dc12017-08-07 18:11:22 -0700873
874 if (usbConnected && !usbConfigured) {
875 // Nothing to do here (only CONNECTED, not yet CONFIGURED).
876 return;
877 }
878
Erik Kline2e88b5e2017-01-18 11:57:45 +0900879 // start tethering if we have a request pending
Erik Klinec438e302017-07-04 22:02:49 +0900880 if (usbConfigured && mRndisEnabled && mUsbTetherRequested) {
Erik Klineea9cc482017-03-10 19:35:34 +0900881 tetherMatchingInterfaces(
882 IControlsTethering.STATE_TETHERED,
883 ConnectivityManager.TETHERING_USB);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900884 }
Erik Kline3897dc12017-08-07 18:11:22 -0700885
886 // TODO: Figure out how to remove the need for this variable.
Erik Kline2e88b5e2017-01-18 11:57:45 +0900887 mUsbTetherRequested = false;
888 }
889 }
890
891 private void handleWifiApAction(Intent intent) {
Erik Kline2efb8272017-05-31 15:53:53 +0900892 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
893 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
894 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
895
Erik Kline2e88b5e2017-01-18 11:57:45 +0900896 synchronized (Tethering.this.mPublicSync) {
897 switch (curState) {
898 case WifiManager.WIFI_AP_STATE_ENABLING:
899 // We can see this state on the way to both enabled and failure states.
900 break;
901 case WifiManager.WIFI_AP_STATE_ENABLED:
Erik Kline2efb8272017-05-31 15:53:53 +0900902 enableWifiIpServingLocked(ifname, ipmode);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900903 break;
904 case WifiManager.WIFI_AP_STATE_DISABLED:
905 case WifiManager.WIFI_AP_STATE_DISABLING:
906 case WifiManager.WIFI_AP_STATE_FAILED:
907 default:
Erik Kline562e0c12017-06-09 16:36:29 +0900908 disableWifiIpServingLocked(ifname, curState);
Erik Kline2efb8272017-05-31 15:53:53 +0900909 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900910 }
911 }
912 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800913 }
914
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100915 @VisibleForTesting
916 protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
917 private final Tethering mWrapper;
918
919 public TetheringUserRestrictionListener(Tethering wrapper) {
920 mWrapper = wrapper;
921 }
922
923 public void onUserRestrictionsChanged(int userId,
924 Bundle newRestrictions,
925 Bundle prevRestrictions) {
926 final boolean newlyDisallowed =
927 newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
928 final boolean previouslyDisallowed =
929 prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
930 final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);
931
932 if (!tetheringDisallowedChanged) {
933 return;
934 }
935
936 mWrapper.clearTetheredNotification();
937 final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
938
939 if (newlyDisallowed && isTetheringActiveOnDevice) {
940 mWrapper.showTetheredNotification(
941 com.android.internal.R.drawable.stat_sys_tether_general, false);
942 mWrapper.untetherAll();
943 }
944 }
945 }
946
Erik Kline562e0c12017-06-09 16:36:29 +0900947 private void disableWifiIpServingLocked(String ifname, int apState) {
948 mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
Erik Kline2efb8272017-05-31 15:53:53 +0900949
Erik Kline562e0c12017-06-09 16:36:29 +0900950 // Regardless of whether we requested this transition, the AP has gone
951 // down. Don't try to tether again unless we're requested to do so.
952 // TODO: Remove this altogether, once Wi-Fi reliably gives us an
953 // interface name with every broadcast.
954 mWifiTetherRequested = false;
955
956 if (!TextUtils.isEmpty(ifname)) {
957 final TetherState ts = mTetherStates.get(ifname);
958 if (ts != null) {
959 ts.stateMachine.unwanted();
960 return;
961 }
962 }
963
Erik Kline2efb8272017-05-31 15:53:53 +0900964 for (int i = 0; i < mTetherStates.size(); i++) {
965 TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine;
966 if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
Erik Kline562e0c12017-06-09 16:36:29 +0900967 tism.unwanted();
968 return;
Erik Kline2efb8272017-05-31 15:53:53 +0900969 }
970 }
Erik Kline562e0c12017-06-09 16:36:29 +0900971
972 mLog.log("Error disabling Wi-Fi IP serving; " +
973 (TextUtils.isEmpty(ifname) ? "no interface name specified"
974 : "specified interface: " + ifname));
Erik Kline2efb8272017-05-31 15:53:53 +0900975 }
976
977 private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
978 // Map wifiIpMode values to IControlsTethering serving states, inferring
979 // from mWifiTetherRequested as a final "best guess".
980 final int ipServingMode;
981 switch (wifiIpMode) {
982 case IFACE_IP_MODE_TETHERED:
983 ipServingMode = IControlsTethering.STATE_TETHERED;
984 break;
985 case IFACE_IP_MODE_LOCAL_ONLY:
986 ipServingMode = IControlsTethering.STATE_LOCAL_ONLY;
987 break;
988 default:
Erik Kline9e225542017-06-08 17:48:48 +0900989 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
990 return;
Erik Kline2efb8272017-05-31 15:53:53 +0900991 }
992
993 if (!TextUtils.isEmpty(ifname)) {
Erik Klinea9cde8b2017-06-20 21:18:31 +0900994 maybeTrackNewInterfaceLocked(ifname, ConnectivityManager.TETHERING_WIFI);
Erik Kline2efb8272017-05-31 15:53:53 +0900995 changeInterfaceState(ifname, ipServingMode);
996 } else {
Erik Kline9e225542017-06-08 17:48:48 +0900997 mLog.e(String.format(
998 "Cannot enable IP serving in mode %s on missing interface name",
999 ipServingMode));
Erik Kline2efb8272017-05-31 15:53:53 +09001000 }
1001 }
1002
Erik Klineea9cc482017-03-10 19:35:34 +09001003 // TODO: Consider renaming to something more accurate in its description.
1004 // This method:
1005 // - allows requesting either tethering or local hotspot serving states
1006 // - handles both enabling and disabling serving states
1007 // - only tethers the first matching interface in listInterfaces()
1008 // order of a given type
1009 private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
1010 if (VDBG) {
1011 Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
1012 }
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001013
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001014 String[] ifaces = null;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001015 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001016 ifaces = mNMService.listInterfaces();
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001017 } catch (Exception e) {
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001018 Log.e(TAG, "Error listing Interfaces", e);
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001019 return;
1020 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001021 String chosenIface = null;
1022 if (ifaces != null) {
1023 for (String iface : ifaces) {
1024 if (ifaceNameToType(iface) == interfaceType) {
1025 chosenIface = iface;
1026 break;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001027 }
1028 }
1029 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001030 if (chosenIface == null) {
1031 Log.e(TAG, "could not find iface of type " + interfaceType);
1032 return;
1033 }
1034
Erik Kline2efb8272017-05-31 15:53:53 +09001035 changeInterfaceState(chosenIface, requestedState);
1036 }
1037
1038 private void changeInterfaceState(String ifname, int requestedState) {
Erik Klineea9cc482017-03-10 19:35:34 +09001039 final int result;
1040 switch (requestedState) {
1041 case IControlsTethering.STATE_UNAVAILABLE:
1042 case IControlsTethering.STATE_AVAILABLE:
Erik Kline2efb8272017-05-31 15:53:53 +09001043 result = untether(ifname);
Erik Klineea9cc482017-03-10 19:35:34 +09001044 break;
1045 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +09001046 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001047 result = tether(ifname, requestedState);
Erik Klineea9cc482017-03-10 19:35:34 +09001048 break;
1049 default:
1050 Log.wtf(TAG, "Unknown interface state: " + requestedState);
1051 return;
1052 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001053 if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Erik Kline2efb8272017-05-31 15:53:53 +09001054 Log.e(TAG, "unable start or stop tethering on iface " + ifname);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001055 return;
1056 }
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001057 }
1058
Erik Kline3e756652017-01-17 13:42:19 +09001059 public TetheringConfiguration getTetheringConfiguration() {
1060 return mConfig;
1061 }
1062
Erik Klined781fba2017-01-23 13:01:58 +09001063 public boolean hasTetherableConfiguration() {
1064 final TetheringConfiguration cfg = mConfig;
1065 final boolean hasDownstreamConfiguration =
1066 (cfg.tetherableUsbRegexs.length != 0) ||
1067 (cfg.tetherableWifiRegexs.length != 0) ||
1068 (cfg.tetherableBluetoothRegexs.length != 0);
1069 final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty();
1070
1071 return hasDownstreamConfiguration && hasUpstreamConfiguration;
1072 }
1073
Erik Kline3e756652017-01-17 13:42:19 +09001074 // TODO - update callers to use getTetheringConfiguration(),
1075 // which has only final members.
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001076 public String[] getTetherableUsbRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001077 return copy(mConfig.tetherableUsbRegexs);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001078 }
1079
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001080 public String[] getTetherableWifiRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001081 return copy(mConfig.tetherableWifiRegexs);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001082 }
1083
Danica Chang6fdd0c62010-08-11 14:54:43 -07001084 public String[] getTetherableBluetoothRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001085 return copy(mConfig.tetherableBluetoothRegexs);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001086 }
1087
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001088 public int setUsbTethering(boolean enable) {
Wink Savillec9acde92011-09-21 11:05:43 -07001089 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
Erik Klinec438e302017-07-04 22:02:49 +09001090 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001091
Robert Greenwaltb4453622011-11-03 16:01:40 -07001092 synchronized (mPublicSync) {
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001093 if (enable) {
1094 if (mRndisEnabled) {
Jeremy Klein36c7aa02016-01-22 14:11:45 -08001095 final long ident = Binder.clearCallingIdentity();
1096 try {
Erik Klineea9cc482017-03-10 19:35:34 +09001097 tetherMatchingInterfaces(IControlsTethering.STATE_TETHERED,
1098 ConnectivityManager.TETHERING_USB);
Jeremy Klein36c7aa02016-01-22 14:11:45 -08001099 } finally {
1100 Binder.restoreCallingIdentity(ident);
1101 }
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001102 } else {
1103 mUsbTetherRequested = true;
Jerry Zhang935372b2016-10-12 15:49:32 -07001104 usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001105 }
1106 } else {
Jeremy Klein36c7aa02016-01-22 14:11:45 -08001107 final long ident = Binder.clearCallingIdentity();
1108 try {
Erik Klineea9cc482017-03-10 19:35:34 +09001109 tetherMatchingInterfaces(IControlsTethering.STATE_AVAILABLE,
1110 ConnectivityManager.TETHERING_USB);
Jeremy Klein36c7aa02016-01-22 14:11:45 -08001111 } finally {
1112 Binder.restoreCallingIdentity(ident);
1113 }
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001114 if (mRndisEnabled) {
Jerry Zhang935372b2016-10-12 15:49:32 -07001115 usbManager.setCurrentFunction(null, false);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001116 }
1117 mUsbTetherRequested = false;
1118 }
1119 }
1120 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
1121 }
1122
Erik Kline1fdc2e22017-05-08 17:56:35 +09001123 // TODO review API - figure out how to delete these entirely.
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001124 public String[] getTetheredIfaces() {
1125 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001126 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001127 for (int i = 0; i < mTetherStates.size(); i++) {
1128 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001129 if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001130 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001131 }
1132 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001133 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001134 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001135 }
1136
1137 public String[] getTetherableIfaces() {
1138 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001139 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001140 for (int i = 0; i < mTetherStates.size(); i++) {
1141 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001142 if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001143 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001144 }
1145 }
1146 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001147 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001148 }
1149
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001150 public String[] getTetheredDhcpRanges() {
Erik Kline3e756652017-01-17 13:42:19 +09001151 return mConfig.dhcpRanges;
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001152 }
1153
Robert Greenwalt5a735062010-03-02 17:25:02 -08001154 public String[] getErroredIfaces() {
1155 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001156 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001157 for (int i = 0; i < mTetherStates.size(); i++) {
1158 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001159 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001160 list.add(mTetherStates.keyAt(i));
Robert Greenwalt5a735062010-03-02 17:25:02 -08001161 }
1162 }
1163 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001164 return list.toArray(new String[list.size()]);
Robert Greenwalt5a735062010-03-02 17:25:02 -08001165 }
1166
Erik Kline22108902017-07-06 16:40:06 +09001167 private void logMessage(State state, int what) {
1168 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001169 }
1170
Erik Klineea9cc482017-03-10 19:35:34 +09001171 private boolean upstreamWanted() {
1172 if (!mForwardedDownstreams.isEmpty()) return true;
1173
1174 synchronized (mPublicSync) {
1175 return mUsbTetherRequested || mWifiTetherRequested;
1176 }
1177 }
1178
Erik Kline00019f42016-06-30 19:31:46 +09001179 // Needed because the canonical source of upstream truth is just the
1180 // upstream interface name, |mCurrentUpstreamIface|. This is ripe for
1181 // future simplification, once the upstream Network is canonical.
Erik Kline3a5278f2017-06-24 19:29:10 +09001182 private boolean pertainsToCurrentUpstream(NetworkState ns) {
Erik Kline00019f42016-06-30 19:31:46 +09001183 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIface != null) {
1184 for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
1185 if (mCurrentUpstreamIface.equals(ifname)) {
1186 return true;
Erik Kline6ff17f72015-12-10 20:42:12 +09001187 }
1188 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001189 }
Erik Kline00019f42016-06-30 19:31:46 +09001190 return false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001191 }
1192
Erik Kline227648f2017-01-20 20:26:10 +09001193 private void reevaluateSimCardProvisioning() {
1194 if (!hasMobileHotspotProvisionApp()) return;
1195
1196 ArrayList<Integer> tethered = new ArrayList<>();
1197 synchronized (mPublicSync) {
1198 for (int i = 0; i < mTetherStates.size(); i++) {
1199 TetherState tetherState = mTetherStates.valueAt(i);
1200 if (tetherState.lastState != IControlsTethering.STATE_TETHERED) {
1201 continue; // Skip interfaces that aren't tethered.
1202 }
1203 String iface = mTetherStates.keyAt(i);
1204 int interfaceType = ifaceNameToType(iface);
1205 if (interfaceType != ConnectivityManager.TETHERING_INVALID) {
1206 tethered.add(interfaceType);
1207 }
1208 }
1209 }
1210
1211 for (int tetherType : tethered) {
1212 startProvisionIntent(tetherType);
1213 }
1214 }
1215
Wink Saville64c42ca2011-04-18 14:55:10 -07001216 class TetherMasterSM extends StateMachine {
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001217 private static final int BASE_MASTER = Protocol.BASE_TETHERING;
Erik Klineea9cc482017-03-10 19:35:34 +09001218 // an interface SM has requested Tethering/Local Hotspot
1219 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
1220 // an interface SM has unrequested Tethering/Local Hotspot
1221 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001222 // upstream connection change - do the right thing
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001223 static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001224 // we don't have a valid upstream conn, check again after a delay
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001225 static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
Erik Kline6ff17f72015-12-10 20:42:12 +09001226 // Events from NetworkCallbacks that we process on the master state
1227 // machine thread on behalf of the UpstreamNetworkMonitor.
Erik Kline00019f42016-06-30 19:31:46 +09001228 static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001229 // we treated the error and want now to clear it
1230 static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
Erik Kline6e9a1012017-06-06 19:24:21 +09001231 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001232
Erik Kline32179ff2017-07-04 18:28:11 +09001233 private final State mInitialState;
1234 private final State mTetherModeAliveState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001235
Erik Kline32179ff2017-07-04 18:28:11 +09001236 private final State mSetIpForwardingEnabledErrorState;
1237 private final State mSetIpForwardingDisabledErrorState;
1238 private final State mStartTetheringErrorState;
1239 private final State mStopTetheringErrorState;
1240 private final State mSetDnsForwardersErrorState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001241
Christopher Wileyd985dde2016-05-31 10:44:35 -07001242 // This list is a little subtle. It contains all the interfaces that currently are
1243 // requesting tethering, regardless of whether these interfaces are still members of
1244 // mTetherStates. This allows us to maintain the following predicates:
1245 //
1246 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1247 // interfaces.
1248 // 2) mNotifyList contains all state machines that may have outstanding tethering state
1249 // that needs to be torn down.
1250 //
1251 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1252 // so that the garbage collector does not clean up the state machine before it has a chance
1253 // to tear itself down.
Erik Kline1eb8c692016-07-08 17:21:26 +09001254 private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
1255 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
Erik Klineed962a82017-07-06 19:49:35 +09001256 private final OffloadWrapper mOffload;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001257
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001258 private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001259
Robert Greenwaltdfadaea2010-03-11 15:03:08 -08001260 TetherMasterSM(String name, Looper looper) {
1261 super(name, looper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001262
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001263 mInitialState = new InitialState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001264 mTetherModeAliveState = new TetherModeAliveState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001265 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001266 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001267 mStartTetheringErrorState = new StartTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001268 mStopTetheringErrorState = new StopTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001269 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
Erik Kline1fdc2e22017-05-08 17:56:35 +09001270
1271 addState(mInitialState);
1272 addState(mTetherModeAliveState);
1273 addState(mSetIpForwardingEnabledErrorState);
1274 addState(mSetIpForwardingDisabledErrorState);
1275 addState(mStartTetheringErrorState);
1276 addState(mStopTetheringErrorState);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001277 addState(mSetDnsForwardersErrorState);
1278
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001279 mNotifyList = new ArrayList<>();
Erik Kline7747fd42017-05-12 16:52:48 +09001280 mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog);
Erik Klineed962a82017-07-06 19:49:35 +09001281 mOffload = new OffloadWrapper();
Erik Kline32179ff2017-07-04 18:28:11 +09001282
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001283 setInitialState(mInitialState);
1284 }
1285
Erik Kline1fdc2e22017-05-08 17:56:35 +09001286 class InitialState extends State {
1287 @Override
1288 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001289 logMessage(this, message.what);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001290 switch (message.what) {
1291 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001292 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001293 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1294 handleInterfaceServingStateActive(message.arg1, who);
1295 transitionTo(mTetherModeAliveState);
1296 break;
1297 case EVENT_IFACE_SERVING_STATE_INACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001298 who = (TetherInterfaceStateMachine) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001299 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1300 handleInterfaceServingStateInactive(who);
1301 break;
Erik Kline6e9a1012017-06-06 19:24:21 +09001302 case EVENT_IFACE_UPDATE_LINKPROPERTIES:
1303 // Silently ignore these for now.
1304 break;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001305 default:
1306 return NOT_HANDLED;
1307 }
1308 return HANDLED;
1309 }
1310 }
1311
Erik Kline3a5278f2017-06-24 19:29:10 +09001312 protected boolean turnOnMasterTetherSettings() {
1313 final TetheringConfiguration cfg = mConfig;
1314 try {
1315 mNMService.setIpForwardingEnabled(true);
1316 } catch (Exception e) {
1317 mLog.e(e);
1318 transitionTo(mSetIpForwardingEnabledErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001319 return false;
1320 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001321 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
1322 try {
1323 // TODO: Find a more accurate method name (startDHCPv4()?).
1324 mNMService.startTethering(cfg.dhcpRanges);
1325 } catch (Exception e) {
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001326 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001327 mNMService.stopTethering();
Erik Kline3a5278f2017-06-24 19:29:10 +09001328 mNMService.startTethering(cfg.dhcpRanges);
1329 } catch (Exception ee) {
1330 mLog.e(ee);
1331 transitionTo(mStartTetheringErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001332 return false;
1333 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001334 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001335 mLog.log("SET master tether settings: ON");
1336 return true;
1337 }
Robert Greenwalt10398722010-12-17 15:20:36 -08001338
Erik Kline3a5278f2017-06-24 19:29:10 +09001339 protected boolean turnOffMasterTetherSettings() {
1340 try {
1341 mNMService.stopTethering();
1342 } catch (Exception e) {
1343 mLog.e(e);
1344 transitionTo(mStopTetheringErrorState);
1345 return false;
Erik Kline14f7faf2017-02-14 19:03:09 +09001346 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001347 try {
1348 mNMService.setIpForwardingEnabled(false);
1349 } catch (Exception e) {
1350 mLog.e(e);
1351 transitionTo(mSetIpForwardingDisabledErrorState);
1352 return false;
1353 }
1354 transitionTo(mInitialState);
1355 mLog.log("SET master tether settings: OFF");
1356 return true;
1357 }
Erik Kline14f7faf2017-02-14 19:03:09 +09001358
Erik Kline3a5278f2017-06-24 19:29:10 +09001359 protected void chooseUpstreamType(boolean tryCell) {
Erik Kline6ee73da2017-07-08 20:36:37 +09001360 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
1361 // do not currently know how to watch for changes in DUN settings.
1362 maybeUpdateConfiguration();
Erik Kline1e2897d2017-06-09 17:08:52 +09001363
Erik Kline3a5278f2017-06-24 19:29:10 +09001364 final NetworkState ns = mUpstreamNetworkMonitor.selectPreferredUpstreamType(
1365 mConfig.preferredUpstreamIfaceTypes);
1366 if (ns == null) {
1367 if (tryCell) {
1368 mUpstreamNetworkMonitor.registerMobileNetworkRequest();
1369 // We think mobile should be coming up; don't set a retry.
1370 } else {
1371 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
Erik Kline1e2897d2017-06-09 17:08:52 +09001372 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001373 }
1374 setUpstreamNetwork(ns);
1375 }
1376
1377 protected void setUpstreamNetwork(NetworkState ns) {
1378 String iface = null;
1379 if (ns != null && ns.linkProperties != null) {
1380 // Find the interface with the default IPv4 route. It may be the
1381 // interface described by linkProperties, or one of the interfaces
1382 // stacked on top of it.
Erik Kline22108902017-07-06 16:40:06 +09001383 mLog.i("Finding IPv4 upstream interface on: " + ns.linkProperties);
Erik Kline3a5278f2017-06-24 19:29:10 +09001384 RouteInfo ipv4Default = RouteInfo.selectBestRoute(
1385 ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
1386 if (ipv4Default != null) {
1387 iface = ipv4Default.getInterface();
Erik Kline22108902017-07-06 16:40:06 +09001388 mLog.i("Found interface " + ipv4Default.getInterface());
Erik Kline3a5278f2017-06-24 19:29:10 +09001389 } else {
Erik Kline22108902017-07-06 16:40:06 +09001390 mLog.i("No IPv4 upstream interface, giving up.");
Erik Kline00019f42016-06-30 19:31:46 +09001391 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001392 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -07001393
Erik Kline3a5278f2017-06-24 19:29:10 +09001394 if (iface != null) {
1395 setDnsForwarders(ns.network, ns.linkProperties);
Erik Kline6ff17f72015-12-10 20:42:12 +09001396 }
Erik Kline22108902017-07-06 16:40:06 +09001397 notifyDownstreamsOfNewUpstreamIface(iface);
Erik Kline3a5278f2017-06-24 19:29:10 +09001398 if (ns != null && pertainsToCurrentUpstream(ns)) {
1399 // If we already have NetworkState for this network examine
1400 // it immediately, because there likely will be no second
1401 // EVENT_ON_AVAILABLE (it was already received).
1402 handleNewUpstreamNetworkState(ns);
1403 } else if (mCurrentUpstreamIface == null) {
1404 // There are no available upstream networks, or none that
1405 // have an IPv4 default route (current metric for success).
1406 handleNewUpstreamNetworkState(null);
1407 }
1408 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001409
Erik Kline3a5278f2017-06-24 19:29:10 +09001410 protected void setDnsForwarders(final Network network, final LinkProperties lp) {
1411 // TODO: Set v4 and/or v6 DNS per available connectivity.
1412 String[] dnsServers = mConfig.defaultIPv4DNS;
1413 final Collection<InetAddress> dnses = lp.getDnsServers();
1414 // TODO: Properly support the absence of DNS servers.
1415 if (dnses != null && !dnses.isEmpty()) {
1416 // TODO: remove this invocation of NetworkUtils.makeStrings().
1417 dnsServers = NetworkUtils.makeStrings(dnses);
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001418 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001419 try {
1420 mNMService.setDnsForwarders(network, dnsServers);
1421 mLog.log(String.format(
1422 "SET DNS forwarders: network=%s dnsServers=%s",
1423 network, Arrays.toString(dnsServers)));
1424 } catch (Exception e) {
1425 // TODO: Investigate how this can fail and what exactly
1426 // happens if/when such failures occur.
1427 mLog.e("setting DNS forwarders failed, " + e);
1428 transitionTo(mSetDnsForwardersErrorState);
1429 }
1430 }
Erik Kline00019f42016-06-30 19:31:46 +09001431
Erik Kline22108902017-07-06 16:40:06 +09001432 protected void notifyDownstreamsOfNewUpstreamIface(String ifaceName) {
1433 mLog.log("Notifying downstreams of upstream=" + ifaceName);
Erik Kline3a5278f2017-06-24 19:29:10 +09001434 mCurrentUpstreamIface = ifaceName;
1435 for (TetherInterfaceStateMachine sm : mNotifyList) {
1436 sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
1437 ifaceName);
Erik Kline00019f42016-06-30 19:31:46 +09001438 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001439 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001440
Erik Kline3a5278f2017-06-24 19:29:10 +09001441 protected void handleNewUpstreamNetworkState(NetworkState ns) {
1442 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
Erik Klineed962a82017-07-06 19:49:35 +09001443 mOffload.updateUpstreamNetworkState(ns);
Erik Kline3a5278f2017-06-24 19:29:10 +09001444 }
1445
Erik Klineea9cc482017-03-10 19:35:34 +09001446 private void handleInterfaceServingStateActive(int mode, TetherInterfaceStateMachine who) {
1447 if (mNotifyList.indexOf(who) < 0) {
1448 mNotifyList.add(who);
1449 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
1450 }
1451
1452 if (mode == IControlsTethering.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001453 // No need to notify OffloadController just yet as there are no
1454 // "offload-able" prefixes to pass along. This will handled
1455 // when the TISM informs Tethering of its LinkProperties.
Erik Klineea9cc482017-03-10 19:35:34 +09001456 mForwardedDownstreams.add(who);
1457 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001458 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001459 mForwardedDownstreams.remove(who);
1460 }
Erik Kline216af6d2017-04-27 20:57:23 +09001461
1462 // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
1463 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
1464 final WifiManager mgr = getWifiManager();
1465 final String iface = who.interfaceName();
1466 switch (mode) {
1467 case IControlsTethering.STATE_TETHERED:
Erik Kline2efb8272017-05-31 15:53:53 +09001468 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +09001469 break;
1470 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001471 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +09001472 break;
1473 default:
1474 Log.wtf(TAG, "Unknown active serving mode: " + mode);
1475 break;
1476 }
1477 }
Erik Klineea9cc482017-03-10 19:35:34 +09001478 }
1479
1480 private void handleInterfaceServingStateInactive(TetherInterfaceStateMachine who) {
1481 mNotifyList.remove(who);
1482 mIPv6TetheringCoordinator.removeActiveDownstream(who);
Erik Klineed962a82017-07-06 19:49:35 +09001483 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001484 mForwardedDownstreams.remove(who);
Erik Kline216af6d2017-04-27 20:57:23 +09001485
1486 // If this is a Wi-Fi interface, tell WifiManager of any errors.
1487 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
1488 if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
1489 getWifiManager().updateInterfaceIpState(
Erik Kline2efb8272017-05-31 15:53:53 +09001490 who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline216af6d2017-04-27 20:57:23 +09001491 }
1492 }
Erik Klineea9cc482017-03-10 19:35:34 +09001493 }
1494
Erik Kline3a5278f2017-06-24 19:29:10 +09001495 private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
Erik Kline32179ff2017-07-04 18:28:11 +09001496 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
Erik Klineed962a82017-07-06 19:49:35 +09001497 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
Erik Kline3a5278f2017-06-24 19:29:10 +09001498 return;
1499 }
1500
1501 final NetworkState ns = (NetworkState) o;
1502
1503 if (ns == null || !pertainsToCurrentUpstream(ns)) {
1504 // TODO: In future, this is where upstream evaluation and selection
1505 // could be handled for notifications which include sufficient data.
1506 // For example, after CONNECTIVITY_ACTION listening is removed, here
1507 // is where we could observe a Wi-Fi network becoming available and
1508 // passing validation.
1509 if (mCurrentUpstreamIface == null) {
1510 // If we have no upstream interface, try to run through upstream
1511 // selection again. If, for example, IPv4 connectivity has shown up
1512 // after IPv6 (e.g., 464xlat became available) we want the chance to
1513 // notice and act accordingly.
1514 chooseUpstreamType(false);
1515 }
1516 return;
1517 }
1518
1519 switch (arg1) {
1520 case UpstreamNetworkMonitor.EVENT_ON_AVAILABLE:
1521 // The default network changed, or DUN connected
1522 // before this callback was processed. Updates
1523 // for the current NetworkCapabilities and
1524 // LinkProperties have been requested (default
1525 // request) or are being sent shortly (DUN). Do
1526 // nothing until they arrive; if no updates
1527 // arrive there's nothing to do.
1528 break;
1529 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
1530 handleNewUpstreamNetworkState(ns);
1531 break;
1532 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
1533 setDnsForwarders(ns.network, ns.linkProperties);
1534 handleNewUpstreamNetworkState(ns);
1535 break;
1536 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1537 // TODO: Re-evaluate possible upstreams. Currently upstream
1538 // reevaluation is triggered via received CONNECTIVITY_ACTION
1539 // broadcasts that result in being passed a
1540 // TetherMasterSM.CMD_UPSTREAM_CHANGED.
1541 handleNewUpstreamNetworkState(null);
1542 break;
1543 default:
1544 mLog.e("Unknown arg1 value: " + arg1);
1545 break;
1546 }
1547 }
1548
1549 class TetherModeAliveState extends State {
Erik Klineea9cc482017-03-10 19:35:34 +09001550 boolean mUpstreamWanted = false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001551 boolean mTryCell = true;
Erik Klinee0cce212017-03-06 14:05:23 +09001552
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001553 @Override
1554 public void enter() {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001555 // If turning on master tether settings fails, we have already
1556 // transitioned to an error state; exit early.
1557 if (!turnOnMasterTetherSettings()) {
1558 return;
1559 }
1560
Erik Kline227648f2017-01-20 20:26:10 +09001561 mSimChange.startListening();
Erik Kline6ff17f72015-12-10 20:42:12 +09001562 mUpstreamNetworkMonitor.start();
Robert Greenwalt4f74d552011-12-19 16:59:31 -08001563
Erik Klinef4b6e342017-04-25 19:19:59 +09001564 // TODO: De-duplicate with updateUpstreamWanted() below.
Erik Klineea9cc482017-03-10 19:35:34 +09001565 if (upstreamWanted()) {
1566 mUpstreamWanted = true;
Erik Klineed962a82017-07-06 19:49:35 +09001567 mOffload.start();
Erik Klineea9cc482017-03-10 19:35:34 +09001568 chooseUpstreamType(true);
1569 mTryCell = false;
1570 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001571 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001572
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001573 @Override
1574 public void exit() {
Erik Klineed962a82017-07-06 19:49:35 +09001575 mOffload.stop();
Erik Kline6ff17f72015-12-10 20:42:12 +09001576 mUpstreamNetworkMonitor.stop();
Erik Kline227648f2017-01-20 20:26:10 +09001577 mSimChange.stopListening();
Erik Kline22108902017-07-06 16:40:06 +09001578 notifyDownstreamsOfNewUpstreamIface(null);
Erik Klinefa37b2f2016-08-02 18:27:03 +09001579 handleNewUpstreamNetworkState(null);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001580 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001581
Erik Klineea9cc482017-03-10 19:35:34 +09001582 private boolean updateUpstreamWanted() {
1583 final boolean previousUpstreamWanted = mUpstreamWanted;
1584 mUpstreamWanted = upstreamWanted();
Erik Klinef4b6e342017-04-25 19:19:59 +09001585 if (mUpstreamWanted != previousUpstreamWanted) {
1586 if (mUpstreamWanted) {
Erik Klineed962a82017-07-06 19:49:35 +09001587 mOffload.start();
Erik Klinef4b6e342017-04-25 19:19:59 +09001588 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001589 mOffload.stop();
Erik Klinef4b6e342017-04-25 19:19:59 +09001590 }
1591 }
Erik Klineea9cc482017-03-10 19:35:34 +09001592 return previousUpstreamWanted;
1593 }
1594
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001595 @Override
1596 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001597 logMessage(this, message.what);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001598 boolean retValue = true;
1599 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001600 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
Erik Kline32179ff2017-07-04 18:28:11 +09001601 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001602 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001603 handleInterfaceServingStateActive(message.arg1, who);
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001604 who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
Erik Kline6ff17f72015-12-10 20:42:12 +09001605 mCurrentUpstreamIface);
Erik Klineea9cc482017-03-10 19:35:34 +09001606 // If there has been a change and an upstream is now
1607 // desired, kick off the selection process.
1608 final boolean previousUpstreamWanted = updateUpstreamWanted();
1609 if (!previousUpstreamWanted && mUpstreamWanted) {
1610 chooseUpstreamType(true);
1611 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001612 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001613 }
Erik Klineea9cc482017-03-10 19:35:34 +09001614 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
Erik Kline32179ff2017-07-04 18:28:11 +09001615 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001616 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001617 handleInterfaceServingStateInactive(who);
1618
1619 if (mNotifyList.isEmpty()) {
Erik Kline47222fc2017-04-30 19:36:15 +09001620 // This transitions us out of TetherModeAliveState,
1621 // either to InitialState or an error state.
Erik Kline1fdc2e22017-05-08 17:56:35 +09001622 turnOffMasterTetherSettings();
1623 break;
1624 }
1625
1626 if (DBG) {
1627 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
1628 " live requests:");
1629 for (TetherInterfaceStateMachine o : mNotifyList) {
1630 Log.d(TAG, " " + o);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001631 }
1632 }
Erik Klineea9cc482017-03-10 19:35:34 +09001633 // If there has been a change and an upstream is no
1634 // longer desired, release any mobile requests.
1635 final boolean previousUpstreamWanted = updateUpstreamWanted();
1636 if (previousUpstreamWanted && !mUpstreamWanted) {
1637 mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
1638 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001639 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001640 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001641 case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
1642 final LinkProperties newLp = (LinkProperties) message.obj;
1643 if (message.arg1 == IControlsTethering.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001644 mOffload.updateDownstreamLinkProperties(newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09001645 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001646 mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
Erik Kline6e9a1012017-06-06 19:24:21 +09001647 }
1648 break;
1649 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001650 case CMD_UPSTREAM_CHANGED:
Erik Klineea9cc482017-03-10 19:35:34 +09001651 updateUpstreamWanted();
1652 if (!mUpstreamWanted) break;
1653
Erik Klinefb413432017-02-14 18:26:04 +09001654 // Need to try DUN immediately if Wi-Fi goes down.
1655 chooseUpstreamType(true);
1656 mTryCell = false;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001657 break;
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001658 case CMD_RETRY_UPSTREAM:
Erik Klineea9cc482017-03-10 19:35:34 +09001659 updateUpstreamWanted();
1660 if (!mUpstreamWanted) break;
1661
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001662 chooseUpstreamType(mTryCell);
1663 mTryCell = !mTryCell;
1664 break;
Erik Kline00019f42016-06-30 19:31:46 +09001665 case EVENT_UPSTREAM_CALLBACK: {
Erik Klineea9cc482017-03-10 19:35:34 +09001666 updateUpstreamWanted();
Erik Kline3a5278f2017-06-24 19:29:10 +09001667 if (mUpstreamWanted) {
1668 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
Erik Kline6ff17f72015-12-10 20:42:12 +09001669 }
1670 break;
Erik Kline00019f42016-06-30 19:31:46 +09001671 }
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001672 default:
1673 retValue = false;
1674 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001675 }
1676 return retValue;
1677 }
1678 }
1679
Wink Saville64c42ca2011-04-18 14:55:10 -07001680 class ErrorState extends State {
Erik Kline8351faa2017-04-17 16:47:23 +09001681 private int mErrorNotification;
1682
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001683 @Override
1684 public boolean processMessage(Message message) {
1685 boolean retValue = true;
1686 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001687 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001688 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001689 who.sendMessage(mErrorNotification);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001690 break;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001691 case CMD_CLEAR_ERROR:
1692 mErrorNotification = ConnectivityManager.TETHER_ERROR_NO_ERROR;
1693 transitionTo(mInitialState);
1694 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001695 default:
1696 retValue = false;
1697 }
1698 return retValue;
1699 }
Erik Kline8351faa2017-04-17 16:47:23 +09001700
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001701 void notify(int msgType) {
1702 mErrorNotification = msgType;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001703 for (TetherInterfaceStateMachine sm : mNotifyList) {
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001704 sm.sendMessage(msgType);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001705 }
1706 }
1707
1708 }
Erik Kline8351faa2017-04-17 16:47:23 +09001709
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001710 class SetIpForwardingEnabledErrorState extends ErrorState {
1711 @Override
1712 public void enter() {
1713 Log.e(TAG, "Error in setIpForwardingEnabled");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001714 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001715 }
1716 }
1717
1718 class SetIpForwardingDisabledErrorState extends ErrorState {
1719 @Override
1720 public void enter() {
1721 Log.e(TAG, "Error in setIpForwardingDisabled");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001722 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001723 }
1724 }
1725
1726 class StartTetheringErrorState extends ErrorState {
1727 @Override
1728 public void enter() {
1729 Log.e(TAG, "Error in startTethering");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001730 notify(TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001731 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001732 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001733 } catch (Exception e) {}
1734 }
1735 }
1736
1737 class StopTetheringErrorState extends ErrorState {
1738 @Override
1739 public void enter() {
1740 Log.e(TAG, "Error in stopTethering");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001741 notify(TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001742 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001743 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001744 } catch (Exception e) {}
1745 }
1746 }
1747
1748 class SetDnsForwardersErrorState extends ErrorState {
1749 @Override
1750 public void enter() {
1751 Log.e(TAG, "Error in setDnsForwarders");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001752 notify(TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001753 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001754 mNMService.stopTethering();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001755 } catch (Exception e) {}
1756 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001757 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001758 } catch (Exception e) {}
1759 }
1760 }
Erik Klineed962a82017-07-06 19:49:35 +09001761
1762 // A wrapper class to handle multiple situations where several calls to
1763 // the OffloadController need to happen together.
1764 //
1765 // TODO: This suggests that the interface between OffloadController and
1766 // Tethering is in need of improvement. Refactor these calls into the
1767 // OffloadController implementation.
1768 class OffloadWrapper {
1769 public void start() {
1770 mOffloadController.start();
1771 sendOffloadExemptPrefixes();
1772 }
1773
1774 public void stop() {
1775 mOffloadController.stop();
1776 }
1777
1778 public void updateUpstreamNetworkState(NetworkState ns) {
1779 mOffloadController.setUpstreamLinkProperties(
1780 (ns != null) ? ns.linkProperties : null);
1781 }
1782
1783 public void updateDownstreamLinkProperties(LinkProperties newLp) {
1784 // Update the list of offload-exempt prefixes before adding
1785 // new prefixes on downstream interfaces to the offload HAL.
1786 sendOffloadExemptPrefixes();
1787 mOffloadController.notifyDownstreamLinkProperties(newLp);
1788 }
1789
1790 public void excludeDownstreamInterface(String ifname) {
1791 // This and other interfaces may be in local-only hotspot mode;
1792 // resend all local prefixes to the OffloadController.
1793 sendOffloadExemptPrefixes();
1794 mOffloadController.removeDownstreamInterface(ifname);
1795 }
1796
1797 public void sendOffloadExemptPrefixes() {
1798 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
1799 }
1800
1801 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
1802 // Add in well-known minimum set.
1803 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
1804 // Add tragically hardcoded prefixes.
1805 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
1806
1807 // Maybe add prefixes or addresses for downstreams, depending on
1808 // the IP serving mode of each.
1809 for (TetherInterfaceStateMachine tism : mNotifyList) {
1810 final LinkProperties lp = tism.linkProperties();
1811
1812 switch (tism.servingMode()) {
1813 case IControlsTethering.STATE_UNAVAILABLE:
1814 case IControlsTethering.STATE_AVAILABLE:
1815 // No usable LinkProperties in these states.
1816 continue;
1817 case IControlsTethering.STATE_TETHERED:
1818 // Only add IPv4 /32 and IPv6 /128 prefixes. The
1819 // directly-connected prefixes will be sent as
1820 // downstream "offload-able" prefixes.
1821 for (LinkAddress addr : lp.getAllLinkAddresses()) {
1822 final InetAddress ip = addr.getAddress();
1823 if (ip.isLinkLocalAddress()) continue;
1824 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
1825 }
1826 break;
1827 case IControlsTethering.STATE_LOCAL_ONLY:
1828 // Add prefixes covering all local IPs.
1829 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
1830 break;
1831 }
1832 }
1833
1834 mOffloadController.setLocalPrefixes(localPrefixes);
1835 }
1836 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001837 }
1838
Christopher Wiley499a57a2016-05-16 16:19:07 -07001839 @Override
Lorenzo Colittie3805462015-06-03 11:18:24 +09001840 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Christopher Wiley499a57a2016-05-16 16:19:07 -07001841 // Binder.java closes the resource for us.
1842 @SuppressWarnings("resource")
Lorenzo Colittie3805462015-06-03 11:18:24 +09001843 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001844 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001845
Lorenzo Colittie3805462015-06-03 11:18:24 +09001846 pw.println("Tethering:");
1847 pw.increaseIndent();
Lorenzo Colittie3805462015-06-03 11:18:24 +09001848
Erik Kline9db1b542017-03-16 14:10:27 +09001849 pw.println("Configuration:");
1850 pw.increaseIndent();
1851 final TetheringConfiguration cfg = mConfig;
1852 cfg.dump(pw);
1853 pw.decreaseIndent();
1854
1855 synchronized (mPublicSync) {
Robert Greenwaltb4453622011-11-03 16:01:40 -07001856 pw.println("Tether state:");
Lorenzo Colittie3805462015-06-03 11:18:24 +09001857 pw.increaseIndent();
Christopher Wileyd985dde2016-05-31 10:44:35 -07001858 for (int i = 0; i < mTetherStates.size(); i++) {
1859 final String iface = mTetherStates.keyAt(i);
1860 final TetherState tetherState = mTetherStates.valueAt(i);
1861 pw.print(iface + " - ");
1862
Hugo Benichib55fb222017-03-10 14:20:57 +09001863 switch (tetherState.lastState) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001864 case IControlsTethering.STATE_UNAVAILABLE:
1865 pw.print("UnavailableState");
1866 break;
1867 case IControlsTethering.STATE_AVAILABLE:
1868 pw.print("AvailableState");
1869 break;
1870 case IControlsTethering.STATE_TETHERED:
1871 pw.print("TetheredState");
1872 break;
Erik Klineca41be72017-04-20 22:59:16 +09001873 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09001874 pw.print("LocalHotspotState");
1875 break;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001876 default:
1877 pw.print("UnknownState");
1878 break;
1879 }
Hugo Benichib55fb222017-03-10 14:20:57 +09001880 pw.println(" - lastError = " + tetherState.lastError);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001881 }
Erik Klineea9cc482017-03-10 19:35:34 +09001882 pw.println("Upstream wanted: " + upstreamWanted());
Erik Klineee363c42017-05-29 09:11:03 +09001883 pw.println("Current upstream interface: " + mCurrentUpstreamIface);
Lorenzo Colittie3805462015-06-03 11:18:24 +09001884 pw.decreaseIndent();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001885 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09001886
Lorenzo Colittic2519c52017-07-13 01:48:26 +09001887 pw.println("Hardware offload:");
1888 pw.increaseIndent();
1889 mOffloadController.dump(pw);
1890 pw.decreaseIndent();
1891
Erik Kline1fdc2e22017-05-08 17:56:35 +09001892 pw.println("Log:");
1893 pw.increaseIndent();
Erik Kline7747fd42017-05-12 16:52:48 +09001894 if (argsContain(args, SHORT_ARG)) {
1895 pw.println("<log removed for brevity>");
1896 } else {
1897 mLog.dump(fd, pw, args);
1898 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09001899 pw.decreaseIndent();
1900
Lorenzo Colittie3805462015-06-03 11:18:24 +09001901 pw.decreaseIndent();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001902 }
Christopher Wileye03fb442016-05-18 13:45:20 -07001903
Erik Kline7747fd42017-05-12 16:52:48 +09001904 private static boolean argsContain(String[] args, String target) {
1905 for (String arg : args) {
Erik Klineee363c42017-05-29 09:11:03 +09001906 if (target.equals(arg)) return true;
Erik Kline7747fd42017-05-12 16:52:48 +09001907 }
1908 return false;
1909 }
1910
Erik Kline6e9a1012017-06-06 19:24:21 +09001911 private IControlsTethering makeControlCallback(String ifname) {
1912 return new IControlsTethering() {
1913 @Override
1914 public void updateInterfaceState(
1915 TetherInterfaceStateMachine who, int state, int lastError) {
1916 notifyInterfaceStateChange(ifname, who, state, lastError);
1917 }
1918
1919 @Override
1920 public void updateLinkProperties(
1921 TetherInterfaceStateMachine who, LinkProperties newLp) {
1922 notifyLinkPropertiesChanged(ifname, who, newLp);
1923 }
1924 };
1925 }
1926
1927 // TODO: Move into TetherMasterSM.
1928 private void notifyInterfaceStateChange(
1929 String iface, TetherInterfaceStateMachine who, int state, int error) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001930 synchronized (mPublicSync) {
Erik Kline216af6d2017-04-27 20:57:23 +09001931 final TetherState tetherState = mTetherStates.get(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +09001932 if (tetherState != null && tetherState.stateMachine.equals(who)) {
1933 tetherState.lastState = state;
1934 tetherState.lastError = error;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001935 } else {
1936 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
1937 }
1938 }
1939
Erik Kline7747fd42017-05-12 16:52:48 +09001940 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
Christopher Wileyd985dde2016-05-31 10:44:35 -07001941
Christopher Wileydeebfec2016-09-16 11:14:36 -07001942 try {
1943 // Notify that we're tethering (or not) this interface.
1944 // This is how data saver for instance knows if the user explicitly
1945 // turned on tethering (thus keeping us from being in data saver mode).
1946 mPolicyManager.onTetheringChanged(iface, state == IControlsTethering.STATE_TETHERED);
1947 } catch (RemoteException e) {
1948 // Not really very much we can do here.
1949 }
1950
Yohei, Oshima977aad52016-12-08 13:39:20 +09001951 // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
1952 // Thus we give a chance for TetherMasterSM to recover to InitialState
1953 // by sending CMD_CLEAR_ERROR
1954 if (error == ConnectivityManager.TETHER_ERROR_MASTER_ERROR) {
1955 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
1956 }
Erik Klineea9cc482017-03-10 19:35:34 +09001957 int which;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001958 switch (state) {
1959 case IControlsTethering.STATE_UNAVAILABLE:
1960 case IControlsTethering.STATE_AVAILABLE:
Erik Klineea9cc482017-03-10 19:35:34 +09001961 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001962 break;
1963 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +09001964 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09001965 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001966 break;
Erik Klineea9cc482017-03-10 19:35:34 +09001967 default:
1968 Log.wtf(TAG, "Unknown interface state: " + state);
1969 return;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001970 }
Erik Klineea9cc482017-03-10 19:35:34 +09001971 mTetherMasterSM.sendMessage(which, state, 0, who);
Christopher Wileyd985dde2016-05-31 10:44:35 -07001972 sendTetherStateChangedBroadcast();
1973 }
1974
Erik Kline6e9a1012017-06-06 19:24:21 +09001975 private void notifyLinkPropertiesChanged(String iface, TetherInterfaceStateMachine who,
1976 LinkProperties newLp) {
1977 final int state;
1978 synchronized (mPublicSync) {
1979 final TetherState tetherState = mTetherStates.get(iface);
1980 if (tetherState != null && tetherState.stateMachine.equals(who)) {
1981 state = tetherState.lastState;
1982 } else {
1983 mLog.log("got notification from stale iface " + iface);
1984 return;
1985 }
1986 }
1987
Erik Kline7fd696c2017-06-12 18:20:08 +09001988 mLog.log(String.format(
1989 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
1990 iface, IControlsTethering.getStateString(state), newLp));
Erik Kline6e9a1012017-06-06 19:24:21 +09001991 final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
1992 mTetherMasterSM.sendMessage(which, state, 0, newLp);
1993 }
1994
Erik Kline4dd9bb82017-04-26 11:11:07 +09001995 private void maybeTrackNewInterfaceLocked(final String iface) {
1996 // If we don't care about this type of interface, ignore.
1997 final int interfaceType = ifaceNameToType(iface);
1998 if (interfaceType == ConnectivityManager.TETHERING_INVALID) {
1999 mLog.log(iface + " is not a tetherable iface, ignoring");
2000 return;
2001 }
Erik Klinea9cde8b2017-06-20 21:18:31 +09002002 maybeTrackNewInterfaceLocked(iface, interfaceType);
2003 }
Erik Kline4dd9bb82017-04-26 11:11:07 +09002004
Erik Klinea9cde8b2017-06-20 21:18:31 +09002005 private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09002006 // If we have already started a TISM for this interface, skip.
2007 if (mTetherStates.containsKey(iface)) {
2008 mLog.log("active iface (" + iface + ") reported as added, ignoring");
2009 return;
2010 }
2011
2012 mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
2013 final TetherState tetherState = new TetherState(
2014 new TetherInterfaceStateMachine(
Erik Kline6e9a1012017-06-06 19:24:21 +09002015 iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
Erik Klinea8e2e792017-06-13 21:32:10 +09002016 makeControlCallback(iface)));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002017 mTetherStates.put(iface, tetherState);
Hugo Benichib55fb222017-03-10 14:20:57 +09002018 tetherState.stateMachine.start();
Christopher Wileye03fb442016-05-18 13:45:20 -07002019 }
Erik Kline3e756652017-01-17 13:42:19 +09002020
Erik Kline4dd9bb82017-04-26 11:11:07 +09002021 private void stopTrackingInterfaceLocked(final String iface) {
2022 final TetherState tetherState = mTetherStates.get(iface);
2023 if (tetherState == null) {
2024 mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
2025 return;
2026 }
Erik Kline6e9a1012017-06-06 19:24:21 +09002027 tetherState.stateMachine.stop();
Erik Kline4dd9bb82017-04-26 11:11:07 +09002028 mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
2029 mTetherStates.remove(iface);
2030 }
2031
Erik Kline3e756652017-01-17 13:42:19 +09002032 private static String[] copy(String[] strarray) {
2033 return Arrays.copyOf(strarray, strarray.length);
2034 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002035}