blob: c72ac52740d7a3c4e756fd0a6a534b7b62f45ae3 [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;
markchien62a625d2020-03-19 13:37:43 +080043import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
markchien9e44cde2019-12-25 19:40:32 +080044import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
45import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
46import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
47import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
markchien62a625d2020-03-19 13:37:43 +080048import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +000049import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
50import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
51import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
markchien986750b2019-12-06 15:24:53 +080052import static android.net.util.TetheringMessageBase.BASE_MASTER;
Erik Kline2efb8272017-05-31 15:53:53 +090053import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
54import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
Erik Kline2e88b5e2017-01-18 11:57:45 +090055import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
Erik Kline2efb8272017-05-31 15:53:53 +090056import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
57import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
58import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
59import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
Erik Kline2e88b5e2017-01-18 11:57:45 +090060import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
Erik Klinede637722017-10-12 22:16:01 +090061import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
markchien04bdf872019-06-17 21:05:34 +080062import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
markchienb6eb2c22018-07-18 14:29:20 +080063
markchien503be612020-04-12 21:41:29 +080064import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +000065
Nucca Chen3f856b42020-06-17 07:03:39 +000066import android.app.usage.NetworkStatsManager;
Jeremy Klein36c7aa02016-01-22 14:11:45 -080067import android.bluetooth.BluetoothAdapter;
68import android.bluetooth.BluetoothPan;
69import android.bluetooth.BluetoothProfile;
70import android.bluetooth.BluetoothProfile.ServiceListener;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080071import android.content.BroadcastReceiver;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -080072import android.content.Context;
73import android.content.Intent;
74import android.content.IntentFilter;
markchien0ed433e2020-06-03 12:27:37 +080075import android.content.pm.PackageManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080076import android.hardware.usb.UsbManager;
markchien3fe660b2019-12-05 12:04:59 +080077import android.net.ConnectivityManager;
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +090078import android.net.EthernetManager;
markchiene8b9d752020-01-20 19:31:56 +080079import android.net.IIntResultListener;
markchien0f63ca62019-09-30 14:40:57 +080080import android.net.INetd;
markchienae8aa642019-12-16 20:15:20 +080081import android.net.ITetheringEventCallback;
Erik Kline3a5278f2017-06-24 19:29:10 +090082import android.net.IpPrefix;
Erik Klineed962a82017-07-06 19:49:35 +090083import android.net.LinkAddress;
Robert Greenwalt05d89362011-01-23 16:04:05 -080084import android.net.LinkProperties;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070085import android.net.Network;
Chalard Jeanc0fc2762020-04-17 17:12:44 +000086import android.net.NetworkCapabilities;
Robert Greenwalt2a091d72010-02-11 18:18:40 -080087import android.net.NetworkInfo;
markchien0f63ca62019-09-30 14:40:57 +080088import android.net.TetherStatesParcel;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +090089import android.net.TetheredClient;
markchien40898ca2020-01-21 13:11:06 +080090import android.net.TetheringCallbackStartedParcel;
markchien0f63ca62019-09-30 14:40:57 +080091import android.net.TetheringConfigurationParcel;
markchiene8b9d752020-01-20 19:31:56 +080092import android.net.TetheringRequestParcel;
markchienb6eb2c22018-07-18 14:29:20 +080093import android.net.ip.IpServer;
markchiena9d9ef82020-01-07 14:43:17 +080094import android.net.shared.NetdUtils;
markchien0f63ca62019-09-30 14:40:57 +080095import android.net.util.BaseNetdUnsolicitedEventListener;
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +090096import android.net.util.InterfaceSet;
Erik Kline32179ff2017-07-04 18:28:11 +090097import android.net.util.PrefixUtils;
Erik Kline7747fd42017-05-12 16:52:48 +090098import android.net.util.SharedLog;
Automerger Merge Worker37a22752020-03-17 16:59:57 +000099import android.net.util.TetheringUtils;
Erik Klinede637722017-10-12 22:16:01 +0900100import android.net.util.VersionedBroadcastListener;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900101import android.net.wifi.WifiClient;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800102import android.net.wifi.WifiManager;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800103import android.net.wifi.p2p.WifiP2pGroup;
104import android.net.wifi.p2p.WifiP2pInfo;
105import android.net.wifi.p2p.WifiP2pManager;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800106import android.os.Binder;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800107import android.os.Bundle;
Erik Klinef4b6e342017-04-25 19:19:59 +0900108import android.os.Handler;
Robert Greenwaltdfadaea2010-03-11 15:03:08 -0800109import android.os.Looper;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800110import android.os.Message;
markchienae8aa642019-12-16 20:15:20 +0800111import android.os.RemoteCallbackList;
Christopher Wileydeebfec2016-09-16 11:14:36 -0700112import android.os.RemoteException;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800113import android.os.ResultReceiver;
markchiena9d9ef82020-01-07 14:43:17 +0800114import android.os.ServiceSpecificException;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700115import android.os.UserHandle;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +0100116import android.os.UserManager;
markchiencb8860c2020-05-12 00:08:27 +0800117import android.provider.Settings;
markchien04bdf872019-06-17 21:05:34 +0800118import android.telephony.PhoneStateListener;
119import android.telephony.TelephonyManager;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900120import android.text.TextUtils;
Christopher Wileye9490392016-05-26 15:57:29 -0700121import android.util.ArrayMap;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800122import android.util.Log;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900123import android.util.SparseArray;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800124
markchiena9d9ef82020-01-07 14:43:17 +0800125import androidx.annotation.NonNull;
126import androidx.annotation.Nullable;
127
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900128import com.android.internal.annotations.GuardedBy;
Christopher Wiley497c1472016-10-11 13:26:03 -0700129import com.android.internal.annotations.VisibleForTesting;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800130import com.android.internal.util.IndentingPrintWriter;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900131import com.android.internal.util.MessageUtils;
Wink Saville64c42ca2011-04-18 14:55:10 -0700132import com.android.internal.util.State;
133import com.android.internal.util.StateMachine;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800134
135import java.io.FileDescriptor;
136import java.io.PrintWriter;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800137import java.net.InetAddress;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800138import java.util.ArrayList;
Lorenzo Colittib57edc52014-08-22 17:10:50 -0700139import java.util.Arrays;
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700140import java.util.Collection;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900141import java.util.Collections;
markchien0f63ca62019-09-30 14:40:57 +0800142import java.util.Iterator;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900143import java.util.LinkedHashSet;
144import java.util.List;
Erik Kline3a5278f2017-06-24 19:29:10 +0900145import java.util.Set;
markchien986750b2019-12-06 15:24:53 +0800146import java.util.concurrent.Executor;
147import java.util.concurrent.RejectedExecutionException;
Robert Greenwalt2ffe4122014-12-12 12:22:31 -0800148
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800149/**
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800150 *
Christopher Wiley3b1d9222016-05-20 16:44:04 -0700151 * This class holds much of the business logic to allow Android devices
152 * to act as IP gateways via USB, BT, and WiFi interfaces.
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800153 */
markchien0f63ca62019-09-30 14:40:57 +0800154public class Tethering {
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800155
markchien0f63ca62019-09-30 14:40:57 +0800156 private static final String TAG = Tethering.class.getSimpleName();
157 private static final boolean DBG = false;
158 private static final boolean VDBG = false;
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800159
markchien0f63ca62019-09-30 14:40:57 +0800160 private static final Class[] sMessageClasses = {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900161 Tethering.class, TetherMasterSM.class, IpServer.class
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900162 };
163 private static final SparseArray<String> sMagicDecoderRing =
markchien0f63ca62019-09-30 14:40:57 +0800164 MessageUtils.findMessageNames(sMessageClasses);
markchiena9d9ef82020-01-07 14:43:17 +0800165 // Keep in sync with NETID_UNSET in system/netd/include/netid_client.h
166 private static final int NETID_UNSET = 0;
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900167
Hugo Benichib55fb222017-03-10 14:20:57 +0900168 private static class TetherState {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900169 public final IpServer ipServer;
Hugo Benichib55fb222017-03-10 14:20:57 +0900170 public int lastState;
171 public int lastError;
Erik Klineea9cc482017-03-10 19:35:34 +0900172
markchien0f63ca62019-09-30 14:40:57 +0800173 TetherState(IpServer ipServer) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900174 this.ipServer = ipServer;
Hugo Benichib55fb222017-03-10 14:20:57 +0900175 // Assume all state machines start out available and with no errors.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900176 lastState = IpServer.STATE_AVAILABLE;
Erik Kline7a26ba32018-03-09 14:18:02 +0900177 lastError = TETHER_ERROR_NO_ERROR;
Hugo Benichib55fb222017-03-10 14:20:57 +0900178 }
Erik Klineea9cc482017-03-10 19:35:34 +0900179
180 public boolean isCurrentlyServing() {
181 switch (lastState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900182 case IpServer.STATE_TETHERED:
183 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +0900184 return true;
185 default:
186 return false;
187 }
188 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900189 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -0700190
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900191 /**
192 * Cookie added when registering {@link android.net.TetheringManager.TetheringEventCallback}.
193 */
194 private static class CallbackCookie {
195 public final boolean hasListClientsPermission;
196
197 private CallbackCookie(boolean hasListClientsPermission) {
198 this.hasListClientsPermission = hasListClientsPermission;
199 }
200 }
201
Erik Kline7747fd42017-05-12 16:52:48 +0900202 private final SharedLog mLog = new SharedLog(TAG);
markchienae8aa642019-12-16 20:15:20 +0800203 private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
204 new RemoteCallbackList<>();
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000205 // Currently active tethering requests per tethering type. Only one of each type can be
206 // requested at a time. After a tethering type is requested, the map keeps tethering parameters
207 // to be used after the interface comes up asynchronously.
208 private final SparseArray<TetheringRequestParcel> mActiveTetheringRequests =
209 new SparseArray<>();
Erik Kline1fdc2e22017-05-08 17:56:35 +0900210
Robert Greenwaltb4453622011-11-03 16:01:40 -0700211 // used to synchronize public access to members
Mark Chiendb6befb2020-05-29 22:07:37 +0000212 // TODO(b/153621704): remove mPublicSync to make Tethering lock free
Erik Kline6ff17f72015-12-10 20:42:12 +0900213 private final Object mPublicSync;
Hugo Benichib55fb222017-03-10 14:20:57 +0900214 private final Context mContext;
215 private final ArrayMap<String, TetherState> mTetherStates;
216 private final BroadcastReceiver mStateReceiver;
Erik Kline6ff17f72015-12-10 20:42:12 +0900217 private final Looper mLooper;
Erik Kline6ff17f72015-12-10 20:42:12 +0900218 private final StateMachine mTetherMasterSM;
Erik Klinee0cce212017-03-06 14:05:23 +0900219 private final OffloadController mOffloadController;
Erik Kline6ff17f72015-12-10 20:42:12 +0900220 private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
Erik Kline6e9a1012017-06-06 19:24:21 +0900221 // TODO: Figure out how to merge this and other downstream-tracking objects
222 // into a single coherent structure.
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900223 // Use LinkedHashSet for predictable ordering order for ConnectedClientsTracker.
224 private final LinkedHashSet<IpServer> mForwardedDownstreams;
Erik Klinede637722017-10-12 22:16:01 +0900225 private final VersionedBroadcastListener mCarrierConfigChange;
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900226 private final TetheringDependencies mDeps;
markchienb6eb2c22018-07-18 14:29:20 +0800227 private final EntitlementManager mEntitlementMgr;
markchien26299ed2019-02-27 14:56:11 +0800228 private final Handler mHandler;
markchien0f63ca62019-09-30 14:40:57 +0800229 private final INetd mNetd;
230 private final NetdCallback mNetdCallback;
markchien1ddfba42019-11-27 21:20:33 +0800231 private final UserRestrictionActionListener mTetheringRestriction;
markchien986750b2019-12-06 15:24:53 +0800232 private final ActiveDataSubIdListener mActiveDataSubIdListener;
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900233 private final ConnectedClientsTracker mConnectedClientsTracker;
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000234 private final TetheringThreadExecutor mExecutor;
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000235 private final TetheringNotificationUpdater mNotificationUpdater;
markchiencb8860c2020-05-12 00:08:27 +0800236 private final UserManager mUserManager;
Hungming Chenbe4827d2020-06-02 00:13:26 +0000237 private final BpfCoordinator mBpfCoordinator;
Mark Chiendb6befb2020-05-29 22:07:37 +0000238 private final PrivateAddressCoordinator mPrivateAddressCoordinator;
markchien04bdf872019-06-17 21:05:34 +0800239 private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
markchienae8aa642019-12-16 20:15:20 +0800240 // All the usage of mTetheringEventCallback should run in the same thread.
241 private ITetheringEventCallback mTetheringEventCallback = null;
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800242
Hugo Benichib55fb222017-03-10 14:20:57 +0900243 private volatile TetheringConfiguration mConfig;
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +0900244 private InterfaceSet mCurrentUpstreamIfaceSet;
Erik Klineea9cc482017-03-10 19:35:34 +0900245
Mike Lockwood6c2260b2011-07-19 13:04:47 -0700246 private boolean mRndisEnabled; // track the RNDIS function enabled state
Erik Kline6e9a1012017-06-06 19:24:21 +0900247 // True iff. WiFi tethering should be started when soft AP is ready.
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700248 private boolean mWifiTetherRequested;
markchien26299ed2019-02-27 14:56:11 +0800249 private Network mTetherUpstream;
markchien0f63ca62019-09-30 14:40:57 +0800250 private TetherStatesParcel mTetherStatesParcel;
markchien3fe660b2019-12-05 12:04:59 +0800251 private boolean mDataSaverEnabled = false;
Jimmy Chen151384d2019-12-03 11:37:09 +0800252 private String mWifiP2pTetherInterface = null;
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +0000253 private int mOffloadStatus = TETHER_HARDWARE_OFFLOAD_STOPPED;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700254
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900255 @GuardedBy("mPublicSync")
256 private EthernetManager.TetheredInterfaceRequest mEthernetIfaceRequest;
257 @GuardedBy("mPublicSync")
258 private String mConfiguredEthernetIface;
259 @GuardedBy("mPublicSync")
260 private EthernetCallback mEthernetCallback;
261
markchien0f63ca62019-09-30 14:40:57 +0800262 public Tethering(TetheringDependencies deps) {
263 mLog.mark("Tethering.constructed");
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900264 mDeps = deps;
markchien0f63ca62019-09-30 14:40:57 +0800265 mContext = mDeps.getContext();
markchien0f63ca62019-09-30 14:40:57 +0800266 mNetd = mDeps.getINetd(mContext);
267 mLooper = mDeps.getTetheringLooper();
Paul Hu77fa8d62020-04-16 02:54:37 +0000268 mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800269
Robert Greenwaltb4453622011-11-03 16:01:40 -0700270 mPublicSync = new Object();
271
Christopher Wileyd985dde2016-05-31 10:44:35 -0700272 mTetherStates = new ArrayMap<>();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900273 mConnectedClientsTracker = new ConnectedClientsTracker();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800274
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900275 mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800276 mTetherMasterSM.start();
277
markchien26299ed2019-02-27 14:56:11 +0800278 mHandler = mTetherMasterSM.getHandler();
Mark Chien66b9a4a2020-05-07 03:49:42 +0000279 mOffloadController = mDeps.getOffloadController(mHandler, mLog,
280 new OffloadController.Dependencies() {
Junyu Lai833f4f62020-05-05 10:45:38 +0000281
282 @Override
283 public TetheringConfiguration getTetherConfig() {
284 return mConfig;
285 }
286 });
markchiena9d9ef82020-01-07 14:43:17 +0800287 mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +0900288 TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900289 mForwardedDownstreams = new LinkedHashSet<>();
Erik Klinede637722017-10-12 22:16:01 +0900290
291 IntentFilter filter = new IntentFilter();
292 filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
markchien3b519632018-09-07 16:19:12 +0800293 // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
294 // permission is changed according to entitlement check result.
Mark Chien47430c02020-05-08 11:00:42 +0000295 mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
296 () -> mTetherMasterSM.sendMessage(
297 TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
markchien29b70142019-03-26 21:41:59 +0800298 mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
299 mLog.log("OBSERVED UiEnitlementFailed");
300 stopTethering(downstream);
301 });
markchien3394e142019-04-09 15:53:24 +0800302 mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
markchien3394e142019-04-09 15:53:24 +0800303 return mConfig;
304 });
markchien3b519632018-09-07 16:19:12 +0800305
Erik Klinede637722017-10-12 22:16:01 +0900306 mCarrierConfigChange = new VersionedBroadcastListener(
markchien26299ed2019-02-27 14:56:11 +0800307 "CarrierConfigChangeListener", mContext, mHandler, filter,
Erik Klinede637722017-10-12 22:16:01 +0900308 (Intent ignored) -> {
309 mLog.log("OBSERVED carrier config change");
Erik Kline80b7a9f2018-02-28 15:01:35 +0900310 updateConfiguration();
markchien3394e142019-04-09 15:53:24 +0800311 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
Erik Klinede637722017-10-12 22:16:01 +0900312 });
Erik Kline6ff17f72015-12-10 20:42:12 +0900313
Robert Greenwaltbb51d9f2010-03-12 10:23:35 -0800314 mStateReceiver = new StateReceiver();
Erik Kline80b7a9f2018-02-28 15:01:35 +0900315
markchiencb8860c2020-05-12 00:08:27 +0800316 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Paul Huf950dc92020-03-25 12:39:13 +0000317 mTetheringRestriction = new UserRestrictionActionListener(
markchiencb8860c2020-05-12 00:08:27 +0800318 mUserManager, this, mNotificationUpdater);
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000319 mExecutor = new TetheringThreadExecutor(mHandler);
320 mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
Mark Chien674a0122020-03-27 09:37:01 +0000321 mNetdCallback = new NetdCallback();
Mark Chiendb6befb2020-05-29 22:07:37 +0000322 mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext);
markchien1ddfba42019-11-27 21:20:33 +0800323
Erik Kline80b7a9f2018-02-28 15:01:35 +0900324 // Load tethering configuration.
325 updateConfiguration();
markchiencb8860c2020-05-12 00:08:27 +0800326
Nucca Chen3f856b42020-06-17 07:03:39 +0000327 // Must be initialized after tethering configuration is loaded because BpfCoordinator
328 // constructor needs to use the configuration.
329 mBpfCoordinator = mDeps.getBpfCoordinator(
330 new BpfCoordinator.Dependencies() {
331 @NonNull
332 public Handler getHandler() {
333 return mHandler;
334 }
335
336 @NonNull
337 public INetd getNetd() {
338 return mNetd;
339 }
340
341 @NonNull
342 public NetworkStatsManager getNetworkStatsManager() {
Nucca Chen1c63ba32020-06-17 07:03:57 +0000343 return mContext.getSystemService(NetworkStatsManager.class);
Nucca Chen3f856b42020-06-17 07:03:39 +0000344 }
345
346 @NonNull
347 public SharedLog getSharedLog() {
348 return mLog;
349 }
350
351 @Nullable
352 public TetheringConfiguration getTetherConfig() {
353 return mConfig;
354 }
355 });
356
markchiencb8860c2020-05-12 00:08:27 +0800357 startStateMachineUpdaters();
Mark Chien674a0122020-03-27 09:37:01 +0000358 }
359
360 /**
361 * Start to register callbacks.
362 * Call this function when tethering is ready to handle callback events.
363 */
markchiencb8860c2020-05-12 00:08:27 +0800364 private void startStateMachineUpdaters() {
markchiene67c5642020-02-06 15:25:47 +0800365 try {
366 mNetd.registerUnsolicitedEventListener(mNetdCallback);
367 } catch (RemoteException e) {
368 mLog.e("Unable to register netd UnsolicitedEventListener");
369 }
Erik Kline80b7a9f2018-02-28 15:01:35 +0900370 mCarrierConfigChange.startListening();
markchien986750b2019-12-06 15:24:53 +0800371 mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
372 PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
Erik Kline80b7a9f2018-02-28 15:01:35 +0900373
Erik Kline80b7a9f2018-02-28 15:01:35 +0900374 IntentFilter filter = new IntentFilter();
Mike Lockwood770126a2010-12-09 22:30:37 -0800375 filter.addAction(UsbManager.ACTION_USB_STATE);
Erik Kline7a26ba32018-03-09 14:18:02 +0900376 filter.addAction(CONNECTIVITY_ACTION);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700377 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700378 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800379 filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
markchien1ddfba42019-11-27 21:20:33 +0800380 filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
markchien3fe660b2019-12-05 12:04:59 +0800381 filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
Mark Chien674a0122020-03-27 09:37:01 +0000382 mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
383
Paul Hu77fa8d62020-04-16 02:54:37 +0000384 final IntentFilter noUpstreamFilter = new IntentFilter();
385 noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING);
386 mContext.registerReceiver(
387 mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler);
388
Mark Chien674a0122020-03-27 09:37:01 +0000389 final WifiManager wifiManager = getWifiManager();
390 if (wifiManager != null) {
391 wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
392 }
393
394 startTrackDefaultNetwork();
Robert Greenwalt49348e72011-10-21 16:54:26 -0700395 }
396
markchien986750b2019-12-06 15:24:53 +0800397 private class TetheringThreadExecutor implements Executor {
398 private final Handler mTetherHandler;
399 TetheringThreadExecutor(Handler handler) {
400 mTetherHandler = handler;
401 }
402 @Override
403 public void execute(Runnable command) {
404 if (!mTetherHandler.post(command)) {
405 throw new RejectedExecutionException(mTetherHandler + " is shutting down");
406 }
407 }
408 }
409
410 private class ActiveDataSubIdListener extends PhoneStateListener {
411 ActiveDataSubIdListener(Executor executor) {
412 super(executor);
413 }
414
415 @Override
416 public void onActiveDataSubscriptionIdChanged(int subId) {
417 mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
418 + " to " + subId);
419 if (subId == mActiveDataSubId) return;
420
421 mActiveDataSubId = subId;
422 updateConfiguration();
Paul Hu274cc1c2020-03-25 06:22:43 +0000423 mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
markchien986750b2019-12-06 15:24:53 +0800424 // To avoid launching unexpected provisioning checks, ignore re-provisioning
425 // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
Paul Hu274cc1c2020-03-25 06:22:43 +0000426 // will be triggered again when CarrierConfig is loaded.
markchien986750b2019-12-06 15:24:53 +0800427 if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
428 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
429 } else {
430 mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
431 }
432 }
433 }
434
Erik Kline216af6d2017-04-27 20:57:23 +0900435 private WifiManager getWifiManager() {
436 return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
437 }
438
Erik Kline93c4afa2017-06-04 11:36:01 +0900439 // NOTE: This is always invoked on the mLooper thread.
Erik Klined781fba2017-01-23 13:01:58 +0900440 private void updateConfiguration() {
markchien04bdf872019-06-17 21:05:34 +0800441 mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
markchien3394e142019-04-09 15:53:24 +0800442 mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
markchien0f63ca62019-09-30 14:40:57 +0800443 reportConfigurationChanged(mConfig.toStableParcelable());
markchien3394e142019-04-09 15:53:24 +0800444 }
445
446 private void maybeDunSettingChanged() {
markchien986750b2019-12-06 15:24:53 +0800447 final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
markchiendb3a2362018-10-05 12:36:08 +0800448 if (isDunRequired == mConfig.isDunRequired) return;
Erik Kline6ee73da2017-07-08 20:36:37 +0900449 updateConfiguration();
450 }
451
markchien0f63ca62019-09-30 14:40:57 +0800452 private class NetdCallback extends BaseNetdUnsolicitedEventListener {
453 @Override
454 public void onInterfaceChanged(String ifName, boolean up) {
455 mHandler.post(() -> interfaceStatusChanged(ifName, up));
456 }
457
458 @Override
459 public void onInterfaceLinkStateChanged(String ifName, boolean up) {
460 mHandler.post(() -> interfaceLinkStateChanged(ifName, up));
461 }
462
463 @Override
464 public void onInterfaceAdded(String ifName) {
465 mHandler.post(() -> interfaceAdded(ifName));
466 }
467
468 @Override
469 public void onInterfaceRemoved(String ifName) {
470 mHandler.post(() -> interfaceRemoved(ifName));
471 }
472 }
473
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900474 private class TetheringSoftApCallback implements WifiManager.SoftApCallback {
475 // TODO: Remove onStateChanged override when this method has default on
476 // WifiManager#SoftApCallback interface.
477 // Wifi listener for state change of the soft AP
478 @Override
479 public void onStateChanged(final int state, final int failureReason) {
480 // Nothing
481 }
482
483 // Called by wifi when the number of soft AP clients changed.
484 @Override
485 public void onConnectedClientsChanged(final List<WifiClient> clients) {
Treehugger Robot25067812020-03-25 15:32:41 +0000486 updateConnectedClients(clients);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +0900487 }
488 }
489
markchien0f63ca62019-09-30 14:40:57 +0800490 void interfaceStatusChanged(String iface, boolean up) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900491 // Never called directly: only called from interfaceLinkStateChanged.
markchien0f63ca62019-09-30 14:40:57 +0800492 // See NetlinkHandler.cpp: notifyInterfaceChanged.
Wink Savillec9acde92011-09-21 11:05:43 -0700493 if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700494 synchronized (mPublicSync) {
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700495 if (up) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900496 maybeTrackNewInterfaceLocked(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800497 } else {
Erik Kline7a26ba32018-03-09 14:18:02 +0900498 if (ifaceNameToType(iface) == TETHERING_BLUETOOTH) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900499 stopTrackingInterfaceLocked(iface);
Christopher Wileyd30aaeb2016-07-08 09:33:50 -0700500 } else {
501 // Ignore usb0 down after enabling RNDIS.
502 // We will handle disconnect in interfaceRemoved.
503 // Similarly, ignore interface down for WiFi. We monitor WiFi AP status
504 // through the WifiManager.WIFI_AP_STATE_CHANGED_ACTION intent.
505 if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800506 }
507 }
508 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800509 }
510
markchien0f63ca62019-09-30 14:40:57 +0800511 void interfaceLinkStateChanged(String iface, boolean up) {
Irfan Sheriff23eb2972011-07-22 15:21:10 -0700512 interfaceStatusChanged(iface, up);
Mike J. Chenf59c7d02011-06-23 15:33:15 -0700513 }
514
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700515 private int ifaceNameToType(String iface) {
Erik Kline3e756652017-01-17 13:42:19 +0900516 final TetheringConfiguration cfg = mConfig;
517
518 if (cfg.isWifi(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900519 return TETHERING_WIFI;
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800520 } else if (cfg.isWifiP2p(iface)) {
521 return TETHERING_WIFI_P2P;
Erik Kline3e756652017-01-17 13:42:19 +0900522 } else if (cfg.isUsb(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900523 return TETHERING_USB;
Erik Kline3e756652017-01-17 13:42:19 +0900524 } else if (cfg.isBluetooth(iface)) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900525 return TETHERING_BLUETOOTH;
Milim Lee31ef4c02019-10-17 05:02:33 +0900526 } else if (cfg.isNcm(iface)) {
527 return TETHERING_NCM;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700528 }
Erik Kline7a26ba32018-03-09 14:18:02 +0900529 return TETHERING_INVALID;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700530 }
531
markchien0f63ca62019-09-30 14:40:57 +0800532 void interfaceAdded(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700533 if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700534 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900535 maybeTrackNewInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800536 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800537 }
538
markchien0f63ca62019-09-30 14:40:57 +0800539 void interfaceRemoved(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700540 if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700541 synchronized (mPublicSync) {
Erik Kline4dd9bb82017-04-26 11:11:07 +0900542 stopTrackingInterfaceLocked(iface);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800543 }
544 }
545
markchiene8b9d752020-01-20 19:31:56 +0800546 void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000547 mHandler.post(() -> {
548 final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
549 request.tetheringType);
550 // If tethering is already enabled with a different request,
551 // disable before re-enabling.
552 if (unfinishedRequest != null
553 && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {
554 enableTetheringInternal(request.tetheringType, false /* disabled */, null);
555 mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);
556 }
557 mActiveTetheringRequests.put(request.tetheringType, request);
558
markchien5788f2a2020-05-08 18:55:26 +0800559 if (request.exemptFromEntitlementCheck) {
560 mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);
561 } else {
562 mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
563 request.showProvisioningUi);
564 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000565 enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
566 });
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800567 }
568
markchien0f63ca62019-09-30 14:40:57 +0800569 void stopTethering(int type) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000570 mHandler.post(() -> {
571 mActiveTetheringRequests.remove(type);
572
573 enableTetheringInternal(type, false /* disabled */, null);
574 mEntitlementMgr.stopProvisioningIfNeeded(type);
575 });
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800576 }
577
578 /**
markchien3b519632018-09-07 16:19:12 +0800579 * Enables or disables tethering for the given type. If provisioning is required, it will
580 * schedule provisioning rechecks for the specified interface.
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800581 */
markchiene8b9d752020-01-20 19:31:56 +0800582 private void enableTetheringInternal(int type, boolean enable,
583 final IIntResultListener listener) {
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000584 int result = TETHER_ERROR_NO_ERROR;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800585 switch (type) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900586 case TETHERING_WIFI:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700587 result = setWifiTethering(enable);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800588 break;
Erik Kline7a26ba32018-03-09 14:18:02 +0900589 case TETHERING_USB:
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700590 result = setUsbTethering(enable);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800591 break;
Erik Kline7a26ba32018-03-09 14:18:02 +0900592 case TETHERING_BLUETOOTH:
markchiene8b9d752020-01-20 19:31:56 +0800593 setBluetoothTethering(enable, listener);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800594 break;
Milim Lee31ef4c02019-10-17 05:02:33 +0900595 case TETHERING_NCM:
596 result = setNcmTethering(enable);
Milim Lee31ef4c02019-10-17 05:02:33 +0900597 break;
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900598 case TETHERING_ETHERNET:
599 result = setEthernetTethering(enable);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900600 break;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800601 default:
602 Log.w(TAG, "Invalid tether type.");
markchien62a625d2020-03-19 13:37:43 +0800603 result = TETHER_ERROR_UNKNOWN_TYPE;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000604 }
605
606 // The result of Bluetooth tethering will be sent by #setBluetoothTethering.
607 if (type != TETHERING_BLUETOOTH) {
608 sendTetherResult(listener, result, type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800609 }
610 }
611
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000612 private void sendTetherResult(final IIntResultListener listener, final int result,
613 final int type) {
markchiene8b9d752020-01-20 19:31:56 +0800614 if (listener != null) {
615 try {
616 listener.onResult(result);
617 } catch (RemoteException e) { }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800618 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000619
620 // If changing tethering fail, remove corresponding request
621 // no matter who trigger the start/stop.
622 if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800623 }
624
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700625 private int setWifiTethering(final boolean enable) {
Erik Kline256be782017-04-29 13:20:04 +0900626 final long ident = Binder.clearCallingIdentity();
627 try {
628 synchronized (mPublicSync) {
Erik Kline256be782017-04-29 13:20:04 +0900629 final WifiManager mgr = getWifiManager();
Ye Jiao21f96252019-01-28 12:54:22 +0800630 if (mgr == null) {
631 mLog.e("setWifiTethering: failed to get WifiManager!");
632 return TETHER_ERROR_SERVICE_UNAVAIL;
633 }
lesl6b7551a2019-12-13 10:56:35 +0800634 if ((enable && mgr.startTetheredHotspot(null /* use existing softap config */))
markchien0f63ca62019-09-30 14:40:57 +0800635 || (!enable && mgr.stopSoftAp())) {
Ye Jiao21f96252019-01-28 12:54:22 +0800636 mWifiTetherRequested = enable;
637 return TETHER_ERROR_NO_ERROR;
Erik Kline256be782017-04-29 13:20:04 +0900638 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700639 }
Erik Kline256be782017-04-29 13:20:04 +0900640 } finally {
641 Binder.restoreCallingIdentity(ident);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700642 }
Ye Jiao21f96252019-01-28 12:54:22 +0800643
markchien62a625d2020-03-19 13:37:43 +0800644 return TETHER_ERROR_INTERNAL_ERROR;
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700645 }
646
markchiene8b9d752020-01-20 19:31:56 +0800647 private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
markchien3fe660b2019-12-05 12:04:59 +0800648 final BluetoothAdapter adapter = mDeps.getBluetoothAdapter();
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800649 if (adapter == null || !adapter.isEnabled()) {
markchien0f63ca62019-09-30 14:40:57 +0800650 Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
651 + (adapter == null));
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000652 sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800653 return;
654 }
655
656 adapter.getProfileProxy(mContext, new ServiceListener() {
657 @Override
658 public void onServiceDisconnected(int profile) { }
659
660 @Override
661 public void onServiceConnected(int profile, BluetoothProfile proxy) {
markchien560c3ac2019-08-16 15:33:28 +0800662 // Clear identify is fine because caller already pass tethering permission at
663 // ConnectivityService#startTethering()(or stopTethering) before the control comes
664 // here. Bluetooth will check tethering permission again that there is
665 // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
666 // caller's package name for permission check.
667 // Calling BluetoothPan#setBluetoothTethering() here means the package name always
668 // be system server. If calling identity is not cleared, that package's uid might
669 // not match calling uid and end up in permission denied.
670 final long identityToken = Binder.clearCallingIdentity();
671 try {
672 ((BluetoothPan) proxy).setBluetoothTethering(enable);
673 } finally {
674 Binder.restoreCallingIdentity(identityToken);
675 }
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800676 // TODO: Enabling bluetooth tethering can fail asynchronously here.
677 // We should figure out a way to bubble up that failure instead of sending success.
Erik Kline7a26ba32018-03-09 14:18:02 +0900678 final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
679 ? TETHER_ERROR_NO_ERROR
markchien62a625d2020-03-19 13:37:43 +0800680 : TETHER_ERROR_INTERNAL_ERROR;
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000681 sendTetherResult(listener, result, TETHERING_BLUETOOTH);
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800682 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
683 }
684 }, BluetoothProfile.PAN);
685 }
686
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900687 private int setEthernetTethering(final boolean enable) {
688 final EthernetManager em = (EthernetManager) mContext.getSystemService(
689 Context.ETHERNET_SERVICE);
690 synchronized (mPublicSync) {
691 if (enable) {
Treehugger Robot191a03c2020-03-24 15:23:51 +0000692 if (mEthernetCallback != null) {
693 Log.d(TAG, "Ethernet tethering already started");
694 return TETHER_ERROR_NO_ERROR;
695 }
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000696
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900697 mEthernetCallback = new EthernetCallback();
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000698 mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900699 } else {
Automerger Merge Worker06fe92d2020-02-28 03:42:44 +0000700 stopEthernetTetheringLocked();
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900701 }
702 }
703 return TETHER_ERROR_NO_ERROR;
704 }
705
706 private void stopEthernetTetheringLocked() {
Treehugger Robot41c81242020-03-19 15:23:45 +0000707 if (mConfiguredEthernetIface != null) {
708 stopTrackingInterfaceLocked(mConfiguredEthernetIface);
709 mConfiguredEthernetIface = null;
710 }
711 if (mEthernetCallback != null) {
712 mEthernetIfaceRequest.release();
713 mEthernetCallback = null;
714 mEthernetIfaceRequest = null;
715 }
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900716 }
717
718 private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback {
719 @Override
720 public void onAvailable(String iface) {
721 synchronized (mPublicSync) {
722 if (this != mEthernetCallback) {
723 // Ethernet callback arrived after Ethernet tethering stopped. Ignore.
724 return;
725 }
726 maybeTrackNewInterfaceLocked(iface, TETHERING_ETHERNET);
727 changeInterfaceState(iface, IpServer.STATE_TETHERED);
728 mConfiguredEthernetIface = iface;
729 }
730 }
731
732 @Override
733 public void onUnavailable() {
734 synchronized (mPublicSync) {
735 if (this != mEthernetCallback) {
736 // onAvailable called after stopping Ethernet tethering.
737 return;
738 }
739 stopEthernetTetheringLocked();
740 }
741 }
742 }
743
markchien0f63ca62019-09-30 14:40:57 +0800744 int tether(String iface) {
Erik Kline7a4ccc62018-08-27 17:26:47 +0900745 return tether(iface, IpServer.STATE_TETHERED);
Erik Klineea9cc482017-03-10 19:35:34 +0900746 }
747
748 private int tether(String iface, int requestedState) {
Wink Savillec9acde92011-09-21 11:05:43 -0700749 if (DBG) Log.d(TAG, "Tethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700750 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700751 TetherState tetherState = mTetherStates.get(iface);
752 if (tetherState == null) {
Erik Kline00019f42016-06-30 19:31:46 +0900753 Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900754 return TETHER_ERROR_UNKNOWN_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700755 }
756 // Ignore the error status of the interface. If the interface is available,
757 // the errors are referring to past tethering attempts anyway.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900758 if (tetherState.lastState != IpServer.STATE_AVAILABLE) {
Erik Kline00019f42016-06-30 19:31:46 +0900759 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900760 return TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700761 }
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000762 // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's queue but not yet
763 // processed, this will be a no-op and it will not return an error.
Erik Klineea9cc482017-03-10 19:35:34 +0900764 //
Automerger Merge Worker37a22752020-03-17 16:59:57 +0000765 // This code cannot race with untether() because they both synchronize on mPublicSync.
766 // TODO: reexamine the threading and messaging model to totally remove mPublicSync.
767 final int type = tetherState.ipServer.interfaceType();
768 final TetheringRequestParcel request = mActiveTetheringRequests.get(type, null);
769 if (request != null) {
770 mActiveTetheringRequests.delete(type);
771 }
772 tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0,
773 request);
Erik Kline7a26ba32018-03-09 14:18:02 +0900774 return TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800775 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800776 }
777
markchien0f63ca62019-09-30 14:40:57 +0800778 int untether(String iface) {
Wink Savillec9acde92011-09-21 11:05:43 -0700779 if (DBG) Log.d(TAG, "Untethering " + iface);
Robert Greenwaltb4453622011-11-03 16:01:40 -0700780 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700781 TetherState tetherState = mTetherStates.get(iface);
782 if (tetherState == null) {
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700783 Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900784 return TETHER_ERROR_UNKNOWN_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700785 }
Erik Klineea9cc482017-03-10 19:35:34 +0900786 if (!tetherState.isCurrentlyServing()) {
787 Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900788 return TETHER_ERROR_UNAVAIL_IFACE;
Christopher Wiley4312a4c2016-05-23 13:58:00 -0700789 }
Erik Kline7a4ccc62018-08-27 17:26:47 +0900790 tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED);
Erik Kline7a26ba32018-03-09 14:18:02 +0900791 return TETHER_ERROR_NO_ERROR;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800792 }
Robert Greenwalt5a735062010-03-02 17:25:02 -0800793 }
794
markchien0f63ca62019-09-30 14:40:57 +0800795 void untetherAll() {
Erik Kline7a26ba32018-03-09 14:18:02 +0900796 stopTethering(TETHERING_WIFI);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800797 stopTethering(TETHERING_WIFI_P2P);
Erik Kline7a26ba32018-03-09 14:18:02 +0900798 stopTethering(TETHERING_USB);
799 stopTethering(TETHERING_BLUETOOTH);
Remi NGUYEN VAN84229e02020-01-24 22:57:09 +0900800 stopTethering(TETHERING_ETHERNET);
Felipe Leme70c8b9b2016-04-25 14:41:31 -0700801 }
802
markchien0f63ca62019-09-30 14:40:57 +0800803 int getLastTetherError(String iface) {
Robert Greenwaltb4453622011-11-03 16:01:40 -0700804 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700805 TetherState tetherState = mTetherStates.get(iface);
806 if (tetherState == null) {
markchien0f63ca62019-09-30 14:40:57 +0800807 Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface
808 + ", ignoring");
Erik Kline7a26ba32018-03-09 14:18:02 +0900809 return TETHER_ERROR_UNKNOWN_IFACE;
Robert Greenwaltb4453622011-11-03 16:01:40 -0700810 }
Hugo Benichib55fb222017-03-10 14:20:57 +0900811 return tetherState.lastError;
Robert Greenwalt5a735062010-03-02 17:25:02 -0800812 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800813 }
814
markchien0ed433e2020-06-03 12:27:37 +0800815 private boolean isProvisioningNeededButUnavailable() {
816 return isTetherProvisioningRequired() && !doesEntitlementPackageExist();
817 }
818
markchienae8aa642019-12-16 20:15:20 +0800819 boolean isTetherProvisioningRequired() {
820 final TetheringConfiguration cfg = mConfig;
821 return mEntitlementMgr.isTetherProvisioningRequired(cfg);
822 }
823
markchien0ed433e2020-06-03 12:27:37 +0800824 private boolean doesEntitlementPackageExist() {
825 // provisioningApp must contain package and class name.
826 if (mConfig.provisioningApp.length != 2) {
827 return false;
828 }
829
830 final PackageManager pm = mContext.getPackageManager();
831 try {
832 pm.getPackageInfo(mConfig.provisioningApp[0], GET_ACTIVITIES);
833 } catch (PackageManager.NameNotFoundException e) {
834 return false;
835 }
836 return true;
837 }
838
Erik Klineea9cc482017-03-10 19:35:34 +0900839 // TODO: Figure out how to update for local hotspot mode interfaces.
Christopher Wileyd985dde2016-05-31 10:44:35 -0700840 private void sendTetherStateChangedBroadcast() {
markchiencb8860c2020-05-12 00:08:27 +0800841 if (!isTetheringSupported()) return;
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800842
Erik Kline8351faa2017-04-17 16:47:23 +0900843 final ArrayList<String> availableList = new ArrayList<>();
844 final ArrayList<String> tetherList = new ArrayList<>();
845 final ArrayList<String> localOnlyList = new ArrayList<>();
846 final ArrayList<String> erroredList = new ArrayList<>();
markchien0f63ca62019-09-30 14:40:57 +0800847 final ArrayList<Integer> lastErrorList = new ArrayList<>();
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800848
Erik Kline3e756652017-01-17 13:42:19 +0900849 final TetheringConfiguration cfg = mConfig;
markchienae8aa642019-12-16 20:15:20 +0800850 mTetherStatesParcel = new TetherStatesParcel();
Erik Kline3e756652017-01-17 13:42:19 +0900851
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000852 int downstreamTypesMask = DOWNSTREAM_NONE;
Robert Greenwaltb4453622011-11-03 16:01:40 -0700853 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700854 for (int i = 0; i < mTetherStates.size(); i++) {
855 TetherState tetherState = mTetherStates.valueAt(i);
856 String iface = mTetherStates.keyAt(i);
Erik Kline7a26ba32018-03-09 14:18:02 +0900857 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700858 erroredList.add(iface);
markchien0f63ca62019-09-30 14:40:57 +0800859 lastErrorList.add(tetherState.lastError);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900860 } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -0700861 availableList.add(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900862 } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) {
Erik Kline8351faa2017-04-17 16:47:23 +0900863 localOnlyList.add(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +0900864 } else if (tetherState.lastState == IpServer.STATE_TETHERED) {
Erik Kline3e756652017-01-17 13:42:19 +0900865 if (cfg.isUsb(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000866 downstreamTypesMask |= (1 << TETHERING_USB);
Erik Kline3e756652017-01-17 13:42:19 +0900867 } else if (cfg.isWifi(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000868 downstreamTypesMask |= (1 << TETHERING_WIFI);
Erik Kline3e756652017-01-17 13:42:19 +0900869 } else if (cfg.isBluetooth(iface)) {
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000870 downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800871 }
Erik Kline8351faa2017-04-17 16:47:23 +0900872 tetherList.add(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800873 }
874 }
875 }
markchien0f63ca62019-09-30 14:40:57 +0800876
877 mTetherStatesParcel.availableList = availableList.toArray(new String[0]);
878 mTetherStatesParcel.tetheredList = tetherList.toArray(new String[0]);
879 mTetherStatesParcel.localOnlyList = localOnlyList.toArray(new String[0]);
880 mTetherStatesParcel.erroredIfaceList = erroredList.toArray(new String[0]);
881 mTetherStatesParcel.lastErrorList = new int[lastErrorList.size()];
882 Iterator<Integer> iterator = lastErrorList.iterator();
883 for (int i = 0; i < lastErrorList.size(); i++) {
884 mTetherStatesParcel.lastErrorList[i] = iterator.next().intValue();
885 }
886 reportTetherStateChanged(mTetherStatesParcel);
887
Erik Kline7a26ba32018-03-09 14:18:02 +0900888 final Intent bcast = new Intent(ACTION_TETHER_STATE_CHANGED);
markchien4cbc1a92020-01-06 21:08:19 +0800889 bcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
Erik Kline7a26ba32018-03-09 14:18:02 +0900890 bcast.putStringArrayListExtra(EXTRA_AVAILABLE_TETHER, availableList);
891 bcast.putStringArrayListExtra(EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
892 bcast.putStringArrayListExtra(EXTRA_ACTIVE_TETHER, tetherList);
893 bcast.putStringArrayListExtra(EXTRA_ERRORED_TETHER, erroredList);
Erik Kline8351faa2017-04-17 16:47:23 +0900894 mContext.sendStickyBroadcastAsUser(bcast, UserHandle.ALL);
Robert Greenwaltfd1be2b2011-11-11 12:30:19 -0800895 if (DBG) {
Lorenzo Colitticd63d242016-04-10 15:39:53 +0900896 Log.d(TAG, String.format(
Erik Kline8351faa2017-04-17 16:47:23 +0900897 "sendTetherStateChangedBroadcast %s=[%s] %s=[%s] %s=[%s] %s=[%s]",
898 "avail", TextUtils.join(",", availableList),
899 "local_only", TextUtils.join(",", localOnlyList),
900 "tether", TextUtils.join(",", tetherList),
901 "error", TextUtils.join(",", erroredList)));
Robert Greenwalt924cc942010-06-28 10:26:19 -0700902 }
Robert Greenwalta599fe7c2010-03-08 18:30:14 -0800903
Automerger Merge Worker2d7bacc2020-03-09 08:54:00 +0000904 mNotificationUpdater.onDownstreamChanged(downstreamTypesMask);
Robert Greenwalt5a735062010-03-02 17:25:02 -0800905 }
906
Robert Greenwalt2a091d72010-02-11 18:18:40 -0800907 private class StateReceiver extends BroadcastReceiver {
Nick Kralevich70c117a2014-05-27 15:30:02 -0700908 @Override
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800909 public void onReceive(Context content, Intent intent) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900910 final String action = intent.getAction();
911 if (action == null) return;
912
Mike Lockwood770126a2010-12-09 22:30:37 -0800913 if (action.equals(UsbManager.ACTION_USB_STATE)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900914 handleUsbAction(intent);
Erik Kline7a26ba32018-03-09 14:18:02 +0900915 } else if (action.equals(CONNECTIVITY_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900916 handleConnectivityAction(intent);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -0700917 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900918 handleWifiApAction(intent);
Jimmy Chenbcd86d02019-07-15 18:03:23 +0800919 } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
920 handleWifiP2pAction(intent);
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700921 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
Erik Klinede637722017-10-12 22:16:01 +0900922 mLog.log("OBSERVED configuration changed");
Robert Greenwaltc13368b2013-07-18 14:24:42 -0700923 updateConfiguration();
markchien1ddfba42019-11-27 21:20:33 +0800924 } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) {
925 mLog.log("OBSERVED user restrictions changed");
926 handleUserRestrictionAction();
markchien3fe660b2019-12-05 12:04:59 +0800927 } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) {
928 mLog.log("OBSERVED data saver changed");
929 handleDataSaverChanged();
Paul Hu77fa8d62020-04-16 02:54:37 +0000930 } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) {
931 untetherAll();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -0800932 }
933 }
Erik Kline2e88b5e2017-01-18 11:57:45 +0900934
935 private void handleConnectivityAction(Intent intent) {
Erik Kline7a26ba32018-03-09 14:18:02 +0900936 final NetworkInfo networkInfo =
937 (NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO);
markchien0f63ca62019-09-30 14:40:57 +0800938 if (networkInfo == null
939 || networkInfo.getDetailedState() == NetworkInfo.DetailedState.FAILED) {
Erik Kline2e88b5e2017-01-18 11:57:45 +0900940 return;
941 }
942
943 if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION: " + networkInfo.toString());
944 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
945 }
946
947 private void handleUsbAction(Intent intent) {
948 final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
Erik Klinec438e302017-07-04 22:02:49 +0900949 final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900950 final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);
Milim Lee31ef4c02019-10-17 05:02:33 +0900951 final boolean ncmEnabled = intent.getBooleanExtra(USB_FUNCTION_NCM, false);
Erik Klinec438e302017-07-04 22:02:49 +0900952
953 mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
954 usbConnected, usbConfigured, rndisEnabled));
955
956 // There are three types of ACTION_USB_STATE:
957 //
958 // - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
959 // Meaning: USB connection has ended either because of
960 // software reset or hard unplug.
961 //
962 // - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
963 // Meaning: the first stage of USB protocol handshake has
964 // occurred but it is not complete.
965 //
966 // - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
967 // Meaning: the USB handshake is completely done and all the
968 // functions are ready to use.
969 //
970 // For more explanation, see b/62552150 .
Erik Kline2e88b5e2017-01-18 11:57:45 +0900971 synchronized (Tethering.this.mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800972 if (!usbConnected && mRndisEnabled) {
973 // Turn off tethering if it was enabled and there is a disconnect.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900974 tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
markchien3b519632018-09-07 16:19:12 +0800975 mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800976 } else if (usbConfigured && rndisEnabled) {
977 // Tether if rndis is enabled and usb is configured.
Erik Kline7a4ccc62018-08-27 17:26:47 +0900978 tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
Milim Lee31ef4c02019-10-17 05:02:33 +0900979 } else if (usbConnected && ncmEnabled) {
980 tetherMatchingInterfaces(IpServer.STATE_LOCAL_ONLY, TETHERING_NCM);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900981 }
Jerry Zhang656a7bc2017-12-20 14:26:39 -0800982 mRndisEnabled = usbConfigured && rndisEnabled;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900983 }
984 }
985
986 private void handleWifiApAction(Intent intent) {
Erik Kline2efb8272017-05-31 15:53:53 +0900987 final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
988 final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
989 final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
990
Erik Kline2e88b5e2017-01-18 11:57:45 +0900991 synchronized (Tethering.this.mPublicSync) {
992 switch (curState) {
993 case WifiManager.WIFI_AP_STATE_ENABLING:
994 // We can see this state on the way to both enabled and failure states.
995 break;
996 case WifiManager.WIFI_AP_STATE_ENABLED:
Erik Kline2efb8272017-05-31 15:53:53 +0900997 enableWifiIpServingLocked(ifname, ipmode);
Erik Kline2e88b5e2017-01-18 11:57:45 +0900998 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +0900999 case WifiManager.WIFI_AP_STATE_DISABLING:
Mark Chien19487bf2020-04-15 17:28:27 +00001000 // We can see this state on the way to disabled.
1001 break;
1002 case WifiManager.WIFI_AP_STATE_DISABLED:
Erik Kline2e88b5e2017-01-18 11:57:45 +09001003 case WifiManager.WIFI_AP_STATE_FAILED:
1004 default:
Erik Kline562e0c12017-06-09 16:36:29 +09001005 disableWifiIpServingLocked(ifname, curState);
Erik Kline2efb8272017-05-31 15:53:53 +09001006 break;
Erik Kline2e88b5e2017-01-18 11:57:45 +09001007 }
1008 }
1009 }
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001010
Jimmy Chen151384d2019-12-03 11:37:09 +08001011 private boolean isGroupOwner(WifiP2pGroup group) {
1012 return group != null && group.isGroupOwner()
1013 && !TextUtils.isEmpty(group.getInterface());
1014 }
1015
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001016 private void handleWifiP2pAction(Intent intent) {
1017 if (mConfig.isWifiP2pLegacyTetheringMode()) return;
1018
1019 final WifiP2pInfo p2pInfo =
1020 (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
1021 final WifiP2pGroup group =
1022 (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
1023
1024 if (VDBG) {
1025 Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
1026 }
1027
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001028 synchronized (Tethering.this.mPublicSync) {
Jimmy Chen151384d2019-12-03 11:37:09 +08001029 // if no group is formed, bring it down if needed.
1030 if (p2pInfo == null || !p2pInfo.groupFormed) {
1031 disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
1032 mWifiP2pTetherInterface = null;
1033 return;
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001034 }
Jimmy Chen151384d2019-12-03 11:37:09 +08001035
1036 // If there is a group but the device is not the owner, bail out.
1037 if (!isGroupOwner(group)) return;
1038
1039 // If already serving from the correct interface, nothing to do.
1040 if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
1041
1042 // If already serving from another interface, turn it down first.
1043 if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
1044 mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
1045 + "is different from current interface "
1046 + group.getInterface() + ", re-tether it");
1047 disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
1048 }
1049
1050 // Finally bring up serving on the new interface
1051 mWifiP2pTetherInterface = group.getInterface();
1052 enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001053 }
1054 }
markchien1ddfba42019-11-27 21:20:33 +08001055
1056 private void handleUserRestrictionAction() {
1057 mTetheringRestriction.onUserRestrictionsChanged();
1058 }
markchien3fe660b2019-12-05 12:04:59 +08001059
1060 private void handleDataSaverChanged() {
1061 final ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(
1062 Context.CONNECTIVITY_SERVICE);
1063 final boolean isDataSaverEnabled = connMgr.getRestrictBackgroundStatus()
1064 != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
1065
1066 if (mDataSaverEnabled == isDataSaverEnabled) return;
1067
1068 mDataSaverEnabled = isDataSaverEnabled;
1069 if (mDataSaverEnabled) {
1070 untetherAll();
1071 }
1072 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001073 }
1074
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001075 @VisibleForTesting
Paul Hu4089bb12020-04-23 09:07:00 +00001076 boolean isTetheringActive() {
1077 return mActiveTetheringRequests.size() > 0;
1078 }
1079
1080 @VisibleForTesting
markchien1ddfba42019-11-27 21:20:33 +08001081 protected static class UserRestrictionActionListener {
markchiencb8860c2020-05-12 00:08:27 +08001082 private final UserManager mUserMgr;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001083 private final Tethering mWrapper;
Paul Huf950dc92020-03-25 12:39:13 +00001084 private final TetheringNotificationUpdater mNotificationUpdater;
markchien1ddfba42019-11-27 21:20:33 +08001085 public boolean mDisallowTethering;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001086
Paul Huf950dc92020-03-25 12:39:13 +00001087 public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
1088 @NonNull TetheringNotificationUpdater updater) {
markchiencb8860c2020-05-12 00:08:27 +08001089 mUserMgr = um;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001090 mWrapper = wrapper;
Paul Huf950dc92020-03-25 12:39:13 +00001091 mNotificationUpdater = updater;
markchien1ddfba42019-11-27 21:20:33 +08001092 mDisallowTethering = false;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001093 }
1094
markchien1ddfba42019-11-27 21:20:33 +08001095 public void onUserRestrictionsChanged() {
1096 // getUserRestrictions gets restriction for this process' user, which is the primary
1097 // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
1098 // user. See UserManager.DISALLOW_CONFIG_TETHERING.
markchiencb8860c2020-05-12 00:08:27 +08001099 final Bundle restrictions = mUserMgr.getUserRestrictions();
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001100 final boolean newlyDisallowed =
markchien1ddfba42019-11-27 21:20:33 +08001101 restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
1102 final boolean prevDisallowed = mDisallowTethering;
1103 mDisallowTethering = newlyDisallowed;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001104
markchien1ddfba42019-11-27 21:20:33 +08001105 final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed);
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001106 if (!tetheringDisallowedChanged) {
1107 return;
1108 }
1109
Paul Huf950dc92020-03-25 12:39:13 +00001110 if (!newlyDisallowed) {
1111 // Clear the restricted notification when user is allowed to have tethering
1112 // function.
1113 mNotificationUpdater.tetheringRestrictionLifted();
1114 return;
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001115 }
Paul Huf950dc92020-03-25 12:39:13 +00001116
Paul Hu4089bb12020-04-23 09:07:00 +00001117 if (mWrapper.isTetheringActive()) {
1118 // Restricted notification is shown when tethering function is disallowed on
1119 // user's device.
1120 mNotificationUpdater.notifyTetheringDisabledByRestriction();
Paul Huf950dc92020-03-25 12:39:13 +00001121
Paul Hu4089bb12020-04-23 09:07:00 +00001122 // Untether from all downstreams since tethering is disallowed.
1123 mWrapper.untetherAll();
1124 }
Paul Huf950dc92020-03-25 12:39:13 +00001125 // TODO(b/148139325): send tetheringSupported on restriction change
Alexandru-Andrei Rotarufa6d5c52017-07-18 16:49:22 +01001126 }
1127 }
1128
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001129 private void disableWifiIpServingLockedCommon(int tetheringType, String ifname, int apState) {
1130 mLog.log("Canceling WiFi tethering request -"
1131 + " type=" + tetheringType
1132 + " interface=" + ifname
1133 + " state=" + apState);
Erik Kline562e0c12017-06-09 16:36:29 +09001134
1135 if (!TextUtils.isEmpty(ifname)) {
1136 final TetherState ts = mTetherStates.get(ifname);
1137 if (ts != null) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001138 ts.ipServer.unwanted();
Erik Kline562e0c12017-06-09 16:36:29 +09001139 return;
1140 }
1141 }
1142
Erik Kline2efb8272017-05-31 15:53:53 +09001143 for (int i = 0; i < mTetherStates.size(); i++) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001144 final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001145 if (ipServer.interfaceType() == tetheringType) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001146 ipServer.unwanted();
Erik Kline562e0c12017-06-09 16:36:29 +09001147 return;
Erik Kline2efb8272017-05-31 15:53:53 +09001148 }
1149 }
Erik Kline562e0c12017-06-09 16:36:29 +09001150
markchien0f63ca62019-09-30 14:40:57 +08001151 mLog.log("Error disabling Wi-Fi IP serving; "
1152 + (TextUtils.isEmpty(ifname) ? "no interface name specified"
Erik Kline562e0c12017-06-09 16:36:29 +09001153 : "specified interface: " + ifname));
Erik Kline2efb8272017-05-31 15:53:53 +09001154 }
1155
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001156 private void disableWifiIpServingLocked(String ifname, int apState) {
1157 // Regardless of whether we requested this transition, the AP has gone
1158 // down. Don't try to tether again unless we're requested to do so.
1159 // TODO: Remove this altogether, once Wi-Fi reliably gives us an
1160 // interface name with every broadcast.
1161 mWifiTetherRequested = false;
1162
1163 disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
1164 }
1165
Jimmy Chen151384d2019-12-03 11:37:09 +08001166 private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
1167 if (TextUtils.isEmpty(ifname)) return;
1168
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001169 disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
1170 }
1171
Erik Kline2efb8272017-05-31 15:53:53 +09001172 private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001173 // Map wifiIpMode values to IpServer.Callback serving states, inferring
Erik Kline2efb8272017-05-31 15:53:53 +09001174 // from mWifiTetherRequested as a final "best guess".
1175 final int ipServingMode;
1176 switch (wifiIpMode) {
1177 case IFACE_IP_MODE_TETHERED:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001178 ipServingMode = IpServer.STATE_TETHERED;
Erik Kline2efb8272017-05-31 15:53:53 +09001179 break;
1180 case IFACE_IP_MODE_LOCAL_ONLY:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001181 ipServingMode = IpServer.STATE_LOCAL_ONLY;
Erik Kline2efb8272017-05-31 15:53:53 +09001182 break;
1183 default:
Erik Kline9e225542017-06-08 17:48:48 +09001184 mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
1185 return;
Erik Kline2efb8272017-05-31 15:53:53 +09001186 }
1187
1188 if (!TextUtils.isEmpty(ifname)) {
Jimmy Chenbcd86d02019-07-15 18:03:23 +08001189 maybeTrackNewInterfaceLocked(ifname);
Erik Kline2efb8272017-05-31 15:53:53 +09001190 changeInterfaceState(ifname, ipServingMode);
1191 } else {
Erik Kline9e225542017-06-08 17:48:48 +09001192 mLog.e(String.format(
markchien0f63ca62019-09-30 14:40:57 +08001193 "Cannot enable IP serving in mode %s on missing interface name",
1194 ipServingMode));
Erik Kline2efb8272017-05-31 15:53:53 +09001195 }
1196 }
1197
Erik Klineea9cc482017-03-10 19:35:34 +09001198 // TODO: Consider renaming to something more accurate in its description.
1199 // This method:
1200 // - allows requesting either tethering or local hotspot serving states
1201 // - handles both enabling and disabling serving states
1202 // - only tethers the first matching interface in listInterfaces()
1203 // order of a given type
1204 private void tetherMatchingInterfaces(int requestedState, int interfaceType) {
1205 if (VDBG) {
1206 Log.d(TAG, "tetherMatchingInterfaces(" + requestedState + ", " + interfaceType + ")");
1207 }
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001208
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001209 String[] ifaces = null;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001210 try {
markchiena9d9ef82020-01-07 14:43:17 +08001211 ifaces = mNetd.interfaceGetList();
1212 } catch (RemoteException | ServiceSpecificException e) {
Mike Lockwood3c2a2f62011-06-08 15:10:26 -07001213 Log.e(TAG, "Error listing Interfaces", e);
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001214 return;
1215 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001216 String chosenIface = null;
1217 if (ifaces != null) {
1218 for (String iface : ifaces) {
1219 if (ifaceNameToType(iface) == interfaceType) {
1220 chosenIface = iface;
1221 break;
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001222 }
1223 }
1224 }
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001225 if (chosenIface == null) {
1226 Log.e(TAG, "could not find iface of type " + interfaceType);
1227 return;
1228 }
1229
Erik Kline2efb8272017-05-31 15:53:53 +09001230 changeInterfaceState(chosenIface, requestedState);
1231 }
1232
1233 private void changeInterfaceState(String ifname, int requestedState) {
Erik Klineea9cc482017-03-10 19:35:34 +09001234 final int result;
1235 switch (requestedState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001236 case IpServer.STATE_UNAVAILABLE:
1237 case IpServer.STATE_AVAILABLE:
Erik Kline2efb8272017-05-31 15:53:53 +09001238 result = untether(ifname);
Erik Klineea9cc482017-03-10 19:35:34 +09001239 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001240 case IpServer.STATE_TETHERED:
1241 case IpServer.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001242 result = tether(ifname, requestedState);
Erik Klineea9cc482017-03-10 19:35:34 +09001243 break;
1244 default:
1245 Log.wtf(TAG, "Unknown interface state: " + requestedState);
1246 return;
1247 }
Erik Kline7a26ba32018-03-09 14:18:02 +09001248 if (result != TETHER_ERROR_NO_ERROR) {
Erik Kline2efb8272017-05-31 15:53:53 +09001249 Log.e(TAG, "unable start or stop tethering on iface " + ifname);
Christopher Wiley5c0b10a2016-05-31 14:43:08 -07001250 return;
1251 }
Robert Greenwalt65ae29b2010-02-18 11:25:54 -08001252 }
1253
markchien0f63ca62019-09-30 14:40:57 +08001254 TetheringConfiguration getTetheringConfiguration() {
Erik Kline3e756652017-01-17 13:42:19 +09001255 return mConfig;
1256 }
1257
markchien0f63ca62019-09-30 14:40:57 +08001258 boolean hasTetherableConfiguration() {
Erik Klined781fba2017-01-23 13:01:58 +09001259 final TetheringConfiguration cfg = mConfig;
1260 final boolean hasDownstreamConfiguration =
markchien1be8d8f2018-12-05 21:20:01 +08001261 (cfg.tetherableUsbRegexs.length != 0)
1262 || (cfg.tetherableWifiRegexs.length != 0)
1263 || (cfg.tetherableBluetoothRegexs.length != 0);
1264 final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
1265 || cfg.chooseUpstreamAutomatically;
Erik Klined781fba2017-01-23 13:01:58 +09001266
1267 return hasDownstreamConfiguration && hasUpstreamConfiguration;
1268 }
1269
Erik Kline3e756652017-01-17 13:42:19 +09001270 // TODO - update callers to use getTetheringConfiguration(),
1271 // which has only final members.
markchien0f63ca62019-09-30 14:40:57 +08001272 String[] getTetherableUsbRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001273 return copy(mConfig.tetherableUsbRegexs);
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001274 }
1275
markchien0f63ca62019-09-30 14:40:57 +08001276 String[] getTetherableWifiRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001277 return copy(mConfig.tetherableWifiRegexs);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001278 }
1279
markchien0f63ca62019-09-30 14:40:57 +08001280 String[] getTetherableBluetoothRegexs() {
Erik Kline3e756652017-01-17 13:42:19 +09001281 return copy(mConfig.tetherableBluetoothRegexs);
Danica Chang6fdd0c62010-08-11 14:54:43 -07001282 }
1283
markchien0f63ca62019-09-30 14:40:57 +08001284 int setUsbTethering(boolean enable) {
Wink Savillec9acde92011-09-21 11:05:43 -07001285 if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
Erik Klinec438e302017-07-04 22:02:49 +09001286 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
Ye Jiao21f96252019-01-28 12:54:22 +08001287 if (usbManager == null) {
1288 mLog.e("setUsbTethering: failed to get UsbManager!");
1289 return TETHER_ERROR_SERVICE_UNAVAIL;
1290 }
1291
Robert Greenwaltb4453622011-11-03 16:01:40 -07001292 synchronized (mPublicSync) {
Jerry Zhang327b8092018-01-09 17:53:04 -08001293 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
1294 : UsbManager.FUNCTION_NONE);
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001295 }
Erik Kline7a26ba32018-03-09 14:18:02 +09001296 return TETHER_ERROR_NO_ERROR;
Mike Lockwood6c2260b2011-07-19 13:04:47 -07001297 }
1298
Milim Lee31ef4c02019-10-17 05:02:33 +09001299 private int setNcmTethering(boolean enable) {
1300 if (VDBG) Log.d(TAG, "setNcmTethering(" + enable + ")");
1301 UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
1302 synchronized (mPublicSync) {
1303 usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_NCM
1304 : UsbManager.FUNCTION_NONE);
1305 }
1306 return TETHER_ERROR_NO_ERROR;
1307 }
1308
Erik Kline1fdc2e22017-05-08 17:56:35 +09001309 // TODO review API - figure out how to delete these entirely.
markchien0f63ca62019-09-30 14:40:57 +08001310 String[] getTetheredIfaces() {
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001311 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001312 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001313 for (int i = 0; i < mTetherStates.size(); i++) {
1314 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001315 if (tetherState.lastState == IpServer.STATE_TETHERED) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001316 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001317 }
1318 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08001319 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001320 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001321 }
1322
markchien0f63ca62019-09-30 14:40:57 +08001323 String[] getTetherableIfaces() {
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001324 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001325 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001326 for (int i = 0; i < mTetherStates.size(); i++) {
1327 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001328 if (tetherState.lastState == IpServer.STATE_AVAILABLE) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001329 list.add(mTetherStates.keyAt(i));
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001330 }
1331 }
1332 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001333 return list.toArray(new String[list.size()]);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001334 }
1335
markchien0f63ca62019-09-30 14:40:57 +08001336 String[] getTetheredDhcpRanges() {
Remi NGUYEN VANe3bb5c52018-06-12 15:57:04 +09001337 // TODO: this is only valid for the old DHCP server. Latest search suggests it is only used
1338 // by WifiP2pServiceImpl to start dnsmasq: remove/deprecate after migrating callers.
1339 return mConfig.legacyDhcpRanges;
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07001340 }
1341
markchien0f63ca62019-09-30 14:40:57 +08001342 String[] getErroredIfaces() {
Robert Greenwalt5a735062010-03-02 17:25:02 -08001343 ArrayList<String> list = new ArrayList<String>();
Robert Greenwaltb4453622011-11-03 16:01:40 -07001344 synchronized (mPublicSync) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001345 for (int i = 0; i < mTetherStates.size(); i++) {
1346 TetherState tetherState = mTetherStates.valueAt(i);
Erik Kline7a26ba32018-03-09 14:18:02 +09001347 if (tetherState.lastError != TETHER_ERROR_NO_ERROR) {
Christopher Wileyd985dde2016-05-31 10:44:35 -07001348 list.add(mTetherStates.keyAt(i));
Robert Greenwalt5a735062010-03-02 17:25:02 -08001349 }
1350 }
1351 }
Christopher Wileyd985dde2016-05-31 10:44:35 -07001352 return list.toArray(new String[list.size()]);
Robert Greenwalt5a735062010-03-02 17:25:02 -08001353 }
1354
Erik Kline22108902017-07-06 16:40:06 +09001355 private void logMessage(State state, int what) {
1356 mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001357 }
1358
Erik Klineea9cc482017-03-10 19:35:34 +09001359 private boolean upstreamWanted() {
1360 if (!mForwardedDownstreams.isEmpty()) return true;
1361
1362 synchronized (mPublicSync) {
Jerry Zhang656a7bc2017-12-20 14:26:39 -08001363 return mWifiTetherRequested;
Erik Klineea9cc482017-03-10 19:35:34 +09001364 }
1365 }
1366
Erik Kline00019f42016-06-30 19:31:46 +09001367 // Needed because the canonical source of upstream truth is just the
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001368 // upstream interface set, |mCurrentUpstreamIfaceSet|.
markchienb0aca962019-12-05 16:21:17 +08001369 private boolean pertainsToCurrentUpstream(UpstreamNetworkState ns) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001370 if (ns != null && ns.linkProperties != null && mCurrentUpstreamIfaceSet != null) {
Erik Kline00019f42016-06-30 19:31:46 +09001371 for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001372 if (mCurrentUpstreamIfaceSet.ifnames.contains(ifname)) {
Erik Kline00019f42016-06-30 19:31:46 +09001373 return true;
Erik Kline6ff17f72015-12-10 20:42:12 +09001374 }
1375 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001376 }
Erik Kline00019f42016-06-30 19:31:46 +09001377 return false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001378 }
1379
Wink Saville64c42ca2011-04-18 14:55:10 -07001380 class TetherMasterSM extends StateMachine {
Erik Klineea9cc482017-03-10 19:35:34 +09001381 // an interface SM has requested Tethering/Local Hotspot
1382 static final int EVENT_IFACE_SERVING_STATE_ACTIVE = BASE_MASTER + 1;
1383 // an interface SM has unrequested Tethering/Local Hotspot
1384 static final int EVENT_IFACE_SERVING_STATE_INACTIVE = BASE_MASTER + 2;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001385 // upstream connection change - do the right thing
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001386 static final int CMD_UPSTREAM_CHANGED = BASE_MASTER + 3;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001387 // we don't have a valid upstream conn, check again after a delay
Lorenzo Colitticd63d242016-04-10 15:39:53 +09001388 static final int CMD_RETRY_UPSTREAM = BASE_MASTER + 4;
Erik Kline6ff17f72015-12-10 20:42:12 +09001389 // Events from NetworkCallbacks that we process on the master state
1390 // machine thread on behalf of the UpstreamNetworkMonitor.
Erik Kline00019f42016-06-30 19:31:46 +09001391 static final int EVENT_UPSTREAM_CALLBACK = BASE_MASTER + 5;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001392 // we treated the error and want now to clear it
1393 static final int CMD_CLEAR_ERROR = BASE_MASTER + 6;
Erik Kline6e9a1012017-06-06 19:24:21 +09001394 static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7;
markchien3b519632018-09-07 16:19:12 +08001395 // Events from EntitlementManager to choose upstream again.
1396 static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8;
Erik Kline32179ff2017-07-04 18:28:11 +09001397 private final State mInitialState;
1398 private final State mTetherModeAliveState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001399
Erik Kline32179ff2017-07-04 18:28:11 +09001400 private final State mSetIpForwardingEnabledErrorState;
1401 private final State mSetIpForwardingDisabledErrorState;
1402 private final State mStartTetheringErrorState;
1403 private final State mStopTetheringErrorState;
1404 private final State mSetDnsForwardersErrorState;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001405
Christopher Wileyd985dde2016-05-31 10:44:35 -07001406 // This list is a little subtle. It contains all the interfaces that currently are
1407 // requesting tethering, regardless of whether these interfaces are still members of
1408 // mTetherStates. This allows us to maintain the following predicates:
1409 //
1410 // 1) mTetherStates contains the set of all currently existing, tetherable, link state up
1411 // interfaces.
1412 // 2) mNotifyList contains all state machines that may have outstanding tethering state
1413 // that needs to be torn down.
1414 //
1415 // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList
1416 // so that the garbage collector does not clean up the state machine before it has a chance
1417 // to tear itself down.
Erik Kline7a4ccc62018-08-27 17:26:47 +09001418 private final ArrayList<IpServer> mNotifyList;
Erik Kline1eb8c692016-07-08 17:21:26 +09001419 private final IPv6TetheringCoordinator mIPv6TetheringCoordinator;
Erik Klineed962a82017-07-06 19:49:35 +09001420 private final OffloadWrapper mOffload;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001421
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001422 private static final int UPSTREAM_SETTLE_TIME_MS = 10000;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001423
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +09001424 TetherMasterSM(String name, Looper looper, TetheringDependencies deps) {
Robert Greenwaltdfadaea2010-03-11 15:03:08 -08001425 super(name, looper);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001426
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001427 mInitialState = new InitialState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001428 mTetherModeAliveState = new TetherModeAliveState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001429 mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001430 mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001431 mStartTetheringErrorState = new StartTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001432 mStopTetheringErrorState = new StopTetheringErrorState();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001433 mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
Erik Kline1fdc2e22017-05-08 17:56:35 +09001434
1435 addState(mInitialState);
1436 addState(mTetherModeAliveState);
1437 addState(mSetIpForwardingEnabledErrorState);
1438 addState(mSetIpForwardingDisabledErrorState);
1439 addState(mStartTetheringErrorState);
1440 addState(mStopTetheringErrorState);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001441 addState(mSetDnsForwardersErrorState);
1442
Mitchell Wills7040b4e2016-05-23 16:40:10 -07001443 mNotifyList = new ArrayList<>();
Remi NGUYEN VAN5d0dc452018-03-15 11:57:14 +09001444 mIPv6TetheringCoordinator = deps.getIPv6TetheringCoordinator(mNotifyList, mLog);
Erik Klineed962a82017-07-06 19:49:35 +09001445 mOffload = new OffloadWrapper();
Erik Kline32179ff2017-07-04 18:28:11 +09001446
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001447 setInitialState(mInitialState);
1448 }
1449
Erik Kline1fdc2e22017-05-08 17:56:35 +09001450 class InitialState extends State {
1451 @Override
1452 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001453 logMessage(this, message.what);
Erik Kline1fdc2e22017-05-08 17:56:35 +09001454 switch (message.what) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001455 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
1456 final IpServer who = (IpServer) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001457 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
1458 handleInterfaceServingStateActive(message.arg1, who);
1459 transitionTo(mTetherModeAliveState);
1460 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001461 }
1462 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
1463 final IpServer who = (IpServer) message.obj;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001464 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
1465 handleInterfaceServingStateInactive(who);
1466 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001467 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001468 case EVENT_IFACE_UPDATE_LINKPROPERTIES:
1469 // Silently ignore these for now.
1470 break;
Erik Kline1fdc2e22017-05-08 17:56:35 +09001471 default:
1472 return NOT_HANDLED;
1473 }
1474 return HANDLED;
1475 }
1476 }
1477
Erik Kline3a5278f2017-06-24 19:29:10 +09001478 protected boolean turnOnMasterTetherSettings() {
1479 final TetheringConfiguration cfg = mConfig;
1480 try {
markchiena9d9ef82020-01-07 14:43:17 +08001481 mNetd.ipfwdEnableForwarding(TAG);
1482 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001483 mLog.e(e);
1484 transitionTo(mSetIpForwardingEnabledErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001485 return false;
1486 }
markchiena9d9ef82020-01-07 14:43:17 +08001487
Erik Kline3a5278f2017-06-24 19:29:10 +09001488 // TODO: Randomize DHCPv4 ranges, especially in hotspot mode.
Remi NGUYEN VANe3bb5c52018-06-12 15:57:04 +09001489 // Legacy DHCP server is disabled if passed an empty ranges array
1490 final String[] dhcpRanges = cfg.enableLegacyDhcpServer
markchiena9d9ef82020-01-07 14:43:17 +08001491 ? cfg.legacyDhcpRanges : new String[0];
Erik Kline3a5278f2017-06-24 19:29:10 +09001492 try {
markchiena9d9ef82020-01-07 14:43:17 +08001493 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
1494 } catch (RemoteException | ServiceSpecificException e) {
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001495 try {
markchiena9d9ef82020-01-07 14:43:17 +08001496 // Stop and retry.
1497 mNetd.tetherStop();
1498 NetdUtils.tetherStart(mNetd, true /** usingLegacyDnsProxy */, dhcpRanges);
1499 } catch (RemoteException | ServiceSpecificException ee) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001500 mLog.e(ee);
1501 transitionTo(mStartTetheringErrorState);
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001502 return false;
1503 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001504 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001505 mLog.log("SET master tether settings: ON");
1506 return true;
1507 }
Robert Greenwalt10398722010-12-17 15:20:36 -08001508
Erik Kline3a5278f2017-06-24 19:29:10 +09001509 protected boolean turnOffMasterTetherSettings() {
1510 try {
markchiena9d9ef82020-01-07 14:43:17 +08001511 mNetd.tetherStop();
1512 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001513 mLog.e(e);
1514 transitionTo(mStopTetheringErrorState);
1515 return false;
Erik Kline14f7faf2017-02-14 19:03:09 +09001516 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001517 try {
markchiena9d9ef82020-01-07 14:43:17 +08001518 mNetd.ipfwdDisableForwarding(TAG);
1519 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001520 mLog.e(e);
1521 transitionTo(mSetIpForwardingDisabledErrorState);
1522 return false;
1523 }
1524 transitionTo(mInitialState);
1525 mLog.log("SET master tether settings: OFF");
1526 return true;
1527 }
Erik Kline14f7faf2017-02-14 19:03:09 +09001528
Erik Kline3a5278f2017-06-24 19:29:10 +09001529 protected void chooseUpstreamType(boolean tryCell) {
Erik Kline6ee73da2017-07-08 20:36:37 +09001530 // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we
1531 // do not currently know how to watch for changes in DUN settings.
markchien3394e142019-04-09 15:53:24 +08001532 maybeDunSettingChanged();
Erik Kline1e2897d2017-06-09 17:08:52 +09001533
Erik Kline72302902018-06-14 17:36:40 +09001534 final TetheringConfiguration config = mConfig;
markchienb0aca962019-12-05 16:21:17 +08001535 final UpstreamNetworkState ns = (config.chooseUpstreamAutomatically)
Erik Kline72302902018-06-14 17:36:40 +09001536 ? mUpstreamNetworkMonitor.getCurrentPreferredUpstream()
1537 : mUpstreamNetworkMonitor.selectPreferredUpstreamType(
1538 config.preferredUpstreamIfaceTypes);
Erik Kline3a5278f2017-06-24 19:29:10 +09001539 if (ns == null) {
1540 if (tryCell) {
1541 mUpstreamNetworkMonitor.registerMobileNetworkRequest();
1542 // We think mobile should be coming up; don't set a retry.
1543 } else {
1544 sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
Erik Kline1e2897d2017-06-09 17:08:52 +09001545 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001546 }
1547 setUpstreamNetwork(ns);
markchien26299ed2019-02-27 14:56:11 +08001548 final Network newUpstream = (ns != null) ? ns.network : null;
1549 if (mTetherUpstream != newUpstream) {
1550 mTetherUpstream = newUpstream;
1551 mUpstreamNetworkMonitor.setCurrentUpstream(mTetherUpstream);
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001552 reportUpstreamChanged(ns);
markchien26299ed2019-02-27 14:56:11 +08001553 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001554 }
1555
markchienb0aca962019-12-05 16:21:17 +08001556 protected void setUpstreamNetwork(UpstreamNetworkState ns) {
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001557 InterfaceSet ifaces = null;
Erik Klinee8bdb402018-02-23 14:16:06 -08001558 if (ns != null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001559 // Find the interface with the default IPv4 route. It may be the
1560 // interface described by linkProperties, or one of the interfaces
1561 // stacked on top of it.
Erik Klinee8bdb402018-02-23 14:16:06 -08001562 mLog.i("Looking for default routes on: " + ns.linkProperties);
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001563 ifaces = TetheringInterfaceUtils.getTetheringInterfaces(ns);
1564 mLog.i("Found upstream interface(s): " + ifaces);
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001565 }
Robert Greenwaltccf83af12011-06-02 17:30:47 -07001566
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001567 if (ifaces != null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001568 setDnsForwarders(ns.network, ns.linkProperties);
Erik Kline6ff17f72015-12-10 20:42:12 +09001569 }
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001570 notifyDownstreamsOfNewUpstreamIface(ifaces);
Erik Kline3a5278f2017-06-24 19:29:10 +09001571 if (ns != null && pertainsToCurrentUpstream(ns)) {
markchienb0aca962019-12-05 16:21:17 +08001572 // If we already have UpstreamNetworkState for this network update it immediately.
Erik Kline3a5278f2017-06-24 19:29:10 +09001573 handleNewUpstreamNetworkState(ns);
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001574 } else if (mCurrentUpstreamIfaceSet == null) {
1575 // There are no available upstream networks.
Erik Kline3a5278f2017-06-24 19:29:10 +09001576 handleNewUpstreamNetworkState(null);
1577 }
1578 }
Erik Kline6ff17f72015-12-10 20:42:12 +09001579
Erik Kline3a5278f2017-06-24 19:29:10 +09001580 protected void setDnsForwarders(final Network network, final LinkProperties lp) {
1581 // TODO: Set v4 and/or v6 DNS per available connectivity.
Erik Kline3a5278f2017-06-24 19:29:10 +09001582 final Collection<InetAddress> dnses = lp.getDnsServers();
1583 // TODO: Properly support the absence of DNS servers.
markchien87d3f7d2020-01-08 20:58:23 +08001584 final String[] dnsServers;
Erik Kline3a5278f2017-06-24 19:29:10 +09001585 if (dnses != null && !dnses.isEmpty()) {
markchien87d3f7d2020-01-08 20:58:23 +08001586 dnsServers = new String[dnses.size()];
1587 int i = 0;
1588 for (InetAddress dns : dnses) {
1589 dnsServers[i++] = dns.getHostAddress();
1590 }
1591 } else {
1592 dnsServers = mConfig.defaultIPv4DNS;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001593 }
markchien587ecb32020-03-18 08:43:07 +08001594 final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
Erik Kline3a5278f2017-06-24 19:29:10 +09001595 try {
markchiena9d9ef82020-01-07 14:43:17 +08001596 mNetd.tetherDnsSet(netId, dnsServers);
Erik Kline3a5278f2017-06-24 19:29:10 +09001597 mLog.log(String.format(
1598 "SET DNS forwarders: network=%s dnsServers=%s",
1599 network, Arrays.toString(dnsServers)));
markchiena9d9ef82020-01-07 14:43:17 +08001600 } catch (RemoteException | ServiceSpecificException e) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001601 // TODO: Investigate how this can fail and what exactly
1602 // happens if/when such failures occur.
1603 mLog.e("setting DNS forwarders failed, " + e);
1604 transitionTo(mSetDnsForwardersErrorState);
1605 }
1606 }
Erik Kline00019f42016-06-30 19:31:46 +09001607
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001608 protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) {
1609 mCurrentUpstreamIfaceSet = ifaces;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001610 for (IpServer ipServer : mNotifyList) {
1611 ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces);
Erik Kline00019f42016-06-30 19:31:46 +09001612 }
Robert Greenwaltd70a3d42010-02-23 18:15:29 -08001613 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001614
markchienb0aca962019-12-05 16:21:17 +08001615 protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001616 mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
Erik Klineed962a82017-07-06 19:49:35 +09001617 mOffload.updateUpstreamNetworkState(ns);
Erik Kline3a5278f2017-06-24 19:29:10 +09001618 }
1619
Erik Kline7a4ccc62018-08-27 17:26:47 +09001620 private void handleInterfaceServingStateActive(int mode, IpServer who) {
Erik Klineea9cc482017-03-10 19:35:34 +09001621 if (mNotifyList.indexOf(who) < 0) {
1622 mNotifyList.add(who);
1623 mIPv6TetheringCoordinator.addActiveDownstream(who, mode);
1624 }
1625
Erik Kline7a4ccc62018-08-27 17:26:47 +09001626 if (mode == IpServer.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001627 // No need to notify OffloadController just yet as there are no
1628 // "offload-able" prefixes to pass along. This will handled
1629 // when the TISM informs Tethering of its LinkProperties.
Erik Klineea9cc482017-03-10 19:35:34 +09001630 mForwardedDownstreams.add(who);
1631 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001632 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001633 mForwardedDownstreams.remove(who);
1634 }
Erik Kline216af6d2017-04-27 20:57:23 +09001635
1636 // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
Erik Kline7a26ba32018-03-09 14:18:02 +09001637 if (who.interfaceType() == TETHERING_WIFI) {
Erik Kline216af6d2017-04-27 20:57:23 +09001638 final WifiManager mgr = getWifiManager();
1639 final String iface = who.interfaceName();
1640 switch (mode) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001641 case IpServer.STATE_TETHERED:
Erik Kline2efb8272017-05-31 15:53:53 +09001642 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
Erik Kline216af6d2017-04-27 20:57:23 +09001643 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001644 case IpServer.STATE_LOCAL_ONLY:
Erik Kline2efb8272017-05-31 15:53:53 +09001645 mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
Erik Kline216af6d2017-04-27 20:57:23 +09001646 break;
1647 default:
1648 Log.wtf(TAG, "Unknown active serving mode: " + mode);
1649 break;
1650 }
1651 }
Erik Klineea9cc482017-03-10 19:35:34 +09001652 }
1653
Erik Kline7a4ccc62018-08-27 17:26:47 +09001654 private void handleInterfaceServingStateInactive(IpServer who) {
Erik Klineea9cc482017-03-10 19:35:34 +09001655 mNotifyList.remove(who);
1656 mIPv6TetheringCoordinator.removeActiveDownstream(who);
Erik Klineed962a82017-07-06 19:49:35 +09001657 mOffload.excludeDownstreamInterface(who.interfaceName());
Erik Klineea9cc482017-03-10 19:35:34 +09001658 mForwardedDownstreams.remove(who);
Treehugger Robot25067812020-03-25 15:32:41 +00001659 updateConnectedClients(null /* wifiClients */);
Erik Kline216af6d2017-04-27 20:57:23 +09001660
Jianpeng Lia70feec2019-05-24 17:40:15 +09001661 // If this is a Wi-Fi interface, tell WifiManager of any errors
1662 // or the inactive serving state.
Erik Kline7a26ba32018-03-09 14:18:02 +09001663 if (who.interfaceType() == TETHERING_WIFI) {
1664 if (who.lastError() != TETHER_ERROR_NO_ERROR) {
Erik Kline216af6d2017-04-27 20:57:23 +09001665 getWifiManager().updateInterfaceIpState(
Erik Kline2efb8272017-05-31 15:53:53 +09001666 who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
Jianpeng Lia70feec2019-05-24 17:40:15 +09001667 } else {
1668 getWifiManager().updateInterfaceIpState(
1669 who.interfaceName(), IFACE_IP_MODE_UNSPECIFIED);
Erik Kline216af6d2017-04-27 20:57:23 +09001670 }
1671 }
Erik Klineea9cc482017-03-10 19:35:34 +09001672 }
1673
Mark Chiendb6befb2020-05-29 22:07:37 +00001674 private void addUpstreamPrefixes(final UpstreamNetworkState ns) {
1675 mPrivateAddressCoordinator.updateUpstreamPrefix(ns.network, ns.linkProperties);
1676 }
1677
1678 private void removeUpstreamPrefixes(final UpstreamNetworkState ns) {
1679 mPrivateAddressCoordinator.removeUpstreamPrefix(ns.network);
1680 }
1681
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001682 @VisibleForTesting
1683 void handleUpstreamNetworkMonitorCallback(int arg1, Object o) {
Erik Kline32179ff2017-07-04 18:28:11 +09001684 if (arg1 == UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES) {
Erik Klineed962a82017-07-06 19:49:35 +09001685 mOffload.sendOffloadExemptPrefixes((Set<IpPrefix>) o);
Erik Kline3a5278f2017-06-24 19:29:10 +09001686 return;
1687 }
1688
markchienb0aca962019-12-05 16:21:17 +08001689 final UpstreamNetworkState ns = (UpstreamNetworkState) o;
Mark Chiendb6befb2020-05-29 22:07:37 +00001690 switch (arg1) {
1691 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
1692 addUpstreamPrefixes(ns);
1693 break;
1694 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1695 removeUpstreamPrefixes(ns);
1696 break;
1697 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001698
1699 if (ns == null || !pertainsToCurrentUpstream(ns)) {
1700 // TODO: In future, this is where upstream evaluation and selection
1701 // could be handled for notifications which include sufficient data.
1702 // For example, after CONNECTIVITY_ACTION listening is removed, here
1703 // is where we could observe a Wi-Fi network becoming available and
1704 // passing validation.
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001705 if (mCurrentUpstreamIfaceSet == null) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001706 // If we have no upstream interface, try to run through upstream
1707 // selection again. If, for example, IPv4 connectivity has shown up
1708 // after IPv6 (e.g., 464xlat became available) we want the chance to
1709 // notice and act accordingly.
1710 chooseUpstreamType(false);
1711 }
1712 return;
1713 }
1714
1715 switch (arg1) {
Erik Kline3a5278f2017-06-24 19:29:10 +09001716 case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
Chalard Jeanc0fc2762020-04-17 17:12:44 +00001717 if (ns.network.equals(mTetherUpstream)) {
1718 mNotificationUpdater.onUpstreamCapabilitiesChanged(ns.networkCapabilities);
1719 }
Erik Kline3a5278f2017-06-24 19:29:10 +09001720 handleNewUpstreamNetworkState(ns);
1721 break;
1722 case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001723 chooseUpstreamType(false);
Erik Kline3a5278f2017-06-24 19:29:10 +09001724 break;
1725 case UpstreamNetworkMonitor.EVENT_ON_LOST:
1726 // TODO: Re-evaluate possible upstreams. Currently upstream
1727 // reevaluation is triggered via received CONNECTIVITY_ACTION
1728 // broadcasts that result in being passed a
1729 // TetherMasterSM.CMD_UPSTREAM_CHANGED.
1730 handleNewUpstreamNetworkState(null);
1731 break;
1732 default:
1733 mLog.e("Unknown arg1 value: " + arg1);
1734 break;
1735 }
1736 }
1737
1738 class TetherModeAliveState extends State {
Erik Klineea9cc482017-03-10 19:35:34 +09001739 boolean mUpstreamWanted = false;
Erik Kline6ff17f72015-12-10 20:42:12 +09001740 boolean mTryCell = true;
Erik Klinee0cce212017-03-06 14:05:23 +09001741
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001742 @Override
1743 public void enter() {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001744 // If turning on master tether settings fails, we have already
1745 // transitioned to an error state; exit early.
1746 if (!turnOnMasterTetherSettings()) {
1747 return;
1748 }
1749
markchiena6c72872018-11-13 18:34:56 +09001750 mUpstreamNetworkMonitor.startObserveAllNetworks();
Robert Greenwalt4f74d552011-12-19 16:59:31 -08001751
Erik Klinef4b6e342017-04-25 19:19:59 +09001752 // TODO: De-duplicate with updateUpstreamWanted() below.
Erik Klineea9cc482017-03-10 19:35:34 +09001753 if (upstreamWanted()) {
1754 mUpstreamWanted = true;
Erik Klineed962a82017-07-06 19:49:35 +09001755 mOffload.start();
Erik Klineea9cc482017-03-10 19:35:34 +09001756 chooseUpstreamType(true);
1757 mTryCell = false;
1758 }
Hungming Chenbe4827d2020-06-02 00:13:26 +00001759
1760 // TODO: Check the upstream interface if it is managed by BPF offload.
Treehugger Robot96895192020-06-09 13:28:38 +00001761 mBpfCoordinator.startPolling();
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001762 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001763
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001764 @Override
1765 public void exit() {
Erik Klineed962a82017-07-06 19:49:35 +09001766 mOffload.stop();
Erik Kline6ff17f72015-12-10 20:42:12 +09001767 mUpstreamNetworkMonitor.stop();
Erik Kline22108902017-07-06 16:40:06 +09001768 notifyDownstreamsOfNewUpstreamIface(null);
Erik Klinefa37b2f2016-08-02 18:27:03 +09001769 handleNewUpstreamNetworkState(null);
markchien26299ed2019-02-27 14:56:11 +08001770 if (mTetherUpstream != null) {
1771 mTetherUpstream = null;
1772 reportUpstreamChanged(null);
1773 }
Treehugger Robot96895192020-06-09 13:28:38 +00001774 mBpfCoordinator.stopPolling();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001775 }
Erik Klinefa37b2f2016-08-02 18:27:03 +09001776
Erik Klineea9cc482017-03-10 19:35:34 +09001777 private boolean updateUpstreamWanted() {
1778 final boolean previousUpstreamWanted = mUpstreamWanted;
1779 mUpstreamWanted = upstreamWanted();
Erik Klinef4b6e342017-04-25 19:19:59 +09001780 if (mUpstreamWanted != previousUpstreamWanted) {
1781 if (mUpstreamWanted) {
Erik Klineed962a82017-07-06 19:49:35 +09001782 mOffload.start();
Erik Klinef4b6e342017-04-25 19:19:59 +09001783 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001784 mOffload.stop();
Erik Klinef4b6e342017-04-25 19:19:59 +09001785 }
1786 }
Erik Klineea9cc482017-03-10 19:35:34 +09001787 return previousUpstreamWanted;
1788 }
1789
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001790 @Override
1791 public boolean processMessage(Message message) {
Erik Kline22108902017-07-06 16:40:06 +09001792 logMessage(this, message.what);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001793 boolean retValue = true;
1794 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001795 case EVENT_IFACE_SERVING_STATE_ACTIVE: {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001796 IpServer who = (IpServer) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001797 if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001798 handleInterfaceServingStateActive(message.arg1, who);
Erik Kline7a4ccc62018-08-27 17:26:47 +09001799 who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED,
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09001800 mCurrentUpstreamIfaceSet);
Erik Klineea9cc482017-03-10 19:35:34 +09001801 // If there has been a change and an upstream is now
1802 // desired, kick off the selection process.
1803 final boolean previousUpstreamWanted = updateUpstreamWanted();
1804 if (!previousUpstreamWanted && mUpstreamWanted) {
1805 chooseUpstreamType(true);
1806 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001807 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001808 }
Erik Klineea9cc482017-03-10 19:35:34 +09001809 case EVENT_IFACE_SERVING_STATE_INACTIVE: {
Erik Kline7a4ccc62018-08-27 17:26:47 +09001810 IpServer who = (IpServer) message.obj;
Robert Greenwalt68ea9b02012-05-10 16:58:16 -07001811 if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
Erik Klineea9cc482017-03-10 19:35:34 +09001812 handleInterfaceServingStateInactive(who);
1813
1814 if (mNotifyList.isEmpty()) {
Erik Kline47222fc2017-04-30 19:36:15 +09001815 // This transitions us out of TetherModeAliveState,
1816 // either to InitialState or an error state.
Erik Kline1fdc2e22017-05-08 17:56:35 +09001817 turnOffMasterTetherSettings();
1818 break;
1819 }
1820
1821 if (DBG) {
markchien0f63ca62019-09-30 14:40:57 +08001822 Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size()
1823 + " live requests:");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001824 for (IpServer o : mNotifyList) {
Erik Kline1fdc2e22017-05-08 17:56:35 +09001825 Log.d(TAG, " " + o);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001826 }
1827 }
Erik Klineea9cc482017-03-10 19:35:34 +09001828 // If there has been a change and an upstream is no
1829 // longer desired, release any mobile requests.
1830 final boolean previousUpstreamWanted = updateUpstreamWanted();
1831 if (previousUpstreamWanted && !mUpstreamWanted) {
1832 mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
1833 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001834 break;
Erik Kline6e29bf02016-08-15 16:16:18 +09001835 }
Erik Kline6e9a1012017-06-06 19:24:21 +09001836 case EVENT_IFACE_UPDATE_LINKPROPERTIES: {
1837 final LinkProperties newLp = (LinkProperties) message.obj;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001838 if (message.arg1 == IpServer.STATE_TETHERED) {
Erik Klineed962a82017-07-06 19:49:35 +09001839 mOffload.updateDownstreamLinkProperties(newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09001840 } else {
Erik Klineed962a82017-07-06 19:49:35 +09001841 mOffload.excludeDownstreamInterface(newLp.getInterfaceName());
Erik Kline6e9a1012017-06-06 19:24:21 +09001842 }
1843 break;
1844 }
markchien3b519632018-09-07 16:19:12 +08001845 case EVENT_UPSTREAM_PERMISSION_CHANGED:
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001846 case CMD_UPSTREAM_CHANGED:
Erik Klineea9cc482017-03-10 19:35:34 +09001847 updateUpstreamWanted();
1848 if (!mUpstreamWanted) break;
1849
Erik Klinefb413432017-02-14 18:26:04 +09001850 // Need to try DUN immediately if Wi-Fi goes down.
1851 chooseUpstreamType(true);
1852 mTryCell = false;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001853 break;
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001854 case CMD_RETRY_UPSTREAM:
Erik Klineea9cc482017-03-10 19:35:34 +09001855 updateUpstreamWanted();
1856 if (!mUpstreamWanted) break;
1857
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001858 chooseUpstreamType(mTryCell);
1859 mTryCell = !mTryCell;
1860 break;
Erik Kline00019f42016-06-30 19:31:46 +09001861 case EVENT_UPSTREAM_CALLBACK: {
Erik Klineea9cc482017-03-10 19:35:34 +09001862 updateUpstreamWanted();
Erik Kline3a5278f2017-06-24 19:29:10 +09001863 if (mUpstreamWanted) {
1864 handleUpstreamNetworkMonitorCallback(message.arg1, message.obj);
Erik Kline6ff17f72015-12-10 20:42:12 +09001865 }
1866 break;
Erik Kline00019f42016-06-30 19:31:46 +09001867 }
Kazuhiro Ondo01758e82011-04-30 20:10:57 -05001868 default:
1869 retValue = false;
1870 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001871 }
1872 return retValue;
1873 }
1874 }
1875
Wink Saville64c42ca2011-04-18 14:55:10 -07001876 class ErrorState extends State {
Erik Kline8351faa2017-04-17 16:47:23 +09001877 private int mErrorNotification;
1878
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001879 @Override
1880 public boolean processMessage(Message message) {
1881 boolean retValue = true;
1882 switch (message.what) {
Erik Klineea9cc482017-03-10 19:35:34 +09001883 case EVENT_IFACE_SERVING_STATE_ACTIVE:
Erik Kline7a4ccc62018-08-27 17:26:47 +09001884 IpServer who = (IpServer) message.obj;
Robert Greenwalt6a1967c2010-03-17 11:19:57 -07001885 who.sendMessage(mErrorNotification);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001886 break;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001887 case CMD_CLEAR_ERROR:
Erik Kline7a26ba32018-03-09 14:18:02 +09001888 mErrorNotification = TETHER_ERROR_NO_ERROR;
Yohei, Oshima977aad52016-12-08 13:39:20 +09001889 transitionTo(mInitialState);
1890 break;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001891 default:
markchien0f63ca62019-09-30 14:40:57 +08001892 retValue = false;
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001893 }
1894 return retValue;
1895 }
Erik Kline8351faa2017-04-17 16:47:23 +09001896
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001897 void notify(int msgType) {
1898 mErrorNotification = msgType;
Erik Kline7a4ccc62018-08-27 17:26:47 +09001899 for (IpServer ipServer : mNotifyList) {
1900 ipServer.sendMessage(msgType);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001901 }
1902 }
1903
1904 }
Erik Kline8351faa2017-04-17 16:47:23 +09001905
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001906 class SetIpForwardingEnabledErrorState extends ErrorState {
1907 @Override
1908 public void enter() {
1909 Log.e(TAG, "Error in setIpForwardingEnabled");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001910 notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001911 }
1912 }
1913
1914 class SetIpForwardingDisabledErrorState extends ErrorState {
1915 @Override
1916 public void enter() {
1917 Log.e(TAG, "Error in setIpForwardingDisabled");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001918 notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001919 }
1920 }
1921
1922 class StartTetheringErrorState extends ErrorState {
1923 @Override
1924 public void enter() {
1925 Log.e(TAG, "Error in startTethering");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001926 notify(IpServer.CMD_START_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001927 try {
markchiena9d9ef82020-01-07 14:43:17 +08001928 mNetd.ipfwdDisableForwarding(TAG);
1929 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001930 }
1931 }
1932
1933 class StopTetheringErrorState extends ErrorState {
1934 @Override
1935 public void enter() {
1936 Log.e(TAG, "Error in stopTethering");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001937 notify(IpServer.CMD_STOP_TETHERING_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001938 try {
markchiena9d9ef82020-01-07 14:43:17 +08001939 mNetd.ipfwdDisableForwarding(TAG);
1940 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001941 }
1942 }
1943
1944 class SetDnsForwardersErrorState extends ErrorState {
1945 @Override
1946 public void enter() {
1947 Log.e(TAG, "Error in setDnsForwarders");
Erik Kline7a4ccc62018-08-27 17:26:47 +09001948 notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001949 try {
markchiena9d9ef82020-01-07 14:43:17 +08001950 mNetd.tetherStop();
1951 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001952 try {
markchiena9d9ef82020-01-07 14:43:17 +08001953 mNetd.ipfwdDisableForwarding(TAG);
1954 } catch (RemoteException | ServiceSpecificException e) { }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08001955 }
1956 }
Erik Klineed962a82017-07-06 19:49:35 +09001957
1958 // A wrapper class to handle multiple situations where several calls to
1959 // the OffloadController need to happen together.
1960 //
1961 // TODO: This suggests that the interface between OffloadController and
1962 // Tethering is in need of improvement. Refactor these calls into the
1963 // OffloadController implementation.
1964 class OffloadWrapper {
1965 public void start() {
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001966 final int status = mOffloadController.start() ? TETHER_HARDWARE_OFFLOAD_STARTED
1967 : TETHER_HARDWARE_OFFLOAD_FAILED;
1968 updateOffloadStatus(status);
Erik Klineed962a82017-07-06 19:49:35 +09001969 sendOffloadExemptPrefixes();
1970 }
1971
1972 public void stop() {
1973 mOffloadController.stop();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00001974 updateOffloadStatus(TETHER_HARDWARE_OFFLOAD_STOPPED);
Erik Klineed962a82017-07-06 19:49:35 +09001975 }
1976
markchienb0aca962019-12-05 16:21:17 +08001977 public void updateUpstreamNetworkState(UpstreamNetworkState ns) {
Erik Klineed962a82017-07-06 19:49:35 +09001978 mOffloadController.setUpstreamLinkProperties(
1979 (ns != null) ? ns.linkProperties : null);
1980 }
1981
1982 public void updateDownstreamLinkProperties(LinkProperties newLp) {
1983 // Update the list of offload-exempt prefixes before adding
1984 // new prefixes on downstream interfaces to the offload HAL.
1985 sendOffloadExemptPrefixes();
1986 mOffloadController.notifyDownstreamLinkProperties(newLp);
1987 }
1988
1989 public void excludeDownstreamInterface(String ifname) {
1990 // This and other interfaces may be in local-only hotspot mode;
1991 // resend all local prefixes to the OffloadController.
1992 sendOffloadExemptPrefixes();
1993 mOffloadController.removeDownstreamInterface(ifname);
1994 }
1995
1996 public void sendOffloadExemptPrefixes() {
1997 sendOffloadExemptPrefixes(mUpstreamNetworkMonitor.getLocalPrefixes());
1998 }
1999
2000 public void sendOffloadExemptPrefixes(final Set<IpPrefix> localPrefixes) {
2001 // Add in well-known minimum set.
2002 PrefixUtils.addNonForwardablePrefixes(localPrefixes);
2003 // Add tragically hardcoded prefixes.
2004 localPrefixes.add(PrefixUtils.DEFAULT_WIFI_P2P_PREFIX);
2005
2006 // Maybe add prefixes or addresses for downstreams, depending on
2007 // the IP serving mode of each.
Erik Kline7a4ccc62018-08-27 17:26:47 +09002008 for (IpServer ipServer : mNotifyList) {
2009 final LinkProperties lp = ipServer.linkProperties();
Erik Klineed962a82017-07-06 19:49:35 +09002010
Erik Kline7a4ccc62018-08-27 17:26:47 +09002011 switch (ipServer.servingMode()) {
2012 case IpServer.STATE_UNAVAILABLE:
2013 case IpServer.STATE_AVAILABLE:
Erik Klineed962a82017-07-06 19:49:35 +09002014 // No usable LinkProperties in these states.
2015 continue;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002016 case IpServer.STATE_TETHERED:
Erik Klineed962a82017-07-06 19:49:35 +09002017 // Only add IPv4 /32 and IPv6 /128 prefixes. The
2018 // directly-connected prefixes will be sent as
2019 // downstream "offload-able" prefixes.
2020 for (LinkAddress addr : lp.getAllLinkAddresses()) {
2021 final InetAddress ip = addr.getAddress();
2022 if (ip.isLinkLocalAddress()) continue;
2023 localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip));
2024 }
2025 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002026 case IpServer.STATE_LOCAL_ONLY:
Erik Klineed962a82017-07-06 19:49:35 +09002027 // Add prefixes covering all local IPs.
2028 localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp));
2029 break;
2030 }
2031 }
2032
2033 mOffloadController.setLocalPrefixes(localPrefixes);
2034 }
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002035
2036 private void updateOffloadStatus(final int newStatus) {
2037 if (newStatus == mOffloadStatus) return;
2038
2039 mOffloadStatus = newStatus;
2040 reportOffloadStatusChanged(mOffloadStatus);
2041 }
Erik Klineed962a82017-07-06 19:49:35 +09002042 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002043 }
2044
markchien0f63ca62019-09-30 14:40:57 +08002045 private void startTrackDefaultNetwork() {
markchien3b519632018-09-07 16:19:12 +08002046 mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
2047 mEntitlementMgr);
markchiena6c72872018-11-13 18:34:56 +09002048 }
2049
markchienf2731272019-01-16 17:44:13 +08002050 /** Get the latest value of the tethering entitlement check. */
markchien0f63ca62019-09-30 14:40:57 +08002051 void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
markchienf2731272019-01-16 17:44:13 +08002052 boolean showEntitlementUi) {
Mark Chien3075fbb2020-04-16 02:47:22 +00002053 if (receiver == null) return;
2054
2055 mHandler.post(() -> {
markchien0f63ca62019-09-30 14:40:57 +08002056 mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver,
2057 showEntitlementUi);
Mark Chien3075fbb2020-04-16 02:47:22 +00002058 });
markchienf2731272019-01-16 17:44:13 +08002059 }
2060
markchien26299ed2019-02-27 14:56:11 +08002061 /** Register tethering event callback */
markchienae8aa642019-12-16 20:15:20 +08002062 void registerTetheringEventCallback(ITetheringEventCallback callback) {
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002063 final boolean hasListPermission =
Chiachang Wang96ca8e92020-02-21 17:50:18 +08002064 hasCallingPermission(NETWORK_SETTINGS)
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002065 || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
Chiachang Wang96ca8e92020-02-21 17:50:18 +08002066 || hasCallingPermission(NETWORK_STACK);
markchien26299ed2019-02-27 14:56:11 +08002067 mHandler.post(() -> {
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002068 mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
markchien40898ca2020-01-21 13:11:06 +08002069 final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
markchiencb8860c2020-05-12 00:08:27 +08002070 parcel.tetheringSupported = isTetheringSupported();
markchien40898ca2020-01-21 13:11:06 +08002071 parcel.upstreamNetwork = mTetherUpstream;
2072 parcel.config = mConfig.toStableParcelable();
markchienfaa37282020-02-06 14:34:08 +08002073 parcel.states =
2074 mTetherStatesParcel != null ? mTetherStatesParcel : emptyTetherStatesParcel();
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002075 parcel.tetheredClients = hasListPermission
2076 ? mConnectedClientsTracker.getLastTetheredClients()
2077 : Collections.emptyList();
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002078 parcel.offloadStatus = mOffloadStatus;
markchien26299ed2019-02-27 14:56:11 +08002079 try {
markchien40898ca2020-01-21 13:11:06 +08002080 callback.onCallbackStarted(parcel);
markchien26299ed2019-02-27 14:56:11 +08002081 } catch (RemoteException e) {
2082 // Not really very much to do here.
2083 }
markchien26299ed2019-02-27 14:56:11 +08002084 });
2085 }
2086
markchienfaa37282020-02-06 14:34:08 +08002087 private TetherStatesParcel emptyTetherStatesParcel() {
2088 final TetherStatesParcel parcel = new TetherStatesParcel();
2089 parcel.availableList = new String[0];
2090 parcel.tetheredList = new String[0];
2091 parcel.localOnlyList = new String[0];
2092 parcel.erroredIfaceList = new String[0];
2093 parcel.lastErrorList = new int[0];
2094
2095 return parcel;
2096 }
2097
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002098 private boolean hasCallingPermission(@NonNull String permission) {
2099 return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED;
2100 }
2101
markchienae8aa642019-12-16 20:15:20 +08002102 /** Unregister tethering event callback */
2103 void unregisterTetheringEventCallback(ITetheringEventCallback callback) {
2104 mHandler.post(() -> {
2105 mTetheringEventCallbacks.unregister(callback);
2106 });
2107 }
markchien0f63ca62019-09-30 14:40:57 +08002108
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002109 private void reportUpstreamChanged(UpstreamNetworkState ns) {
markchienae8aa642019-12-16 20:15:20 +08002110 final int length = mTetheringEventCallbacks.beginBroadcast();
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002111 final Network network = (ns != null) ? ns.network : null;
2112 final NetworkCapabilities capabilities = (ns != null) ? ns.networkCapabilities : null;
markchien26299ed2019-02-27 14:56:11 +08002113 try {
markchienae8aa642019-12-16 20:15:20 +08002114 for (int i = 0; i < length; i++) {
2115 try {
2116 mTetheringEventCallbacks.getBroadcastItem(i).onUpstreamChanged(network);
2117 } catch (RemoteException e) {
2118 // Not really very much to do here.
2119 }
2120 }
2121 } finally {
2122 mTetheringEventCallbacks.finishBroadcast();
markchien26299ed2019-02-27 14:56:11 +08002123 }
Chalard Jeanc0fc2762020-04-17 17:12:44 +00002124 // Need to notify capabilities change after upstream network changed because new network's
2125 // capabilities should be checked every time.
2126 mNotificationUpdater.onUpstreamCapabilitiesChanged(capabilities);
markchien26299ed2019-02-27 14:56:11 +08002127 }
2128
markchien0f63ca62019-09-30 14:40:57 +08002129 private void reportConfigurationChanged(TetheringConfigurationParcel config) {
markchienae8aa642019-12-16 20:15:20 +08002130 final int length = mTetheringEventCallbacks.beginBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002131 try {
markchienae8aa642019-12-16 20:15:20 +08002132 for (int i = 0; i < length; i++) {
2133 try {
2134 mTetheringEventCallbacks.getBroadcastItem(i).onConfigurationChanged(config);
markchien40898ca2020-01-21 13:11:06 +08002135 // TODO(b/148139325): send tetheringSupported on configuration change
markchienae8aa642019-12-16 20:15:20 +08002136 } catch (RemoteException e) {
2137 // Not really very much to do here.
2138 }
2139 }
2140 } finally {
2141 mTetheringEventCallbacks.finishBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002142 }
2143 }
2144
2145 private void reportTetherStateChanged(TetherStatesParcel states) {
markchienae8aa642019-12-16 20:15:20 +08002146 final int length = mTetheringEventCallbacks.beginBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002147 try {
markchienae8aa642019-12-16 20:15:20 +08002148 for (int i = 0; i < length; i++) {
2149 try {
2150 mTetheringEventCallbacks.getBroadcastItem(i).onTetherStatesChanged(states);
2151 } catch (RemoteException e) {
2152 // Not really very much to do here.
2153 }
2154 }
2155 } finally {
2156 mTetheringEventCallbacks.finishBroadcast();
markchien0f63ca62019-09-30 14:40:57 +08002157 }
2158 }
2159
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002160 private void reportTetherClientsChanged(List<TetheredClient> clients) {
2161 final int length = mTetheringEventCallbacks.beginBroadcast();
2162 try {
2163 for (int i = 0; i < length; i++) {
2164 try {
2165 final CallbackCookie cookie =
2166 (CallbackCookie) mTetheringEventCallbacks.getBroadcastCookie(i);
2167 if (!cookie.hasListClientsPermission) continue;
2168 mTetheringEventCallbacks.getBroadcastItem(i).onTetherClientsChanged(clients);
2169 } catch (RemoteException e) {
2170 // Not really very much to do here.
2171 }
2172 }
2173 } finally {
2174 mTetheringEventCallbacks.finishBroadcast();
2175 }
2176 }
2177
Automerger Merge Workerc22ab7b2020-03-09 04:07:07 +00002178 private void reportOffloadStatusChanged(final int status) {
2179 final int length = mTetheringEventCallbacks.beginBroadcast();
2180 try {
2181 for (int i = 0; i < length; i++) {
2182 try {
2183 mTetheringEventCallbacks.getBroadcastItem(i).onOffloadStatusChanged(status);
2184 } catch (RemoteException e) {
2185 // Not really very much to do here.
2186 }
2187 }
2188 } finally {
2189 mTetheringEventCallbacks.finishBroadcast();
2190 }
2191 }
2192
markchiencb8860c2020-05-12 00:08:27 +08002193 // if ro.tether.denied = true we default to no tethering
2194 // gservices could set the secure setting to 1 though to enable it on a build where it
2195 // had previously been turned off.
2196 boolean isTetheringSupported() {
markchien0ed433e2020-06-03 12:27:37 +08002197 final int defaultVal = mDeps.isTetheringDenied() ? 0 : 1;
markchiencb8860c2020-05-12 00:08:27 +08002198 final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
2199 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
2200 final boolean tetherEnabledInSettings = tetherSupported
2201 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
2202
markchien0ed433e2020-06-03 12:27:37 +08002203 return tetherEnabledInSettings && hasTetherableConfiguration()
2204 && !isProvisioningNeededButUnavailable();
markchiencb8860c2020-05-12 00:08:27 +08002205 }
2206
markchiena9d9ef82020-01-07 14:43:17 +08002207 void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
Christopher Wiley499a57a2016-05-16 16:19:07 -07002208 // Binder.java closes the resource for us.
2209 @SuppressWarnings("resource")
Lorenzo Colittie3805462015-06-03 11:18:24 +09002210 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
markchienae8aa642019-12-16 20:15:20 +08002211 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2212 != PERMISSION_GRANTED) {
2213 pw.println("Permission Denial: can't dump.");
2214 return;
2215 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002216
Lorenzo Colittie3805462015-06-03 11:18:24 +09002217 pw.println("Tethering:");
2218 pw.increaseIndent();
Lorenzo Colittie3805462015-06-03 11:18:24 +09002219
Erik Kline9db1b542017-03-16 14:10:27 +09002220 pw.println("Configuration:");
2221 pw.increaseIndent();
2222 final TetheringConfiguration cfg = mConfig;
2223 cfg.dump(pw);
2224 pw.decreaseIndent();
2225
markchien3b519632018-09-07 16:19:12 +08002226 pw.println("Entitlement:");
2227 pw.increaseIndent();
2228 mEntitlementMgr.dump(pw);
2229 pw.decreaseIndent();
2230
Erik Kline9db1b542017-03-16 14:10:27 +09002231 synchronized (mPublicSync) {
Robert Greenwaltb4453622011-11-03 16:01:40 -07002232 pw.println("Tether state:");
Lorenzo Colittie3805462015-06-03 11:18:24 +09002233 pw.increaseIndent();
Christopher Wileyd985dde2016-05-31 10:44:35 -07002234 for (int i = 0; i < mTetherStates.size(); i++) {
2235 final String iface = mTetherStates.keyAt(i);
2236 final TetherState tetherState = mTetherStates.valueAt(i);
2237 pw.print(iface + " - ");
2238
Hugo Benichib55fb222017-03-10 14:20:57 +09002239 switch (tetherState.lastState) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09002240 case IpServer.STATE_UNAVAILABLE:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002241 pw.print("UnavailableState");
2242 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002243 case IpServer.STATE_AVAILABLE:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002244 pw.print("AvailableState");
2245 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002246 case IpServer.STATE_TETHERED:
Christopher Wileyd985dde2016-05-31 10:44:35 -07002247 pw.print("TetheredState");
2248 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002249 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09002250 pw.print("LocalHotspotState");
2251 break;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002252 default:
2253 pw.print("UnknownState");
2254 break;
2255 }
Hugo Benichib55fb222017-03-10 14:20:57 +09002256 pw.println(" - lastError = " + tetherState.lastError);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002257 }
Erik Klineea9cc482017-03-10 19:35:34 +09002258 pw.println("Upstream wanted: " + upstreamWanted());
Remi NGUYEN VAN6c02f992018-03-09 14:07:18 +09002259 pw.println("Current upstream interface(s): " + mCurrentUpstreamIfaceSet);
Lorenzo Colittie3805462015-06-03 11:18:24 +09002260 pw.decreaseIndent();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002261 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09002262
Lorenzo Colittic2519c52017-07-13 01:48:26 +09002263 pw.println("Hardware offload:");
2264 pw.increaseIndent();
2265 mOffloadController.dump(pw);
2266 pw.decreaseIndent();
2267
Nucca Chen1f9efaf2020-06-17 06:32:35 +00002268 pw.println("BPF offload:");
2269 pw.increaseIndent();
2270 mBpfCoordinator.dump(pw);
2271 pw.decreaseIndent();
2272
Mark Chiendb6befb2020-05-29 22:07:37 +00002273 pw.println("Private address coordinator:");
2274 pw.increaseIndent();
2275 mPrivateAddressCoordinator.dump(pw);
2276 pw.decreaseIndent();
2277
Erik Kline1fdc2e22017-05-08 17:56:35 +09002278 pw.println("Log:");
2279 pw.increaseIndent();
markchien0f63ca62019-09-30 14:40:57 +08002280 if (argsContain(args, "--short")) {
Erik Kline7747fd42017-05-12 16:52:48 +09002281 pw.println("<log removed for brevity>");
2282 } else {
2283 mLog.dump(fd, pw, args);
2284 }
Erik Kline1fdc2e22017-05-08 17:56:35 +09002285 pw.decreaseIndent();
2286
Lorenzo Colittie3805462015-06-03 11:18:24 +09002287 pw.decreaseIndent();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002288 }
Christopher Wileye03fb442016-05-18 13:45:20 -07002289
Erik Kline7747fd42017-05-12 16:52:48 +09002290 private static boolean argsContain(String[] args, String target) {
2291 for (String arg : args) {
Erik Klineee363c42017-05-29 09:11:03 +09002292 if (target.equals(arg)) return true;
Erik Kline7747fd42017-05-12 16:52:48 +09002293 }
2294 return false;
2295 }
2296
Treehugger Robot25067812020-03-25 15:32:41 +00002297 private void updateConnectedClients(final List<WifiClient> wifiClients) {
2298 if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, wifiClients)) {
2299 reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
2300 }
2301 }
2302
Erik Kline7a4ccc62018-08-27 17:26:47 +09002303 private IpServer.Callback makeControlCallback() {
2304 return new IpServer.Callback() {
Erik Kline6e9a1012017-06-06 19:24:21 +09002305 @Override
Erik Kline7a4ccc62018-08-27 17:26:47 +09002306 public void updateInterfaceState(IpServer who, int state, int lastError) {
2307 notifyInterfaceStateChange(who, state, lastError);
Erik Kline6e9a1012017-06-06 19:24:21 +09002308 }
2309
2310 @Override
Erik Kline7a4ccc62018-08-27 17:26:47 +09002311 public void updateLinkProperties(IpServer who, LinkProperties newLp) {
2312 notifyLinkPropertiesChanged(who, newLp);
Erik Kline6e9a1012017-06-06 19:24:21 +09002313 }
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002314
2315 @Override
2316 public void dhcpLeasesChanged() {
Treehugger Robot25067812020-03-25 15:32:41 +00002317 updateConnectedClients(null /* wifiClients */);
Remi NGUYEN VAN43b0e5c2020-02-13 09:16:19 +09002318 }
Mark Chiendb6befb2020-05-29 22:07:37 +00002319
2320 @Override
2321 public void requestEnableTethering(int tetheringType, boolean enabled) {
2322 enableTetheringInternal(tetheringType, enabled, null);
2323 }
Erik Kline6e9a1012017-06-06 19:24:21 +09002324 };
2325 }
2326
2327 // TODO: Move into TetherMasterSM.
Erik Kline7a4ccc62018-08-27 17:26:47 +09002328 private void notifyInterfaceStateChange(IpServer who, int state, int error) {
2329 final String iface = who.interfaceName();
Christopher Wileyd985dde2016-05-31 10:44:35 -07002330 synchronized (mPublicSync) {
Erik Kline216af6d2017-04-27 20:57:23 +09002331 final TetherState tetherState = mTetherStates.get(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002332 if (tetherState != null && tetherState.ipServer.equals(who)) {
Hugo Benichib55fb222017-03-10 14:20:57 +09002333 tetherState.lastState = state;
2334 tetherState.lastError = error;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002335 } else {
2336 if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
2337 }
2338 }
2339
Erik Kline7747fd42017-05-12 16:52:48 +09002340 mLog.log(String.format("OBSERVED iface=%s state=%s error=%s", iface, state, error));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002341
Yohei, Oshima977aad52016-12-08 13:39:20 +09002342 // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
2343 // Thus we give a chance for TetherMasterSM to recover to InitialState
2344 // by sending CMD_CLEAR_ERROR
markchien62a625d2020-03-19 13:37:43 +08002345 if (error == TETHER_ERROR_INTERNAL_ERROR) {
Yohei, Oshima977aad52016-12-08 13:39:20 +09002346 mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
2347 }
Erik Klineea9cc482017-03-10 19:35:34 +09002348 int which;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002349 switch (state) {
Erik Kline7a4ccc62018-08-27 17:26:47 +09002350 case IpServer.STATE_UNAVAILABLE:
2351 case IpServer.STATE_AVAILABLE:
Erik Klineea9cc482017-03-10 19:35:34 +09002352 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002353 break;
Erik Kline7a4ccc62018-08-27 17:26:47 +09002354 case IpServer.STATE_TETHERED:
2355 case IpServer.STATE_LOCAL_ONLY:
Erik Klineea9cc482017-03-10 19:35:34 +09002356 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002357 break;
Erik Klineea9cc482017-03-10 19:35:34 +09002358 default:
2359 Log.wtf(TAG, "Unknown interface state: " + state);
2360 return;
Christopher Wileyd985dde2016-05-31 10:44:35 -07002361 }
Erik Klineea9cc482017-03-10 19:35:34 +09002362 mTetherMasterSM.sendMessage(which, state, 0, who);
Christopher Wileyd985dde2016-05-31 10:44:35 -07002363 sendTetherStateChangedBroadcast();
2364 }
2365
Erik Kline7a4ccc62018-08-27 17:26:47 +09002366 private void notifyLinkPropertiesChanged(IpServer who, LinkProperties newLp) {
2367 final String iface = who.interfaceName();
Erik Kline6e9a1012017-06-06 19:24:21 +09002368 final int state;
2369 synchronized (mPublicSync) {
2370 final TetherState tetherState = mTetherStates.get(iface);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002371 if (tetherState != null && tetherState.ipServer.equals(who)) {
Erik Kline6e9a1012017-06-06 19:24:21 +09002372 state = tetherState.lastState;
2373 } else {
2374 mLog.log("got notification from stale iface " + iface);
2375 return;
2376 }
2377 }
2378
Erik Kline7fd696c2017-06-12 18:20:08 +09002379 mLog.log(String.format(
2380 "OBSERVED LinkProperties update iface=%s state=%s lp=%s",
Erik Kline7a4ccc62018-08-27 17:26:47 +09002381 iface, IpServer.getStateString(state), newLp));
Erik Kline6e9a1012017-06-06 19:24:21 +09002382 final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES;
2383 mTetherMasterSM.sendMessage(which, state, 0, newLp);
2384 }
2385
Erik Kline4dd9bb82017-04-26 11:11:07 +09002386 private void maybeTrackNewInterfaceLocked(final String iface) {
2387 // If we don't care about this type of interface, ignore.
2388 final int interfaceType = ifaceNameToType(iface);
Erik Kline7a26ba32018-03-09 14:18:02 +09002389 if (interfaceType == TETHERING_INVALID) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09002390 mLog.log(iface + " is not a tetherable iface, ignoring");
2391 return;
2392 }
Erik Klinea9cde8b2017-06-20 21:18:31 +09002393 maybeTrackNewInterfaceLocked(iface, interfaceType);
2394 }
Erik Kline4dd9bb82017-04-26 11:11:07 +09002395
Erik Klinea9cde8b2017-06-20 21:18:31 +09002396 private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
Erik Kline4dd9bb82017-04-26 11:11:07 +09002397 // If we have already started a TISM for this interface, skip.
2398 if (mTetherStates.containsKey(iface)) {
2399 mLog.log("active iface (" + iface + ") reported as added, ignoring");
2400 return;
2401 }
2402
2403 mLog.log("adding TetheringInterfaceStateMachine for: " + iface);
2404 final TetherState tetherState = new TetherState(
Hungming Chenbe4827d2020-06-02 00:13:26 +00002405 new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator,
Erik Kline7a4ccc62018-08-27 17:26:47 +09002406 makeControlCallback(), mConfig.enableLegacyDhcpServer,
Nucca Chen1c63ba32020-06-17 07:03:57 +00002407 mConfig.isBpfOffloadEnabled(), mPrivateAddressCoordinator,
Mark Chiendb6befb2020-05-29 22:07:37 +00002408 mDeps.getIpServerDependencies()));
Christopher Wileyd985dde2016-05-31 10:44:35 -07002409 mTetherStates.put(iface, tetherState);
Erik Kline7a4ccc62018-08-27 17:26:47 +09002410 tetherState.ipServer.start();
Christopher Wileye03fb442016-05-18 13:45:20 -07002411 }
Erik Kline3e756652017-01-17 13:42:19 +09002412
Erik Kline4dd9bb82017-04-26 11:11:07 +09002413 private void stopTrackingInterfaceLocked(final String iface) {
2414 final TetherState tetherState = mTetherStates.get(iface);
2415 if (tetherState == null) {
2416 mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
2417 return;
2418 }
Erik Kline7a4ccc62018-08-27 17:26:47 +09002419 tetherState.ipServer.stop();
Erik Kline4dd9bb82017-04-26 11:11:07 +09002420 mLog.log("removing TetheringInterfaceStateMachine for: " + iface);
2421 mTetherStates.remove(iface);
2422 }
2423
Erik Kline3e756652017-01-17 13:42:19 +09002424 private static String[] copy(String[] strarray) {
2425 return Arrays.copyOf(strarray, strarray.length);
2426 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08002427}