blob: ff0572346cc4713b2024a7517de34492ffaeed77 [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 Kline2efb8272017-05-31 15:53:53 +090022import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
23import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
Erik Kline2e88b5e2017-01-18 11:57:45 +090024import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
Erik Kline2efb8272017-05-31 15:53:53 +090025import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
26import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
27import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
28import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090029import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
Erik Klinede637722017-10-12 22:16:01 +090030import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
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;
45import android.content.res.Resources;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080046import android.hardware.usb.UsbManager;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080047import android.net.ConnectivityManager;
Christopher Wileydeebfec2016-09-16 11:14:36 -070048import android.net.INetworkPolicyManager;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070049import android.net.INetworkStatsService;
Erik Kline3a5278f2017-06-24 19:29:10 +090050import android.net.IpPrefix;
Erik Klineed962a82017-07-06 19:49:35 +090051import android.net.LinkAddress;
Robert Greenwalt05d89362011-01-23 16:04:05 -080052import android.net.LinkProperties;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070053import android.net.Network;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080054import android.net.NetworkInfo;
Erik Kline6ff17f72015-12-10 20:42:12 +090055import android.net.NetworkState;
Robert Greenwalte5903732011-02-22 16:00:42 -080056import android.net.NetworkUtils;
Lorenzo Colitti13c9fde2013-03-15 04:22:37 +090057import android.net.RouteInfo;
Erik Kline32179ff2017-07-04 18:28:11 +090058import android.net.util.PrefixUtils;
Erik Kline7747fd42017-05-12 16:52:48 +090059import android.net.util.SharedLog;
Erik Klinede637722017-10-12 22:16:01 +090060import android.net.util.VersionedBroadcastListener;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080061import android.net.wifi.WifiManager;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080062import android.os.Binder;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080063import android.os.Bundle;
Erik Klinef4b6e342017-04-25 19:19:59 +090064import android.os.Handler;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080065import android.os.INetworkManagementService;
Robert Greenwaltdfadaea2010-03-11 15:03:08 -080066import android.os.Looper;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080067import android.os.Message;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080068import android.os.Parcel;
Erik Klinede637722017-10-12 22:16:01 +090069import android.os.PersistableBundle;
Christopher Wileydeebfec2016-09-16 11:14:36 -070070import android.os.RemoteException;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080071import android.os.ResultReceiver;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070072import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010073import android.os.UserManager;
74import android.os.UserManagerInternal;
75import android.os.UserManagerInternal.UserRestrictionsListener;
Jeremy Klein15f3d212016-01-24 17:01:09 -080076import android.provider.Settings;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080077import android.telephony.CarrierConfigManager;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090078import android.text.TextUtils;
Christopher Wileye9490392016-05-26 15:57:29 -070079import android.util.ArrayMap;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080080import android.util.Log;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090081import android.util.SparseArray;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080082
Christopher Wiley497c1472016-10-11 13:26:03 -070083import com.android.internal.annotations.VisibleForTesting;
Chris Wren282cfef2017-03-27 15:01:44 -040084import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -050085import com.android.internal.notification.SystemNotificationChannels;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060086import com.android.internal.util.DumpUtils;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080087import com.android.internal.util.IndentingPrintWriter;
Lorenzo Colitticd63d242016-04-10 15:39:53 +090088import com.android.internal.util.MessageUtils;
89import com.android.internal.util.Protocol;
Wink Saville64c42ca2011-04-18 14:55:10 -070090import com.android.internal.util.State;
91import com.android.internal.util.StateMachine;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +010092import com.android.server.LocalServices;
Christopher Wileye03fb442016-05-18 13:45:20 -070093import com.android.server.connectivity.tethering.IControlsTethering;
Erik Kline1eb8c692016-07-08 17:21:26 +090094import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
Erik Klinee0cce212017-03-06 14:05:23 +090095import com.android.server.connectivity.tethering.OffloadController;
Erik Kline227648f2017-01-20 20:26:10 +090096import com.android.server.connectivity.tethering.SimChangeListener;
Mitchell Wills7040b4e2016-05-23 16:40:10 -070097import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
Hugo Benichib55fb222017-03-10 14:20:57 +090098import com.android.server.connectivity.tethering.TetheringConfiguration;
Erik Kline47222fc2017-04-30 19:36:15 +090099import com.android.server.connectivity.tethering.TetheringDependencies;
Erik Kline9bba3402017-01-13 16:46:52 +0900100import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
Lorenzo Colittif4e90ea2013-10-31 23:30:47 +0900101import com.android.server.net.BaseNetworkObserver;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800102
103import java.io.FileDescriptor;
104import java.io.PrintWriter;
Robert Greenwalt4f74d552011-12-19 16:59:31 -0800105import java.net.Inet4Address;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800106import java.net.InetAddress;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800107import java.util.ArrayList;
Lorenzo Colittib57edc52014-08-22 17:10:50 -0700108import java.util.Arrays;
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700109import java.util.Collection;
Erik Klineea9cc482017-03-10 19:35:34 +0900110import java.util.HashSet;
Erik Kline3a5278f2017-06-24 19:29:10 +0900111import java.util.Set;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -0800112
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700113
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800114/**
115 * @hide
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800116 *
Christopher Wiley3b1d9222016-05-20 16:44:04 -0700117 * This class holds much of the business logic to allow Android devices
118 * to act as IP gateways via USB, BT, and WiFi interfaces.
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800119 */
Erik Kline6e9a1012017-06-06 19:24:21 +0900120public class Tethering extends BaseNetworkObserver {
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800121
Hugo Benichib55fb222017-03-10 14:20:57 +0900122 private final static String TAG = Tethering.class.getSimpleName();
Joe Onorato12acbd72016-02-01 17:49:31 -0800123 private final static boolean DBG = false;
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800124 private final static boolean VDBG = false;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800125
Christopher Wiley497c1472016-10-11 13:26:03 -0700126 protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
127
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900128 private static final Class[] messageClasses = {
Mitchell Wills7040b4e2016-05-23 16:40:10 -0700129 Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900130 };
131 private static final SparseArray<String> sMagicDecoderRing =
132 MessageUtils.findMessageNames(messageClasses);
133
Hugo Benichib55fb222017-03-10 14:20:57 +0900134 // {@link ComponentName} of the Service used to run tether provisioning.
135 private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
136 .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
137
138 private static class TetherState {
139 public final TetherInterfaceStateMachine stateMachine;
140 public int lastState;
141 public int lastError;
Erik Klineea9cc482017-03-10 19:35:34 +0900142
Hugo Benichib55fb222017-03-10 14:20:57 +0900143 public TetherState(TetherInterfaceStateMachine sm) {
144 stateMachine = sm;
145 // Assume all state machines start out available and with no errors.
146 lastState = IControlsTethering.STATE_AVAILABLE;
147 lastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
148 }
Erik Klineea9cc482017-03-10 19:35:34 +0900149
150 public boolean isCurrentlyServing() {
151 switch (lastState) {
152 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +0900153 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +0900154 return true;
155 default:
156 return false;
157 }
158 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900159 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700160
Erik Kline7747fd42017-05-12 16:52:48 +0900161 private final SharedLog mLog = new SharedLog(TAG);
Erik Kline1fdc2e22017-05-08 17:56:35 +0900162
Robert Greenwaltb4453622011-11-03 16:01:40 -0700163 // used to synchronize public access to members
Erik Kline6ff17f72015-12-10 20:42:12 +0900164 private final Object mPublicSync;
Hugo Benichib55fb222017-03-10 14:20:57 +0900165 private final Context mContext;
166 private final ArrayMap<String, TetherState> mTetherStates;
167 private final BroadcastReceiver mStateReceiver;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700168 private final INetworkManagementService mNMService;
169 private final INetworkStatsService mStatsService;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700170 private final INetworkPolicyManager mPolicyManager;
Erik Kline6ff17f72015-12-10 20:42:12 +0900171 private final Looper mLooper;
Christopher Wiley497c1472016-10-11 13:26:03 -0700172 private final MockableSystemProperties mSystemProperties;
Erik Kline6ff17f72015-12-10 20:42:12 +0900173 private final StateMachine mTetherMasterSM;
Erik Klinee0cce212017-03-06 14:05:23 +0900174 private final OffloadController mOffloadController;
Erik Kline6ff17f72015-12-10 20:42:12 +0900175 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
Erik Kline6e9a1012017-06-06 19:24:21 +0900176 // TODO: Figure out how to merge this and other downstream-tracking objects
177 // into a single coherent structure.
Erik Klineea9cc482017-03-10 19:35:34 +0900178 private final HashSet<TetherInterfaceStateMachine> mForwardedDownstreams;
Erik Klinede637722017-10-12 22:16:01 +0900179 private final VersionedBroadcastListener mCarrierConfigChange;
180 // TODO: Delete SimChangeListener; it's obsolete.
Erik Kline227648f2017-01-20 20:26:10 +0900181 private final SimChangeListener mSimChange;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800182
Hugo Benichib55fb222017-03-10 14:20:57 +0900183 private volatile TetheringConfiguration mConfig;
184 private String mCurrentUpstreamIface;
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400185 private Notification.Builder mTetheredNotificationBuilder;
186 private int mLastNotificationId;
Erik Klineea9cc482017-03-10 19:35:34 +0900187
Mike Lockwood6c2260b2011-07-19 13:04:47 -0700188 private boolean mRndisEnabled; // track the RNDIS function enabled state
Erik Kline6e9a1012017-06-06 19:24:21 +0900189 // True iff. WiFi tethering should be started when soft AP is ready.
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700190 private boolean mWifiTetherRequested;
191
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700192 public Tethering(Context context, INetworkManagementService nmService,
Christopher Wiley497c1472016-10-11 13:26:03 -0700193 INetworkStatsService statsService, INetworkPolicyManager policyManager,
Erik Kline47222fc2017-04-30 19:36:15 +0900194 Looper looper, MockableSystemProperties systemProperties,
195 TetheringDependencies deps) {
Erik Kline7747fd42017-05-12 16:52:48 +0900196 mLog.mark("constructed");
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800197 mContext = context;
Chia-chi Yehc9338302011-05-11 16:35:13 -0700198 mNMService = nmService;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700199 mStatsService = statsService;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700200 mPolicyManager = policyManager;
Christopher Wiley497c1472016-10-11 13:26:03 -0700201 mLooper = looper;
202 mSystemProperties = systemProperties;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800203
Robert Greenwaltb4453622011-11-03 16:01:40 -0700204 mPublicSync = new Object();
205
Christopher Wileyd985dde2016-05-31 10:44:35 -0700206 mTetherStates = new ArrayMap<>();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800207
Robert Greenwaltdfadaea2010-03-11 15:03:08 -0800208 mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800209 mTetherMasterSM.start();
210
Erik Klinef4b6e342017-04-25 19:19:59 +0900211 final Handler smHandler = mTetherMasterSM.getHandler();
212 mOffloadController = new OffloadController(smHandler,
213 deps.getOffloadHardwareInterface(smHandler, mLog),
Lorenzo Colitti5a7dea12017-07-12 15:48:07 +0900214 mContext.getContentResolver(), mNMService,
Erik Klinef4b6e342017-04-25 19:19:59 +0900215 mLog);
Erik Klineebdb8c82017-01-10 17:37:54 +0900216 mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
Erik Kline32179ff2017-07-04 18:28:11 +0900217 mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
Erik Klineea9cc482017-03-10 19:35:34 +0900218 mForwardedDownstreams = new HashSet<>();
Erik Klinede637722017-10-12 22:16:01 +0900219
220 IntentFilter filter = new IntentFilter();
221 filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
222 mCarrierConfigChange = new VersionedBroadcastListener(
223 "CarrierConfigChangeListener", mContext, smHandler, filter,
224 (Intent ignored) -> {
225 mLog.log("OBSERVED carrier config change");
226 reevaluateSimCardProvisioning();
227 });
228 // TODO: Remove SimChangeListener altogether. For now, we retain it
229 // for logging purposes in case we need to debug something that might
230 // be related to changing signals from ACTION_SIM_STATE_CHANGED to
231 // ACTION_CARRIER_CONFIG_CHANGED.
Erik Kline227648f2017-01-20 20:26:10 +0900232 mSimChange = new SimChangeListener(
Erik Klinede637722017-10-12 22:16:01 +0900233 mContext, smHandler, () -> {
234 mLog.log("OBSERVED SIM card change");
235 });
Erik Kline6ff17f72015-12-10 20:42:12 +0900236
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800237 mStateReceiver = new StateReceiver();
Erik Klinede637722017-10-12 22:16:01 +0900238 filter = new IntentFilter();
Mike Lockwood770126a2010-12-09 22:30:37 -0800239 filter.addAction(UsbManager.ACTION_USB_STATE);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800240 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700241 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700242 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
Erik Kline32179ff2017-07-04 18:28:11 +0900243 mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800244
245 filter = new IntentFilter();
Robert Greenwalt030f5e12010-03-10 16:41:03 -0800246 filter.addAction(Intent.ACTION_MEDIA_SHARED);
247 filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800248 filter.addDataScheme("file");
Erik Kline32179ff2017-07-04 18:28:11 +0900249 mContext.registerReceiver(mStateReceiver, filter, null, smHandler);
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800250
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100251 UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
252
253 // this check is useful only for some unit tests; example: ConnectivityServiceTest
254 if (userManager != null) {
255 userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
256 }
257
Robert Greenwalt49348e72011-10-21 16:54:26 -0700258 // load device config info
259 updateConfiguration();
Robert Greenwalt49348e72011-10-21 16:54:26 -0700260 }
261
Sreeram Ramachandran62a61312014-07-24 16:05:17 -0700262 // We can't do this once in the Tethering() constructor and cache the value, because the
263 // CONNECTIVITY_SERVICE is registered only after the Tethering() constructor has completed.
264 private ConnectivityManager getConnectivityManager() {
265 return (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
266 }
267
Erik Kline216af6d2017-04-27 20:57:23 +0900268 private WifiManager getWifiManager() {
269 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
270 }
271
Erik Kline93c4afa2017-06-04 11:36:01 +0900272 // NOTE: This is always invoked on the mLooper thread.
Erik Klined781fba2017-01-23 13:01:58 +0900273 private void updateConfiguration() {
Erik Kline6bd74532017-05-19 10:10:41 +0900274 mConfig = new TetheringConfiguration(mContext, mLog);
Erik Kline93c4afa2017-06-04 11:36:01 +0900275 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800276 }
277
Erik Kline6ee73da2017-07-08 20:36:37 +0900278 private void maybeUpdateConfiguration() {
279 final int dunCheck = TetheringConfiguration.checkDunRequired(mContext);
280 if (dunCheck == mConfig.dunCheck) return;
281 updateConfiguration();
282 }
283
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900284 @Override
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700285 public void interfaceStatusChanged(String iface, boolean up) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900286 // Never called directly: only called from interfaceLinkStateChanged.
287 // See NetlinkHandler.cpp:71.
Wink Savillec9acde92011-09-21 11:05:43 -0700288 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700289 synchronized (mPublicSync) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700290 if (up) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900291 maybeTrackNewInterfaceLocked(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800292 } else {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900293 if (ifaceNameToType(iface) == ConnectivityManager.TETHERING_BLUETOOTH) {
294 stopTrackingInterfaceLocked(iface);
Christopher Wileyd30aaeb2016-07-08 09:33:50 -0700295 } else {
296 // Ignore usb0 down after enabling RNDIS.
297 // We will handle disconnect in interfaceRemoved.
298 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status
299 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
300 if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800301 }
302 }
303 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800304 }
305
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900306 @Override
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700307 public void interfaceLinkStateChanged(String iface, boolean up) {
Irfan Sheriff23eb2972011-07-22 15:21:10 -0700308 interfaceStatusChanged(iface, up);
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700309 }
310
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700311 private int ifaceNameToType(String iface) {
Erik Kline3e756652017-01-17 13:42:19 +0900312 final TetheringConfiguration cfg = mConfig;
313
314 if (cfg.isWifi(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700315 return ConnectivityManager.TETHERING_WIFI;
Erik Kline3e756652017-01-17 13:42:19 +0900316 } else if (cfg.isUsb(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700317 return ConnectivityManager.TETHERING_USB;
Erik Kline3e756652017-01-17 13:42:19 +0900318 } else if (cfg.isBluetooth(iface)) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700319 return ConnectivityManager.TETHERING_BLUETOOTH;
320 }
321 return ConnectivityManager.TETHERING_INVALID;
322 }
323
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900324 @Override
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800325 public void interfaceAdded(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700326 if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700327 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900328 maybeTrackNewInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800329 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800330 }
331
Erik Kline0c9cb2b2015-11-20 17:47:08 +0900332 @Override
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800333 public void interfaceRemoved(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700334 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700335 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900336 stopTrackingInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800337 }
338 }
339
Hugo Benichib55fb222017-03-10 14:20:57 +0900340 public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800341 if (!isTetherProvisioningRequired()) {
342 enableTetheringInternal(type, true, receiver);
343 return;
344 }
345
346 if (showProvisioningUi) {
347 runUiTetherProvisioningAndEnable(type, receiver);
348 } else {
349 runSilentTetherProvisioningAndEnable(type, receiver);
350 }
351 }
352
353 public void stopTethering(int type) {
354 enableTetheringInternal(type, false, null);
355 if (isTetherProvisioningRequired()) {
356 cancelTetherProvisioningRechecks(type);
357 }
358 }
359
360 /**
361 * Check if the device requires a provisioning check in order to enable tethering.
362 *
363 * @return a boolean - {@code true} indicating tether provisioning is required by the carrier.
364 */
Christopher Wiley497c1472016-10-11 13:26:03 -0700365 @VisibleForTesting
366 protected boolean isTetherProvisioningRequired() {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800367 String[] provisionApp = mContext.getResources().getStringArray(
368 com.android.internal.R.array.config_mobile_hotspot_provision_app);
Christopher Wiley497c1472016-10-11 13:26:03 -0700369 if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800370 || provisionApp == null) {
371 return false;
372 }
373
Erik Klinede637722017-10-12 22:16:01 +0900374 if (carrierConfigAffirmsEntitlementCheckNotRequired()) {
375 return false;
376 }
377 return (provisionApp.length == 2);
378 }
379
380 // The logic here is aimed solely at confirming that a CarrierConfig exists
381 // and affirms that entitlement checks are not required.
382 //
383 // TODO: find a better way to express this, or alter the checking process
384 // entirely so that this is more intuitive.
385 private boolean carrierConfigAffirmsEntitlementCheckNotRequired() {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800386 // Check carrier config for entitlement checks
387 final CarrierConfigManager configManager = (CarrierConfigManager) mContext
388 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
Erik Klinede637722017-10-12 22:16:01 +0900389 if (configManager == null) return false;
390
391 final PersistableBundle carrierConfig = configManager.getConfig();
392 if (carrierConfig == null) return false;
393
394 // A CarrierConfigManager was found and it has a config.
395 final boolean isEntitlementCheckRequired = carrierConfig.getBoolean(
396 CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
397 return !isEntitlementCheckRequired;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800398 }
399
Erik Kline227648f2017-01-20 20:26:10 +0900400 // Used by the SIM card change observation code.
401 // TODO: De-duplicate above code.
402 private boolean hasMobileHotspotProvisionApp() {
403 try {
404 if (!mContext.getResources().getString(com.android.internal.R.string.
405 config_mobile_hotspot_provision_app_no_ui).isEmpty()) {
406 Log.d(TAG, "re-evaluate provisioning");
407 return true;
408 }
409 } catch (Resources.NotFoundException e) {}
410 Log.d(TAG, "no prov-check needed for new SIM");
411 return false;
412 }
413
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800414 /**
415 * Enables or disables tethering for the given type. This should only be called once
416 * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
417 * for the specified interface.
418 */
419 private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700420 boolean isProvisioningRequired = enable && isTetherProvisioningRequired();
421 int result;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800422 switch (type) {
423 case ConnectivityManager.TETHERING_WIFI:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700424 result = setWifiTethering(enable);
425 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
426 scheduleProvisioningRechecks(type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800427 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700428 sendTetherResult(receiver, result);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800429 break;
430 case ConnectivityManager.TETHERING_USB:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700431 result = setUsbTethering(enable);
432 if (isProvisioningRequired && result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800433 scheduleProvisioningRechecks(type);
434 }
435 sendTetherResult(receiver, result);
436 break;
437 case ConnectivityManager.TETHERING_BLUETOOTH:
438 setBluetoothTethering(enable, receiver);
439 break;
440 default:
441 Log.w(TAG, "Invalid tether type.");
442 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE);
443 }
444 }
445
446 private void sendTetherResult(ResultReceiver receiver, int result) {
447 if (receiver != null) {
448 receiver.send(result, null);
449 }
450 }
451
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700452 private int setWifiTethering(final boolean enable) {
Erik Kline256be782017-04-29 13:20:04 +0900453 int rval = ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
454 final long ident = Binder.clearCallingIdentity();
455 try {
456 synchronized (mPublicSync) {
457 mWifiTetherRequested = enable;
458 final WifiManager mgr = getWifiManager();
459 if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||
460 (!enable && mgr.stopSoftAp())) {
461 rval = ConnectivityManager.TETHER_ERROR_NO_ERROR;
462 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700463 }
Erik Kline256be782017-04-29 13:20:04 +0900464 } finally {
465 Binder.restoreCallingIdentity(ident);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700466 }
Erik Kline256be782017-04-29 13:20:04 +0900467 return rval;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700468 }
469
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800470 private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
471 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
472 if (adapter == null || !adapter.isEnabled()) {
473 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " +
474 (adapter == null));
475 sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL);
476 return;
477 }
478
479 adapter.getProfileProxy(mContext, new ServiceListener() {
480 @Override
481 public void onServiceDisconnected(int profile) { }
482
483 @Override
484 public void onServiceConnected(int profile, BluetoothProfile proxy) {
485 ((BluetoothPan) proxy).setBluetoothTethering(enable);
486 // TODO: Enabling bluetooth tethering can fail asynchronously here.
487 // We should figure out a way to bubble up that failure instead of sending success.
Jeremy Klein45ae04a2016-02-05 10:37:32 -0800488 int result = ((BluetoothPan) proxy).isTetheringOn() == enable ?
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800489 ConnectivityManager.TETHER_ERROR_NO_ERROR :
490 ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
491 sendTetherResult(receiver, result);
492 if (enable && isTetherProvisioningRequired()) {
493 scheduleProvisioningRechecks(ConnectivityManager.TETHERING_BLUETOOTH);
494 }
495 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
496 }
497 }, BluetoothProfile.PAN);
498 }
499
500 private void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
Jeremy Klein15f3d212016-01-24 17:01:09 -0800501 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
502 sendUiTetherProvisionIntent(type, proxyReceiver);
503 }
504
505 private void sendUiTetherProvisionIntent(int type, ResultReceiver receiver) {
506 Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING);
507 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
508 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
509 final long ident = Binder.clearCallingIdentity();
510 try {
511 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
512 } finally {
513 Binder.restoreCallingIdentity(ident);
514 }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800515 }
516
517 /**
Erik Klinefdd41112017-01-12 17:02:51 +0900518 * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result
519 * is successful before firing back up to the wrapped receiver.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800520 *
521 * @param type The type of tethering being enabled.
522 * @param receiver A ResultReceiver which will be called back with an int resultCode.
523 * @return The proxy receiver.
524 */
525 private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) {
526 ResultReceiver rr = new ResultReceiver(null) {
527 @Override
528 protected void onReceiveResult(int resultCode, Bundle resultData) {
529 // If provisioning is successful, enable tethering, otherwise just send the error.
530 if (resultCode == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
531 enableTetheringInternal(type, true, receiver);
532 } else {
533 sendTetherResult(receiver, resultCode);
534 }
535 }
536 };
537
538 // The following is necessary to avoid unmarshalling issues when sending the receiver
Erik Kline6ff17f72015-12-10 20:42:12 +0900539 // across processes.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800540 Parcel parcel = Parcel.obtain();
541 rr.writeToParcel(parcel,0);
542 parcel.setDataPosition(0);
543 ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
544 parcel.recycle();
545 return receiverForSending;
546 }
547
548 private void scheduleProvisioningRechecks(int type) {
549 Intent intent = new Intent();
550 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
551 intent.putExtra(ConnectivityManager.EXTRA_SET_ALARM, true);
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 runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
562 ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
563 sendSilentTetherProvisionIntent(type, proxyReceiver);
564 }
565
566 private void sendSilentTetherProvisionIntent(int type, ResultReceiver receiver) {
567 Intent intent = new Intent();
568 intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
569 intent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
570 intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
571 intent.setComponent(TETHER_SERVICE);
572 final long ident = Binder.clearCallingIdentity();
573 try {
574 mContext.startServiceAsUser(intent, UserHandle.CURRENT);
575 } finally {
576 Binder.restoreCallingIdentity(ident);
577 }
578 }
579
580 private void cancelTetherProvisioningRechecks(int type) {
581 if (getConnectivityManager().isTetheringSupported()) {
582 Intent intent = new Intent();
583 intent.putExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE, type);
584 intent.setComponent(TETHER_SERVICE);
585 final long ident = Binder.clearCallingIdentity();
586 try {
587 mContext.startServiceAsUser(intent, UserHandle.CURRENT);
588 } finally {
589 Binder.restoreCallingIdentity(ident);
590 }
591 }
592 }
Erik Kline6ff17f72015-12-10 20:42:12 +0900593
Erik Kline227648f2017-01-20 20:26:10 +0900594 // Used by the SIM card change observation code.
595 // TODO: De-duplicate with above code, where possible.
596 private void startProvisionIntent(int tetherType) {
597 final Intent startProvIntent = new Intent();
598 startProvIntent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, tetherType);
599 startProvIntent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
600 startProvIntent.setComponent(TETHER_SERVICE);
601 mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT);
602 }
603
Robert Greenwalt5a735062010-03-02 17:25:02 -0800604 public int tether(String iface) {
Erik Klineea9cc482017-03-10 19:35:34 +0900605 return tether(iface, IControlsTethering.STATE_TETHERED);
606 }
607
608 private int tether(String iface, int requestedState) {
Wink Savillec9acde92011-09-21 11:05:43 -0700609 if (DBG) Log.d(TAG, "Tethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700610 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700611 TetherState tetherState = mTetherStates.get(iface);
612 if (tetherState == null) {
Erik Kline00019f42016-06-30 19:31:46 +0900613 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700614 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
615 }
616 // Ignore the error status of the interface. If the interface is available,
617 // the errors are referring to past tethering attempts anyway.
Hugo Benichib55fb222017-03-10 14:20:57 +0900618 if (tetherState.lastState != IControlsTethering.STATE_AVAILABLE) {
Erik Kline00019f42016-06-30 19:31:46 +0900619 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700620 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700621 }
Erik Klineea9cc482017-03-10 19:35:34 +0900622 // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's
623 // queue but not yet processed, this will be a no-op and it will not
624 // return an error.
625 //
626 // TODO: reexamine the threading and messaging model.
627 tetherState.stateMachine.sendMessage(
628 TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, requestedState);
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700629 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800630 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800631 }
632
Robert Greenwalt5a735062010-03-02 17:25:02 -0800633 public int untether(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700634 if (DBG) Log.d(TAG, "Untethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700635 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700636 TetherState tetherState = mTetherStates.get(iface);
637 if (tetherState == null) {
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700638 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
639 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
640 }
Erik Klineea9cc482017-03-10 19:35:34 +0900641 if (!tetherState.isCurrentlyServing()) {
642 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700643 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
644 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900645 tetherState.stateMachine.sendMessage(
Christopher Wileyd985dde2016-05-31 10:44:35 -0700646 TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700647 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800648 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800649 }
650
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700651 public void untetherAll() {
Christopher Wileyfa6a4862016-09-19 08:58:06 -0700652 stopTethering(ConnectivityManager.TETHERING_WIFI);
653 stopTethering(ConnectivityManager.TETHERING_USB);
654 stopTethering(ConnectivityManager.TETHERING_BLUETOOTH);
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700655 }
656
Robert Greenwalt5a735062010-03-02 17:25:02 -0800657 public int getLastTetherError(String iface) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700658 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700659 TetherState tetherState = mTetherStates.get(iface);
660 if (tetherState == null) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700661 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
662 ", ignoring");
663 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
664 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900665 return tetherState.lastError;
Robert Greenwalt5a735062010-03-02 17:25:02 -0800666 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800667 }
668
Erik Klineea9cc482017-03-10 19:35:34 +0900669 // TODO: Figure out how to update for local hotspot mode interfaces.
Christopher Wileyd985dde2016-05-31 10:44:35 -0700670 private void sendTetherStateChangedBroadcast() {
Sreeram Ramachandran62a61312014-07-24 16:05:17 -0700671 if (!getConnectivityManager().isTetheringSupported()) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800672
Erik Kline8351faa2017-04-17 16:47:23 +0900673 final ArrayList<String> availableList = new ArrayList<>();
674 final ArrayList<String> tetherList = new ArrayList<>();
675 final ArrayList<String> localOnlyList = new ArrayList<>();
676 final ArrayList<String> erroredList = new ArrayList<>();
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800677
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800678 boolean wifiTethered = false;
679 boolean usbTethered = false;
Danica Chang6fdd0c62010-08-11 14:54:43 -0700680 boolean bluetoothTethered = false;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800681
Erik Kline3e756652017-01-17 13:42:19 +0900682 final TetheringConfiguration cfg = mConfig;
683
Robert Greenwaltb4453622011-11-03 16:01:40 -0700684 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700685 for (int i = 0; i < mTetherStates.size(); i++) {
686 TetherState tetherState = mTetherStates.valueAt(i);
687 String iface = mTetherStates.keyAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +0900688 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700689 erroredList.add(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +0900690 } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700691 availableList.add(iface);
Erik Klineca41be72017-04-20 22:59:16 +0900692 } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_ONLY) {
Erik Kline8351faa2017-04-17 16:47:23 +0900693 localOnlyList.add(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +0900694 } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
Erik Kline3e756652017-01-17 13:42:19 +0900695 if (cfg.isUsb(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700696 usbTethered = true;
Erik Kline3e756652017-01-17 13:42:19 +0900697 } else if (cfg.isWifi(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700698 wifiTethered = true;
Erik Kline3e756652017-01-17 13:42:19 +0900699 } else if (cfg.isBluetooth(iface)) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700700 bluetoothTethered = true;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800701 }
Erik Kline8351faa2017-04-17 16:47:23 +0900702 tetherList.add(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800703 }
704 }
705 }
Erik Kline8351faa2017-04-17 16:47:23 +0900706 final Intent bcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
707 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
Robert Greenwalt98c79e52011-07-28 11:51:11 -0700708 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Erik Kline8351faa2017-04-17 16:47:23 +0900709 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER, availableList);
710 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
711 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, tetherList);
712 bcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, erroredList);
713 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800714 if (DBG) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900715 Log.d(TAG, String.format(
Erik Kline8351faa2017-04-17 16:47:23 +0900716 "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
717 "avail", TextUtils.join(",", availableList),
718 "local_only", TextUtils.join(",", localOnlyList),
719 "tether", TextUtils.join(",", tetherList),
720 "error", TextUtils.join(",", erroredList)));
Robert Greenwalt924cc942010-06-28 10:26:19 -0700721 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800722
723 if (usbTethered) {
Danica Chang6fdd0c62010-08-11 14:54:43 -0700724 if (wifiTethered || bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400725 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800726 } else {
Chris Wren282cfef2017-03-27 15:01:44 -0400727 showTetheredNotification(SystemMessage.NOTE_TETHER_USB);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800728 }
729 } else if (wifiTethered) {
Danica Chang6fdd0c62010-08-11 14:54:43 -0700730 if (bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400731 showTetheredNotification(SystemMessage.NOTE_TETHER_GENERAL);
Danica Chang6fdd0c62010-08-11 14:54:43 -0700732 } else {
Vinit Deshpande2576a802014-11-18 13:56:15 -0800733 /* We now have a status bar icon for WifiTethering, so drop the notification */
734 clearTetheredNotification();
Danica Chang6fdd0c62010-08-11 14:54:43 -0700735 }
736 } else if (bluetoothTethered) {
Chris Wren282cfef2017-03-27 15:01:44 -0400737 showTetheredNotification(SystemMessage.NOTE_TETHER_BLUETOOTH);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800738 } else {
739 clearTetheredNotification();
740 }
741 }
742
Chris Wren282cfef2017-03-27 15:01:44 -0400743 private void showTetheredNotification(int id) {
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100744 showTetheredNotification(id, true);
745 }
746
747 @VisibleForTesting
748 protected void showTetheredNotification(int id, boolean tetheringOn) {
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800749 NotificationManager notificationManager =
Erik Klinec438e302017-07-04 22:02:49 +0900750 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800751 if (notificationManager == null) {
752 return;
753 }
Chris Wren282cfef2017-03-27 15:01:44 -0400754 int icon = 0;
755 switch(id) {
756 case SystemMessage.NOTE_TETHER_USB:
757 icon = com.android.internal.R.drawable.stat_sys_tether_usb;
758 break;
759 case SystemMessage.NOTE_TETHER_BLUETOOTH:
760 icon = com.android.internal.R.drawable.stat_sys_tether_bluetooth;
761 break;
762 case SystemMessage.NOTE_TETHER_GENERAL:
763 default:
764 icon = com.android.internal.R.drawable.stat_sys_tether_general;
765 break;
766 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800767
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400768 if (mLastNotificationId != 0) {
769 if (mLastNotificationId == icon) {
Robert Greenwaltdb3fe9e2010-03-18 16:28:30 -0700770 return;
771 }
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400772 notificationManager.cancelAsUser(null, mLastNotificationId,
Robert Greenwalt3cab6b02012-10-04 16:44:26 -0700773 UserHandle.ALL);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400774 mLastNotificationId = 0;
Robert Greenwaltdb3fe9e2010-03-18 16:28:30 -0700775 }
776
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800777 Intent intent = new Intent();
778 intent.setClassName("com.android.settings", "com.android.settings.TetherSettings");
779 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
780
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700781 PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, intent, 0,
782 null, UserHandle.CURRENT);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800783
784 Resources r = Resources.getSystem();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100785 final CharSequence title;
786 final CharSequence message;
787
788 if (tetheringOn) {
789 title = r.getText(com.android.internal.R.string.tethered_notification_title);
790 message = r.getText(com.android.internal.R.string.tethered_notification_message);
791 } else {
792 title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
793 message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
794 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800795
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400796 if (mTetheredNotificationBuilder == null) {
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500797 mTetheredNotificationBuilder =
798 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400799 mTetheredNotificationBuilder.setWhen(0)
800 .setOngoing(true)
801 .setColor(mContext.getColor(
802 com.android.internal.R.color.system_notification_accent_color))
803 .setVisibility(Notification.VISIBILITY_PUBLIC)
804 .setCategory(Notification.CATEGORY_STATUS);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800805 }
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400806 mTetheredNotificationBuilder.setSmallIcon(icon)
807 .setContentTitle(title)
808 .setContentText(message)
809 .setContentIntent(pi);
Chris Wren282cfef2017-03-27 15:01:44 -0400810 mLastNotificationId = id;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800811
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400812 notificationManager.notifyAsUser(null, mLastNotificationId,
zhouzhijie130d4592017-05-18 10:02:59 +0800813 mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800814 }
815
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100816 @VisibleForTesting
817 protected void clearTetheredNotification() {
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800818 NotificationManager notificationManager =
Erik Klinec438e302017-07-04 22:02:49 +0900819 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400820 if (notificationManager != null && mLastNotificationId != 0) {
821 notificationManager.cancelAsUser(null, mLastNotificationId,
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700822 UserHandle.ALL);
Chris Wren1ce4b6d2015-06-11 10:19:43 -0400823 mLastNotificationId = 0;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800824 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800825 }
826
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800827 private class StateReceiver extends BroadcastReceiver {
Nick Kralevich70c117a2014-05-27 15:30:02 -0700828 @Override
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800829 public void onReceive(Context content, Intent intent) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900830 final String action = intent.getAction();
831 if (action == null) return;
832
Mike Lockwood770126a2010-12-09 22:30:37 -0800833 if (action.equals(UsbManager.ACTION_USB_STATE)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900834 handleUsbAction(intent);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800835 } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900836 handleConnectivityAction(intent);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700837 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900838 handleWifiApAction(intent);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700839 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
Erik Klinede637722017-10-12 22:16:01 +0900840 mLog.log("OBSERVED configuration changed");
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700841 updateConfiguration();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800842 }
843 }
Erik Kline2e88b5e2017-01-18 11:57:45 +0900844
845 private void handleConnectivityAction(Intent intent) {
846 final NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(
847 ConnectivityManager.EXTRA_NETWORK_INFO);
848 if (networkInfo == null ||
849 networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
850 return;
851 }
852
853 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
854 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
855 }
856
857 private void handleUsbAction(Intent intent) {
858 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
Erik Klinec438e302017-07-04 22:02:49 +0900859 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900860 final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
Erik Klinec438e302017-07-04 22:02:49 +0900861
862 mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
863 usbConnected, usbConfigured, rndisEnabled));
864
865 // There are three types of ACTION_USB_STATE:
866 //
867 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
868 // Meaning: USB connection has ended either because of
869 // software reset or hard unplug.
870 //
871 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
872 // Meaning: the first stage of USB protocol handshake has
873 // occurred but it is not complete.
874 //
875 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
876 // Meaning: the USB handshake is completely done and all the
877 // functions are ready to use.
878 //
879 // For more explanation, see b/62552150 .
Erik Kline2e88b5e2017-01-18 11:57:45 +0900880 synchronized (Tethering.this.mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800881 if (!usbConnected && mRndisEnabled) {
882 // Turn off tethering if it was enabled and there is a disconnect.
883 tetherMatchingInterfaces(
884 IControlsTethering.STATE_AVAILABLE,
885 ConnectivityManager.TETHERING_USB);
886 } else if (usbConfigured && rndisEnabled) {
887 // Tether if rndis is enabled and usb is configured.
Erik Klineea9cc482017-03-10 19:35:34 +0900888 tetherMatchingInterfaces(
889 IControlsTethering.STATE_TETHERED,
890 ConnectivityManager.TETHERING_USB);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900891 }
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800892 mRndisEnabled = usbConfigured && rndisEnabled;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900893 }
894 }
895
896 private void handleWifiApAction(Intent intent) {
Erik Kline2efb8272017-05-31 15:53:53 +0900897 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
898 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
899 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
900
Erik Kline2e88b5e2017-01-18 11:57:45 +0900901 synchronized (Tethering.this.mPublicSync) {
902 switch (curState) {
903 case WifiManager.WIFI_AP_STATE_ENABLING:
904 // We can see this state on the way to both enabled and failure states.
905 break;
906 case WifiManager.WIFI_AP_STATE_ENABLED:
Erik Kline2efb8272017-05-31 15:53:53 +0900907 enableWifiIpServingLocked(ifname, ipmode);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900908 break;
909 case WifiManager.WIFI_AP_STATE_DISABLED:
910 case WifiManager.WIFI_AP_STATE_DISABLING:
911 case WifiManager.WIFI_AP_STATE_FAILED:
912 default:
Erik Kline562e0c12017-06-09 16:36:29 +0900913 disableWifiIpServingLocked(ifname, curState);
Erik Kline2efb8272017-05-31 15:53:53 +0900914 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900915 }
916 }
917 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800918 }
919
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100920 @VisibleForTesting
921 protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
922 private final Tethering mWrapper;
923
924 public TetheringUserRestrictionListener(Tethering wrapper) {
925 mWrapper = wrapper;
926 }
927
928 public void onUserRestrictionsChanged(int userId,
929 Bundle newRestrictions,
930 Bundle prevRestrictions) {
931 final boolean newlyDisallowed =
932 newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
933 final boolean previouslyDisallowed =
934 prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
935 final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);
936
937 if (!tetheringDisallowedChanged) {
938 return;
939 }
940
941 mWrapper.clearTetheredNotification();
942 final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
943
944 if (newlyDisallowed && isTetheringActiveOnDevice) {
945 mWrapper.showTetheredNotification(
946 com.android.internal.R.drawable.stat_sys_tether_general, false);
947 mWrapper.untetherAll();
948 }
949 }
950 }
951
Erik Kline562e0c12017-06-09 16:36:29 +0900952 private void disableWifiIpServingLocked(String ifname, int apState) {
953 mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);
Erik Kline2efb8272017-05-31 15:53:53 +0900954
Erik Kline562e0c12017-06-09 16:36:29 +0900955 // Regardless of whether we requested this transition, the AP has gone
956 // down. Don't try to tether again unless we're requested to do so.
957 // TODO: Remove this altogether, once Wi-Fi reliably gives us an
958 // interface name with every broadcast.
959 mWifiTetherRequested = false;
960
961 if (!TextUtils.isEmpty(ifname)) {
962 final TetherState ts = mTetherStates.get(ifname);
963 if (ts != null) {
964 ts.stateMachine.unwanted();
965 return;
966 }
967 }
968
Erik Kline2efb8272017-05-31 15:53:53 +0900969 for (int i = 0; i < mTetherStates.size(); i++) {
970 TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine;
971 if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
Erik Kline562e0c12017-06-09 16:36:29 +0900972 tism.unwanted();
973 return;
Erik Kline2efb8272017-05-31 15:53:53 +0900974 }
975 }
Erik Kline562e0c12017-06-09 16:36:29 +0900976
977 mLog.log("Error disabling Wi-Fi IP serving; " +
978 (TextUtils.isEmpty(ifname) ? "no interface name specified"
979 : "specified interface: " + ifname));
Erik Kline2efb8272017-05-31 15:53:53 +0900980 }
981
982 private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
983 // Map wifiIpMode values to IControlsTethering serving states, inferring
984 // from mWifiTetherRequested as a final "best guess".
985 final int ipServingMode;
986 switch (wifiIpMode) {
987 case IFACE_IP_MODE_TETHERED:
988 ipServingMode = IControlsTethering.STATE_TETHERED;
989 break;
990 case IFACE_IP_MODE_LOCAL_ONLY:
991 ipServingMode = IControlsTethering.STATE_LOCAL_ONLY;
992 break;
993 default:
Erik Kline9e225542017-06-08 17:48:48 +0900994 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
995 return;
Erik Kline2efb8272017-05-31 15:53:53 +0900996 }
997
998 if (!TextUtils.isEmpty(ifname)) {
Erik Klinea9cde8b2017-06-20 21:18:31 +0900999 maybeTrackNewInterfaceLocked(ifname, ConnectivityManager.TETHERING_WIFI);
Erik Kline2efb8272017-05-31 15:53:53 +09001000 changeInterfaceState(ifname, ipServingMode);
1001 } else {
Erik Kline9e225542017-06-08 17:48:48 +09001002 mLog.e(String.format(
1003 "Cannot enable IP serving in mode %s on missing interface name",
1004 ipServingMode));
Erik Kline2efb8272017-05-31 15:53:53 +09001005 }
1006 }
1007
Erik Klineea9cc482017-03-10 19:35:34 +09001008 // TODO: Consider renaming to something more accurate in its description.
1009 // This method:
1010 // - allows requesting either tethering or local hotspot serving states
1011 // - handles both enabling and disabling serving states
1012 // - only tethers the first matching interface in listInterfaces()
1013 // order of a given type
1014 private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
1015 if (VDBG) {
1016 Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
1017 }
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001018
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001019 String[] ifaces = null;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001020 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001021 ifaces = mNMService.listInterfaces();
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001022 } catch (Exception e) {
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001023 Log.e(TAG, "Error listing Interfaces", e);
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001024 return;
1025 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001026 String chosenIface = null;
1027 if (ifaces != null) {
1028 for (String iface : ifaces) {
1029 if (ifaceNameToType(iface) == interfaceType) {
1030 chosenIface = iface;
1031 break;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001032 }
1033 }
1034 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001035 if (chosenIface == null) {
1036 Log.e(TAG, "could not find iface of type " + interfaceType);
1037 return;
1038 }
1039
Erik Kline2efb8272017-05-31 15:53:53 +09001040 changeInterfaceState(chosenIface, requestedState);
1041 }
1042
1043 private void changeInterfaceState(String ifname, int requestedState) {
Erik Klineea9cc482017-03-10 19:35:34 +09001044 final int result;
1045 switch (requestedState) {
1046 case IControlsTethering.STATE_UNAVAILABLE:
1047 case IControlsTethering.STATE_AVAILABLE:
Erik Kline2efb8272017-05-31 15:53:53 +09001048 result = untether(ifname);
Erik Klineea9cc482017-03-10 19:35:34 +09001049 break;
1050 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +09001051 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001052 result = tether(ifname, requestedState);
Erik Klineea9cc482017-03-10 19:35:34 +09001053 break;
1054 default:
1055 Log.wtf(TAG, "Unknown interface state: " + requestedState);
1056 return;
1057 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001058 if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Erik Kline2efb8272017-05-31 15:53:53 +09001059 Log.e(TAG, "unable start or stop tethering on iface " + ifname);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001060 return;
1061 }
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001062 }
1063
Erik Kline3e756652017-01-17 13:42:19 +09001064 public TetheringConfiguration getTetheringConfiguration() {
1065 return mConfig;
1066 }
1067
Erik Klined781fba2017-01-23 13:01:58 +09001068 public boolean hasTetherableConfiguration() {
1069 final TetheringConfiguration cfg = mConfig;
1070 final boolean hasDownstreamConfiguration =
1071 (cfg.tetherableUsbRegexs.length != 0) ||
1072 (cfg.tetherableWifiRegexs.length != 0) ||
1073 (cfg.tetherableBluetoothRegexs.length != 0);
1074 final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty();
1075
1076 return hasDownstreamConfiguration && hasUpstreamConfiguration;
1077 }
1078
Erik Kline3e756652017-01-17 13:42:19 +09001079 // TODO - update callers to use getTetheringConfiguration(),
1080 // which has only final members.
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001081 public String[] getTetherableUsbRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001082 return copy(mConfig.tetherableUsbRegexs);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001083 }
1084
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001085 public String[] getTetherableWifiRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001086 return copy(mConfig.tetherableWifiRegexs);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001087 }
1088
Danica Chang6fdd0c62010-08-11 14:54:43 -07001089 public String[] getTetherableBluetoothRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001090 return copy(mConfig.tetherableBluetoothRegexs);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001091 }
1092
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001093 public int setUsbTethering(boolean enable) {
Wink Savillec9acde92011-09-21 11:05:43 -07001094 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
Erik Klinec438e302017-07-04 22:02:49 +09001095 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
Robert Greenwaltb4453622011-11-03 16:01:40 -07001096 synchronized (mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -08001097 usbManager.setCurrentFunction(enable ? UsbManager.USB_FUNCTION_RNDIS : null, false);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001098 }
1099 return ConnectivityManager.TETHER_ERROR_NO_ERROR;
1100 }
1101
Erik Kline1fdc2e22017-05-08 17:56:35 +09001102 // TODO review API - figure out how to delete these entirely.
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001103 public String[] getTetheredIfaces() {
1104 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001105 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001106 for (int i = 0; i < mTetherStates.size(); i++) {
1107 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001108 if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001109 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001110 }
1111 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001112 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001113 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001114 }
1115
1116 public String[] getTetherableIfaces() {
1117 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001118 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001119 for (int i = 0; i < mTetherStates.size(); i++) {
1120 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001121 if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001122 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001123 }
1124 }
1125 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001126 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001127 }
1128
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001129 public String[] getTetheredDhcpRanges() {
Erik Kline3e756652017-01-17 13:42:19 +09001130 return mConfig.dhcpRanges;
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001131 }
1132
Robert Greenwalt5a735062010-03-02 17:25:02 -08001133 public String[] getErroredIfaces() {
1134 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001135 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001136 for (int i = 0; i < mTetherStates.size(); i++) {
1137 TetherState tetherState = mTetherStates.valueAt(i);
Hugo Benichib55fb222017-03-10 14:20:57 +09001138 if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001139 list.add(mTetherStates.keyAt(i));
Robert Greenwalt5a735062010-03-02 17:25:02 -08001140 }
1141 }
1142 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001143 return list.toArray(new String[list.size()]);
Robert Greenwalt5a735062010-03-02 17:25:02 -08001144 }
1145
Erik Kline22108902017-07-06 16:40:06 +09001146 private void logMessage(State state, int what) {
1147 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001148 }
1149
Erik Klineea9cc482017-03-10 19:35:34 +09001150 private boolean upstreamWanted() {
1151 if (!mForwardedDownstreams.isEmpty()) return true;
1152
1153 synchronized (mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -08001154 return mWifiTetherRequested;
Erik Klineea9cc482017-03-10 19:35:34 +09001155 }
1156 }
1157
Erik Kline00019f42016-06-30 19:31:46 +09001158 // Needed because the canonical source of upstream truth is just the
1159 // upstream interface name, |mCurrentUpstreamIface|. This is ripe for
1160 // future simplification, once the upstream Network is canonical.
Erik Kline3a5278f2017-06-24 19:29:10 +09001161 private boolean pertainsToCurrentUpstream(NetworkState ns) {
Erik Kline00019f42016-06-30 19:31:46 +09001162 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIface != null) {
1163 for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
1164 if (mCurrentUpstreamIface.equals(ifname)) {
1165 return true;
Erik Kline6ff17f72015-12-10 20:42:12 +09001166 }
1167 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001168 }
Erik Kline00019f42016-06-30 19:31:46 +09001169 return false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001170 }
1171
Erik Kline227648f2017-01-20 20:26:10 +09001172 private void reevaluateSimCardProvisioning() {
1173 if (!hasMobileHotspotProvisionApp()) return;
Erik Klinede637722017-10-12 22:16:01 +09001174 if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
Erik Kline227648f2017-01-20 20:26:10 +09001175
1176 ArrayList<Integer> tethered = new ArrayList<>();
1177 synchronized (mPublicSync) {
1178 for (int i = 0; i < mTetherStates.size(); i++) {
1179 TetherState tetherState = mTetherStates.valueAt(i);
1180 if (tetherState.lastState != IControlsTethering.STATE_TETHERED) {
1181 continue; // Skip interfaces that aren't tethered.
1182 }
1183 String iface = mTetherStates.keyAt(i);
1184 int interfaceType = ifaceNameToType(iface);
1185 if (interfaceType != ConnectivityManager.TETHERING_INVALID) {
1186 tethered.add(interfaceType);
1187 }
1188 }
1189 }
1190
1191 for (int tetherType : tethered) {
1192 startProvisionIntent(tetherType);
1193 }
1194 }
1195
Wink Saville64c42ca2011-04-18 14:55:10 -07001196 class TetherMasterSM extends StateMachine {
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001197 private static final int BASE_MASTER = Protocol.BASE_TETHERING;
Erik Klineea9cc482017-03-10 19:35:34 +09001198 // an interface SM has requested Tethering/Local Hotspot
1199 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
1200 // an interface SM has unrequested Tethering/Local Hotspot
1201 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001202 // upstream connection change - do the right thing
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001203 static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001204 // we don't have a valid upstream conn, check again after a delay
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001205 static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
Erik Kline6ff17f72015-12-10 20:42:12 +09001206 // Events from NetworkCallbacks that we process on the master state
1207 // machine thread on behalf of the UpstreamNetworkMonitor.
Erik Kline00019f42016-06-30 19:31:46 +09001208 static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001209 // we treated the error and want now to clear it
1210 static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
Erik Kline6e9a1012017-06-06 19:24:21 +09001211 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001212
Erik Kline32179ff2017-07-04 18:28:11 +09001213 private final State mInitialState;
1214 private final State mTetherModeAliveState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001215
Erik Kline32179ff2017-07-04 18:28:11 +09001216 private final State mSetIpForwardingEnabledErrorState;
1217 private final State mSetIpForwardingDisabledErrorState;
1218 private final State mStartTetheringErrorState;
1219 private final State mStopTetheringErrorState;
1220 private final State mSetDnsForwardersErrorState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001221
Christopher Wileyd985dde2016-05-31 10:44:35 -07001222 // This list is a little subtle. It contains all the interfaces that currently are
1223 // requesting tethering, regardless of whether these interfaces are still members of
1224 // mTetherStates. This allows us to maintain the following predicates:
1225 //
1226 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1227 // interfaces.
1228 // 2) mNotifyList contains all state machines that may have outstanding tethering state
1229 // that needs to be torn down.
1230 //
1231 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1232 // so that the garbage collector does not clean up the state machine before it has a chance
1233 // to tear itself down.
Erik Kline1eb8c692016-07-08 17:21:26 +09001234 private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
1235 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
Erik Klineed962a82017-07-06 19:49:35 +09001236 private final OffloadWrapper mOffload;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001237
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001238 private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001239
Robert Greenwaltdfadaea2010-03-11 15:03:08 -08001240 TetherMasterSM(String name, Looper looper) {
1241 super(name, looper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001242
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001243 mInitialState = new InitialState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001244 mTetherModeAliveState = new TetherModeAliveState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001245 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001246 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001247 mStartTetheringErrorState = new StartTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001248 mStopTetheringErrorState = new StopTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001249 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
Erik Kline1fdc2e22017-05-08 17:56:35 +09001250
1251 addState(mInitialState);
1252 addState(mTetherModeAliveState);
1253 addState(mSetIpForwardingEnabledErrorState);
1254 addState(mSetIpForwardingDisabledErrorState);
1255 addState(mStartTetheringErrorState);
1256 addState(mStopTetheringErrorState);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001257 addState(mSetDnsForwardersErrorState);
1258
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001259 mNotifyList = new ArrayList<>();
Erik Kline7747fd42017-05-12 16:52:48 +09001260 mIPv6TetheringCoordinator = new IPv6TetheringCoordinator(mNotifyList, mLog);
Erik Klineed962a82017-07-06 19:49:35 +09001261 mOffload = new OffloadWrapper();
Erik Kline32179ff2017-07-04 18:28:11 +09001262
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001263 setInitialState(mInitialState);
1264 }
1265
Erik Kline1fdc2e22017-05-08 17:56:35 +09001266 class InitialState extends State {
1267 @Override
1268 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001269 logMessage(this, message.what);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001270 switch (message.what) {
1271 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001272 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001273 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1274 handleInterfaceServingStateActive(message.arg1, who);
1275 transitionTo(mTetherModeAliveState);
1276 break;
1277 case EVENT_IFACE_SERVING_STATE_INACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001278 who = (TetherInterfaceStateMachine) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001279 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1280 handleInterfaceServingStateInactive(who);
1281 break;
Erik Kline6e9a1012017-06-06 19:24:21 +09001282 case EVENT_IFACE_UPDATE_LINKPROPERTIES:
1283 // Silently ignore these for now.
1284 break;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001285 default:
1286 return NOT_HANDLED;
1287 }
1288 return HANDLED;
1289 }
1290 }
1291
Erik Kline3a5278f2017-06-24 19:29:10 +09001292 protected boolean turnOnMasterTetherSettings() {
1293 final TetheringConfiguration cfg = mConfig;
1294 try {
1295 mNMService.setIpForwardingEnabled(true);
1296 } catch (Exception e) {
1297 mLog.e(e);
1298 transitionTo(mSetIpForwardingEnabledErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001299 return false;
1300 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001301 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
1302 try {
1303 // TODO: Find a more accurate method name (startDHCPv4()?).
1304 mNMService.startTethering(cfg.dhcpRanges);
1305 } catch (Exception e) {
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001306 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001307 mNMService.stopTethering();
Erik Kline3a5278f2017-06-24 19:29:10 +09001308 mNMService.startTethering(cfg.dhcpRanges);
1309 } catch (Exception ee) {
1310 mLog.e(ee);
1311 transitionTo(mStartTetheringErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001312 return false;
1313 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001314 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001315 mLog.log("SET master tether settings: ON");
1316 return true;
1317 }
Robert Greenwalt10398722010-12-17 15:20:36 -08001318
Erik Kline3a5278f2017-06-24 19:29:10 +09001319 protected boolean turnOffMasterTetherSettings() {
1320 try {
1321 mNMService.stopTethering();
1322 } catch (Exception e) {
1323 mLog.e(e);
1324 transitionTo(mStopTetheringErrorState);
1325 return false;
Erik Kline14f7faf2017-02-14 19:03:09 +09001326 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001327 try {
1328 mNMService.setIpForwardingEnabled(false);
1329 } catch (Exception e) {
1330 mLog.e(e);
1331 transitionTo(mSetIpForwardingDisabledErrorState);
1332 return false;
1333 }
1334 transitionTo(mInitialState);
1335 mLog.log("SET master tether settings: OFF");
1336 return true;
1337 }
Erik Kline14f7faf2017-02-14 19:03:09 +09001338
Erik Kline3a5278f2017-06-24 19:29:10 +09001339 protected void chooseUpstreamType(boolean tryCell) {
Erik Kline6ee73da2017-07-08 20:36:37 +09001340 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
1341 // do not currently know how to watch for changes in DUN settings.
1342 maybeUpdateConfiguration();
Erik Kline1e2897d2017-06-09 17:08:52 +09001343
Erik Kline3a5278f2017-06-24 19:29:10 +09001344 final NetworkState ns = mUpstreamNetworkMonitor.selectPreferredUpstreamType(
1345 mConfig.preferredUpstreamIfaceTypes);
1346 if (ns == null) {
1347 if (tryCell) {
1348 mUpstreamNetworkMonitor.registerMobileNetworkRequest();
1349 // We think mobile should be coming up; don't set a retry.
1350 } else {
1351 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
Erik Kline1e2897d2017-06-09 17:08:52 +09001352 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001353 }
Erik Kline60caf7d2017-10-10 11:54:08 +09001354 mUpstreamNetworkMonitor.setCurrentUpstream((ns != null) ? ns.network : null);
Erik Kline3a5278f2017-06-24 19:29:10 +09001355 setUpstreamNetwork(ns);
1356 }
1357
1358 protected void setUpstreamNetwork(NetworkState ns) {
1359 String iface = null;
1360 if (ns != null && ns.linkProperties != null) {
1361 // Find the interface with the default IPv4 route. It may be the
1362 // interface described by linkProperties, or one of the interfaces
1363 // stacked on top of it.
Erik Kline22108902017-07-06 16:40:06 +09001364 mLog.i("Finding IPv4 upstream interface on: " + ns.linkProperties);
Erik Kline3a5278f2017-06-24 19:29:10 +09001365 RouteInfo ipv4Default = RouteInfo.selectBestRoute(
1366 ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
1367 if (ipv4Default != null) {
1368 iface = ipv4Default.getInterface();
Erik Kline22108902017-07-06 16:40:06 +09001369 mLog.i("Found interface " + ipv4Default.getInterface());
Erik Kline3a5278f2017-06-24 19:29:10 +09001370 } else {
Erik Kline22108902017-07-06 16:40:06 +09001371 mLog.i("No IPv4 upstream interface, giving up.");
Erik Kline00019f42016-06-30 19:31:46 +09001372 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001373 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -07001374
Erik Kline3a5278f2017-06-24 19:29:10 +09001375 if (iface != null) {
1376 setDnsForwarders(ns.network, ns.linkProperties);
Erik Kline6ff17f72015-12-10 20:42:12 +09001377 }
Erik Kline22108902017-07-06 16:40:06 +09001378 notifyDownstreamsOfNewUpstreamIface(iface);
Erik Kline3a5278f2017-06-24 19:29:10 +09001379 if (ns != null && pertainsToCurrentUpstream(ns)) {
1380 // If we already have NetworkState for this network examine
1381 // it immediately, because there likely will be no second
1382 // EVENT_ON_AVAILABLE (it was already received).
1383 handleNewUpstreamNetworkState(ns);
1384 } else if (mCurrentUpstreamIface == null) {
1385 // There are no available upstream networks, or none that
1386 // have an IPv4 default route (current metric for success).
1387 handleNewUpstreamNetworkState(null);
1388 }
1389 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001390
Erik Kline3a5278f2017-06-24 19:29:10 +09001391 protected void setDnsForwarders(final Network network, final LinkProperties lp) {
1392 // TODO: Set v4 and/or v6 DNS per available connectivity.
1393 String[] dnsServers = mConfig.defaultIPv4DNS;
1394 final Collection<InetAddress> dnses = lp.getDnsServers();
1395 // TODO: Properly support the absence of DNS servers.
1396 if (dnses != null && !dnses.isEmpty()) {
1397 // TODO: remove this invocation of NetworkUtils.makeStrings().
1398 dnsServers = NetworkUtils.makeStrings(dnses);
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001399 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001400 try {
1401 mNMService.setDnsForwarders(network, dnsServers);
1402 mLog.log(String.format(
1403 "SET DNS forwarders: network=%s dnsServers=%s",
1404 network, Arrays.toString(dnsServers)));
1405 } catch (Exception e) {
1406 // TODO: Investigate how this can fail and what exactly
1407 // happens if/when such failures occur.
1408 mLog.e("setting DNS forwarders failed, " + e);
1409 transitionTo(mSetDnsForwardersErrorState);
1410 }
1411 }
Erik Kline00019f42016-06-30 19:31:46 +09001412
Erik Kline22108902017-07-06 16:40:06 +09001413 protected void notifyDownstreamsOfNewUpstreamIface(String ifaceName) {
1414 mLog.log("Notifying downstreams of upstream=" + ifaceName);
Erik Kline3a5278f2017-06-24 19:29:10 +09001415 mCurrentUpstreamIface = ifaceName;
1416 for (TetherInterfaceStateMachine sm : mNotifyList) {
1417 sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
1418 ifaceName);
Erik Kline00019f42016-06-30 19:31:46 +09001419 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001420 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001421
Erik Kline3a5278f2017-06-24 19:29:10 +09001422 protected void handleNewUpstreamNetworkState(NetworkState ns) {
1423 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
Erik Klineed962a82017-07-06 19:49:35 +09001424 mOffload.updateUpstreamNetworkState(ns);
Erik Kline3a5278f2017-06-24 19:29:10 +09001425 }
1426
Erik Klineea9cc482017-03-10 19:35:34 +09001427 private void handleInterfaceServingStateActive(int mode, TetherInterfaceStateMachine who) {
1428 if (mNotifyList.indexOf(who) < 0) {
1429 mNotifyList.add(who);
1430 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
1431 }
1432
1433 if (mode == IControlsTethering.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001434 // No need to notify OffloadController just yet as there are no
1435 // "offload-able" prefixes to pass along. This will handled
1436 // when the TISM informs Tethering of its LinkProperties.
Erik Klineea9cc482017-03-10 19:35:34 +09001437 mForwardedDownstreams.add(who);
1438 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001439 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001440 mForwardedDownstreams.remove(who);
1441 }
Erik Kline216af6d2017-04-27 20:57:23 +09001442
1443 // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
1444 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
1445 final WifiManager mgr = getWifiManager();
1446 final String iface = who.interfaceName();
1447 switch (mode) {
1448 case IControlsTethering.STATE_TETHERED:
Erik Kline2efb8272017-05-31 15:53:53 +09001449 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +09001450 break;
1451 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001452 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +09001453 break;
1454 default:
1455 Log.wtf(TAG, "Unknown active serving mode: " + mode);
1456 break;
1457 }
1458 }
Erik Klineea9cc482017-03-10 19:35:34 +09001459 }
1460
1461 private void handleInterfaceServingStateInactive(TetherInterfaceStateMachine who) {
1462 mNotifyList.remove(who);
1463 mIPv6TetheringCoordinator.removeActiveDownstream(who);
Erik Klineed962a82017-07-06 19:49:35 +09001464 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001465 mForwardedDownstreams.remove(who);
Erik Kline216af6d2017-04-27 20:57:23 +09001466
1467 // If this is a Wi-Fi interface, tell WifiManager of any errors.
1468 if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
1469 if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
1470 getWifiManager().updateInterfaceIpState(
Erik Kline2efb8272017-05-31 15:53:53 +09001471 who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
Erik Kline216af6d2017-04-27 20:57:23 +09001472 }
1473 }
Erik Klineea9cc482017-03-10 19:35:34 +09001474 }
1475
Erik Kline3a5278f2017-06-24 19:29:10 +09001476 private void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
Erik Kline32179ff2017-07-04 18:28:11 +09001477 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
Erik Klineed962a82017-07-06 19:49:35 +09001478 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
Erik Kline3a5278f2017-06-24 19:29:10 +09001479 return;
1480 }
1481
1482 final NetworkState ns = (NetworkState) o;
1483
1484 if (ns == null || !pertainsToCurrentUpstream(ns)) {
1485 // TODO: In future, this is where upstream evaluation and selection
1486 // could be handled for notifications which include sufficient data.
1487 // For example, after CONNECTIVITY_ACTION listening is removed, here
1488 // is where we could observe a Wi-Fi network becoming available and
1489 // passing validation.
1490 if (mCurrentUpstreamIface == null) {
1491 // If we have no upstream interface, try to run through upstream
1492 // selection again. If, for example, IPv4 connectivity has shown up
1493 // after IPv6 (e.g., 464xlat became available) we want the chance to
1494 // notice and act accordingly.
1495 chooseUpstreamType(false);
1496 }
1497 return;
1498 }
1499
1500 switch (arg1) {
1501 case UpstreamNetworkMonitor.EVENT_ON_AVAILABLE:
1502 // The default network changed, or DUN connected
1503 // before this callback was processed. Updates
1504 // for the current NetworkCapabilities and
1505 // LinkProperties have been requested (default
1506 // request) or are being sent shortly (DUN). Do
1507 // nothing until they arrive; if no updates
1508 // arrive there's nothing to do.
1509 break;
1510 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
1511 handleNewUpstreamNetworkState(ns);
1512 break;
1513 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
1514 setDnsForwarders(ns.network, ns.linkProperties);
1515 handleNewUpstreamNetworkState(ns);
1516 break;
1517 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1518 // TODO: Re-evaluate possible upstreams. Currently upstream
1519 // reevaluation is triggered via received CONNECTIVITY_ACTION
1520 // broadcasts that result in being passed a
1521 // TetherMasterSM.CMD_UPSTREAM_CHANGED.
1522 handleNewUpstreamNetworkState(null);
1523 break;
1524 default:
1525 mLog.e("Unknown arg1 value: " + arg1);
1526 break;
1527 }
1528 }
1529
1530 class TetherModeAliveState extends State {
Erik Klineea9cc482017-03-10 19:35:34 +09001531 boolean mUpstreamWanted = false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001532 boolean mTryCell = true;
Erik Klinee0cce212017-03-06 14:05:23 +09001533
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001534 @Override
1535 public void enter() {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001536 // If turning on master tether settings fails, we have already
1537 // transitioned to an error state; exit early.
1538 if (!turnOnMasterTetherSettings()) {
1539 return;
1540 }
1541
Erik Klinede637722017-10-12 22:16:01 +09001542 mCarrierConfigChange.startListening();
Erik Kline227648f2017-01-20 20:26:10 +09001543 mSimChange.startListening();
Erik Kline6ff17f72015-12-10 20:42:12 +09001544 mUpstreamNetworkMonitor.start();
Robert Greenwalt4f74d552011-12-19 16:59:31 -08001545
Erik Klinef4b6e342017-04-25 19:19:59 +09001546 // TODO: De-duplicate with updateUpstreamWanted() below.
Erik Klineea9cc482017-03-10 19:35:34 +09001547 if (upstreamWanted()) {
1548 mUpstreamWanted = true;
Erik Klineed962a82017-07-06 19:49:35 +09001549 mOffload.start();
Erik Klineea9cc482017-03-10 19:35:34 +09001550 chooseUpstreamType(true);
1551 mTryCell = false;
1552 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001553 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001554
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001555 @Override
1556 public void exit() {
Erik Klineed962a82017-07-06 19:49:35 +09001557 mOffload.stop();
Erik Kline6ff17f72015-12-10 20:42:12 +09001558 mUpstreamNetworkMonitor.stop();
Erik Kline227648f2017-01-20 20:26:10 +09001559 mSimChange.stopListening();
Erik Klinede637722017-10-12 22:16:01 +09001560 mCarrierConfigChange.stopListening();
Erik Kline22108902017-07-06 16:40:06 +09001561 notifyDownstreamsOfNewUpstreamIface(null);
Erik Klinefa37b2f2016-08-02 18:27:03 +09001562 handleNewUpstreamNetworkState(null);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001563 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001564
Erik Klineea9cc482017-03-10 19:35:34 +09001565 private boolean updateUpstreamWanted() {
1566 final boolean previousUpstreamWanted = mUpstreamWanted;
1567 mUpstreamWanted = upstreamWanted();
Erik Klinef4b6e342017-04-25 19:19:59 +09001568 if (mUpstreamWanted != previousUpstreamWanted) {
1569 if (mUpstreamWanted) {
Erik Klineed962a82017-07-06 19:49:35 +09001570 mOffload.start();
Erik Klinef4b6e342017-04-25 19:19:59 +09001571 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001572 mOffload.stop();
Erik Klinef4b6e342017-04-25 19:19:59 +09001573 }
1574 }
Erik Klineea9cc482017-03-10 19:35:34 +09001575 return previousUpstreamWanted;
1576 }
1577
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001578 @Override
1579 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001580 logMessage(this, message.what);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001581 boolean retValue = true;
1582 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001583 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
Erik Kline32179ff2017-07-04 18:28:11 +09001584 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001585 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001586 handleInterfaceServingStateActive(message.arg1, who);
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001587 who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
Erik Kline6ff17f72015-12-10 20:42:12 +09001588 mCurrentUpstreamIface);
Erik Klineea9cc482017-03-10 19:35:34 +09001589 // If there has been a change and an upstream is now
1590 // desired, kick off the selection process.
1591 final boolean previousUpstreamWanted = updateUpstreamWanted();
1592 if (!previousUpstreamWanted && mUpstreamWanted) {
1593 chooseUpstreamType(true);
1594 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001595 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001596 }
Erik Klineea9cc482017-03-10 19:35:34 +09001597 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
Erik Kline32179ff2017-07-04 18:28:11 +09001598 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001599 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001600 handleInterfaceServingStateInactive(who);
1601
1602 if (mNotifyList.isEmpty()) {
Erik Kline47222fc2017-04-30 19:36:15 +09001603 // This transitions us out of TetherModeAliveState,
1604 // either to InitialState or an error state.
Erik Kline1fdc2e22017-05-08 17:56:35 +09001605 turnOffMasterTetherSettings();
1606 break;
1607 }
1608
1609 if (DBG) {
1610 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
1611 " live requests:");
1612 for (TetherInterfaceStateMachine o : mNotifyList) {
1613 Log.d(TAG, " " + o);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001614 }
1615 }
Erik Klineea9cc482017-03-10 19:35:34 +09001616 // If there has been a change and an upstream is no
1617 // longer desired, release any mobile requests.
1618 final boolean previousUpstreamWanted = updateUpstreamWanted();
1619 if (previousUpstreamWanted && !mUpstreamWanted) {
1620 mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
1621 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001622 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001623 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001624 case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
1625 final LinkProperties newLp = (LinkProperties) message.obj;
1626 if (message.arg1 == IControlsTethering.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001627 mOffload.updateDownstreamLinkProperties(newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09001628 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001629 mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
Erik Kline6e9a1012017-06-06 19:24:21 +09001630 }
1631 break;
1632 }
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001633 case CMD_UPSTREAM_CHANGED:
Erik Klineea9cc482017-03-10 19:35:34 +09001634 updateUpstreamWanted();
1635 if (!mUpstreamWanted) break;
1636
Erik Klinefb413432017-02-14 18:26:04 +09001637 // Need to try DUN immediately if Wi-Fi goes down.
1638 chooseUpstreamType(true);
1639 mTryCell = false;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001640 break;
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001641 case CMD_RETRY_UPSTREAM:
Erik Klineea9cc482017-03-10 19:35:34 +09001642 updateUpstreamWanted();
1643 if (!mUpstreamWanted) break;
1644
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001645 chooseUpstreamType(mTryCell);
1646 mTryCell = !mTryCell;
1647 break;
Erik Kline00019f42016-06-30 19:31:46 +09001648 case EVENT_UPSTREAM_CALLBACK: {
Erik Klineea9cc482017-03-10 19:35:34 +09001649 updateUpstreamWanted();
Erik Kline3a5278f2017-06-24 19:29:10 +09001650 if (mUpstreamWanted) {
1651 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
Erik Kline6ff17f72015-12-10 20:42:12 +09001652 }
1653 break;
Erik Kline00019f42016-06-30 19:31:46 +09001654 }
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001655 default:
1656 retValue = false;
1657 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001658 }
1659 return retValue;
1660 }
1661 }
1662
Wink Saville64c42ca2011-04-18 14:55:10 -07001663 class ErrorState extends State {
Erik Kline8351faa2017-04-17 16:47:23 +09001664 private int mErrorNotification;
1665
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001666 @Override
1667 public boolean processMessage(Message message) {
1668 boolean retValue = true;
1669 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001670 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline32179ff2017-07-04 18:28:11 +09001671 TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001672 who.sendMessage(mErrorNotification);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001673 break;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001674 case CMD_CLEAR_ERROR:
1675 mErrorNotification = ConnectivityManager.TETHER_ERROR_NO_ERROR;
1676 transitionTo(mInitialState);
1677 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001678 default:
1679 retValue = false;
1680 }
1681 return retValue;
1682 }
Erik Kline8351faa2017-04-17 16:47:23 +09001683
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001684 void notify(int msgType) {
1685 mErrorNotification = msgType;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001686 for (TetherInterfaceStateMachine sm : mNotifyList) {
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001687 sm.sendMessage(msgType);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001688 }
1689 }
1690
1691 }
Erik Kline8351faa2017-04-17 16:47:23 +09001692
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001693 class SetIpForwardingEnabledErrorState extends ErrorState {
1694 @Override
1695 public void enter() {
1696 Log.e(TAG, "Error in setIpForwardingEnabled");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001697 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001698 }
1699 }
1700
1701 class SetIpForwardingDisabledErrorState extends ErrorState {
1702 @Override
1703 public void enter() {
1704 Log.e(TAG, "Error in setIpForwardingDisabled");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001705 notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001706 }
1707 }
1708
1709 class StartTetheringErrorState extends ErrorState {
1710 @Override
1711 public void enter() {
1712 Log.e(TAG, "Error in startTethering");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001713 notify(TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001714 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001715 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001716 } catch (Exception e) {}
1717 }
1718 }
1719
1720 class StopTetheringErrorState extends ErrorState {
1721 @Override
1722 public void enter() {
1723 Log.e(TAG, "Error in stopTethering");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001724 notify(TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001725 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001726 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001727 } catch (Exception e) {}
1728 }
1729 }
1730
1731 class SetDnsForwardersErrorState extends ErrorState {
1732 @Override
1733 public void enter() {
1734 Log.e(TAG, "Error in setDnsForwarders");
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001735 notify(TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001736 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001737 mNMService.stopTethering();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001738 } catch (Exception e) {}
1739 try {
Chia-chi Yehc9338302011-05-11 16:35:13 -07001740 mNMService.setIpForwardingEnabled(false);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001741 } catch (Exception e) {}
1742 }
1743 }
Erik Klineed962a82017-07-06 19:49:35 +09001744
1745 // A wrapper class to handle multiple situations where several calls to
1746 // the OffloadController need to happen together.
1747 //
1748 // TODO: This suggests that the interface between OffloadController and
1749 // Tethering is in need of improvement. Refactor these calls into the
1750 // OffloadController implementation.
1751 class OffloadWrapper {
1752 public void start() {
1753 mOffloadController.start();
1754 sendOffloadExemptPrefixes();
1755 }
1756
1757 public void stop() {
1758 mOffloadController.stop();
1759 }
1760
1761 public void updateUpstreamNetworkState(NetworkState ns) {
1762 mOffloadController.setUpstreamLinkProperties(
1763 (ns != null) ? ns.linkProperties : null);
1764 }
1765
1766 public void updateDownstreamLinkProperties(LinkProperties newLp) {
1767 // Update the list of offload-exempt prefixes before adding
1768 // new prefixes on downstream interfaces to the offload HAL.
1769 sendOffloadExemptPrefixes();
1770 mOffloadController.notifyDownstreamLinkProperties(newLp);
1771 }
1772
1773 public void excludeDownstreamInterface(String ifname) {
1774 // This and other interfaces may be in local-only hotspot mode;
1775 // resend all local prefixes to the OffloadController.
1776 sendOffloadExemptPrefixes();
1777 mOffloadController.removeDownstreamInterface(ifname);
1778 }
1779
1780 public void sendOffloadExemptPrefixes() {
1781 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
1782 }
1783
1784 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
1785 // Add in well-known minimum set.
1786 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
1787 // Add tragically hardcoded prefixes.
1788 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
1789
1790 // Maybe add prefixes or addresses for downstreams, depending on
1791 // the IP serving mode of each.
1792 for (TetherInterfaceStateMachine tism : mNotifyList) {
1793 final LinkProperties lp = tism.linkProperties();
1794
1795 switch (tism.servingMode()) {
1796 case IControlsTethering.STATE_UNAVAILABLE:
1797 case IControlsTethering.STATE_AVAILABLE:
1798 // No usable LinkProperties in these states.
1799 continue;
1800 case IControlsTethering.STATE_TETHERED:
1801 // Only add IPv4 /32 and IPv6 /128 prefixes. The
1802 // directly-connected prefixes will be sent as
1803 // downstream "offload-able" prefixes.
1804 for (LinkAddress addr : lp.getAllLinkAddresses()) {
1805 final InetAddress ip = addr.getAddress();
1806 if (ip.isLinkLocalAddress()) continue;
1807 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
1808 }
1809 break;
1810 case IControlsTethering.STATE_LOCAL_ONLY:
1811 // Add prefixes covering all local IPs.
1812 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
1813 break;
1814 }
1815 }
1816
1817 mOffloadController.setLocalPrefixes(localPrefixes);
1818 }
1819 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001820 }
1821
Christopher Wiley499a57a2016-05-16 16:19:07 -07001822 @Override
Lorenzo Colittie3805462015-06-03 11:18:24 +09001823 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Christopher Wiley499a57a2016-05-16 16:19:07 -07001824 // Binder.java closes the resource for us.
1825 @SuppressWarnings("resource")
Lorenzo Colittie3805462015-06-03 11:18:24 +09001826 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001827 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001828
Lorenzo Colittie3805462015-06-03 11:18:24 +09001829 pw.println("Tethering:");
1830 pw.increaseIndent();
Lorenzo Colittie3805462015-06-03 11:18:24 +09001831
Erik Kline9db1b542017-03-16 14:10:27 +09001832 pw.println("Configuration:");
1833 pw.increaseIndent();
1834 final TetheringConfiguration cfg = mConfig;
1835 cfg.dump(pw);
1836 pw.decreaseIndent();
1837
1838 synchronized (mPublicSync) {
Robert Greenwaltb4453622011-11-03 16:01:40 -07001839 pw.println("Tether state:");
Lorenzo Colittie3805462015-06-03 11:18:24 +09001840 pw.increaseIndent();
Christopher Wileyd985dde2016-05-31 10:44:35 -07001841 for (int i = 0; i < mTetherStates.size(); i++) {
1842 final String iface = mTetherStates.keyAt(i);
1843 final TetherState tetherState = mTetherStates.valueAt(i);
1844 pw.print(iface + " - ");
1845
Hugo Benichib55fb222017-03-10 14:20:57 +09001846 switch (tetherState.lastState) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001847 case IControlsTethering.STATE_UNAVAILABLE:
1848 pw.print("UnavailableState");
1849 break;
1850 case IControlsTethering.STATE_AVAILABLE:
1851 pw.print("AvailableState");
1852 break;
1853 case IControlsTethering.STATE_TETHERED:
1854 pw.print("TetheredState");
1855 break;
Erik Klineca41be72017-04-20 22:59:16 +09001856 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09001857 pw.print("LocalHotspotState");
1858 break;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001859 default:
1860 pw.print("UnknownState");
1861 break;
1862 }
Hugo Benichib55fb222017-03-10 14:20:57 +09001863 pw.println(" - lastError = " + tetherState.lastError);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001864 }
Erik Klineea9cc482017-03-10 19:35:34 +09001865 pw.println("Upstream wanted: " + upstreamWanted());
Erik Klineee363c42017-05-29 09:11:03 +09001866 pw.println("Current upstream interface: " + mCurrentUpstreamIface);
Lorenzo Colittie3805462015-06-03 11:18:24 +09001867 pw.decreaseIndent();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001868 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09001869
Lorenzo Colittic2519c52017-07-13 01:48:26 +09001870 pw.println("Hardware offload:");
1871 pw.increaseIndent();
1872 mOffloadController.dump(pw);
1873 pw.decreaseIndent();
1874
Erik Kline1fdc2e22017-05-08 17:56:35 +09001875 pw.println("Log:");
1876 pw.increaseIndent();
Erik Kline7747fd42017-05-12 16:52:48 +09001877 if (argsContain(args, SHORT_ARG)) {
1878 pw.println("<log removed for brevity>");
1879 } else {
1880 mLog.dump(fd, pw, args);
1881 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09001882 pw.decreaseIndent();
1883
Lorenzo Colittie3805462015-06-03 11:18:24 +09001884 pw.decreaseIndent();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001885 }
Christopher Wileye03fb442016-05-18 13:45:20 -07001886
Erik Kline7747fd42017-05-12 16:52:48 +09001887 private static boolean argsContain(String[] args, String target) {
1888 for (String arg : args) {
Erik Klineee363c42017-05-29 09:11:03 +09001889 if (target.equals(arg)) return true;
Erik Kline7747fd42017-05-12 16:52:48 +09001890 }
1891 return false;
1892 }
1893
Erik Kline6e9a1012017-06-06 19:24:21 +09001894 private IControlsTethering makeControlCallback(String ifname) {
1895 return new IControlsTethering() {
1896 @Override
1897 public void updateInterfaceState(
1898 TetherInterfaceStateMachine who, int state, int lastError) {
1899 notifyInterfaceStateChange(ifname, who, state, lastError);
1900 }
1901
1902 @Override
1903 public void updateLinkProperties(
1904 TetherInterfaceStateMachine who, LinkProperties newLp) {
1905 notifyLinkPropertiesChanged(ifname, who, newLp);
1906 }
1907 };
1908 }
1909
1910 // TODO: Move into TetherMasterSM.
1911 private void notifyInterfaceStateChange(
1912 String iface, TetherInterfaceStateMachine who, int state, int error) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001913 synchronized (mPublicSync) {
Erik Kline216af6d2017-04-27 20:57:23 +09001914 final TetherState tetherState = mTetherStates.get(iface);
Hugo Benichib55fb222017-03-10 14:20:57 +09001915 if (tetherState != null && tetherState.stateMachine.equals(who)) {
1916 tetherState.lastState = state;
1917 tetherState.lastError = error;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001918 } else {
1919 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
1920 }
1921 }
1922
Erik Kline7747fd42017-05-12 16:52:48 +09001923 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
Christopher Wileyd985dde2016-05-31 10:44:35 -07001924
Christopher Wileydeebfec2016-09-16 11:14:36 -07001925 try {
1926 // Notify that we're tethering (or not) this interface.
1927 // This is how data saver for instance knows if the user explicitly
1928 // turned on tethering (thus keeping us from being in data saver mode).
1929 mPolicyManager.onTetheringChanged(iface, state == IControlsTethering.STATE_TETHERED);
1930 } catch (RemoteException e) {
1931 // Not really very much we can do here.
1932 }
1933
Yohei, Oshima977aad52016-12-08 13:39:20 +09001934 // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
1935 // Thus we give a chance for TetherMasterSM to recover to InitialState
1936 // by sending CMD_CLEAR_ERROR
1937 if (error == ConnectivityManager.TETHER_ERROR_MASTER_ERROR) {
1938 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
1939 }
Erik Klineea9cc482017-03-10 19:35:34 +09001940 int which;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001941 switch (state) {
1942 case IControlsTethering.STATE_UNAVAILABLE:
1943 case IControlsTethering.STATE_AVAILABLE:
Erik Klineea9cc482017-03-10 19:35:34 +09001944 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001945 break;
1946 case IControlsTethering.STATE_TETHERED:
Erik Klineca41be72017-04-20 22:59:16 +09001947 case IControlsTethering.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09001948 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001949 break;
Erik Klineea9cc482017-03-10 19:35:34 +09001950 default:
1951 Log.wtf(TAG, "Unknown interface state: " + state);
1952 return;
Christopher Wileyd985dde2016-05-31 10:44:35 -07001953 }
Erik Klineea9cc482017-03-10 19:35:34 +09001954 mTetherMasterSM.sendMessage(which, state, 0, who);
Christopher Wileyd985dde2016-05-31 10:44:35 -07001955 sendTetherStateChangedBroadcast();
1956 }
1957
Erik Kline6e9a1012017-06-06 19:24:21 +09001958 private void notifyLinkPropertiesChanged(String iface, TetherInterfaceStateMachine who,
1959 LinkProperties newLp) {
1960 final int state;
1961 synchronized (mPublicSync) {
1962 final TetherState tetherState = mTetherStates.get(iface);
1963 if (tetherState != null && tetherState.stateMachine.equals(who)) {
1964 state = tetherState.lastState;
1965 } else {
1966 mLog.log("got notification from stale iface " + iface);
1967 return;
1968 }
1969 }
1970
Erik Kline7fd696c2017-06-12 18:20:08 +09001971 mLog.log(String.format(
1972 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
1973 iface, IControlsTethering.getStateString(state), newLp));
Erik Kline6e9a1012017-06-06 19:24:21 +09001974 final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
1975 mTetherMasterSM.sendMessage(which, state, 0, newLp);
1976 }
1977
Erik Kline4dd9bb82017-04-26 11:11:07 +09001978 private void maybeTrackNewInterfaceLocked(final String iface) {
1979 // If we don't care about this type of interface, ignore.
1980 final int interfaceType = ifaceNameToType(iface);
1981 if (interfaceType == ConnectivityManager.TETHERING_INVALID) {
1982 mLog.log(iface + " is not a tetherable iface, ignoring");
1983 return;
1984 }
Erik Klinea9cde8b2017-06-20 21:18:31 +09001985 maybeTrackNewInterfaceLocked(iface, interfaceType);
1986 }
Erik Kline4dd9bb82017-04-26 11:11:07 +09001987
Erik Klinea9cde8b2017-06-20 21:18:31 +09001988 private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09001989 // If we have already started a TISM for this interface, skip.
1990 if (mTetherStates.containsKey(iface)) {
1991 mLog.log("active iface (" + iface + ") reported as added, ignoring");
1992 return;
1993 }
1994
1995 mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
1996 final TetherState tetherState = new TetherState(
1997 new TetherInterfaceStateMachine(
Erik Kline6e9a1012017-06-06 19:24:21 +09001998 iface, mLooper, interfaceType, mLog, mNMService, mStatsService,
Erik Klinea8e2e792017-06-13 21:32:10 +09001999 makeControlCallback(iface)));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002000 mTetherStates.put(iface, tetherState);
Hugo Benichib55fb222017-03-10 14:20:57 +09002001 tetherState.stateMachine.start();
Christopher Wileye03fb442016-05-18 13:45:20 -07002002 }
Erik Kline3e756652017-01-17 13:42:19 +09002003
Erik Kline4dd9bb82017-04-26 11:11:07 +09002004 private void stopTrackingInterfaceLocked(final String iface) {
2005 final TetherState tetherState = mTetherStates.get(iface);
2006 if (tetherState == null) {
2007 mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
2008 return;
2009 }
Erik Kline6e9a1012017-06-06 19:24:21 +09002010 tetherState.stateMachine.stop();
Erik Kline4dd9bb82017-04-26 11:11:07 +09002011 mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
2012 mTetherStates.remove(iface);
2013 }
2014
Erik Kline3e756652017-01-17 13:42:19 +09002015 private static String[] copy(String[] strarray) {
2016 return Arrays.copyOf(strarray, strarray.length);
2017 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002018}