blob: 3695ec65d5c09f629307eeaf5c98804fbdc56f29 [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
markchien503be612020-04-12 21:41:29 +080017package com.android.networkstack.tethering;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080018
Chiachang Wang96ca8e92020-02-21 17:50:18 +080019import static android.Manifest.permission.NETWORK_SETTINGS;
20import static android.Manifest.permission.NETWORK_STACK;
markchien0ed433e2020-06-03 12:27:37 +080021import static android.content.pm.PackageManager.GET_ACTIVITIES;
markchienae8aa642019-12-16 20:15:20 +080022import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Erik Klinec438e302017-07-04 22:02:49 +090023import static android.hardware.usb.UsbManager.USB_CONFIGURED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090024import static android.hardware.usb.UsbManager.USB_CONNECTED;
Milim Lee31ef4c02019-10-17 05:02:33 +090025import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
Erik Kline2e88b5e2017-01-18 11:57:45 +090026import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
markchien3fe660b2019-12-05 12:04:59 +080027import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
Erik Kline7a26ba32018-03-09 14:18:02 +090028import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Erik Kline7a26ba32018-03-09 14:18:02 +090029import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +090030import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
markchien9e44cde2019-12-25 19:40:32 +080031import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
32import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
33import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
34import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
35import static android.net.TetheringManager.EXTRA_ERRORED_TETHER;
36import static android.net.TetheringManager.TETHERING_BLUETOOTH;
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +090037import static android.net.TetheringManager.TETHERING_ETHERNET;
markchien9e44cde2019-12-25 19:40:32 +080038import static android.net.TetheringManager.TETHERING_INVALID;
Milim Lee31ef4c02019-10-17 05:02:33 +090039import static android.net.TetheringManager.TETHERING_NCM;
markchien9e44cde2019-12-25 19:40:32 +080040import static android.net.TetheringManager.TETHERING_USB;
41import static android.net.TetheringManager.TETHERING_WIFI;
42import static android.net.TetheringManager.TETHERING_WIFI_P2P;
Dedy Lansky04bef3c2019-11-21 00:36:14 +020043import static android.net.TetheringManager.TETHERING_WIGIG;
markchien62a625d2020-03-19 13:37:43 +080044import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
markchien9e44cde2019-12-25 19:40:32 +080045import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
46import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
47import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
48import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
markchien62a625d2020-03-19 13:37:43 +080049import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +000050import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
51import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
52import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
markchien986750b2019-12-06 15:24:53 +080053import static android.net.util.TetheringMessageBase.BASE_MASTER;
Erik Kline2efb8272017-05-31 15:53:53 +090054import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
55import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
Erik Kline2e88b5e2017-01-18 11:57:45 +090056import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
Erik Kline2efb8272017-05-31 15:53:53 +090057import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
58import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
59import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
60import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090061import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
Erik Klinede637722017-10-12 22:16:01 +090062import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
markchien04bdf872019-06-17 21:05:34 +080063import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
markchienb6eb2c22018-07-18 14:29:20 +080064
markchien503be612020-04-12 21:41:29 +080065import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +000066
Nucca Chen3f856b42020-06-17 07:03:39 +000067import android.app.usage.NetworkStatsManager;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080068import android.bluetooth.BluetoothAdapter;
69import android.bluetooth.BluetoothPan;
70import android.bluetooth.BluetoothProfile;
71import android.bluetooth.BluetoothProfile.ServiceListener;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080072import android.content.BroadcastReceiver;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080073import android.content.Context;
74import android.content.Intent;
75import android.content.IntentFilter;
markchien0ed433e2020-06-03 12:27:37 +080076import android.content.pm.PackageManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080077import android.hardware.usb.UsbManager;
markchien3fe660b2019-12-05 12:04:59 +080078import android.net.ConnectivityManager;
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +090079import android.net.EthernetManager;
markchiene8b9d752020-01-20 19:31:56 +080080import android.net.IIntResultListener;
markchien0f63ca62019-09-30 14:40:57 +080081import android.net.INetd;
markchienae8aa642019-12-16 20:15:20 +080082import android.net.ITetheringEventCallback;
Erik Kline3a5278f2017-06-24 19:29:10 +090083import android.net.IpPrefix;
Erik Klineed962a82017-07-06 19:49:35 +090084import android.net.LinkAddress;
Robert Greenwalt05d89362011-01-23 16:04:05 -080085import android.net.LinkProperties;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070086import android.net.Network;
Chalard Jeanc0fc2762020-04-17 17:12:44 +000087import android.net.NetworkCapabilities;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080088import android.net.NetworkInfo;
markchien0f63ca62019-09-30 14:40:57 +080089import android.net.TetherStatesParcel;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +090090import android.net.TetheredClient;
markchien40898ca2020-01-21 13:11:06 +080091import android.net.TetheringCallbackStartedParcel;
markchien0f63ca62019-09-30 14:40:57 +080092import android.net.TetheringConfigurationParcel;
markchiene8b9d752020-01-20 19:31:56 +080093import android.net.TetheringRequestParcel;
markchienb6eb2c22018-07-18 14:29:20 +080094import android.net.ip.IpServer;
markchiena9d9ef82020-01-07 14:43:17 +080095import android.net.shared.NetdUtils;
markchien0f63ca62019-09-30 14:40:57 +080096import android.net.util.BaseNetdUnsolicitedEventListener;
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +090097import android.net.util.InterfaceSet;
Erik Kline32179ff2017-07-04 18:28:11 +090098import android.net.util.PrefixUtils;
Erik Kline7747fd42017-05-12 16:52:48 +090099import android.net.util.SharedLog;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000100import android.net.util.TetheringUtils;
Erik Klinede637722017-10-12 22:16:01 +0900101import android.net.util.VersionedBroadcastListener;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900102import android.net.wifi.WifiClient;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800103import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800104import android.net.wifi.p2p.WifiP2pGroup;
105import android.net.wifi.p2p.WifiP2pInfo;
106import android.net.wifi.p2p.WifiP2pManager;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800107import android.os.Binder;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800108import android.os.Bundle;
Erik Klinef4b6e342017-04-25 19:19:59 +0900109import android.os.Handler;
Robert Greenwaltdfadaea2010-03-11 15:03:08 -0800110import android.os.Looper;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800111import android.os.Message;
markchienae8aa642019-12-16 20:15:20 +0800112import android.os.RemoteCallbackList;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700113import android.os.RemoteException;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800114import android.os.ResultReceiver;
markchiena9d9ef82020-01-07 14:43:17 +0800115import android.os.ServiceSpecificException;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700116import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100117import android.os.UserManager;
markchiencb8860c2020-05-12 00:08:27 +0800118import android.provider.Settings;
markchien04bdf872019-06-17 21:05:34 +0800119import android.telephony.PhoneStateListener;
120import android.telephony.TelephonyManager;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900121import android.text.TextUtils;
Christopher Wileye9490392016-05-26 15:57:29 -0700122import android.util.ArrayMap;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800123import android.util.Log;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900124import android.util.SparseArray;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800125
markchiena9d9ef82020-01-07 14:43:17 +0800126import androidx.annotation.NonNull;
127import androidx.annotation.Nullable;
128
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900129import com.android.internal.annotations.GuardedBy;
Christopher Wiley497c1472016-10-11 13:26:03 -0700130import com.android.internal.annotations.VisibleForTesting;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800131import com.android.internal.util.IndentingPrintWriter;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900132import com.android.internal.util.MessageUtils;
Wink Saville64c42ca2011-04-18 14:55:10 -0700133import com.android.internal.util.State;
134import com.android.internal.util.StateMachine;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800135
136import java.io.FileDescriptor;
137import java.io.PrintWriter;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800138import java.net.InetAddress;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800139import java.util.ArrayList;
Lorenzo Colittib57edc52014-08-22 17:10:50 -0700140import java.util.Arrays;
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700141import java.util.Collection;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900142import java.util.Collections;
markchien0f63ca62019-09-30 14:40:57 +0800143import java.util.Iterator;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900144import java.util.LinkedHashSet;
145import java.util.List;
Erik Kline3a5278f2017-06-24 19:29:10 +0900146import java.util.Set;
markchien986750b2019-12-06 15:24:53 +0800147import java.util.concurrent.Executor;
148import java.util.concurrent.RejectedExecutionException;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -0800149
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800150/**
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800151 *
Christopher Wiley3b1d9222016-05-20 16:44:04 -0700152 * This class holds much of the business logic to allow Android devices
153 * to act as IP gateways via USB, BT, and WiFi interfaces.
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800154 */
markchien0f63ca62019-09-30 14:40:57 +0800155public class Tethering {
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800156
markchien0f63ca62019-09-30 14:40:57 +0800157 private static final String TAG = Tethering.class.getSimpleName();
158 private static final boolean DBG = false;
159 private static final boolean VDBG = false;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800160
markchien0f63ca62019-09-30 14:40:57 +0800161 private static final Class[] sMessageClasses = {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900162 Tethering.class, TetherMasterSM.class, IpServer.class
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900163 };
164 private static final SparseArray<String> sMagicDecoderRing =
markchien0f63ca62019-09-30 14:40:57 +0800165 MessageUtils.findMessageNames(sMessageClasses);
markchiena9d9ef82020-01-07 14:43:17 +0800166 // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
167 private static final int NETID_UNSET = 0;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900168
Hugo Benichib55fb222017-03-10 14:20:57 +0900169 private static class TetherState {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900170 public final IpServer ipServer;
Hugo Benichib55fb222017-03-10 14:20:57 +0900171 public int lastState;
172 public int lastError;
Erik Klineea9cc482017-03-10 19:35:34 +0900173
markchien0f63ca62019-09-30 14:40:57 +0800174 TetherState(IpServer ipServer) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900175 this.ipServer = ipServer;
Hugo Benichib55fb222017-03-10 14:20:57 +0900176 // Assume all state machines start out available and with no errors.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900177 lastState = IpServer.STATE_AVAILABLE;
Erik Kline7a26ba32018-03-09 14:18:02 +0900178 lastError = TETHER_ERROR_NO_ERROR;
Hugo Benichib55fb222017-03-10 14:20:57 +0900179 }
Erik Klineea9cc482017-03-10 19:35:34 +0900180
181 public boolean isCurrentlyServing() {
182 switch (lastState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900183 case IpServer.STATE_TETHERED:
184 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +0900185 return true;
186 default:
187 return false;
188 }
189 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900190 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700191
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900192 /**
193 * Cookie added when registering {@link android.net.TetheringManager.TetheringEventCallback}.
194 */
195 private static class CallbackCookie {
196 public final boolean hasListClientsPermission;
197
198 private CallbackCookie(boolean hasListClientsPermission) {
199 this.hasListClientsPermission = hasListClientsPermission;
200 }
201 }
202
Erik Kline7747fd42017-05-12 16:52:48 +0900203 private final SharedLog mLog = new SharedLog(TAG);
markchienae8aa642019-12-16 20:15:20 +0800204 private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
205 new RemoteCallbackList<>();
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000206 // Currently active tethering requests per tethering type. Only one of each type can be
207 // requested at a time. After a tethering type is requested, the map keeps tethering parameters
208 // to be used after the interface comes up asynchronously.
209 private final SparseArray<TetheringRequestParcel> mActiveTetheringRequests =
210 new SparseArray<>();
Erik Kline1fdc2e22017-05-08 17:56:35 +0900211
Robert Greenwaltb4453622011-11-03 16:01:40 -0700212 // used to synchronize public access to members
Mark Chiendb6befb2020-05-29 22:07:37 +0000213 // TODO(b/153621704): remove mPublicSync to make Tethering lock free
Erik Kline6ff17f72015-12-10 20:42:12 +0900214 private final Object mPublicSync;
Hugo Benichib55fb222017-03-10 14:20:57 +0900215 private final Context mContext;
216 private final ArrayMap<String, TetherState> mTetherStates;
217 private final BroadcastReceiver mStateReceiver;
Erik Kline6ff17f72015-12-10 20:42:12 +0900218 private final Looper mLooper;
Erik Kline6ff17f72015-12-10 20:42:12 +0900219 private final StateMachine mTetherMasterSM;
Erik Klinee0cce212017-03-06 14:05:23 +0900220 private final OffloadController mOffloadController;
Erik Kline6ff17f72015-12-10 20:42:12 +0900221 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
Erik Kline6e9a1012017-06-06 19:24:21 +0900222 // TODO: Figure out how to merge this and other downstream-tracking objects
223 // into a single coherent structure.
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900224 // Use LinkedHashSet for predictable ordering order for ConnectedClientsTracker.
225 private final LinkedHashSet<IpServer> mForwardedDownstreams;
Erik Klinede637722017-10-12 22:16:01 +0900226 private final VersionedBroadcastListener mCarrierConfigChange;
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900227 private final TetheringDependencies mDeps;
markchienb6eb2c22018-07-18 14:29:20 +0800228 private final EntitlementManager mEntitlementMgr;
markchien26299ed2019-02-27 14:56:11 +0800229 private final Handler mHandler;
markchien0f63ca62019-09-30 14:40:57 +0800230 private final INetd mNetd;
231 private final NetdCallback mNetdCallback;
markchien1ddfba42019-11-27 21:20:33 +0800232 private final UserRestrictionActionListener mTetheringRestriction;
markchien986750b2019-12-06 15:24:53 +0800233 private final ActiveDataSubIdListener mActiveDataSubIdListener;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900234 private final ConnectedClientsTracker mConnectedClientsTracker;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000235 private final TetheringThreadExecutor mExecutor;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000236 private final TetheringNotificationUpdater mNotificationUpdater;
markchiencb8860c2020-05-12 00:08:27 +0800237 private final UserManager mUserManager;
Hungming Chenbe4827d2020-06-02 00:13:26 +0000238 private final BpfCoordinator mBpfCoordinator;
Mark Chiendb6befb2020-05-29 22:07:37 +0000239 private final PrivateAddressCoordinator mPrivateAddressCoordinator;
markchien04bdf872019-06-17 21:05:34 +0800240 private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
markchienae8aa642019-12-16 20:15:20 +0800241 // All the usage of mTetheringEventCallback should run in the same thread.
242 private ITetheringEventCallback mTetheringEventCallback = null;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800243
Hugo Benichib55fb222017-03-10 14:20:57 +0900244 private volatile TetheringConfiguration mConfig;
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +0900245 private InterfaceSet mCurrentUpstreamIfaceSet;
Erik Klineea9cc482017-03-10 19:35:34 +0900246
Mike Lockwood6c2260b2011-07-19 13:04:47 -0700247 private boolean mRndisEnabled; // track the RNDIS function enabled state
Erik Kline6e9a1012017-06-06 19:24:21 +0900248 // True iff. WiFi tethering should be started when soft AP is ready.
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700249 private boolean mWifiTetherRequested;
markchien26299ed2019-02-27 14:56:11 +0800250 private Network mTetherUpstream;
markchien0f63ca62019-09-30 14:40:57 +0800251 private TetherStatesParcel mTetherStatesParcel;
markchien3fe660b2019-12-05 12:04:59 +0800252 private boolean mDataSaverEnabled = false;
Jimmy Chen151384d2019-12-03 11:37:09 +0800253 private String mWifiP2pTetherInterface = null;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000254 private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700255
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900256 @GuardedBy("mPublicSync")
257 private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest;
258 @GuardedBy("mPublicSync")
259 private String mConfiguredEthernetIface;
260 @GuardedBy("mPublicSync")
261 private EthernetCallback mEthernetCallback;
262
markchien0f63ca62019-09-30 14:40:57 +0800263 public Tethering(TetheringDependencies deps) {
264 mLog.mark("Tethering.constructed");
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900265 mDeps = deps;
markchien0f63ca62019-09-30 14:40:57 +0800266 mContext = mDeps.getContext();
markchien0f63ca62019-09-30 14:40:57 +0800267 mNetd = mDeps.getINetd(mContext);
268 mLooper = mDeps.getTetheringLooper();
Paul Hu77fa8d62020-04-16 02:54:37 +0000269 mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800270
Robert Greenwaltb4453622011-11-03 16:01:40 -0700271 mPublicSync = new Object();
272
Christopher Wileyd985dde2016-05-31 10:44:35 -0700273 mTetherStates = new ArrayMap<>();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900274 mConnectedClientsTracker = new ConnectedClientsTracker();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800275
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900276 mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800277 mTetherMasterSM.start();
278
markchien26299ed2019-02-27 14:56:11 +0800279 mHandler = mTetherMasterSM.getHandler();
Mark Chien66b9a4a2020-05-07 03:49:42 +0000280 mOffloadController = mDeps.getOffloadController(mHandler, mLog,
281 new OffloadController.Dependencies() {
Junyu Lai833f4f62020-05-05 10:45:38 +0000282
283 @Override
284 public TetheringConfiguration getTetherConfig() {
285 return mConfig;
286 }
287 });
markchiena9d9ef82020-01-07 14:43:17 +0800288 mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900289 TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900290 mForwardedDownstreams = new LinkedHashSet<>();
Erik Klinede637722017-10-12 22:16:01 +0900291
292 IntentFilter filter = new IntentFilter();
293 filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
markchien3b519632018-09-07 16:19:12 +0800294 // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
295 // permission is changed according to entitlement check result.
Mark Chien47430c02020-05-08 11:00:42 +0000296 mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
297 () -> mTetherMasterSM.sendMessage(
298 TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
markchien29b70142019-03-26 21:41:59 +0800299 mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
300 mLog.log("OBSERVED UiEnitlementFailed");
301 stopTethering(downstream);
302 });
markchien3394e142019-04-09 15:53:24 +0800303 mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
markchien3394e142019-04-09 15:53:24 +0800304 return mConfig;
305 });
markchien3b519632018-09-07 16:19:12 +0800306
Erik Klinede637722017-10-12 22:16:01 +0900307 mCarrierConfigChange = new VersionedBroadcastListener(
markchien26299ed2019-02-27 14:56:11 +0800308 "CarrierConfigChangeListener", mContext, mHandler, filter,
Erik Klinede637722017-10-12 22:16:01 +0900309 (Intent ignored) -> {
310 mLog.log("OBSERVED carrier config change");
Erik Kline80b7a9f2018-02-28 15:01:35 +0900311 updateConfiguration();
markchien3394e142019-04-09 15:53:24 +0800312 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
Erik Klinede637722017-10-12 22:16:01 +0900313 });
Erik Kline6ff17f72015-12-10 20:42:12 +0900314
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800315 mStateReceiver = new StateReceiver();
Erik Kline80b7a9f2018-02-28 15:01:35 +0900316
markchiencb8860c2020-05-12 00:08:27 +0800317 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Paul Huf950dc92020-03-25 12:39:13 +0000318 mTetheringRestriction = new UserRestrictionActionListener(
markchiencb8860c2020-05-12 00:08:27 +0800319 mUserManager, this, mNotificationUpdater);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000320 mExecutor = new TetheringThreadExecutor(mHandler);
321 mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
Mark Chien674a0122020-03-27 09:37:01 +0000322 mNetdCallback = new NetdCallback();
Mark Chiendb6befb2020-05-29 22:07:37 +0000323 mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext);
markchien1ddfba42019-11-27 21:20:33 +0800324
Erik Kline80b7a9f2018-02-28 15:01:35 +0900325 // Load tethering configuration.
326 updateConfiguration();
markchiencb8860c2020-05-12 00:08:27 +0800327
Nucca Chen3f856b42020-06-17 07:03:39 +0000328 // Must be initialized after tethering configuration is loaded because BpfCoordinator
329 // constructor needs to use the configuration.
330 mBpfCoordinator = mDeps.getBpfCoordinator(
331 new BpfCoordinator.Dependencies() {
332 @NonNull
333 public Handler getHandler() {
334 return mHandler;
335 }
336
337 @NonNull
338 public INetd getNetd() {
339 return mNetd;
340 }
341
342 @NonNull
343 public NetworkStatsManager getNetworkStatsManager() {
Nucca Chen1c63ba32020-06-17 07:03:57 +0000344 return mContext.getSystemService(NetworkStatsManager.class);
Nucca Chen3f856b42020-06-17 07:03:39 +0000345 }
346
347 @NonNull
348 public SharedLog getSharedLog() {
349 return mLog;
350 }
351
352 @Nullable
353 public TetheringConfiguration getTetherConfig() {
354 return mConfig;
355 }
356 });
357
markchiencb8860c2020-05-12 00:08:27 +0800358 startStateMachineUpdaters();
Mark Chien674a0122020-03-27 09:37:01 +0000359 }
360
361 /**
362 * Start to register callbacks.
363 * Call this function when tethering is ready to handle callback events.
364 */
markchiencb8860c2020-05-12 00:08:27 +0800365 private void startStateMachineUpdaters() {
markchiene67c5642020-02-06 15:25:47 +0800366 try {
367 mNetd.registerUnsolicitedEventListener(mNetdCallback);
368 } catch (RemoteException e) {
369 mLog.e("Unable to register netd UnsolicitedEventListener");
370 }
Erik Kline80b7a9f2018-02-28 15:01:35 +0900371 mCarrierConfigChange.startListening();
markchien986750b2019-12-06 15:24:53 +0800372 mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
373 PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
Erik Kline80b7a9f2018-02-28 15:01:35 +0900374
Erik Kline80b7a9f2018-02-28 15:01:35 +0900375 IntentFilter filter = new IntentFilter();
Mike Lockwood770126a2010-12-09 22:30:37 -0800376 filter.addAction(UsbManager.ACTION_USB_STATE);
Erik Kline7a26ba32018-03-09 14:18:02 +0900377 filter.addAction(CONNECTIVITY_ACTION);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700378 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700379 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800380 filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
markchien1ddfba42019-11-27 21:20:33 +0800381 filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
markchien3fe660b2019-12-05 12:04:59 +0800382 filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
Mark Chien674a0122020-03-27 09:37:01 +0000383 mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
384
Paul Hu77fa8d62020-04-16 02:54:37 +0000385 final IntentFilter noUpstreamFilter = new IntentFilter();
386 noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING);
387 mContext.registerReceiver(
388 mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler);
389
Mark Chien674a0122020-03-27 09:37:01 +0000390 final WifiManager wifiManager = getWifiManager();
391 if (wifiManager != null) {
392 wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
393 }
394
395 startTrackDefaultNetwork();
Robert Greenwalt49348e72011-10-21 16:54:26 -0700396 }
397
markchien986750b2019-12-06 15:24:53 +0800398 private class TetheringThreadExecutor implements Executor {
399 private final Handler mTetherHandler;
400 TetheringThreadExecutor(Handler handler) {
401 mTetherHandler = handler;
402 }
403 @Override
404 public void execute(Runnable command) {
405 if (!mTetherHandler.post(command)) {
406 throw new RejectedExecutionException(mTetherHandler + " is shutting down");
407 }
408 }
409 }
410
411 private class ActiveDataSubIdListener extends PhoneStateListener {
412 ActiveDataSubIdListener(Executor executor) {
413 super(executor);
414 }
415
416 @Override
417 public void onActiveDataSubscriptionIdChanged(int subId) {
418 mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
419 + " to " + subId);
420 if (subId == mActiveDataSubId) return;
421
422 mActiveDataSubId = subId;
423 updateConfiguration();
Paul Hu274cc1c2020-03-25 06:22:43 +0000424 mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
markchien986750b2019-12-06 15:24:53 +0800425 // To avoid launching unexpected provisioning checks, ignore re-provisioning
426 // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
Paul Hu274cc1c2020-03-25 06:22:43 +0000427 // will be triggered again when CarrierConfig is loaded.
markchien986750b2019-12-06 15:24:53 +0800428 if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
429 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
430 } else {
431 mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
432 }
433 }
434 }
435
Erik Kline216af6d2017-04-27 20:57:23 +0900436 private WifiManager getWifiManager() {
437 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
438 }
439
Erik Kline93c4afa2017-06-04 11:36:01 +0900440 // NOTE: This is always invoked on the mLooper thread.
Erik Klined781fba2017-01-23 13:01:58 +0900441 private void updateConfiguration() {
markchien04bdf872019-06-17 21:05:34 +0800442 mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
markchien3394e142019-04-09 15:53:24 +0800443 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
markchien0f63ca62019-09-30 14:40:57 +0800444 reportConfigurationChanged(mConfig.toStableParcelable());
markchien3394e142019-04-09 15:53:24 +0800445 }
446
447 private void maybeDunSettingChanged() {
markchien986750b2019-12-06 15:24:53 +0800448 final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
markchiendb3a2362018-10-05 12:36:08 +0800449 if (isDunRequired == mConfig.isDunRequired) return;
Erik Kline6ee73da2017-07-08 20:36:37 +0900450 updateConfiguration();
451 }
452
markchien0f63ca62019-09-30 14:40:57 +0800453 private class NetdCallback extends BaseNetdUnsolicitedEventListener {
454 @Override
455 public void onInterfaceChanged(String ifName, boolean up) {
456 mHandler.post(() -> interfaceStatusChanged(ifName, up));
457 }
458
459 @Override
460 public void onInterfaceLinkStateChanged(String ifName, boolean up) {
461 mHandler.post(() -> interfaceLinkStateChanged(ifName, up));
462 }
463
464 @Override
465 public void onInterfaceAdded(String ifName) {
466 mHandler.post(() -> interfaceAdded(ifName));
467 }
468
469 @Override
470 public void onInterfaceRemoved(String ifName) {
471 mHandler.post(() -> interfaceRemoved(ifName));
472 }
473 }
474
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900475 private class TetheringSoftApCallback implements WifiManager.SoftApCallback {
476 // TODO: Remove onStateChanged override when this method has default on
477 // WifiManager#SoftApCallback interface.
478 // Wifi listener for state change of the soft AP
479 @Override
480 public void onStateChanged(final int state, final int failureReason) {
481 // Nothing
482 }
483
484 // Called by wifi when the number of soft AP clients changed.
485 @Override
486 public void onConnectedClientsChanged(final List<WifiClient> clients) {
Treehugger Robot25067812020-03-25 15:32:41 +0000487 updateConnectedClients(clients);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900488 }
489 }
490
markchien0f63ca62019-09-30 14:40:57 +0800491 void interfaceStatusChanged(String iface, boolean up) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900492 // Never called directly: only called from interfaceLinkStateChanged.
markchien0f63ca62019-09-30 14:40:57 +0800493 // See NetlinkHandler.cpp: notifyInterfaceChanged.
Wink Savillec9acde92011-09-21 11:05:43 -0700494 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700495 synchronized (mPublicSync) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700496 if (up) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900497 maybeTrackNewInterfaceLocked(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800498 } else {
Dedy Lansky04bef3c2019-11-21 00:36:14 +0200499 if (ifaceNameToType(iface) == TETHERING_BLUETOOTH
500 || ifaceNameToType(iface) == TETHERING_WIGIG) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900501 stopTrackingInterfaceLocked(iface);
Christopher Wileyd30aaeb2016-07-08 09:33:50 -0700502 } else {
503 // Ignore usb0 down after enabling RNDIS.
504 // We will handle disconnect in interfaceRemoved.
505 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status
506 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
507 if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800508 }
509 }
510 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800511 }
512
markchien0f63ca62019-09-30 14:40:57 +0800513 void interfaceLinkStateChanged(String iface, boolean up) {
Irfan Sheriff23eb2972011-07-22 15:21:10 -0700514 interfaceStatusChanged(iface, up);
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700515 }
516
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700517 private int ifaceNameToType(String iface) {
Erik Kline3e756652017-01-17 13:42:19 +0900518 final TetheringConfiguration cfg = mConfig;
519
520 if (cfg.isWifi(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900521 return TETHERING_WIFI;
Dedy Lansky04bef3c2019-11-21 00:36:14 +0200522 } else if (cfg.isWigig(iface)) {
523 return TETHERING_WIGIG;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800524 } else if (cfg.isWifiP2p(iface)) {
525 return TETHERING_WIFI_P2P;
Erik Kline3e756652017-01-17 13:42:19 +0900526 } else if (cfg.isUsb(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900527 return TETHERING_USB;
Erik Kline3e756652017-01-17 13:42:19 +0900528 } else if (cfg.isBluetooth(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900529 return TETHERING_BLUETOOTH;
Milim Lee31ef4c02019-10-17 05:02:33 +0900530 } else if (cfg.isNcm(iface)) {
531 return TETHERING_NCM;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700532 }
Erik Kline7a26ba32018-03-09 14:18:02 +0900533 return TETHERING_INVALID;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700534 }
535
markchien0f63ca62019-09-30 14:40:57 +0800536 void interfaceAdded(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700537 if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700538 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900539 maybeTrackNewInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800540 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800541 }
542
markchien0f63ca62019-09-30 14:40:57 +0800543 void interfaceRemoved(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700544 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700545 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900546 stopTrackingInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800547 }
548 }
549
markchiene8b9d752020-01-20 19:31:56 +0800550 void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000551 mHandler.post(() -> {
552 final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
553 request.tetheringType);
554 // If tethering is already enabled with a different request,
555 // disable before re-enabling.
556 if (unfinishedRequest != null
557 && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {
558 enableTetheringInternal(request.tetheringType, false /* disabled */, null);
559 mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);
560 }
561 mActiveTetheringRequests.put(request.tetheringType, request);
562
markchien5788f2a2020-05-08 18:55:26 +0800563 if (request.exemptFromEntitlementCheck) {
564 mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);
565 } else {
566 mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
567 request.showProvisioningUi);
568 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000569 enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
570 });
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800571 }
572
markchien0f63ca62019-09-30 14:40:57 +0800573 void stopTethering(int type) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000574 mHandler.post(() -> {
575 mActiveTetheringRequests.remove(type);
576
577 enableTetheringInternal(type, false /* disabled */, null);
578 mEntitlementMgr.stopProvisioningIfNeeded(type);
579 });
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800580 }
581
582 /**
markchien3b519632018-09-07 16:19:12 +0800583 * Enables or disables tethering for the given type. If provisioning is required, it will
584 * schedule provisioning rechecks for the specified interface.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800585 */
markchiene8b9d752020-01-20 19:31:56 +0800586 private void enableTetheringInternal(int type, boolean enable,
587 final IIntResultListener listener) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000588 int result = TETHER_ERROR_NO_ERROR;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800589 switch (type) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900590 case TETHERING_WIFI:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700591 result = setWifiTethering(enable);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800592 break;
Erik Kline7a26ba32018-03-09 14:18:02 +0900593 case TETHERING_USB:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700594 result = setUsbTethering(enable);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800595 break;
Erik Kline7a26ba32018-03-09 14:18:02 +0900596 case TETHERING_BLUETOOTH:
markchiene8b9d752020-01-20 19:31:56 +0800597 setBluetoothTethering(enable, listener);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800598 break;
Milim Lee31ef4c02019-10-17 05:02:33 +0900599 case TETHERING_NCM:
600 result = setNcmTethering(enable);
Milim Lee31ef4c02019-10-17 05:02:33 +0900601 break;
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900602 case TETHERING_ETHERNET:
603 result = setEthernetTethering(enable);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900604 break;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800605 default:
606 Log.w(TAG, "Invalid tether type.");
markchien62a625d2020-03-19 13:37:43 +0800607 result = TETHER_ERROR_UNKNOWN_TYPE;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000608 }
609
610 // The result of Bluetooth tethering will be sent by #setBluetoothTethering.
611 if (type != TETHERING_BLUETOOTH) {
612 sendTetherResult(listener, result, type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800613 }
614 }
615
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000616 private void sendTetherResult(final IIntResultListener listener, final int result,
617 final int type) {
markchiene8b9d752020-01-20 19:31:56 +0800618 if (listener != null) {
619 try {
620 listener.onResult(result);
621 } catch (RemoteException e) { }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800622 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000623
624 // If changing tethering fail, remove corresponding request
625 // no matter who trigger the start/stop.
626 if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800627 }
628
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700629 private int setWifiTethering(final boolean enable) {
Erik Kline256be782017-04-29 13:20:04 +0900630 final long ident = Binder.clearCallingIdentity();
631 try {
632 synchronized (mPublicSync) {
Erik Kline256be782017-04-29 13:20:04 +0900633 final WifiManager mgr = getWifiManager();
Ye Jiao21f96252019-01-28 12:54:22 +0800634 if (mgr == null) {
635 mLog.e("setWifiTethering: failed to get WifiManager!");
636 return TETHER_ERROR_SERVICE_UNAVAIL;
637 }
lesl6b7551a2019-12-13 10:56:35 +0800638 if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */))
markchien0f63ca62019-09-30 14:40:57 +0800639 || (!enable && mgr.stopSoftAp())) {
Ye Jiao21f96252019-01-28 12:54:22 +0800640 mWifiTetherRequested = enable;
641 return TETHER_ERROR_NO_ERROR;
Erik Kline256be782017-04-29 13:20:04 +0900642 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700643 }
Erik Kline256be782017-04-29 13:20:04 +0900644 } finally {
645 Binder.restoreCallingIdentity(ident);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700646 }
Ye Jiao21f96252019-01-28 12:54:22 +0800647
markchien62a625d2020-03-19 13:37:43 +0800648 return TETHER_ERROR_INTERNAL_ERROR;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700649 }
650
markchiene8b9d752020-01-20 19:31:56 +0800651 private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
markchien3fe660b2019-12-05 12:04:59 +0800652 final BluetoothAdapter adapter = mDeps.getBluetoothAdapter();
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800653 if (adapter == null || !adapter.isEnabled()) {
markchien0f63ca62019-09-30 14:40:57 +0800654 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
655 + (adapter == null));
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000656 sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800657 return;
658 }
659
660 adapter.getProfileProxy(mContext, new ServiceListener() {
661 @Override
662 public void onServiceDisconnected(int profile) { }
663
664 @Override
665 public void onServiceConnected(int profile, BluetoothProfile proxy) {
markchien560c3ac2019-08-16 15:33:28 +0800666 // Clear identify is fine because caller already pass tethering permission at
667 // ConnectivityService#startTethering()(or stopTethering) before the control comes
668 // here. Bluetooth will check tethering permission again that there is
669 // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
670 // caller's package name for permission check.
671 // Calling BluetoothPan#setBluetoothTethering() here means the package name always
672 // be system server. If calling identity is not cleared, that package's uid might
673 // not match calling uid and end up in permission denied.
674 final long identityToken = Binder.clearCallingIdentity();
675 try {
676 ((BluetoothPan) proxy).setBluetoothTethering(enable);
677 } finally {
678 Binder.restoreCallingIdentity(identityToken);
679 }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800680 // TODO: Enabling bluetooth tethering can fail asynchronously here.
681 // We should figure out a way to bubble up that failure instead of sending success.
Erik Kline7a26ba32018-03-09 14:18:02 +0900682 final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
683 ? TETHER_ERROR_NO_ERROR
markchien62a625d2020-03-19 13:37:43 +0800684 : TETHER_ERROR_INTERNAL_ERROR;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000685 sendTetherResult(listener, result, TETHERING_BLUETOOTH);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800686 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
687 }
688 }, BluetoothProfile.PAN);
689 }
690
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900691 private int setEthernetTethering(final boolean enable) {
692 final EthernetManager em = (EthernetManager) mContext.getSystemService(
693 Context.ETHERNET_SERVICE);
694 synchronized (mPublicSync) {
695 if (enable) {
Treehugger Robot191a03c2020-03-24 15:23:51 +0000696 if (mEthernetCallback != null) {
697 Log.d(TAG, "Ethernet tethering already started");
698 return TETHER_ERROR_NO_ERROR;
699 }
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000700
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900701 mEthernetCallback = new EthernetCallback();
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000702 mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900703 } else {
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000704 stopEthernetTetheringLocked();
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900705 }
706 }
707 return TETHER_ERROR_NO_ERROR;
708 }
709
710 private void stopEthernetTetheringLocked() {
Treehugger Robot41c81242020-03-19 15:23:45 +0000711 if (mConfiguredEthernetIface != null) {
712 stopTrackingInterfaceLocked(mConfiguredEthernetIface);
713 mConfiguredEthernetIface = null;
714 }
715 if (mEthernetCallback != null) {
716 mEthernetIfaceRequest.release();
717 mEthernetCallback = null;
718 mEthernetIfaceRequest = null;
719 }
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900720 }
721
722 private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback {
723 @Override
724 public void onAvailable(String iface) {
725 synchronized (mPublicSync) {
726 if (this != mEthernetCallback) {
727 // Ethernet callback arrived after Ethernet tethering stopped. Ignore.
728 return;
729 }
730 maybeTrackNewInterfaceLocked(iface, TETHERING_ETHERNET);
731 changeInterfaceState(iface, IpServer.STATE_TETHERED);
732 mConfiguredEthernetIface = iface;
733 }
734 }
735
736 @Override
737 public void onUnavailable() {
738 synchronized (mPublicSync) {
739 if (this != mEthernetCallback) {
740 // onAvailable called after stopping Ethernet tethering.
741 return;
742 }
743 stopEthernetTetheringLocked();
744 }
745 }
746 }
747
markchien0f63ca62019-09-30 14:40:57 +0800748 int tether(String iface) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900749 return tether(iface, IpServer.STATE_TETHERED);
Erik Klineea9cc482017-03-10 19:35:34 +0900750 }
751
752 private int tether(String iface, int requestedState) {
Wink Savillec9acde92011-09-21 11:05:43 -0700753 if (DBG) Log.d(TAG, "Tethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700754 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700755 TetherState tetherState = mTetherStates.get(iface);
756 if (tetherState == null) {
Erik Kline00019f42016-06-30 19:31:46 +0900757 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900758 return TETHER_ERROR_UNKNOWN_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700759 }
760 // Ignore the error status of the interface. If the interface is available,
761 // the errors are referring to past tethering attempts anyway.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900762 if (tetherState.lastState != IpServer.STATE_AVAILABLE) {
Erik Kline00019f42016-06-30 19:31:46 +0900763 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900764 return TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700765 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000766 // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's queue but not yet
767 // processed, this will be a no-op and it will not return an error.
Erik Klineea9cc482017-03-10 19:35:34 +0900768 //
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000769 // This code cannot race with untether() because they both synchronize on mPublicSync.
770 // TODO: reexamine the threading and messaging model to totally remove mPublicSync.
771 final int type = tetherState.ipServer.interfaceType();
772 final TetheringRequestParcel request = mActiveTetheringRequests.get(type, null);
773 if (request != null) {
774 mActiveTetheringRequests.delete(type);
775 }
776 tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0,
777 request);
Erik Kline7a26ba32018-03-09 14:18:02 +0900778 return TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800779 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800780 }
781
markchien0f63ca62019-09-30 14:40:57 +0800782 int untether(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700783 if (DBG) Log.d(TAG, "Untethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700784 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700785 TetherState tetherState = mTetherStates.get(iface);
786 if (tetherState == null) {
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700787 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900788 return TETHER_ERROR_UNKNOWN_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700789 }
Erik Klineea9cc482017-03-10 19:35:34 +0900790 if (!tetherState.isCurrentlyServing()) {
791 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900792 return TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700793 }
Erik Kline7a4ccc62018-08-27 17:26:47 +0900794 tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED);
Erik Kline7a26ba32018-03-09 14:18:02 +0900795 return TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800796 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800797 }
798
markchien0f63ca62019-09-30 14:40:57 +0800799 void untetherAll() {
Erik Kline7a26ba32018-03-09 14:18:02 +0900800 stopTethering(TETHERING_WIFI);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800801 stopTethering(TETHERING_WIFI_P2P);
Erik Kline7a26ba32018-03-09 14:18:02 +0900802 stopTethering(TETHERING_USB);
803 stopTethering(TETHERING_BLUETOOTH);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900804 stopTethering(TETHERING_ETHERNET);
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700805 }
806
markchien0f63ca62019-09-30 14:40:57 +0800807 int getLastTetherError(String iface) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700808 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700809 TetherState tetherState = mTetherStates.get(iface);
810 if (tetherState == null) {
markchien0f63ca62019-09-30 14:40:57 +0800811 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface
812 + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900813 return TETHER_ERROR_UNKNOWN_IFACE;
Robert Greenwaltb4453622011-11-03 16:01:40 -0700814 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900815 return tetherState.lastError;
Robert Greenwalt5a735062010-03-02 17:25:02 -0800816 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800817 }
818
markchien0ed433e2020-06-03 12:27:37 +0800819 private boolean isProvisioningNeededButUnavailable() {
820 return isTetherProvisioningRequired() && !doesEntitlementPackageExist();
821 }
822
markchienae8aa642019-12-16 20:15:20 +0800823 boolean isTetherProvisioningRequired() {
824 final TetheringConfiguration cfg = mConfig;
825 return mEntitlementMgr.isTetherProvisioningRequired(cfg);
826 }
827
markchien0ed433e2020-06-03 12:27:37 +0800828 private boolean doesEntitlementPackageExist() {
829 // provisioningApp must contain package and class name.
830 if (mConfig.provisioningApp.length != 2) {
831 return false;
832 }
833
834 final PackageManager pm = mContext.getPackageManager();
835 try {
836 pm.getPackageInfo(mConfig.provisioningApp[0], GET_ACTIVITIES);
837 } catch (PackageManager.NameNotFoundException e) {
838 return false;
839 }
840 return true;
841 }
842
Erik Klineea9cc482017-03-10 19:35:34 +0900843 // TODO: Figure out how to update for local hotspot mode interfaces.
Christopher Wileyd985dde2016-05-31 10:44:35 -0700844 private void sendTetherStateChangedBroadcast() {
markchiencb8860c2020-05-12 00:08:27 +0800845 if (!isTetheringSupported()) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800846
Erik Kline8351faa2017-04-17 16:47:23 +0900847 final ArrayList<String> availableList = new ArrayList<>();
848 final ArrayList<String> tetherList = new ArrayList<>();
849 final ArrayList<String> localOnlyList = new ArrayList<>();
850 final ArrayList<String> erroredList = new ArrayList<>();
markchien0f63ca62019-09-30 14:40:57 +0800851 final ArrayList<Integer> lastErrorList = new ArrayList<>();
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800852
Erik Kline3e756652017-01-17 13:42:19 +0900853 final TetheringConfiguration cfg = mConfig;
markchienae8aa642019-12-16 20:15:20 +0800854 mTetherStatesParcel = new TetherStatesParcel();
Erik Kline3e756652017-01-17 13:42:19 +0900855
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000856 int downstreamTypesMask = DOWNSTREAM_NONE;
Robert Greenwaltb4453622011-11-03 16:01:40 -0700857 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700858 for (int i = 0; i < mTetherStates.size(); i++) {
859 TetherState tetherState = mTetherStates.valueAt(i);
860 String iface = mTetherStates.keyAt(i);
Erik Kline7a26ba32018-03-09 14:18:02 +0900861 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700862 erroredList.add(iface);
markchien0f63ca62019-09-30 14:40:57 +0800863 lastErrorList.add(tetherState.lastError);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900864 } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700865 availableList.add(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900866 } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) {
Erik Kline8351faa2017-04-17 16:47:23 +0900867 localOnlyList.add(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900868 } else if (tetherState.lastState == IpServer.STATE_TETHERED) {
Erik Kline3e756652017-01-17 13:42:19 +0900869 if (cfg.isUsb(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000870 downstreamTypesMask |= (1 << TETHERING_USB);
Erik Kline3e756652017-01-17 13:42:19 +0900871 } else if (cfg.isWifi(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000872 downstreamTypesMask |= (1 << TETHERING_WIFI);
Erik Kline3e756652017-01-17 13:42:19 +0900873 } else if (cfg.isBluetooth(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000874 downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800875 }
Erik Kline8351faa2017-04-17 16:47:23 +0900876 tetherList.add(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800877 }
878 }
879 }
markchien0f63ca62019-09-30 14:40:57 +0800880
881 mTetherStatesParcel.availableList = availableList.toArray(new String[0]);
882 mTetherStatesParcel.tetheredList = tetherList.toArray(new String[0]);
883 mTetherStatesParcel.localOnlyList = localOnlyList.toArray(new String[0]);
884 mTetherStatesParcel.erroredIfaceList = erroredList.toArray(new String[0]);
885 mTetherStatesParcel.lastErrorList = new int[lastErrorList.size()];
886 Iterator<Integer> iterator = lastErrorList.iterator();
887 for (int i = 0; i < lastErrorList.size(); i++) {
888 mTetherStatesParcel.lastErrorList[i] = iterator.next().intValue();
889 }
890 reportTetherStateChanged(mTetherStatesParcel);
891
Erik Kline7a26ba32018-03-09 14:18:02 +0900892 final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED);
markchien4cbc1a92020-01-06 21:08:19 +0800893 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Erik Kline7a26ba32018-03-09 14:18:02 +0900894 bcast.putStringArrayListExtra(EXTRA_AVAILABLE_TETHER, availableList);
895 bcast.putStringArrayListExtra(EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
896 bcast.putStringArrayListExtra(EXTRA_ACTIVE_TETHER, tetherList);
897 bcast.putStringArrayListExtra(EXTRA_ERRORED_TETHER, erroredList);
Erik Kline8351faa2017-04-17 16:47:23 +0900898 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800899 if (DBG) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900900 Log.d(TAG, String.format(
Erik Kline8351faa2017-04-17 16:47:23 +0900901 "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
902 "avail", TextUtils.join(",", availableList),
903 "local_only", TextUtils.join(",", localOnlyList),
904 "tether", TextUtils.join(",", tetherList),
905 "error", TextUtils.join(",", erroredList)));
Robert Greenwalt924cc942010-06-28 10:26:19 -0700906 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800907
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000908 mNotificationUpdater.onDownstreamChanged(downstreamTypesMask);
Robert Greenwalt5a735062010-03-02 17:25:02 -0800909 }
910
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800911 private class StateReceiver extends BroadcastReceiver {
Nick Kralevich70c117a2014-05-27 15:30:02 -0700912 @Override
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800913 public void onReceive(Context content, Intent intent) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900914 final String action = intent.getAction();
915 if (action == null) return;
916
Mike Lockwood770126a2010-12-09 22:30:37 -0800917 if (action.equals(UsbManager.ACTION_USB_STATE)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900918 handleUsbAction(intent);
Erik Kline7a26ba32018-03-09 14:18:02 +0900919 } else if (action.equals(CONNECTIVITY_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900920 handleConnectivityAction(intent);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700921 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900922 handleWifiApAction(intent);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800923 } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
924 handleWifiP2pAction(intent);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700925 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
Erik Klinede637722017-10-12 22:16:01 +0900926 mLog.log("OBSERVED configuration changed");
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700927 updateConfiguration();
markchien1ddfba42019-11-27 21:20:33 +0800928 } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) {
929 mLog.log("OBSERVED user restrictions changed");
930 handleUserRestrictionAction();
markchien3fe660b2019-12-05 12:04:59 +0800931 } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) {
932 mLog.log("OBSERVED data saver changed");
933 handleDataSaverChanged();
Paul Hu77fa8d62020-04-16 02:54:37 +0000934 } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) {
935 untetherAll();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800936 }
937 }
Erik Kline2e88b5e2017-01-18 11:57:45 +0900938
939 private void handleConnectivityAction(Intent intent) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900940 final NetworkInfo networkInfo =
941 (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO);
markchien0f63ca62019-09-30 14:40:57 +0800942 if (networkInfo == null
943 || networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900944 return;
945 }
946
947 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
948 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
949 }
950
951 private void handleUsbAction(Intent intent) {
952 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
Erik Klinec438e302017-07-04 22:02:49 +0900953 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900954 final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
Milim Lee31ef4c02019-10-17 05:02:33 +0900955 final boolean ncmEnabled = intent.getBooleanExtra(USB_FUNCTION_NCM, false);
Erik Klinec438e302017-07-04 22:02:49 +0900956
957 mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
958 usbConnected, usbConfigured, rndisEnabled));
959
960 // There are three types of ACTION_USB_STATE:
961 //
962 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
963 // Meaning: USB connection has ended either because of
964 // software reset or hard unplug.
965 //
966 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
967 // Meaning: the first stage of USB protocol handshake has
968 // occurred but it is not complete.
969 //
970 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
971 // Meaning: the USB handshake is completely done and all the
972 // functions are ready to use.
973 //
974 // For more explanation, see b/62552150 .
Erik Kline2e88b5e2017-01-18 11:57:45 +0900975 synchronized (Tethering.this.mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800976 if (!usbConnected && mRndisEnabled) {
977 // Turn off tethering if it was enabled and there is a disconnect.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900978 tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
markchien3b519632018-09-07 16:19:12 +0800979 mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800980 } else if (usbConfigured && rndisEnabled) {
981 // Tether if rndis is enabled and usb is configured.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900982 tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
Milim Lee31ef4c02019-10-17 05:02:33 +0900983 } else if (usbConnected && ncmEnabled) {
984 tetherMatchingInterfaces(IpServer.STATE_LOCAL_ONLY, TETHERING_NCM);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900985 }
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800986 mRndisEnabled = usbConfigured && rndisEnabled;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900987 }
988 }
989
990 private void handleWifiApAction(Intent intent) {
Erik Kline2efb8272017-05-31 15:53:53 +0900991 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
992 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
993 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
994
Erik Kline2e88b5e2017-01-18 11:57:45 +0900995 synchronized (Tethering.this.mPublicSync) {
996 switch (curState) {
997 case WifiManager.WIFI_AP_STATE_ENABLING:
998 // We can see this state on the way to both enabled and failure states.
999 break;
1000 case WifiManager.WIFI_AP_STATE_ENABLED:
Erik Kline2efb8272017-05-31 15:53:53 +09001001 enableWifiIpServingLocked(ifname, ipmode);
Erik Kline2e88b5e2017-01-18 11:57:45 +09001002 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +09001003 case WifiManager.WIFI_AP_STATE_DISABLING:
Mark Chien19487bf2020-04-15 17:28:27 +00001004 // We can see this state on the way to disabled.
1005 break;
1006 case WifiManager.WIFI_AP_STATE_DISABLED:
Erik Kline2e88b5e2017-01-18 11:57:45 +09001007 case WifiManager.WIFI_AP_STATE_FAILED:
1008 default:
Erik Kline562e0c12017-06-09 16:36:29 +09001009 disableWifiIpServingLocked(ifname, curState);
Erik Kline2efb8272017-05-31 15:53:53 +09001010 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +09001011 }
1012 }
1013 }
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001014
Jimmy Chen151384d2019-12-03 11:37:09 +08001015 private boolean isGroupOwner(WifiP2pGroup group) {
1016 return group != null && group.isGroupOwner()
1017 && !TextUtils.isEmpty(group.getInterface());
1018 }
1019
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001020 private void handleWifiP2pAction(Intent intent) {
1021 if (mConfig.isWifiP2pLegacyTetheringMode()) return;
1022
1023 final WifiP2pInfo p2pInfo =
1024 (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
1025 final WifiP2pGroup group =
1026 (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
1027
1028 if (VDBG) {
1029 Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
1030 }
1031
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001032 synchronized (Tethering.this.mPublicSync) {
Jimmy Chen151384d2019-12-03 11:37:09 +08001033 // if no group is formed, bring it down if needed.
1034 if (p2pInfo == null || !p2pInfo.groupFormed) {
1035 disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
1036 mWifiP2pTetherInterface = null;
1037 return;
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001038 }
Jimmy Chen151384d2019-12-03 11:37:09 +08001039
1040 // If there is a group but the device is not the owner, bail out.
1041 if (!isGroupOwner(group)) return;
1042
1043 // If already serving from the correct interface, nothing to do.
1044 if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
1045
1046 // If already serving from another interface, turn it down first.
1047 if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
1048 mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
1049 + "is different from current interface "
1050 + group.getInterface() + ", re-tether it");
1051 disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
1052 }
1053
1054 // Finally bring up serving on the new interface
1055 mWifiP2pTetherInterface = group.getInterface();
1056 enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001057 }
1058 }
markchien1ddfba42019-11-27 21:20:33 +08001059
1060 private void handleUserRestrictionAction() {
1061 mTetheringRestriction.onUserRestrictionsChanged();
1062 }
markchien3fe660b2019-12-05 12:04:59 +08001063
1064 private void handleDataSaverChanged() {
1065 final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(
1066 Context.CONNECTIVITY_SERVICE);
1067 final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus()
1068 != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
1069
1070 if (mDataSaverEnabled == isDataSaverEnabled) return;
1071
1072 mDataSaverEnabled = isDataSaverEnabled;
1073 if (mDataSaverEnabled) {
1074 untetherAll();
1075 }
1076 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001077 }
1078
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001079 @VisibleForTesting
Paul Hu4089bb12020-04-23 09:07:00 +00001080 boolean isTetheringActive() {
1081 return mActiveTetheringRequests.size() > 0;
1082 }
1083
1084 @VisibleForTesting
markchien1ddfba42019-11-27 21:20:33 +08001085 protected static class UserRestrictionActionListener {
markchiencb8860c2020-05-12 00:08:27 +08001086 private final UserManager mUserMgr;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001087 private final Tethering mWrapper;
Paul Huf950dc92020-03-25 12:39:13 +00001088 private final TetheringNotificationUpdater mNotificationUpdater;
markchien1ddfba42019-11-27 21:20:33 +08001089 public boolean mDisallowTethering;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001090
Paul Huf950dc92020-03-25 12:39:13 +00001091 public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
1092 @NonNull TetheringNotificationUpdater updater) {
markchiencb8860c2020-05-12 00:08:27 +08001093 mUserMgr = um;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001094 mWrapper = wrapper;
Paul Huf950dc92020-03-25 12:39:13 +00001095 mNotificationUpdater = updater;
markchien1ddfba42019-11-27 21:20:33 +08001096 mDisallowTethering = false;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001097 }
1098
markchien1ddfba42019-11-27 21:20:33 +08001099 public void onUserRestrictionsChanged() {
1100 // getUserRestrictions gets restriction for this process' user, which is the primary
1101 // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
1102 // user. See UserManager.DISALLOW_CONFIG_TETHERING.
markchiencb8860c2020-05-12 00:08:27 +08001103 final Bundle restrictions = mUserMgr.getUserRestrictions();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001104 final boolean newlyDisallowed =
markchien1ddfba42019-11-27 21:20:33 +08001105 restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
1106 final boolean prevDisallowed = mDisallowTethering;
1107 mDisallowTethering = newlyDisallowed;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001108
markchien1ddfba42019-11-27 21:20:33 +08001109 final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed);
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001110 if (!tetheringDisallowedChanged) {
1111 return;
1112 }
1113
Paul Huf950dc92020-03-25 12:39:13 +00001114 if (!newlyDisallowed) {
1115 // Clear the restricted notification when user is allowed to have tethering
1116 // function.
1117 mNotificationUpdater.tetheringRestrictionLifted();
1118 return;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001119 }
Paul Huf950dc92020-03-25 12:39:13 +00001120
Paul Hu4089bb12020-04-23 09:07:00 +00001121 if (mWrapper.isTetheringActive()) {
1122 // Restricted notification is shown when tethering function is disallowed on
1123 // user's device.
1124 mNotificationUpdater.notifyTetheringDisabledByRestriction();
Paul Huf950dc92020-03-25 12:39:13 +00001125
Paul Hu4089bb12020-04-23 09:07:00 +00001126 // Untether from all downstreams since tethering is disallowed.
1127 mWrapper.untetherAll();
1128 }
Paul Huf950dc92020-03-25 12:39:13 +00001129 // TODO(b/148139325): send tetheringSupported on restriction change
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001130 }
1131 }
1132
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001133 private void disableWifiIpServingLockedCommon(int tetheringType, String ifname, int apState) {
1134 mLog.log("Canceling WiFi tethering request -"
1135 + " type=" + tetheringType
1136 + " interface=" + ifname
1137 + " state=" + apState);
Erik Kline562e0c12017-06-09 16:36:29 +09001138
1139 if (!TextUtils.isEmpty(ifname)) {
1140 final TetherState ts = mTetherStates.get(ifname);
1141 if (ts != null) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001142 ts.ipServer.unwanted();
Erik Kline562e0c12017-06-09 16:36:29 +09001143 return;
1144 }
1145 }
1146
Erik Kline2efb8272017-05-31 15:53:53 +09001147 for (int i = 0; i < mTetherStates.size(); i++) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001148 final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001149 if (ipServer.interfaceType() == tetheringType) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001150 ipServer.unwanted();
Erik Kline562e0c12017-06-09 16:36:29 +09001151 return;
Erik Kline2efb8272017-05-31 15:53:53 +09001152 }
1153 }
Erik Kline562e0c12017-06-09 16:36:29 +09001154
markchien0f63ca62019-09-30 14:40:57 +08001155 mLog.log("Error disabling Wi-Fi IP serving; "
1156 + (TextUtils.isEmpty(ifname) ? "no interface name specified"
Erik Kline562e0c12017-06-09 16:36:29 +09001157 : "specified interface: " + ifname));
Erik Kline2efb8272017-05-31 15:53:53 +09001158 }
1159
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001160 private void disableWifiIpServingLocked(String ifname, int apState) {
1161 // Regardless of whether we requested this transition, the AP has gone
1162 // down. Don't try to tether again unless we're requested to do so.
1163 // TODO: Remove this altogether, once Wi-Fi reliably gives us an
1164 // interface name with every broadcast.
1165 mWifiTetherRequested = false;
1166
1167 disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
1168 }
1169
Jimmy Chen151384d2019-12-03 11:37:09 +08001170 private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
1171 if (TextUtils.isEmpty(ifname)) return;
1172
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001173 disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
1174 }
1175
Erik Kline2efb8272017-05-31 15:53:53 +09001176 private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001177 // Map wifiIpMode values to IpServer.Callback serving states, inferring
Erik Kline2efb8272017-05-31 15:53:53 +09001178 // from mWifiTetherRequested as a final "best guess".
1179 final int ipServingMode;
1180 switch (wifiIpMode) {
1181 case IFACE_IP_MODE_TETHERED:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001182 ipServingMode = IpServer.STATE_TETHERED;
Erik Kline2efb8272017-05-31 15:53:53 +09001183 break;
1184 case IFACE_IP_MODE_LOCAL_ONLY:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001185 ipServingMode = IpServer.STATE_LOCAL_ONLY;
Erik Kline2efb8272017-05-31 15:53:53 +09001186 break;
1187 default:
Erik Kline9e225542017-06-08 17:48:48 +09001188 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
1189 return;
Erik Kline2efb8272017-05-31 15:53:53 +09001190 }
1191
1192 if (!TextUtils.isEmpty(ifname)) {
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001193 maybeTrackNewInterfaceLocked(ifname);
Erik Kline2efb8272017-05-31 15:53:53 +09001194 changeInterfaceState(ifname, ipServingMode);
1195 } else {
Erik Kline9e225542017-06-08 17:48:48 +09001196 mLog.e(String.format(
markchien0f63ca62019-09-30 14:40:57 +08001197 "Cannot enable IP serving in mode %s on missing interface name",
1198 ipServingMode));
Erik Kline2efb8272017-05-31 15:53:53 +09001199 }
1200 }
1201
Erik Klineea9cc482017-03-10 19:35:34 +09001202 // TODO: Consider renaming to something more accurate in its description.
1203 // This method:
1204 // - allows requesting either tethering or local hotspot serving states
1205 // - handles both enabling and disabling serving states
1206 // - only tethers the first matching interface in listInterfaces()
1207 // order of a given type
1208 private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
1209 if (VDBG) {
1210 Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
1211 }
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001212
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001213 String[] ifaces = null;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001214 try {
markchiena9d9ef82020-01-07 14:43:17 +08001215 ifaces = mNetd.interfaceGetList();
1216 } catch (RemoteException | ServiceSpecificException e) {
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001217 Log.e(TAG, "Error listing Interfaces", e);
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001218 return;
1219 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001220 String chosenIface = null;
1221 if (ifaces != null) {
1222 for (String iface : ifaces) {
1223 if (ifaceNameToType(iface) == interfaceType) {
1224 chosenIface = iface;
1225 break;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001226 }
1227 }
1228 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001229 if (chosenIface == null) {
1230 Log.e(TAG, "could not find iface of type " + interfaceType);
1231 return;
1232 }
1233
Erik Kline2efb8272017-05-31 15:53:53 +09001234 changeInterfaceState(chosenIface, requestedState);
1235 }
1236
1237 private void changeInterfaceState(String ifname, int requestedState) {
Erik Klineea9cc482017-03-10 19:35:34 +09001238 final int result;
1239 switch (requestedState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001240 case IpServer.STATE_UNAVAILABLE:
1241 case IpServer.STATE_AVAILABLE:
Erik Kline2efb8272017-05-31 15:53:53 +09001242 result = untether(ifname);
Erik Klineea9cc482017-03-10 19:35:34 +09001243 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001244 case IpServer.STATE_TETHERED:
1245 case IpServer.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001246 result = tether(ifname, requestedState);
Erik Klineea9cc482017-03-10 19:35:34 +09001247 break;
1248 default:
1249 Log.wtf(TAG, "Unknown interface state: " + requestedState);
1250 return;
1251 }
Erik Kline7a26ba32018-03-09 14:18:02 +09001252 if (result != TETHER_ERROR_NO_ERROR) {
Erik Kline2efb8272017-05-31 15:53:53 +09001253 Log.e(TAG, "unable start or stop tethering on iface " + ifname);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001254 return;
1255 }
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001256 }
1257
markchien0f63ca62019-09-30 14:40:57 +08001258 TetheringConfiguration getTetheringConfiguration() {
Erik Kline3e756652017-01-17 13:42:19 +09001259 return mConfig;
1260 }
1261
markchien0f63ca62019-09-30 14:40:57 +08001262 boolean hasTetherableConfiguration() {
Erik Klined781fba2017-01-23 13:01:58 +09001263 final TetheringConfiguration cfg = mConfig;
1264 final boolean hasDownstreamConfiguration =
markchien1be8d8f2018-12-05 21:20:01 +08001265 (cfg.tetherableUsbRegexs.length != 0)
1266 || (cfg.tetherableWifiRegexs.length != 0)
1267 || (cfg.tetherableBluetoothRegexs.length != 0);
1268 final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
1269 || cfg.chooseUpstreamAutomatically;
Erik Klined781fba2017-01-23 13:01:58 +09001270
1271 return hasDownstreamConfiguration && hasUpstreamConfiguration;
1272 }
1273
Erik Kline3e756652017-01-17 13:42:19 +09001274 // TODO - update callers to use getTetheringConfiguration(),
1275 // which has only final members.
markchien0f63ca62019-09-30 14:40:57 +08001276 String[] getTetherableUsbRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001277 return copy(mConfig.tetherableUsbRegexs);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001278 }
1279
markchien0f63ca62019-09-30 14:40:57 +08001280 String[] getTetherableWifiRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001281 return copy(mConfig.tetherableWifiRegexs);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001282 }
1283
markchien0f63ca62019-09-30 14:40:57 +08001284 String[] getTetherableBluetoothRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001285 return copy(mConfig.tetherableBluetoothRegexs);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001286 }
1287
markchien0f63ca62019-09-30 14:40:57 +08001288 int setUsbTethering(boolean enable) {
Wink Savillec9acde92011-09-21 11:05:43 -07001289 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
Erik Klinec438e302017-07-04 22:02:49 +09001290 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
Ye Jiao21f96252019-01-28 12:54:22 +08001291 if (usbManager == null) {
1292 mLog.e("setUsbTethering: failed to get UsbManager!");
1293 return TETHER_ERROR_SERVICE_UNAVAIL;
1294 }
1295
Robert Greenwaltb4453622011-11-03 16:01:40 -07001296 synchronized (mPublicSync) {
Jerry Zhang327b8092018-01-09 17:53:04 -08001297 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
1298 : UsbManager.FUNCTION_NONE);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001299 }
Erik Kline7a26ba32018-03-09 14:18:02 +09001300 return TETHER_ERROR_NO_ERROR;
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001301 }
1302
Milim Lee31ef4c02019-10-17 05:02:33 +09001303 private int setNcmTethering(boolean enable) {
1304 if (VDBG) Log.d(TAG, "setNcmTethering(" + enable + ")");
1305 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
1306 synchronized (mPublicSync) {
1307 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_NCM
1308 : UsbManager.FUNCTION_NONE);
1309 }
1310 return TETHER_ERROR_NO_ERROR;
1311 }
1312
Erik Kline1fdc2e22017-05-08 17:56:35 +09001313 // TODO review API - figure out how to delete these entirely.
markchien0f63ca62019-09-30 14:40:57 +08001314 String[] getTetheredIfaces() {
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001315 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001316 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001317 for (int i = 0; i < mTetherStates.size(); i++) {
1318 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001319 if (tetherState.lastState == IpServer.STATE_TETHERED) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001320 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001321 }
1322 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001323 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001324 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001325 }
1326
markchien0f63ca62019-09-30 14:40:57 +08001327 String[] getTetherableIfaces() {
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001328 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001329 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001330 for (int i = 0; i < mTetherStates.size(); i++) {
1331 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001332 if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001333 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001334 }
1335 }
1336 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001337 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001338 }
1339
markchien0f63ca62019-09-30 14:40:57 +08001340 String[] getTetheredDhcpRanges() {
Remi NGUYEN VANe3bb5c52018-06-12 15:57:04 +09001341 // TODO: this is only valid for the old DHCP server. Latest search suggests it is only used
1342 // by WifiP2pServiceImpl to start dnsmasq: remove/deprecate after migrating callers.
1343 return mConfig.legacyDhcpRanges;
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001344 }
1345
markchien0f63ca62019-09-30 14:40:57 +08001346 String[] getErroredIfaces() {
Robert Greenwalt5a735062010-03-02 17:25:02 -08001347 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001348 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001349 for (int i = 0; i < mTetherStates.size(); i++) {
1350 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a26ba32018-03-09 14:18:02 +09001351 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001352 list.add(mTetherStates.keyAt(i));
Robert Greenwalt5a735062010-03-02 17:25:02 -08001353 }
1354 }
1355 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001356 return list.toArray(new String[list.size()]);
Robert Greenwalt5a735062010-03-02 17:25:02 -08001357 }
1358
Erik Kline22108902017-07-06 16:40:06 +09001359 private void logMessage(State state, int what) {
1360 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001361 }
1362
Erik Klineea9cc482017-03-10 19:35:34 +09001363 private boolean upstreamWanted() {
1364 if (!mForwardedDownstreams.isEmpty()) return true;
1365
1366 synchronized (mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -08001367 return mWifiTetherRequested;
Erik Klineea9cc482017-03-10 19:35:34 +09001368 }
1369 }
1370
Erik Kline00019f42016-06-30 19:31:46 +09001371 // Needed because the canonical source of upstream truth is just the
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001372 // upstream interface set, |mCurrentUpstreamIfaceSet|.
markchienb0aca962019-12-05 16:21:17 +08001373 private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001374 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
Erik Kline00019f42016-06-30 19:31:46 +09001375 for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001376 if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
Erik Kline00019f42016-06-30 19:31:46 +09001377 return true;
Erik Kline6ff17f72015-12-10 20:42:12 +09001378 }
1379 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001380 }
Erik Kline00019f42016-06-30 19:31:46 +09001381 return false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001382 }
1383
Wink Saville64c42ca2011-04-18 14:55:10 -07001384 class TetherMasterSM extends StateMachine {
Erik Klineea9cc482017-03-10 19:35:34 +09001385 // an interface SM has requested Tethering/Local Hotspot
1386 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
1387 // an interface SM has unrequested Tethering/Local Hotspot
1388 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001389 // upstream connection change - do the right thing
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001390 static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001391 // we don't have a valid upstream conn, check again after a delay
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001392 static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
Erik Kline6ff17f72015-12-10 20:42:12 +09001393 // Events from NetworkCallbacks that we process on the master state
1394 // machine thread on behalf of the UpstreamNetworkMonitor.
Erik Kline00019f42016-06-30 19:31:46 +09001395 static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001396 // we treated the error and want now to clear it
1397 static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
Erik Kline6e9a1012017-06-06 19:24:21 +09001398 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
markchien3b519632018-09-07 16:19:12 +08001399 // Events from EntitlementManager to choose upstream again.
1400 static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
Erik Kline32179ff2017-07-04 18:28:11 +09001401 private final State mInitialState;
1402 private final State mTetherModeAliveState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001403
Erik Kline32179ff2017-07-04 18:28:11 +09001404 private final State mSetIpForwardingEnabledErrorState;
1405 private final State mSetIpForwardingDisabledErrorState;
1406 private final State mStartTetheringErrorState;
1407 private final State mStopTetheringErrorState;
1408 private final State mSetDnsForwardersErrorState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001409
Christopher Wileyd985dde2016-05-31 10:44:35 -07001410 // This list is a little subtle. It contains all the interfaces that currently are
1411 // requesting tethering, regardless of whether these interfaces are still members of
1412 // mTetherStates. This allows us to maintain the following predicates:
1413 //
1414 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1415 // interfaces.
1416 // 2) mNotifyList contains all state machines that may have outstanding tethering state
1417 // that needs to be torn down.
1418 //
1419 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1420 // so that the garbage collector does not clean up the state machine before it has a chance
1421 // to tear itself down.
Erik Kline7a4ccc62018-08-27 17:26:47 +09001422 private final ArrayList<IpServer> mNotifyList;
Erik Kline1eb8c692016-07-08 17:21:26 +09001423 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
Erik Klineed962a82017-07-06 19:49:35 +09001424 private final OffloadWrapper mOffload;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001425
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001426 private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001427
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +09001428 TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
Robert Greenwaltdfadaea2010-03-11 15:03:08 -08001429 super(name, looper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001430
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001431 mInitialState = new InitialState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001432 mTetherModeAliveState = new TetherModeAliveState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001433 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001434 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001435 mStartTetheringErrorState = new StartTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001436 mStopTetheringErrorState = new StopTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001437 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
Erik Kline1fdc2e22017-05-08 17:56:35 +09001438
1439 addState(mInitialState);
1440 addState(mTetherModeAliveState);
1441 addState(mSetIpForwardingEnabledErrorState);
1442 addState(mSetIpForwardingDisabledErrorState);
1443 addState(mStartTetheringErrorState);
1444 addState(mStopTetheringErrorState);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001445 addState(mSetDnsForwardersErrorState);
1446
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001447 mNotifyList = new ArrayList<>();
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +09001448 mIPv6TetheringCoordinator = deps.getIPv6TetheringCoordinator(mNotifyList, mLog);
Erik Klineed962a82017-07-06 19:49:35 +09001449 mOffload = new OffloadWrapper();
Erik Kline32179ff2017-07-04 18:28:11 +09001450
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001451 setInitialState(mInitialState);
1452 }
1453
Erik Kline1fdc2e22017-05-08 17:56:35 +09001454 class InitialState extends State {
1455 @Override
1456 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001457 logMessage(this, message.what);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001458 switch (message.what) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001459 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
1460 final IpServer who = (IpServer) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001461 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1462 handleInterfaceServingStateActive(message.arg1, who);
1463 transitionTo(mTetherModeAliveState);
1464 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001465 }
1466 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
1467 final IpServer who = (IpServer) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001468 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1469 handleInterfaceServingStateInactive(who);
1470 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001471 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001472 case EVENT_IFACE_UPDATE_LINKPROPERTIES:
1473 // Silently ignore these for now.
1474 break;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001475 default:
1476 return NOT_HANDLED;
1477 }
1478 return HANDLED;
1479 }
1480 }
1481
Erik Kline3a5278f2017-06-24 19:29:10 +09001482 protected boolean turnOnMasterTetherSettings() {
1483 final TetheringConfiguration cfg = mConfig;
1484 try {
markchiena9d9ef82020-01-07 14:43:17 +08001485 mNetd.ipfwdEnableForwarding(TAG);
1486 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001487 mLog.e(e);
1488 transitionTo(mSetIpForwardingEnabledErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001489 return false;
1490 }
markchiena9d9ef82020-01-07 14:43:17 +08001491
Erik Kline3a5278f2017-06-24 19:29:10 +09001492 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
Remi NGUYEN VANe3bb5c52018-06-12 15:57:04 +09001493 // Legacy DHCP server is disabled if passed an empty ranges array
1494 final String[] dhcpRanges = cfg.enableLegacyDhcpServer
markchiena9d9ef82020-01-07 14:43:17 +08001495 ? cfg.legacyDhcpRanges : new String[0];
Erik Kline3a5278f2017-06-24 19:29:10 +09001496 try {
markchiena9d9ef82020-01-07 14:43:17 +08001497 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
1498 } catch (RemoteException | ServiceSpecificException e) {
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001499 try {
markchiena9d9ef82020-01-07 14:43:17 +08001500 // Stop and retry.
1501 mNetd.tetherStop();
1502 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
1503 } catch (RemoteException | ServiceSpecificException ee) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001504 mLog.e(ee);
1505 transitionTo(mStartTetheringErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001506 return false;
1507 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001508 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001509 mLog.log("SET master tether settings: ON");
1510 return true;
1511 }
Robert Greenwalt10398722010-12-17 15:20:36 -08001512
Erik Kline3a5278f2017-06-24 19:29:10 +09001513 protected boolean turnOffMasterTetherSettings() {
1514 try {
markchiena9d9ef82020-01-07 14:43:17 +08001515 mNetd.tetherStop();
1516 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001517 mLog.e(e);
1518 transitionTo(mStopTetheringErrorState);
1519 return false;
Erik Kline14f7faf2017-02-14 19:03:09 +09001520 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001521 try {
markchiena9d9ef82020-01-07 14:43:17 +08001522 mNetd.ipfwdDisableForwarding(TAG);
1523 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001524 mLog.e(e);
1525 transitionTo(mSetIpForwardingDisabledErrorState);
1526 return false;
1527 }
1528 transitionTo(mInitialState);
1529 mLog.log("SET master tether settings: OFF");
1530 return true;
1531 }
Erik Kline14f7faf2017-02-14 19:03:09 +09001532
Erik Kline3a5278f2017-06-24 19:29:10 +09001533 protected void chooseUpstreamType(boolean tryCell) {
Erik Kline6ee73da2017-07-08 20:36:37 +09001534 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
1535 // do not currently know how to watch for changes in DUN settings.
markchien3394e142019-04-09 15:53:24 +08001536 maybeDunSettingChanged();
Erik Kline1e2897d2017-06-09 17:08:52 +09001537
Erik Kline72302902018-06-14 17:36:40 +09001538 final TetheringConfiguration config = mConfig;
markchienb0aca962019-12-05 16:21:17 +08001539 final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically)
Erik Kline72302902018-06-14 17:36:40 +09001540 ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
1541 : mUpstreamNetworkMonitor.selectPreferredUpstreamType(
1542 config.preferredUpstreamIfaceTypes);
Erik Kline3a5278f2017-06-24 19:29:10 +09001543 if (ns == null) {
1544 if (tryCell) {
1545 mUpstreamNetworkMonitor.registerMobileNetworkRequest();
1546 // We think mobile should be coming up; don't set a retry.
1547 } else {
1548 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
Erik Kline1e2897d2017-06-09 17:08:52 +09001549 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001550 }
1551 setUpstreamNetwork(ns);
markchien26299ed2019-02-27 14:56:11 +08001552 final Network newUpstream = (ns != null) ? ns.network : null;
1553 if (mTetherUpstream != newUpstream) {
1554 mTetherUpstream = newUpstream;
1555 mUpstreamNetworkMonitor.setCurrentUpstream(mTetherUpstream);
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001556 reportUpstreamChanged(ns);
markchien26299ed2019-02-27 14:56:11 +08001557 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001558 }
1559
markchienb0aca962019-12-05 16:21:17 +08001560 protected void setUpstreamNetwork(UpstreamNetworkState ns) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001561 InterfaceSet ifaces = null;
Erik Klinee8bdb402018-02-23 14:16:06 -08001562 if (ns != null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001563 // Find the interface with the default IPv4 route. It may be the
1564 // interface described by linkProperties, or one of the interfaces
1565 // stacked on top of it.
Erik Klinee8bdb402018-02-23 14:16:06 -08001566 mLog.i("Looking for default routes on: " + ns.linkProperties);
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001567 ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns);
1568 mLog.i("Found upstream interface(s): " + ifaces);
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001569 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -07001570
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001571 if (ifaces != null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001572 setDnsForwarders(ns.network, ns.linkProperties);
Erik Kline6ff17f72015-12-10 20:42:12 +09001573 }
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001574 notifyDownstreamsOfNewUpstreamIface(ifaces);
Erik Kline3a5278f2017-06-24 19:29:10 +09001575 if (ns != null && pertainsToCurrentUpstream(ns)) {
markchienb0aca962019-12-05 16:21:17 +08001576 // If we already have UpstreamNetworkState for this network update it immediately.
Erik Kline3a5278f2017-06-24 19:29:10 +09001577 handleNewUpstreamNetworkState(ns);
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001578 } else if (mCurrentUpstreamIfaceSet == null) {
1579 // There are no available upstream networks.
Erik Kline3a5278f2017-06-24 19:29:10 +09001580 handleNewUpstreamNetworkState(null);
1581 }
1582 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001583
Erik Kline3a5278f2017-06-24 19:29:10 +09001584 protected void setDnsForwarders(final Network network, final LinkProperties lp) {
1585 // TODO: Set v4 and/or v6 DNS per available connectivity.
Erik Kline3a5278f2017-06-24 19:29:10 +09001586 final Collection<InetAddress> dnses = lp.getDnsServers();
1587 // TODO: Properly support the absence of DNS servers.
markchien87d3f7d2020-01-08 20:58:23 +08001588 final String[] dnsServers;
Erik Kline3a5278f2017-06-24 19:29:10 +09001589 if (dnses != null && !dnses.isEmpty()) {
markchien87d3f7d2020-01-08 20:58:23 +08001590 dnsServers = new String[dnses.size()];
1591 int i = 0;
1592 for (InetAddress dns : dnses) {
1593 dnsServers[i++] = dns.getHostAddress();
1594 }
1595 } else {
1596 dnsServers = mConfig.defaultIPv4DNS;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001597 }
markchien587ecb32020-03-18 08:43:07 +08001598 final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
Erik Kline3a5278f2017-06-24 19:29:10 +09001599 try {
markchiena9d9ef82020-01-07 14:43:17 +08001600 mNetd.tetherDnsSet(netId, dnsServers);
Erik Kline3a5278f2017-06-24 19:29:10 +09001601 mLog.log(String.format(
1602 "SET DNS forwarders: network=%s dnsServers=%s",
1603 network, Arrays.toString(dnsServers)));
markchiena9d9ef82020-01-07 14:43:17 +08001604 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001605 // TODO: Investigate how this can fail and what exactly
1606 // happens if/when such failures occur.
1607 mLog.e("setting DNS forwarders failed, " + e);
1608 transitionTo(mSetDnsForwardersErrorState);
1609 }
1610 }
Erik Kline00019f42016-06-30 19:31:46 +09001611
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001612 protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
1613 mCurrentUpstreamIfaceSet = ifaces;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001614 for (IpServer ipServer : mNotifyList) {
1615 ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
Erik Kline00019f42016-06-30 19:31:46 +09001616 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001617 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001618
markchienb0aca962019-12-05 16:21:17 +08001619 protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001620 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
Erik Klineed962a82017-07-06 19:49:35 +09001621 mOffload.updateUpstreamNetworkState(ns);
Erik Kline3a5278f2017-06-24 19:29:10 +09001622 }
1623
Erik Kline7a4ccc62018-08-27 17:26:47 +09001624 private void handleInterfaceServingStateActive(int mode, IpServer who) {
Erik Klineea9cc482017-03-10 19:35:34 +09001625 if (mNotifyList.indexOf(who) < 0) {
1626 mNotifyList.add(who);
1627 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
1628 }
1629
Erik Kline7a4ccc62018-08-27 17:26:47 +09001630 if (mode == IpServer.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001631 // No need to notify OffloadController just yet as there are no
1632 // "offload-able" prefixes to pass along. This will handled
1633 // when the TISM informs Tethering of its LinkProperties.
Erik Klineea9cc482017-03-10 19:35:34 +09001634 mForwardedDownstreams.add(who);
1635 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001636 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001637 mForwardedDownstreams.remove(who);
1638 }
Erik Kline216af6d2017-04-27 20:57:23 +09001639
1640 // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
Erik Kline7a26ba32018-03-09 14:18:02 +09001641 if (who.interfaceType() == TETHERING_WIFI) {
Erik Kline216af6d2017-04-27 20:57:23 +09001642 final WifiManager mgr = getWifiManager();
1643 final String iface = who.interfaceName();
1644 switch (mode) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001645 case IpServer.STATE_TETHERED:
Erik Kline2efb8272017-05-31 15:53:53 +09001646 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +09001647 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001648 case IpServer.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001649 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +09001650 break;
1651 default:
1652 Log.wtf(TAG, "Unknown active serving mode: " + mode);
1653 break;
1654 }
1655 }
Erik Klineea9cc482017-03-10 19:35:34 +09001656 }
1657
Erik Kline7a4ccc62018-08-27 17:26:47 +09001658 private void handleInterfaceServingStateInactive(IpServer who) {
Erik Klineea9cc482017-03-10 19:35:34 +09001659 mNotifyList.remove(who);
1660 mIPv6TetheringCoordinator.removeActiveDownstream(who);
Erik Klineed962a82017-07-06 19:49:35 +09001661 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001662 mForwardedDownstreams.remove(who);
Treehugger Robot25067812020-03-25 15:32:41 +00001663 updateConnectedClients(null /* wifiClients */);
Erik Kline216af6d2017-04-27 20:57:23 +09001664
Jianpeng Lia70feec2019-05-24 17:40:15 +09001665 // If this is a Wi-Fi interface, tell WifiManager of any errors
1666 // or the inactive serving state.
Erik Kline7a26ba32018-03-09 14:18:02 +09001667 if (who.interfaceType() == TETHERING_WIFI) {
1668 if (who.lastError() != TETHER_ERROR_NO_ERROR) {
Erik Kline216af6d2017-04-27 20:57:23 +09001669 getWifiManager().updateInterfaceIpState(
Erik Kline2efb8272017-05-31 15:53:53 +09001670 who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
Jianpeng Lia70feec2019-05-24 17:40:15 +09001671 } else {
1672 getWifiManager().updateInterfaceIpState(
1673 who.interfaceName(), IFACE_IP_MODE_UNSPECIFIED);
Erik Kline216af6d2017-04-27 20:57:23 +09001674 }
1675 }
Erik Klineea9cc482017-03-10 19:35:34 +09001676 }
1677
Mark Chiendb6befb2020-05-29 22:07:37 +00001678 private void addUpstreamPrefixes(final UpstreamNetworkState ns) {
1679 mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties);
1680 }
1681
1682 private void removeUpstreamPrefixes(final UpstreamNetworkState ns) {
1683 mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network);
1684 }
1685
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001686 @VisibleForTesting
1687 void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
Erik Kline32179ff2017-07-04 18:28:11 +09001688 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
Erik Klineed962a82017-07-06 19:49:35 +09001689 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
Erik Kline3a5278f2017-06-24 19:29:10 +09001690 return;
1691 }
1692
markchienb0aca962019-12-05 16:21:17 +08001693 final UpstreamNetworkState ns = (UpstreamNetworkState) o;
Mark Chiendb6befb2020-05-29 22:07:37 +00001694 switch (arg1) {
1695 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
1696 addUpstreamPrefixes(ns);
1697 break;
1698 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1699 removeUpstreamPrefixes(ns);
1700 break;
1701 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001702
1703 if (ns == null || !pertainsToCurrentUpstream(ns)) {
1704 // TODO: In future, this is where upstream evaluation and selection
1705 // could be handled for notifications which include sufficient data.
1706 // For example, after CONNECTIVITY_ACTION listening is removed, here
1707 // is where we could observe a Wi-Fi network becoming available and
1708 // passing validation.
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001709 if (mCurrentUpstreamIfaceSet == null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001710 // If we have no upstream interface, try to run through upstream
1711 // selection again. If, for example, IPv4 connectivity has shown up
1712 // after IPv6 (e.g., 464xlat became available) we want the chance to
1713 // notice and act accordingly.
1714 chooseUpstreamType(false);
1715 }
1716 return;
1717 }
1718
1719 switch (arg1) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001720 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001721 if (ns.network.equals(mTetherUpstream)) {
1722 mNotificationUpdater.onUpstreamCapabilitiesChanged(ns.networkCapabilities);
1723 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001724 handleNewUpstreamNetworkState(ns);
1725 break;
1726 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001727 chooseUpstreamType(false);
Erik Kline3a5278f2017-06-24 19:29:10 +09001728 break;
1729 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1730 // TODO: Re-evaluate possible upstreams. Currently upstream
1731 // reevaluation is triggered via received CONNECTIVITY_ACTION
1732 // broadcasts that result in being passed a
1733 // TetherMasterSM.CMD_UPSTREAM_CHANGED.
1734 handleNewUpstreamNetworkState(null);
1735 break;
1736 default:
1737 mLog.e("Unknown arg1 value: " + arg1);
1738 break;
1739 }
1740 }
1741
1742 class TetherModeAliveState extends State {
Erik Klineea9cc482017-03-10 19:35:34 +09001743 boolean mUpstreamWanted = false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001744 boolean mTryCell = true;
Erik Klinee0cce212017-03-06 14:05:23 +09001745
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001746 @Override
1747 public void enter() {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001748 // If turning on master tether settings fails, we have already
1749 // transitioned to an error state; exit early.
1750 if (!turnOnMasterTetherSettings()) {
1751 return;
1752 }
1753
markchiena6c72872018-11-13 18:34:56 +09001754 mUpstreamNetworkMonitor.startObserveAllNetworks();
Robert Greenwalt4f74d552011-12-19 16:59:31 -08001755
Erik Klinef4b6e342017-04-25 19:19:59 +09001756 // TODO: De-duplicate with updateUpstreamWanted() below.
Erik Klineea9cc482017-03-10 19:35:34 +09001757 if (upstreamWanted()) {
1758 mUpstreamWanted = true;
Erik Klineed962a82017-07-06 19:49:35 +09001759 mOffload.start();
Erik Klineea9cc482017-03-10 19:35:34 +09001760 chooseUpstreamType(true);
1761 mTryCell = false;
1762 }
Hungming Chenbe4827d2020-06-02 00:13:26 +00001763
1764 // TODO: Check the upstream interface if it is managed by BPF offload.
Treehugger Robot96895192020-06-09 13:28:38 +00001765 mBpfCoordinator.startPolling();
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001766 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001767
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001768 @Override
1769 public void exit() {
Erik Klineed962a82017-07-06 19:49:35 +09001770 mOffload.stop();
Erik Kline6ff17f72015-12-10 20:42:12 +09001771 mUpstreamNetworkMonitor.stop();
Erik Kline22108902017-07-06 16:40:06 +09001772 notifyDownstreamsOfNewUpstreamIface(null);
Erik Klinefa37b2f2016-08-02 18:27:03 +09001773 handleNewUpstreamNetworkState(null);
markchien26299ed2019-02-27 14:56:11 +08001774 if (mTetherUpstream != null) {
1775 mTetherUpstream = null;
1776 reportUpstreamChanged(null);
1777 }
Treehugger Robot96895192020-06-09 13:28:38 +00001778 mBpfCoordinator.stopPolling();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001779 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001780
Erik Klineea9cc482017-03-10 19:35:34 +09001781 private boolean updateUpstreamWanted() {
1782 final boolean previousUpstreamWanted = mUpstreamWanted;
1783 mUpstreamWanted = upstreamWanted();
Erik Klinef4b6e342017-04-25 19:19:59 +09001784 if (mUpstreamWanted != previousUpstreamWanted) {
1785 if (mUpstreamWanted) {
Erik Klineed962a82017-07-06 19:49:35 +09001786 mOffload.start();
Erik Klinef4b6e342017-04-25 19:19:59 +09001787 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001788 mOffload.stop();
Erik Klinef4b6e342017-04-25 19:19:59 +09001789 }
1790 }
Erik Klineea9cc482017-03-10 19:35:34 +09001791 return previousUpstreamWanted;
1792 }
1793
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001794 @Override
1795 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001796 logMessage(this, message.what);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001797 boolean retValue = true;
1798 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001799 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001800 IpServer who = (IpServer) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001801 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001802 handleInterfaceServingStateActive(message.arg1, who);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001803 who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED,
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001804 mCurrentUpstreamIfaceSet);
Erik Klineea9cc482017-03-10 19:35:34 +09001805 // If there has been a change and an upstream is now
1806 // desired, kick off the selection process.
1807 final boolean previousUpstreamWanted = updateUpstreamWanted();
1808 if (!previousUpstreamWanted && mUpstreamWanted) {
1809 chooseUpstreamType(true);
1810 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001811 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001812 }
Erik Klineea9cc482017-03-10 19:35:34 +09001813 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001814 IpServer who = (IpServer) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001815 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001816 handleInterfaceServingStateInactive(who);
1817
1818 if (mNotifyList.isEmpty()) {
Erik Kline47222fc2017-04-30 19:36:15 +09001819 // This transitions us out of TetherModeAliveState,
1820 // either to InitialState or an error state.
Erik Kline1fdc2e22017-05-08 17:56:35 +09001821 turnOffMasterTetherSettings();
1822 break;
1823 }
1824
1825 if (DBG) {
markchien0f63ca62019-09-30 14:40:57 +08001826 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size()
1827 + " live requests:");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001828 for (IpServer o : mNotifyList) {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001829 Log.d(TAG, " " + o);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001830 }
1831 }
Erik Klineea9cc482017-03-10 19:35:34 +09001832 // If there has been a change and an upstream is no
1833 // longer desired, release any mobile requests.
1834 final boolean previousUpstreamWanted = updateUpstreamWanted();
1835 if (previousUpstreamWanted && !mUpstreamWanted) {
1836 mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
1837 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001838 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001839 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001840 case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
1841 final LinkProperties newLp = (LinkProperties) message.obj;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001842 if (message.arg1 == IpServer.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001843 mOffload.updateDownstreamLinkProperties(newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09001844 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001845 mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
Erik Kline6e9a1012017-06-06 19:24:21 +09001846 }
1847 break;
1848 }
markchien3b519632018-09-07 16:19:12 +08001849 case EVENT_UPSTREAM_PERMISSION_CHANGED:
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001850 case CMD_UPSTREAM_CHANGED:
Erik Klineea9cc482017-03-10 19:35:34 +09001851 updateUpstreamWanted();
1852 if (!mUpstreamWanted) break;
1853
Erik Klinefb413432017-02-14 18:26:04 +09001854 // Need to try DUN immediately if Wi-Fi goes down.
1855 chooseUpstreamType(true);
1856 mTryCell = false;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001857 break;
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001858 case CMD_RETRY_UPSTREAM:
Erik Klineea9cc482017-03-10 19:35:34 +09001859 updateUpstreamWanted();
1860 if (!mUpstreamWanted) break;
1861
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001862 chooseUpstreamType(mTryCell);
1863 mTryCell = !mTryCell;
1864 break;
Erik Kline00019f42016-06-30 19:31:46 +09001865 case EVENT_UPSTREAM_CALLBACK: {
Erik Klineea9cc482017-03-10 19:35:34 +09001866 updateUpstreamWanted();
Erik Kline3a5278f2017-06-24 19:29:10 +09001867 if (mUpstreamWanted) {
1868 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
Erik Kline6ff17f72015-12-10 20:42:12 +09001869 }
1870 break;
Erik Kline00019f42016-06-30 19:31:46 +09001871 }
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001872 default:
1873 retValue = false;
1874 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001875 }
1876 return retValue;
1877 }
1878 }
1879
Wink Saville64c42ca2011-04-18 14:55:10 -07001880 class ErrorState extends State {
Erik Kline8351faa2017-04-17 16:47:23 +09001881 private int mErrorNotification;
1882
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001883 @Override
1884 public boolean processMessage(Message message) {
1885 boolean retValue = true;
1886 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001887 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001888 IpServer who = (IpServer) message.obj;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001889 who.sendMessage(mErrorNotification);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001890 break;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001891 case CMD_CLEAR_ERROR:
Erik Kline7a26ba32018-03-09 14:18:02 +09001892 mErrorNotification = TETHER_ERROR_NO_ERROR;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001893 transitionTo(mInitialState);
1894 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001895 default:
markchien0f63ca62019-09-30 14:40:57 +08001896 retValue = false;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001897 }
1898 return retValue;
1899 }
Erik Kline8351faa2017-04-17 16:47:23 +09001900
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001901 void notify(int msgType) {
1902 mErrorNotification = msgType;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001903 for (IpServer ipServer : mNotifyList) {
1904 ipServer.sendMessage(msgType);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001905 }
1906 }
1907
1908 }
Erik Kline8351faa2017-04-17 16:47:23 +09001909
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001910 class SetIpForwardingEnabledErrorState extends ErrorState {
1911 @Override
1912 public void enter() {
1913 Log.e(TAG, "Error in setIpForwardingEnabled");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001914 notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001915 }
1916 }
1917
1918 class SetIpForwardingDisabledErrorState extends ErrorState {
1919 @Override
1920 public void enter() {
1921 Log.e(TAG, "Error in setIpForwardingDisabled");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001922 notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001923 }
1924 }
1925
1926 class StartTetheringErrorState extends ErrorState {
1927 @Override
1928 public void enter() {
1929 Log.e(TAG, "Error in startTethering");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001930 notify(IpServer.CMD_START_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001931 try {
markchiena9d9ef82020-01-07 14:43:17 +08001932 mNetd.ipfwdDisableForwarding(TAG);
1933 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001934 }
1935 }
1936
1937 class StopTetheringErrorState extends ErrorState {
1938 @Override
1939 public void enter() {
1940 Log.e(TAG, "Error in stopTethering");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001941 notify(IpServer.CMD_STOP_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001942 try {
markchiena9d9ef82020-01-07 14:43:17 +08001943 mNetd.ipfwdDisableForwarding(TAG);
1944 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001945 }
1946 }
1947
1948 class SetDnsForwardersErrorState extends ErrorState {
1949 @Override
1950 public void enter() {
1951 Log.e(TAG, "Error in setDnsForwarders");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001952 notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001953 try {
markchiena9d9ef82020-01-07 14:43:17 +08001954 mNetd.tetherStop();
1955 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001956 try {
markchiena9d9ef82020-01-07 14:43:17 +08001957 mNetd.ipfwdDisableForwarding(TAG);
1958 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001959 }
1960 }
Erik Klineed962a82017-07-06 19:49:35 +09001961
1962 // A wrapper class to handle multiple situations where several calls to
1963 // the OffloadController need to happen together.
1964 //
1965 // TODO: This suggests that the interface between OffloadController and
1966 // Tethering is in need of improvement. Refactor these calls into the
1967 // OffloadController implementation.
1968 class OffloadWrapper {
1969 public void start() {
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001970 final int status = mOffloadController.start() ? TETHER_HARDWARE_OFFLOAD_STARTED
1971 : TETHER_HARDWARE_OFFLOAD_FAILED;
1972 updateOffloadStatus(status);
Erik Klineed962a82017-07-06 19:49:35 +09001973 sendOffloadExemptPrefixes();
1974 }
1975
1976 public void stop() {
1977 mOffloadController.stop();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001978 updateOffloadStatus(TETHER_HARDWARE_OFFLOAD_STOPPED);
Erik Klineed962a82017-07-06 19:49:35 +09001979 }
1980
markchienb0aca962019-12-05 16:21:17 +08001981 public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
Erik Klineed962a82017-07-06 19:49:35 +09001982 mOffloadController.setUpstreamLinkProperties(
1983 (ns != null) ? ns.linkProperties : null);
1984 }
1985
1986 public void updateDownstreamLinkProperties(LinkProperties newLp) {
1987 // Update the list of offload-exempt prefixes before adding
1988 // new prefixes on downstream interfaces to the offload HAL.
1989 sendOffloadExemptPrefixes();
1990 mOffloadController.notifyDownstreamLinkProperties(newLp);
1991 }
1992
1993 public void excludeDownstreamInterface(String ifname) {
1994 // This and other interfaces may be in local-only hotspot mode;
1995 // resend all local prefixes to the OffloadController.
1996 sendOffloadExemptPrefixes();
1997 mOffloadController.removeDownstreamInterface(ifname);
1998 }
1999
2000 public void sendOffloadExemptPrefixes() {
2001 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
2002 }
2003
2004 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
2005 // Add in well-known minimum set.
2006 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
2007 // Add tragically hardcoded prefixes.
2008 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
2009
2010 // Maybe add prefixes or addresses for downstreams, depending on
2011 // the IP serving mode of each.
Erik Kline7a4ccc62018-08-27 17:26:47 +09002012 for (IpServer ipServer : mNotifyList) {
2013 final LinkProperties lp = ipServer.linkProperties();
Erik Klineed962a82017-07-06 19:49:35 +09002014
Erik Kline7a4ccc62018-08-27 17:26:47 +09002015 switch (ipServer.servingMode()) {
2016 case IpServer.STATE_UNAVAILABLE:
2017 case IpServer.STATE_AVAILABLE:
Erik Klineed962a82017-07-06 19:49:35 +09002018 // No usable LinkProperties in these states.
2019 continue;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002020 case IpServer.STATE_TETHERED:
Erik Klineed962a82017-07-06 19:49:35 +09002021 // Only add IPv4 /32 and IPv6 /128 prefixes. The
2022 // directly-connected prefixes will be sent as
2023 // downstream "offload-able" prefixes.
2024 for (LinkAddress addr : lp.getAllLinkAddresses()) {
2025 final InetAddress ip = addr.getAddress();
2026 if (ip.isLinkLocalAddress()) continue;
2027 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
2028 }
2029 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002030 case IpServer.STATE_LOCAL_ONLY:
Erik Klineed962a82017-07-06 19:49:35 +09002031 // Add prefixes covering all local IPs.
2032 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
2033 break;
2034 }
2035 }
2036
2037 mOffloadController.setLocalPrefixes(localPrefixes);
2038 }
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002039
2040 private void updateOffloadStatus(final int newStatus) {
2041 if (newStatus == mOffloadStatus) return;
2042
2043 mOffloadStatus = newStatus;
2044 reportOffloadStatusChanged(mOffloadStatus);
2045 }
Erik Klineed962a82017-07-06 19:49:35 +09002046 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002047 }
2048
markchien0f63ca62019-09-30 14:40:57 +08002049 private void startTrackDefaultNetwork() {
markchien3b519632018-09-07 16:19:12 +08002050 mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
2051 mEntitlementMgr);
markchiena6c72872018-11-13 18:34:56 +09002052 }
2053
markchienf2731272019-01-16 17:44:13 +08002054 /** Get the latest value of the tethering entitlement check. */
markchien0f63ca62019-09-30 14:40:57 +08002055 void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
markchienf2731272019-01-16 17:44:13 +08002056 boolean showEntitlementUi) {
Mark Chien3075fbb2020-04-16 02:47:22 +00002057 if (receiver == null) return;
2058
2059 mHandler.post(() -> {
markchien0f63ca62019-09-30 14:40:57 +08002060 mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver,
2061 showEntitlementUi);
Mark Chien3075fbb2020-04-16 02:47:22 +00002062 });
markchienf2731272019-01-16 17:44:13 +08002063 }
2064
markchien26299ed2019-02-27 14:56:11 +08002065 /** Register tethering event callback */
markchienae8aa642019-12-16 20:15:20 +08002066 void registerTetheringEventCallback(ITetheringEventCallback callback) {
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002067 final boolean hasListPermission =
Chiachang Wang96ca8e92020-02-21 17:50:18 +08002068 hasCallingPermission(NETWORK_SETTINGS)
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002069 || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
Chiachang Wang96ca8e92020-02-21 17:50:18 +08002070 || hasCallingPermission(NETWORK_STACK);
markchien26299ed2019-02-27 14:56:11 +08002071 mHandler.post(() -> {
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002072 mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
markchien40898ca2020-01-21 13:11:06 +08002073 final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
markchiencb8860c2020-05-12 00:08:27 +08002074 parcel.tetheringSupported = isTetheringSupported();
markchien40898ca2020-01-21 13:11:06 +08002075 parcel.upstreamNetwork = mTetherUpstream;
2076 parcel.config = mConfig.toStableParcelable();
markchienfaa37282020-02-06 14:34:08 +08002077 parcel.states =
2078 mTetherStatesParcel != null ? mTetherStatesParcel : emptyTetherStatesParcel();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002079 parcel.tetheredClients = hasListPermission
2080 ? mConnectedClientsTracker.getLastTetheredClients()
2081 : Collections.emptyList();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002082 parcel.offloadStatus = mOffloadStatus;
markchien26299ed2019-02-27 14:56:11 +08002083 try {
markchien40898ca2020-01-21 13:11:06 +08002084 callback.onCallbackStarted(parcel);
markchien26299ed2019-02-27 14:56:11 +08002085 } catch (RemoteException e) {
2086 // Not really very much to do here.
2087 }
markchien26299ed2019-02-27 14:56:11 +08002088 });
2089 }
2090
markchienfaa37282020-02-06 14:34:08 +08002091 private TetherStatesParcel emptyTetherStatesParcel() {
2092 final TetherStatesParcel parcel = new TetherStatesParcel();
2093 parcel.availableList = new String[0];
2094 parcel.tetheredList = new String[0];
2095 parcel.localOnlyList = new String[0];
2096 parcel.erroredIfaceList = new String[0];
2097 parcel.lastErrorList = new int[0];
2098
2099 return parcel;
2100 }
2101
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002102 private boolean hasCallingPermission(@NonNull String permission) {
2103 return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED;
2104 }
2105
markchienae8aa642019-12-16 20:15:20 +08002106 /** Unregister tethering event callback */
2107 void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
2108 mHandler.post(() -> {
2109 mTetheringEventCallbacks.unregister(callback);
2110 });
2111 }
markchien0f63ca62019-09-30 14:40:57 +08002112
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002113 private void reportUpstreamChanged(UpstreamNetworkState ns) {
markchienae8aa642019-12-16 20:15:20 +08002114 final int length = mTetheringEventCallbacks.beginBroadcast();
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002115 final Network network = (ns != null) ? ns.network : null;
2116 final NetworkCapabilities capabilities = (ns != null) ? ns.networkCapabilities : null;
markchien26299ed2019-02-27 14:56:11 +08002117 try {
markchienae8aa642019-12-16 20:15:20 +08002118 for (int i = 0; i < length; i++) {
2119 try {
2120 mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
2121 } catch (RemoteException e) {
2122 // Not really very much to do here.
2123 }
2124 }
2125 } finally {
2126 mTetheringEventCallbacks.finishBroadcast();
markchien26299ed2019-02-27 14:56:11 +08002127 }
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002128 // Need to notify capabilities change after upstream network changed because new network's
2129 // capabilities should be checked every time.
2130 mNotificationUpdater.onUpstreamCapabilitiesChanged(capabilities);
markchien26299ed2019-02-27 14:56:11 +08002131 }
2132
markchien0f63ca62019-09-30 14:40:57 +08002133 private void reportConfigurationChanged(TetheringConfigurationParcel config) {
markchienae8aa642019-12-16 20:15:20 +08002134 final int length = mTetheringEventCallbacks.beginBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002135 try {
markchienae8aa642019-12-16 20:15:20 +08002136 for (int i = 0; i < length; i++) {
2137 try {
2138 mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config);
markchien40898ca2020-01-21 13:11:06 +08002139 // TODO(b/148139325): send tetheringSupported on configuration change
markchienae8aa642019-12-16 20:15:20 +08002140 } catch (RemoteException e) {
2141 // Not really very much to do here.
2142 }
2143 }
2144 } finally {
2145 mTetheringEventCallbacks.finishBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002146 }
2147 }
2148
2149 private void reportTetherStateChanged(TetherStatesParcel states) {
markchienae8aa642019-12-16 20:15:20 +08002150 final int length = mTetheringEventCallbacks.beginBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002151 try {
markchienae8aa642019-12-16 20:15:20 +08002152 for (int i = 0; i < length; i++) {
2153 try {
2154 mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(states);
2155 } catch (RemoteException e) {
2156 // Not really very much to do here.
2157 }
2158 }
2159 } finally {
2160 mTetheringEventCallbacks.finishBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002161 }
2162 }
2163
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002164 private void reportTetherClientsChanged(List<TetheredClient> clients) {
2165 final int length = mTetheringEventCallbacks.beginBroadcast();
2166 try {
2167 for (int i = 0; i < length; i++) {
2168 try {
2169 final CallbackCookie cookie =
2170 (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i);
2171 if (!cookie.hasListClientsPermission) continue;
2172 mTetheringEventCallbacks.getBroadcastItem(i).onTetherClientsChanged(clients);
2173 } catch (RemoteException e) {
2174 // Not really very much to do here.
2175 }
2176 }
2177 } finally {
2178 mTetheringEventCallbacks.finishBroadcast();
2179 }
2180 }
2181
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002182 private void reportOffloadStatusChanged(final int status) {
2183 final int length = mTetheringEventCallbacks.beginBroadcast();
2184 try {
2185 for (int i = 0; i < length; i++) {
2186 try {
2187 mTetheringEventCallbacks.getBroadcastItem(i).onOffloadStatusChanged(status);
2188 } catch (RemoteException e) {
2189 // Not really very much to do here.
2190 }
2191 }
2192 } finally {
2193 mTetheringEventCallbacks.finishBroadcast();
2194 }
2195 }
2196
markchiencb8860c2020-05-12 00:08:27 +08002197 // if ro.tether.denied = true we default to no tethering
2198 // gservices could set the secure setting to 1 though to enable it on a build where it
2199 // had previously been turned off.
2200 boolean isTetheringSupported() {
markchien0ed433e2020-06-03 12:27:37 +08002201 final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
markchiencb8860c2020-05-12 00:08:27 +08002202 final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
2203 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
2204 final boolean tetherEnabledInSettings = tetherSupported
2205 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
2206
markchien0ed433e2020-06-03 12:27:37 +08002207 return tetherEnabledInSettings && hasTetherableConfiguration()
2208 && !isProvisioningNeededButUnavailable();
markchiencb8860c2020-05-12 00:08:27 +08002209 }
2210
markchiena9d9ef82020-01-07 14:43:17 +08002211 void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
Christopher Wiley499a57a2016-05-16 16:19:07 -07002212 // Binder.java closes the resource for us.
2213 @SuppressWarnings("resource")
Lorenzo Colittie3805462015-06-03 11:18:24 +09002214 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
markchienae8aa642019-12-16 20:15:20 +08002215 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2216 != PERMISSION_GRANTED) {
2217 pw.println("Permission Denial: can't dump.");
2218 return;
2219 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002220
Lorenzo Colittie3805462015-06-03 11:18:24 +09002221 pw.println("Tethering:");
2222 pw.increaseIndent();
Lorenzo Colittie3805462015-06-03 11:18:24 +09002223
Erik Kline9db1b542017-03-16 14:10:27 +09002224 pw.println("Configuration:");
2225 pw.increaseIndent();
2226 final TetheringConfiguration cfg = mConfig;
2227 cfg.dump(pw);
2228 pw.decreaseIndent();
2229
markchien3b519632018-09-07 16:19:12 +08002230 pw.println("Entitlement:");
2231 pw.increaseIndent();
2232 mEntitlementMgr.dump(pw);
2233 pw.decreaseIndent();
2234
Erik Kline9db1b542017-03-16 14:10:27 +09002235 synchronized (mPublicSync) {
Robert Greenwaltb4453622011-11-03 16:01:40 -07002236 pw.println("Tether state:");
Lorenzo Colittie3805462015-06-03 11:18:24 +09002237 pw.increaseIndent();
Christopher Wileyd985dde2016-05-31 10:44:35 -07002238 for (int i = 0; i < mTetherStates.size(); i++) {
2239 final String iface = mTetherStates.keyAt(i);
2240 final TetherState tetherState = mTetherStates.valueAt(i);
2241 pw.print(iface + " - ");
2242
Hugo Benichib55fb222017-03-10 14:20:57 +09002243 switch (tetherState.lastState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09002244 case IpServer.STATE_UNAVAILABLE:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002245 pw.print("UnavailableState");
2246 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002247 case IpServer.STATE_AVAILABLE:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002248 pw.print("AvailableState");
2249 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002250 case IpServer.STATE_TETHERED:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002251 pw.print("TetheredState");
2252 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002253 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09002254 pw.print("LocalHotspotState");
2255 break;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002256 default:
2257 pw.print("UnknownState");
2258 break;
2259 }
Hugo Benichib55fb222017-03-10 14:20:57 +09002260 pw.println(" - lastError = " + tetherState.lastError);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002261 }
Erik Klineea9cc482017-03-10 19:35:34 +09002262 pw.println("Upstream wanted: " + upstreamWanted());
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09002263 pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet);
Lorenzo Colittie3805462015-06-03 11:18:24 +09002264 pw.decreaseIndent();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002265 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09002266
Lorenzo Colittic2519c52017-07-13 01:48:26 +09002267 pw.println("Hardware offload:");
2268 pw.increaseIndent();
2269 mOffloadController.dump(pw);
2270 pw.decreaseIndent();
2271
Nucca Chen1f9efaf2020-06-17 06:32:35 +00002272 pw.println("BPF offload:");
2273 pw.increaseIndent();
2274 mBpfCoordinator.dump(pw);
2275 pw.decreaseIndent();
2276
Mark Chiendb6befb2020-05-29 22:07:37 +00002277 pw.println("Private address coordinator:");
2278 pw.increaseIndent();
2279 mPrivateAddressCoordinator.dump(pw);
2280 pw.decreaseIndent();
2281
Erik Kline1fdc2e22017-05-08 17:56:35 +09002282 pw.println("Log:");
2283 pw.increaseIndent();
markchien0f63ca62019-09-30 14:40:57 +08002284 if (argsContain(args, "--short")) {
Erik Kline7747fd42017-05-12 16:52:48 +09002285 pw.println("<log removed for brevity>");
2286 } else {
2287 mLog.dump(fd, pw, args);
2288 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09002289 pw.decreaseIndent();
2290
Lorenzo Colittie3805462015-06-03 11:18:24 +09002291 pw.decreaseIndent();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002292 }
Christopher Wileye03fb442016-05-18 13:45:20 -07002293
Erik Kline7747fd42017-05-12 16:52:48 +09002294 private static boolean argsContain(String[] args, String target) {
2295 for (String arg : args) {
Erik Klineee363c42017-05-29 09:11:03 +09002296 if (target.equals(arg)) return true;
Erik Kline7747fd42017-05-12 16:52:48 +09002297 }
2298 return false;
2299 }
2300
Treehugger Robot25067812020-03-25 15:32:41 +00002301 private void updateConnectedClients(final List<WifiClient> wifiClients) {
2302 if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, wifiClients)) {
2303 reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
2304 }
2305 }
2306
Erik Kline7a4ccc62018-08-27 17:26:47 +09002307 private IpServer.Callback makeControlCallback() {
2308 return new IpServer.Callback() {
Erik Kline6e9a1012017-06-06 19:24:21 +09002309 @Override
Erik Kline7a4ccc62018-08-27 17:26:47 +09002310 public void updateInterfaceState(IpServer who, int state, int lastError) {
2311 notifyInterfaceStateChange(who, state, lastError);
Erik Kline6e9a1012017-06-06 19:24:21 +09002312 }
2313
2314 @Override
Erik Kline7a4ccc62018-08-27 17:26:47 +09002315 public void updateLinkProperties(IpServer who, LinkProperties newLp) {
2316 notifyLinkPropertiesChanged(who, newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09002317 }
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002318
2319 @Override
2320 public void dhcpLeasesChanged() {
Treehugger Robot25067812020-03-25 15:32:41 +00002321 updateConnectedClients(null /* wifiClients */);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002322 }
Mark Chiendb6befb2020-05-29 22:07:37 +00002323
2324 @Override
2325 public void requestEnableTethering(int tetheringType, boolean enabled) {
2326 enableTetheringInternal(tetheringType, enabled, null);
2327 }
Erik Kline6e9a1012017-06-06 19:24:21 +09002328 };
2329 }
2330
2331 // TODO: Move into TetherMasterSM.
Erik Kline7a4ccc62018-08-27 17:26:47 +09002332 private void notifyInterfaceStateChange(IpServer who, int state, int error) {
2333 final String iface = who.interfaceName();
Christopher Wileyd985dde2016-05-31 10:44:35 -07002334 synchronized (mPublicSync) {
Erik Kline216af6d2017-04-27 20:57:23 +09002335 final TetherState tetherState = mTetherStates.get(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002336 if (tetherState != null && tetherState.ipServer.equals(who)) {
Hugo Benichib55fb222017-03-10 14:20:57 +09002337 tetherState.lastState = state;
2338 tetherState.lastError = error;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002339 } else {
2340 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
2341 }
2342 }
2343
Erik Kline7747fd42017-05-12 16:52:48 +09002344 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002345
Yohei, Oshima977aad52016-12-08 13:39:20 +09002346 // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
2347 // Thus we give a chance for TetherMasterSM to recover to InitialState
2348 // by sending CMD_CLEAR_ERROR
markchien62a625d2020-03-19 13:37:43 +08002349 if (error == TETHER_ERROR_INTERNAL_ERROR) {
Yohei, Oshima977aad52016-12-08 13:39:20 +09002350 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
2351 }
Erik Klineea9cc482017-03-10 19:35:34 +09002352 int which;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002353 switch (state) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09002354 case IpServer.STATE_UNAVAILABLE:
2355 case IpServer.STATE_AVAILABLE:
Erik Klineea9cc482017-03-10 19:35:34 +09002356 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002357 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002358 case IpServer.STATE_TETHERED:
2359 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09002360 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002361 break;
Erik Klineea9cc482017-03-10 19:35:34 +09002362 default:
2363 Log.wtf(TAG, "Unknown interface state: " + state);
2364 return;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002365 }
Erik Klineea9cc482017-03-10 19:35:34 +09002366 mTetherMasterSM.sendMessage(which, state, 0, who);
Christopher Wileyd985dde2016-05-31 10:44:35 -07002367 sendTetherStateChangedBroadcast();
2368 }
2369
Erik Kline7a4ccc62018-08-27 17:26:47 +09002370 private void notifyLinkPropertiesChanged(IpServer who, LinkProperties newLp) {
2371 final String iface = who.interfaceName();
Erik Kline6e9a1012017-06-06 19:24:21 +09002372 final int state;
2373 synchronized (mPublicSync) {
2374 final TetherState tetherState = mTetherStates.get(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002375 if (tetherState != null && tetherState.ipServer.equals(who)) {
Erik Kline6e9a1012017-06-06 19:24:21 +09002376 state = tetherState.lastState;
2377 } else {
2378 mLog.log("got notification from stale iface " + iface);
2379 return;
2380 }
2381 }
2382
Erik Kline7fd696c2017-06-12 18:20:08 +09002383 mLog.log(String.format(
2384 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
Erik Kline7a4ccc62018-08-27 17:26:47 +09002385 iface, IpServer.getStateString(state), newLp));
Erik Kline6e9a1012017-06-06 19:24:21 +09002386 final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
2387 mTetherMasterSM.sendMessage(which, state, 0, newLp);
2388 }
2389
Erik Kline4dd9bb82017-04-26 11:11:07 +09002390 private void maybeTrackNewInterfaceLocked(final String iface) {
2391 // If we don't care about this type of interface, ignore.
2392 final int interfaceType = ifaceNameToType(iface);
Erik Kline7a26ba32018-03-09 14:18:02 +09002393 if (interfaceType == TETHERING_INVALID) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09002394 mLog.log(iface + " is not a tetherable iface, ignoring");
2395 return;
2396 }
Erik Klinea9cde8b2017-06-20 21:18:31 +09002397 maybeTrackNewInterfaceLocked(iface, interfaceType);
2398 }
Erik Kline4dd9bb82017-04-26 11:11:07 +09002399
Erik Klinea9cde8b2017-06-20 21:18:31 +09002400 private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09002401 // If we have already started a TISM for this interface, skip.
2402 if (mTetherStates.containsKey(iface)) {
2403 mLog.log("active iface (" + iface + ") reported as added, ignoring");
2404 return;
2405 }
2406
2407 mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
2408 final TetherState tetherState = new TetherState(
Hungming Chenbe4827d2020-06-02 00:13:26 +00002409 new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
Erik Kline7a4ccc62018-08-27 17:26:47 +09002410 makeControlCallback(), mConfig.enableLegacyDhcpServer,
Nucca Chen1c63ba32020-06-17 07:03:57 +00002411 mConfig.isBpfOffloadEnabled(), mPrivateAddressCoordinator,
Mark Chiendb6befb2020-05-29 22:07:37 +00002412 mDeps.getIpServerDependencies()));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002413 mTetherStates.put(iface, tetherState);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002414 tetherState.ipServer.start();
Christopher Wileye03fb442016-05-18 13:45:20 -07002415 }
Erik Kline3e756652017-01-17 13:42:19 +09002416
Erik Kline4dd9bb82017-04-26 11:11:07 +09002417 private void stopTrackingInterfaceLocked(final String iface) {
2418 final TetherState tetherState = mTetherStates.get(iface);
2419 if (tetherState == null) {
2420 mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
2421 return;
2422 }
Erik Kline7a4ccc62018-08-27 17:26:47 +09002423 tetherState.ipServer.stop();
Erik Kline4dd9bb82017-04-26 11:11:07 +09002424 mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
2425 mTetherStates.remove(iface);
2426 }
2427
Erik Kline3e756652017-01-17 13:42:19 +09002428 private static String[] copy(String[] strarray) {
2429 return Arrays.copyOf(strarray, strarray.length);
2430 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002431}