blob: 2f66fd7dc7c7151b8a74568b4ddb0d78952c7f12 [file] [log] [blame]
San Mehat873f2142010-01-14 10:25:07 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Jeff Sharkey4529bb62011-12-14 10:31:54 -080019import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Sehee Parka9139bc2017-12-22 13:54:05 +090020import static android.Manifest.permission.NETWORK_SETTINGS;
Lorenzo Colitti07f13042017-07-10 19:06:57 +090021import static android.Manifest.permission.NETWORK_STACK;
Jeff Sharkeyaf75c332011-11-18 12:41:12 -080022import static android.Manifest.permission.SHUTDOWN;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070023import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
24import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
Felipe Leme011b98f2016-02-10 17:28:31 -080025import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070026import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
27import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE;
Felipe Leme011b98f2016-02-10 17:28:31 -080028import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070029import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
Sudheer Shanka62f5c172017-03-17 16:25:55 -070030import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070031import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
Sudheer Shanka62f5c172017-03-17 16:25:55 -070032import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070033import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST;
34import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070035import static android.net.NetworkStats.SET_DEFAULT;
Lorenzo Colittif1912ca2017-08-17 19:23:08 +090036import static android.net.NetworkStats.STATS_PER_UID;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080037import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070038import static android.net.NetworkStats.TAG_NONE;
39import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyae2c1812011-10-04 13:11:40 -070040import static android.net.TrafficStats.UID_TETHERING;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090041
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080042import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
Jeff Sharkeya63ba592011-07-19 23:47:12 -070043import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
Erik Klineb2cfdfb2017-01-18 20:54:14 +090044
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070045import android.annotation.NonNull;
Sudheer Shankadc589ac2016-11-10 15:30:17 -080046import android.app.ActivityManager;
San Mehat873f2142010-01-14 10:25:07 -080047import android.content.Context;
Dianne Hackborn77b987f2014-02-26 16:20:52 -080048import android.net.ConnectivityManager;
Lorenzo Colitti58967ba2016-02-02 17:21:21 +090049import android.net.INetd;
San Mehat4d02d002010-01-22 16:07:46 -080050import android.net.INetworkManagementEventObserver;
Lorenzo Colitti07f13042017-07-10 19:06:57 +090051import android.net.ITetheringStatsProvider;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070052import android.net.InterfaceConfiguration;
Luke Huang14f75442018-08-15 19:22:54 +080053import android.net.InterfaceConfigurationParcel;
Lorenzo Colittic18cbfd2014-06-13 21:21:03 +090054import android.net.IpPrefix;
Robert Greenwalted126402011-01-28 15:34:55 -080055import android.net.LinkAddress;
Lorenzo Colittib57edc52014-08-22 17:10:50 -070056import android.net.Network;
Amith Yamasani15e472352015-04-24 19:06:07 -070057import android.net.NetworkPolicyManager;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -070058import android.net.NetworkStats;
Robert Greenwalted126402011-01-28 15:34:55 -080059import android.net.NetworkUtils;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070060import android.net.RouteInfo;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090061import android.net.TetherStatsParcel;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -040062import android.net.UidRange;
Remi NGUYEN VAN3c600a12019-01-10 19:12:46 +090063import android.net.shared.NetdService;
Lorenzo Colittid8bc8292019-01-24 13:28:50 +090064import android.net.shared.NetworkObserverRegistry;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070065import android.os.BatteryStats;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070066import android.os.Binder;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070067import android.os.Handler;
Lorenzo Colittia0868002017-07-11 02:29:28 +090068import android.os.IBinder;
Dianne Hackborn77b987f2014-02-26 16:20:52 -080069import android.os.INetworkActivityListener;
San Mehat873f2142010-01-14 10:25:07 -080070import android.os.INetworkManagementService;
Dianne Hackborn77b987f2014-02-26 16:20:52 -080071import android.os.PowerManager;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -070072import android.os.Process;
Jeff Sharkey3df273e2011-12-15 15:47:12 -080073import android.os.RemoteCallbackList;
74import android.os.RemoteException;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070075import android.os.ServiceManager;
Lorenzo Colitti4cb42402016-04-24 12:52:00 +090076import android.os.ServiceSpecificException;
Jeff Sharkey605eb792014-11-04 13:34:06 -080077import android.os.StrictMode;
Jeff Sharkey9a13f362011-04-26 16:25:36 -070078import android.os.SystemClock;
Marco Nelissen62dbb222010-02-18 10:56:30 -080079import android.os.SystemProperties;
Felipe Leme29e72ea2016-09-08 13:26:55 -070080import android.os.Trace;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070081import android.telephony.DataConnectionRealTimeInfo;
Irfan Sheriff9ab518ad2010-03-12 15:48:17 -080082import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080083import android.util.Slog;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -070084import android.util.SparseBooleanArray;
Jeff Sharkey605eb792014-11-04 13:34:06 -080085import android.util.SparseIntArray;
San Mehat873f2142010-01-14 10:25:07 -080086
Jeff Sharkey605eb792014-11-04 13:34:06 -080087import com.android.internal.annotations.GuardedBy;
Sudheer Shanka62f5c172017-03-17 16:25:55 -070088import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070089import com.android.internal.app.IBatteryStats;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070090import com.android.internal.net.NetworkStatsFactory;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060091import com.android.internal.util.DumpUtils;
Jeff Sharkey605eb792014-11-04 13:34:06 -080092import com.android.internal.util.HexDump;
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070093import com.android.internal.util.Preconditions;
Lorenzo Colitti9307ca22019-01-12 01:54:23 +090094
Jeff Sharkeyb24a7852012-05-01 15:19:37 -070095import com.google.android.collect.Maps;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070096
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -070097import java.io.BufferedReader;
98import java.io.DataInputStream;
Jeff Sharkey47eb1022011-08-25 17:48:52 -070099import java.io.FileDescriptor;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700100import java.io.FileInputStream;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700101import java.io.IOException;
Jeff Sharkey9a13f362011-04-26 16:25:36 -0700102import java.io.InputStreamReader;
Jeff Sharkey47eb1022011-08-25 17:48:52 -0700103import java.io.PrintWriter;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -0700104import java.net.InetAddress;
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -0700105import java.net.InterfaceAddress;
Jeff Sharkeyeedcb952011-05-17 14:55:15 -0700106import java.util.ArrayList;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400107import java.util.Arrays;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700108import java.util.HashMap;
jiaguo1da35f72014-01-09 16:39:59 +0800109import java.util.List;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700110import java.util.Map;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700111import java.util.concurrent.CountDownLatch;
San Mehat873f2142010-01-14 10:25:07 -0800112
113/**
114 * @hide
115 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700116public class NetworkManagementService extends INetworkManagementService.Stub
117 implements Watchdog.Monitor {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900118
119 /**
120 * Helper class that encapsulates NetworkManagementService dependencies and makes them
121 * easier to mock in unit tests.
122 */
123 static class SystemServices {
124 public IBinder getService(String name) {
125 return ServiceManager.getService(name);
126 }
127 public void registerLocalService(NetworkManagementInternal nmi) {
128 LocalServices.addService(NetworkManagementInternal.class, nmi);
129 }
130 public INetd getNetd() {
131 return NetdService.get();
132 }
133 }
134
Amith Yamasani15e472352015-04-24 19:06:07 -0700135 private static final String TAG = "NetworkManagement";
136 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
Kenny Root305bcbf2010-09-03 07:56:38 -0700137 private static final String NETD_TAG = "NetdConnector";
Lorenzo Colittia0868002017-07-11 02:29:28 +0900138 static final String NETD_SERVICE_NAME = "netd";
Kenny Root305bcbf2010-09-03 07:56:38 -0700139
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400140 private static final int MAX_UID_RANGES_PER_COMMAND = 10;
141
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700142 /**
143 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
144 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
145 */
146 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
147
Andrew Scull45f533c2017-05-19 15:37:20 +0100148 static class NetdResponseCode {
Sreeram Ramachandran03666c72014-07-19 23:21:46 -0700149 /* Keep in sync with system/netd/server/ResponseCode.h */
San Mehat873f2142010-01-14 10:25:07 -0800150 public static final int InterfaceListResult = 110;
151 public static final int TetherInterfaceListResult = 111;
152 public static final int TetherDnsFwdTgtListResult = 112;
San Mehat72759df2010-01-19 13:50:37 -0800153 public static final int TtyListResult = 113;
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700154 public static final int TetheringStatsListResult = 114;
San Mehat873f2142010-01-14 10:25:07 -0800155
156 public static final int TetherStatusResult = 210;
157 public static final int IpFwdStatusResult = 211;
San Mehated4fc8a2010-01-22 12:28:36 -0800158 public static final int InterfaceGetCfgResult = 213;
Robert Greenwalte3253922010-02-18 09:23:25 -0800159 public static final int SoftapStatusResult = 214;
San Mehat91cac642010-03-31 14:31:36 -0700160 public static final int InterfaceRxCounterResult = 216;
161 public static final int InterfaceTxCounterResult = 217;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700162 public static final int QuotaCounterResult = 220;
163 public static final int TetheringStatsResult = 221;
Selim Gurun84c00c62012-02-27 15:42:38 -0800164 public static final int DnsProxyQueryResult = 222;
Lorenzo Colitti79751842013-02-28 16:16:03 +0900165 public static final int ClatdStatusResult = 223;
Robert Greenwalte3253922010-02-18 09:23:25 -0800166
167 public static final int InterfaceChange = 600;
JP Abgrall12b933d2011-07-14 18:09:22 -0700168 public static final int BandwidthControl = 601;
Haoyu Bai6b7358d2012-07-17 16:36:50 -0700169 public static final int InterfaceClassActivity = 613;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900170 public static final int InterfaceAddressChange = 614;
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900171 public static final int InterfaceDnsServerInfo = 615;
Lorenzo Colittic18cbfd2014-06-13 21:21:03 +0900172 public static final int RouteChange = 616;
Jeff Sharkey605eb792014-11-04 13:34:06 -0800173 public static final int StrictCleartext = 617;
San Mehat873f2142010-01-14 10:25:07 -0800174 }
175
Rebecca Silbersteine2ec94f2016-03-24 13:29:00 -0700176 /**
177 * String indicating a softap command.
178 */
179 static final String SOFT_AP_COMMAND = "softap";
180
181 /**
182 * String passed back to netd connector indicating softap command success.
183 */
184 static final String SOFT_AP_COMMAND_SUCCESS = "Ok";
185
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700186 static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
187
Luke Huang8a462ec2018-08-24 20:33:16 +0800188 static final boolean MODIFY_OPERATION_ADD = true;
189 static final boolean MODIFY_OPERATION_REMOVE = false;
190
San Mehat873f2142010-01-14 10:25:07 -0800191 /**
192 * Binder context for this service
193 */
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700194 private final Context mContext;
San Mehat873f2142010-01-14 10:25:07 -0800195
196 /**
197 * connector object for communicating with netd
198 */
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700199 private final NativeDaemonConnector mConnector;
San Mehat873f2142010-01-14 10:25:07 -0800200
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700201 private final Handler mFgHandler;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700202 private final Handler mDaemonHandler;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700203
Lorenzo Colittia0868002017-07-11 02:29:28 +0900204 private final SystemServices mServices;
205
Lorenzo Colitti58967ba2016-02-02 17:21:21 +0900206 private INetd mNetdService;
207
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900208 private NMSNetworkObserverRegistry mNetworkObserverRegistry;
Luke Huangd290dd52018-09-04 17:08:18 +0800209
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800210 private IBatteryStats mBatteryStats;
211
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700212 private final Thread mThread;
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700213 private CountDownLatch mConnectedSignal = new CountDownLatch(1);
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700214
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700215 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
216
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900217 @GuardedBy("mTetheringStatsProviders")
218 private final HashMap<ITetheringStatsProvider, String>
219 mTetheringStatsProviders = Maps.newHashMap();
220
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700221 /**
222 * If both locks need to be held, then they should be obtained in the order:
223 * first {@link #mQuotaLock} and then {@link #mRulesLock}.
224 */
Andrew Scull45f533c2017-05-19 15:37:20 +0100225 private final Object mQuotaLock = new Object();
Andrew Scull519291f2017-05-23 13:11:03 +0100226 private final Object mRulesLock = new Object();
Jeff Sharkey605eb792014-11-04 13:34:06 -0800227
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700228 /** Set of interfaces with active quotas. */
Jeff Sharkey605eb792014-11-04 13:34:06 -0800229 @GuardedBy("mQuotaLock")
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700230 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700231 /** Set of interfaces with active alerts. */
Jeff Sharkey605eb792014-11-04 13:34:06 -0800232 @GuardedBy("mQuotaLock")
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700233 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
Felipe Leme65be3022016-03-22 14:53:13 -0700234 /** Set of UIDs blacklisted on metered networks. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700235 @GuardedBy("mRulesLock")
Felipe Leme65be3022016-03-22 14:53:13 -0700236 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
237 /** Set of UIDs whitelisted on metered networks. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700238 @GuardedBy("mRulesLock")
Felipe Leme65be3022016-03-22 14:53:13 -0700239 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
Jeff Sharkey605eb792014-11-04 13:34:06 -0800240 /** Set of UIDs with cleartext penalties. */
241 @GuardedBy("mQuotaLock")
242 private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
Amith Yamasani15e472352015-04-24 19:06:07 -0700243 /** Set of UIDs that are to be blocked/allowed by firewall controller. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700244 @GuardedBy("mRulesLock")
Amith Yamasani15e472352015-04-24 19:06:07 -0700245 private SparseIntArray mUidFirewallRules = new SparseIntArray();
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700246 /**
247 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
248 * to application idles.
249 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700250 @GuardedBy("mRulesLock")
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700251 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
252 /**
253 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
254 * to device idles.
255 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700256 @GuardedBy("mRulesLock")
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700257 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
Felipe Leme011b98f2016-02-10 17:28:31 -0800258 /**
259 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
260 * to device on power-save mode.
261 */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700262 @GuardedBy("mRulesLock")
Felipe Leme011b98f2016-02-10 17:28:31 -0800263 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700264 /** Set of states for the child firewall chains. True if the chain is active. */
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700265 @GuardedBy("mRulesLock")
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700266 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700267
Felipe Leme65be3022016-03-22 14:53:13 -0700268 @GuardedBy("mQuotaLock")
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700269 private volatile boolean mDataSaverMode;
Felipe Leme65be3022016-03-22 14:53:13 -0700270
Andrew Scull45f533c2017-05-19 15:37:20 +0100271 private final Object mIdleTimerLock = new Object();
Haoyu Bai04124232012-06-28 15:26:19 -0700272 /** Set of interfaces with active idle timers. */
273 private static class IdleTimerParams {
274 public final int timeout;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800275 public final int type;
Haoyu Bai04124232012-06-28 15:26:19 -0700276 public int networkCount;
277
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800278 IdleTimerParams(int timeout, int type) {
Haoyu Bai04124232012-06-28 15:26:19 -0700279 this.timeout = timeout;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800280 this.type = type;
Haoyu Bai04124232012-06-28 15:26:19 -0700281 this.networkCount = 1;
282 }
283 }
284 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
285
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700286 private volatile boolean mFirewallEnabled;
Jeff Sharkey605eb792014-11-04 13:34:06 -0800287 private volatile boolean mStrictEnabled;
Jeff Sharkey350083e2011-06-29 10:45:16 -0700288
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700289 private boolean mMobileActivityFromRadio = false;
290 private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Adam Lesinskie08af192015-03-25 16:42:59 -0700291 private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700292
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800293 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
Christopher Wiley212b95f2016-08-02 11:38:57 -0700294 new RemoteCallbackList<>();
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800295 private boolean mNetworkActive;
296
San Mehat873f2142010-01-14 10:25:07 -0800297 /**
298 * Constructs a new NetworkManagementService instance
299 *
300 * @param context Binder context for this service
301 */
Lorenzo Colittia0868002017-07-11 02:29:28 +0900302 private NetworkManagementService(
303 Context context, String socket, SystemServices services) {
San Mehat873f2142010-01-14 10:25:07 -0800304 mContext = context;
Lorenzo Colittia0868002017-07-11 02:29:28 +0900305 mServices = services;
San Mehat4d02d002010-01-22 16:07:46 -0800306
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700307 // make sure this is on the same looper as our NativeDaemonConnector for sync purposes
308 mFgHandler = new Handler(FgThread.get().getLooper());
309
Dianne Hackborn4590e522014-03-24 13:36:46 -0700310 // Don't need this wake lock, since we now have a time stamp for when
311 // the network actually went inactive. (It might be nice to still do this,
312 // but I don't want to do it through the power manager because that pollutes the
313 // battery stats history with pointless noise.)
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700314 //PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
Dianne Hackborn4590e522014-03-24 13:36:46 -0700315 PowerManager.WakeLock wl = null; //pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800316
San Mehat873f2142010-01-14 10:25:07 -0800317 mConnector = new NativeDaemonConnector(
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700318 new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl,
319 FgThread.get().getLooper());
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700320 mThread = new Thread(mConnector, NETD_TAG);
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700321
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700322 mDaemonHandler = new Handler(FgThread.get().getLooper());
Wink Saville67e07892014-06-18 16:43:14 -0700323
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700324 // Add ourself to the Watchdog monitors.
325 Watchdog.getInstance().addMonitor(this);
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700326
Lorenzo Colittia0868002017-07-11 02:29:28 +0900327 mServices.registerLocalService(new LocalService());
Lorenzo Colitti8228eb32017-07-19 06:17:33 +0900328
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900329 synchronized (mTetheringStatsProviders) {
330 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
331 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700332 }
333
334 @VisibleForTesting
335 NetworkManagementService() {
336 mConnector = null;
337 mContext = null;
338 mDaemonHandler = null;
339 mFgHandler = null;
340 mThread = null;
Lorenzo Colittia0868002017-07-11 02:29:28 +0900341 mServices = null;
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900342 mNetworkObserverRegistry = null;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700343 }
344
Lorenzo Colittia0868002017-07-11 02:29:28 +0900345 static NetworkManagementService create(Context context, String socket, SystemServices services)
Felipe Leme03e689d2016-03-02 16:17:38 -0800346 throws InterruptedException {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900347 final NetworkManagementService service =
348 new NetworkManagementService(context, socket, services);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700349 final CountDownLatch connectedSignal = service.mConnectedSignal;
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700350 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
351 service.mThread.start();
352 if (DBG) Slog.d(TAG, "Awaiting socket connection");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700353 connectedSignal.await();
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700354 if (DBG) Slog.d(TAG, "Connected");
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900355 if (DBG) Slog.d(TAG, "Connecting native netd service");
bohu07cc3bb2016-05-03 15:58:01 -0700356 service.connectNativeNetdService();
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900357 if (DBG) Slog.d(TAG, "Connected");
Robert Greenwalte5c3afb2010-09-22 14:32:35 -0700358 return service;
San Mehat873f2142010-01-14 10:25:07 -0800359 }
360
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900361 public static NetworkManagementService create(Context context) throws InterruptedException {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900362 return create(context, NETD_SERVICE_NAME, new SystemServices());
Lorenzo Colitti7421a012013-08-20 22:51:24 +0900363 }
364
Jeff Sharkey350083e2011-06-29 10:45:16 -0700365 public void systemReady() {
Felipe Leme03e689d2016-03-02 16:17:38 -0800366 if (DBG) {
367 final long start = System.currentTimeMillis();
368 prepareNativeDaemon();
369 final long delta = System.currentTimeMillis() - start;
370 Slog.d(TAG, "Prepared in " + delta + "ms");
371 return;
372 } else {
373 prepareNativeDaemon();
374 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700375 }
376
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800377 private IBatteryStats getBatteryStats() {
378 synchronized (this) {
379 if (mBatteryStats != null) {
380 return mBatteryStats;
381 }
Lorenzo Colittia0868002017-07-11 02:29:28 +0900382 mBatteryStats =
383 IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME));
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800384 return mBatteryStats;
385 }
386 }
387
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800388 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800389 public void registerObserver(INetworkManagementEventObserver observer) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900390 mNetworkObserverRegistry.registerObserver(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800391 }
392
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800393 @Override
Jeff Sharkey3df273e2011-12-15 15:47:12 -0800394 public void unregisterObserver(INetworkManagementEventObserver observer) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900395 mNetworkObserverRegistry.unregisterObserver(observer);
San Mehat4d02d002010-01-22 16:07:46 -0800396 }
397
Erik Klineb2cfdfb2017-01-18 20:54:14 +0900398 @FunctionalInterface
399 private interface NetworkManagementEventCallback {
400 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
401 }
402
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900403 private class NMSNetworkObserverRegistry extends NetworkObserverRegistry {
404 NMSNetworkObserverRegistry(Context context, Handler handler, INetd netd)
405 throws RemoteException {
406 super(context, handler, netd);
407 }
408
409 /**
410 * Notify our observers of a change in the data activity state of the interface
411 */
412 @Override
413 public void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
414 int uid, boolean fromRadio) {
415 final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
416 int powerState = isActive
417 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
418 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
419
420 if (isMobile) {
421 if (!fromRadio) {
422 if (mMobileActivityFromRadio) {
423 // If this call is not coming from a report from the radio itself, but we
424 // have previously received reports from the radio, then we will take the
425 // power state to just be whatever the radio last reported.
426 powerState = mLastPowerStateFromRadio;
427 }
428 } else {
429 mMobileActivityFromRadio = true;
430 }
431 if (mLastPowerStateFromRadio != powerState) {
432 mLastPowerStateFromRadio = powerState;
433 try {
434 getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
435 } catch (RemoteException e) {
436 }
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700437 }
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700438 }
Mike J. Chen6143f5f2011-06-23 15:17:51 -0700439
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900440 if (ConnectivityManager.isNetworkTypeWifi(type)) {
441 if (mLastPowerStateFromWifi != powerState) {
442 mLastPowerStateFromWifi = powerState;
443 try {
444 getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
445 } catch (RemoteException e) {
446 }
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700447 }
Haoyu Baidb3c8672012-06-20 14:29:57 -0700448 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700449
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900450 if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
451 // Report the change in data activity. We don't do this if this is a change
452 // on the mobile network, that is not coming from the radio itself, and we
453 // have previously seen change reports from the radio. In that case only
454 // the radio is the authority for the current state.
455 final boolean active = isActive;
456 super.notifyInterfaceClassActivity(type, isActive, tsNanos, uid, fromRadio);
457 }
458
459 boolean report = false;
460 synchronized (mIdleTimerLock) {
461 if (mActiveIdleTimers.isEmpty()) {
462 // If there are no idle timers, we are not monitoring activity, so we
463 // are always considered active.
464 isActive = true;
465 }
466 if (mNetworkActive != isActive) {
467 mNetworkActive = isActive;
468 report = isActive;
Adam Lesinskie08af192015-03-25 16:42:59 -0700469 }
470 }
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900471 if (report) {
472 reportNetworkActive();
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800473 }
474 }
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900475
476 /**
477 * Notify our observers of an interface removal.
478 */
479 @Override
480 public void notifyInterfaceRemoved(String iface) {
481 // netd already clears out quota and alerts for removed ifaces; update
482 // our sanity-checking state.
483 mActiveAlerts.remove(iface);
484 mActiveQuotas.remove(iface);
485 super.notifyInterfaceRemoved(iface);
486 }
487
488 @Override
489 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
490 // Don't need to post to mDaemonHandler because the only thing
491 // that notifyCleartextNetwork does is post to a handler
492 ActivityManager.getService().notifyCleartextNetwork(uid,
493 HexDump.hexStringToByteArray(hex));
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800494 }
Haoyu Baidb3c8672012-06-20 14:29:57 -0700495 }
496
Lorenzo Colitti07f13042017-07-10 19:06:57 +0900497 @Override
498 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
499 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
500 Preconditions.checkNotNull(provider);
501 synchronized(mTetheringStatsProviders) {
502 mTetheringStatsProviders.put(provider, name);
503 }
504 }
505
506 @Override
507 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) {
508 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
509 synchronized(mTetheringStatsProviders) {
510 mTetheringStatsProviders.remove(provider);
511 }
512 }
513
Lorenzo Colitti9f0baa92017-08-15 19:25:51 +0900514 @Override
515 public void tetherLimitReached(ITetheringStatsProvider provider) {
516 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
517 synchronized(mTetheringStatsProviders) {
518 if (!mTetheringStatsProviders.containsKey(provider)) {
519 return;
520 }
521 // No current code examines the interface parameter in a global alert. Just pass null.
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900522 mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyLimitReached(
523 LIMIT_GLOBAL_ALERT, null));
Lorenzo Colitti9f0baa92017-08-15 19:25:51 +0900524 }
525 }
526
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900527 // Sync the state of the given chain with the native daemon.
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700528 private void syncFirewallChainLocked(int chain, String name) {
529 SparseIntArray rules;
530 synchronized (mRulesLock) {
531 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900532 // Make a copy of the current rules, and then clear them. This is because
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700533 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they
534 // are different from the current rules stored in the mUidFirewall*Rules array for
535 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal
536 // will do nothing.
537 rules = uidFirewallRules.clone();
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900538 uidFirewallRules.clear();
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700539 }
540 if (rules.size() > 0) {
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900541 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the
542 // native daemon, and also add them to the mUidFirewall*Rules array for the specified
543 // chain.
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700544 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall "
545 + name + "UID rules");
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900546 for (int i = 0; i < rules.size(); i++) {
Felipe Lemea701cad2016-05-12 09:58:14 -0700547 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i));
Lorenzo Colitti9eb844e2016-03-23 23:22:49 +0900548 }
549 }
550 }
551
bohu07cc3bb2016-05-03 15:58:01 -0700552 private void connectNativeNetdService() {
Lorenzo Colittia0868002017-07-11 02:29:28 +0900553 mNetdService = mServices.getNetd();
Luke Huangd290dd52018-09-04 17:08:18 +0800554 try {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900555 mNetworkObserverRegistry = new NMSNetworkObserverRegistry(
556 mContext, mDaemonHandler, mNetdService);
557 if (DBG) Slog.d(TAG, "Registered NetworkObserverRegistry");
Luke Huangd290dd52018-09-04 17:08:18 +0800558 } catch (RemoteException | ServiceSpecificException e) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900559 Slog.wtf(TAG, "Failed to register NetworkObserverRegistry: " + e);
Luke Huangd290dd52018-09-04 17:08:18 +0800560 }
bohu07cc3bb2016-05-03 15:58:01 -0700561 }
562
563 /**
564 * Prepare native daemon once connected, enabling modules and pushing any
565 * existing in-memory rules.
566 */
567 private void prepareNativeDaemon() {
Lorenzo Colitti58967ba2016-02-02 17:21:21 +0900568
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700569 // push any existing quota or UID rules
570 synchronized (mQuotaLock) {
Felipe Leme65be3022016-03-22 14:53:13 -0700571
Luke Huang56a03a02018-09-07 12:02:16 +0800572 // Netd unconditionally enable bandwidth control
573 SystemProperties.set(PROP_QTAGUID_ENABLED, "1");
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900574
Luke Huang473eb872018-07-26 17:33:14 +0800575 mStrictEnabled = true;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900576
Felipe Leme65be3022016-03-22 14:53:13 -0700577 setDataSaverModeEnabled(mDataSaverMode);
578
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700579 int size = mActiveQuotas.size();
580 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800581 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700582 final HashMap<String, Long> activeQuotas = mActiveQuotas;
583 mActiveQuotas = Maps.newHashMap();
584 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
585 setInterfaceQuota(entry.getKey(), entry.getValue());
586 }
587 }
588
589 size = mActiveAlerts.size();
590 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800591 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700592 final HashMap<String, Long> activeAlerts = mActiveAlerts;
593 mActiveAlerts = Maps.newHashMap();
594 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
595 setInterfaceAlert(entry.getKey(), entry.getValue());
596 }
597 }
598
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700599 SparseBooleanArray uidRejectOnQuota = null;
600 SparseBooleanArray uidAcceptOnQuota = null;
601 synchronized (mRulesLock) {
602 size = mUidRejectOnMetered.size();
603 if (size > 0) {
604 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules");
605 uidRejectOnQuota = mUidRejectOnMetered;
606 mUidRejectOnMetered = new SparseBooleanArray();
607 }
608
609 size = mUidAllowOnMetered.size();
610 if (size > 0) {
611 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules");
612 uidAcceptOnQuota = mUidAllowOnMetered;
613 mUidAllowOnMetered = new SparseBooleanArray();
614 }
615 }
616 if (uidRejectOnQuota != null) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700617 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
Felipe Leme65be3022016-03-22 14:53:13 -0700618 setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
619 uidRejectOnQuota.valueAt(i));
620 }
621 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700622 if (uidAcceptOnQuota != null) {
Felipe Leme65be3022016-03-22 14:53:13 -0700623 for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
624 setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
625 uidAcceptOnQuota.valueAt(i));
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700626 }
627 }
Jeff Sharkey605eb792014-11-04 13:34:06 -0800628
629 size = mUidCleartextPolicy.size();
630 if (size > 0) {
Felipe Leme03e689d2016-03-02 16:17:38 -0800631 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies");
Jeff Sharkey605eb792014-11-04 13:34:06 -0800632 final SparseIntArray local = mUidCleartextPolicy;
633 mUidCleartextPolicy = new SparseIntArray();
634 for (int i = 0; i < local.size(); i++) {
635 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i));
636 }
637 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700638
Robin Leec3736bc2017-03-10 16:19:54 +0000639 setFirewallEnabled(mFirewallEnabled);
Amith Yamasani15e472352015-04-24 19:06:07 -0700640
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700641 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, "");
642 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
643 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
644 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
Xiaohui Chenb41c9f72015-06-17 15:55:37 -0700645
Sudheer Shanka62f5c172017-03-17 16:25:55 -0700646 final int[] chains =
647 {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
648 for (int chain : chains) {
649 if (getFirewallChainState(chain)) {
650 setFirewallChainEnabled(chain, true);
651 }
Felipe Leme011b98f2016-02-10 17:28:31 -0800652 }
Amith Yamasani15e472352015-04-24 19:06:07 -0700653 }
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900654
Luke Huang56a03a02018-09-07 12:02:16 +0800655
656 try {
657 getBatteryStats().noteNetworkStatsEnabled();
658 } catch (RemoteException e) {
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +0900659 }
660
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700661 }
San Mehat4d02d002010-01-22 16:07:46 -0800662
San Mehat873f2142010-01-14 10:25:07 -0800663 //
664 // Netd Callback handling
665 //
666
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700667 private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
668 @Override
San Mehat873f2142010-01-14 10:25:07 -0800669 public void onDaemonConnected() {
Felipe Leme65be3022016-03-22 14:53:13 -0700670 Slog.i(TAG, "onDaemonConnected()");
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700671 // event is dispatched from internal NDC thread, so we prepare the
672 // daemon back on main thread.
673 if (mConnectedSignal != null) {
bohu07cc3bb2016-05-03 15:58:01 -0700674 // The system is booting and we're connecting to netd for the first time.
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700675 mConnectedSignal.countDown();
676 mConnectedSignal = null;
677 } else {
bohu07cc3bb2016-05-03 15:58:01 -0700678 // We're reconnecting to netd after the socket connection
679 // was interrupted (e.g., if it crashed).
Robert Greenwalt2c9f5472014-04-21 14:50:28 -0700680 mFgHandler.post(new Runnable() {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700681 @Override
682 public void run() {
bohu07cc3bb2016-05-03 15:58:01 -0700683 connectNativeNetdService();
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700684 prepareNativeDaemon();
685 }
686 });
687 }
San Mehat873f2142010-01-14 10:25:07 -0800688 }
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -0700689
Jeff Sharkeyb24a7852012-05-01 15:19:37 -0700690 @Override
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800691 public boolean onCheckHoldWakeLock(int code) {
692 return code == NetdResponseCode.InterfaceClassActivity;
693 }
694
695 @Override
San Mehat873f2142010-01-14 10:25:07 -0800696 public boolean onEvent(int code, String raw, String[] cooked) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900697 String errorMessage = String.format("Invalid event from daemon (%s)", raw);
JP Abgrall12b933d2011-07-14 18:09:22 -0700698 switch (code) {
699 case NetdResponseCode.InterfaceChange:
700 /*
701 * a network interface change occured
702 * Format: "NNN Iface added <name>"
703 * "NNN Iface removed <name>"
704 * "NNN Iface changed <name> <up/down>"
705 * "NNN Iface linkstatus <name> <up/down>"
706 */
707 if (cooked.length < 4 || !cooked[1].equals("Iface")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900708 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700709 }
710 if (cooked[2].equals("added")) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900711 mNetworkObserverRegistry.notifyInterfaceAdded(cooked[3]);
JP Abgrall12b933d2011-07-14 18:09:22 -0700712 return true;
713 } else if (cooked[2].equals("removed")) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900714 mNetworkObserverRegistry.notifyInterfaceRemoved(cooked[3]);
JP Abgrall12b933d2011-07-14 18:09:22 -0700715 return true;
716 } else if (cooked[2].equals("changed") && cooked.length == 5) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900717 mNetworkObserverRegistry.notifyInterfaceStatusChanged(
718 cooked[3], cooked[4].equals("up"));
JP Abgrall12b933d2011-07-14 18:09:22 -0700719 return true;
720 } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900721 mNetworkObserverRegistry.notifyInterfaceLinkStateChanged(
722 cooked[3], cooked[4].equals("up"));
JP Abgrall12b933d2011-07-14 18:09:22 -0700723 return true;
724 }
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900725 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700726 // break;
727 case NetdResponseCode.BandwidthControl:
728 /*
729 * Bandwidth control needs some attention
730 * Format: "NNN limit alert <alertName> <ifaceName>"
731 */
732 if (cooked.length < 5 || !cooked[1].equals("limit")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900733 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700734 }
735 if (cooked[2].equals("alert")) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900736 mNetworkObserverRegistry.notifyLimitReached(cooked[3], cooked[4]);
JP Abgrall12b933d2011-07-14 18:09:22 -0700737 return true;
738 }
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900739 throw new IllegalStateException(errorMessage);
JP Abgrall12b933d2011-07-14 18:09:22 -0700740 // break;
Haoyu Baidb3c8672012-06-20 14:29:57 -0700741 case NetdResponseCode.InterfaceClassActivity:
742 /*
743 * An network interface class state changed (active/idle)
744 * Format: "NNN IfaceClass <active/idle> <label>"
745 */
746 if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900747 throw new IllegalStateException(errorMessage);
Haoyu Baidb3c8672012-06-20 14:29:57 -0700748 }
Ashish Sharma0535a9f2014-03-12 18:42:23 -0700749 long timestampNanos = 0;
Ruchi Kandoifa97fcf2016-05-13 15:10:39 -0700750 int processUid = -1;
751 if (cooked.length >= 5) {
Ashish Sharma0535a9f2014-03-12 18:42:23 -0700752 try {
753 timestampNanos = Long.parseLong(cooked[4]);
Ruchi Kandoifa97fcf2016-05-13 15:10:39 -0700754 if (cooked.length == 6) {
755 processUid = Integer.parseInt(cooked[5]);
756 }
Ashish Sharma0535a9f2014-03-12 18:42:23 -0700757 } catch(NumberFormatException ne) {}
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700758 } else {
759 timestampNanos = SystemClock.elapsedRealtimeNanos();
Ashish Sharma0535a9f2014-03-12 18:42:23 -0700760 }
Haoyu Baidb3c8672012-06-20 14:29:57 -0700761 boolean isActive = cooked[2].equals("active");
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900762 mNetworkObserverRegistry.notifyInterfaceClassActivity(
763 Integer.parseInt(cooked[3]), isActive,
764 timestampNanos, processUid, false);
Haoyu Baidb3c8672012-06-20 14:29:57 -0700765 return true;
766 // break;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900767 case NetdResponseCode.InterfaceAddressChange:
768 /*
769 * A network address change occurred
770 * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
771 * "NNN Address removed <addr> <iface> <flags> <scope>"
772 */
Lorenzo Colittia9626c12013-11-04 17:44:09 +0900773 if (cooked.length < 7 || !cooked[1].equals("Address")) {
774 throw new IllegalStateException(errorMessage);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900775 }
776
Lorenzo Colitti64483942013-11-15 18:43:52 +0900777 String iface = cooked[4];
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900778 LinkAddress address;
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900779 try {
Lorenzo Colitti64483942013-11-15 18:43:52 +0900780 int flags = Integer.parseInt(cooked[5]);
781 int scope = Integer.parseInt(cooked[6]);
782 address = new LinkAddress(cooked[3], flags, scope);
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900783 } catch(NumberFormatException e) { // Non-numeric lifetime or scope.
784 throw new IllegalStateException(errorMessage, e);
Lorenzo Colitti64483942013-11-15 18:43:52 +0900785 } catch(IllegalArgumentException e) { // Malformed/invalid IP address.
Lorenzo Colitti5ad421a2013-11-17 15:05:02 +0900786 throw new IllegalStateException(errorMessage, e);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900787 }
788
789 if (cooked[2].equals("updated")) {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900790 mNetworkObserverRegistry.notifyAddressUpdated(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900791 } else {
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900792 mNetworkObserverRegistry.notifyAddressRemoved(iface, address);
Lorenzo Colitti5c7daac2013-08-05 10:39:37 +0900793 }
794 return true;
795 // break;
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900796 case NetdResponseCode.InterfaceDnsServerInfo:
797 /*
798 * Information about available DNS servers has been received.
799 * Format: "NNN DnsInfo servers <interface> <lifetime> <servers>"
800 */
801 long lifetime; // Actually a 32-bit unsigned integer.
802
803 if (cooked.length == 6 &&
804 cooked[1].equals("DnsInfo") &&
805 cooked[2].equals("servers")) {
806 try {
807 lifetime = Long.parseLong(cooked[4]);
808 } catch (NumberFormatException e) {
809 throw new IllegalStateException(errorMessage);
810 }
811 String[] servers = cooked[5].split(",");
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900812 mNetworkObserverRegistry.notifyInterfaceDnsServerInfo(
813 cooked[3], lifetime, servers);
Lorenzo Colitti5ae4a532013-10-31 11:59:46 +0900814 }
815 return true;
816 // break;
Lorenzo Colittic18cbfd2014-06-13 21:21:03 +0900817 case NetdResponseCode.RouteChange:
818 /*
819 * A route has been updated or removed.
820 * Format: "NNN Route <updated|removed> <dst> [via <gateway] [dev <iface>]"
821 */
822 if (!cooked[1].equals("Route") || cooked.length < 6) {
823 throw new IllegalStateException(errorMessage);
824 }
825
826 String via = null;
827 String dev = null;
828 boolean valid = true;
829 for (int i = 4; (i + 1) < cooked.length && valid; i += 2) {
830 if (cooked[i].equals("dev")) {
831 if (dev == null) {
832 dev = cooked[i+1];
833 } else {
834 valid = false; // Duplicate interface.
835 }
836 } else if (cooked[i].equals("via")) {
837 if (via == null) {
838 via = cooked[i+1];
839 } else {
840 valid = false; // Duplicate gateway.
841 }
842 } else {
843 valid = false; // Unknown syntax.
844 }
845 }
846 if (valid) {
847 try {
848 // InetAddress.parseNumericAddress(null) inexplicably returns ::1.
849 InetAddress gateway = null;
850 if (via != null) gateway = InetAddress.parseNumericAddress(via);
851 RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev);
Lorenzo Colittid8bc8292019-01-24 13:28:50 +0900852 mNetworkObserverRegistry.notifyRouteChange(
853 cooked[2].equals("updated"), route);
Lorenzo Colittic18cbfd2014-06-13 21:21:03 +0900854 return true;
855 } catch (IllegalArgumentException e) {}
856 }
857 throw new IllegalStateException(errorMessage);
858 // break;
Jeff Sharkey605eb792014-11-04 13:34:06 -0800859 case NetdResponseCode.StrictCleartext:
860 final int uid = Integer.parseInt(cooked[1]);
861 final byte[] firstPacket = HexDump.hexStringToByteArray(cooked[2]);
862 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800863 ActivityManager.getService().notifyCleartextNetwork(uid, firstPacket);
Jeff Sharkey605eb792014-11-04 13:34:06 -0800864 } catch (RemoteException ignored) {
865 }
866 break;
JP Abgrall12b933d2011-07-14 18:09:22 -0700867 default: break;
Robert Greenwalte3253922010-02-18 09:23:25 -0800868 }
869 return false;
San Mehat873f2142010-01-14 10:25:07 -0800870 }
871 }
872
San Mehated4fc8a2010-01-22 12:28:36 -0800873
San Mehat873f2142010-01-14 10:25:07 -0800874 //
875 // INetworkManagementService members
876 //
Erik Kline4e37b702016-07-05 11:34:21 +0900877 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800878 public String[] listInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800879 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -0700880 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +0800881 return mNetdService.interfaceGetList();
Luke Huang14f75442018-08-15 19:22:54 +0800882 } catch (RemoteException | ServiceSpecificException e) {
883 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700884 }
San Mehated4fc8a2010-01-22 12:28:36 -0800885 }
886
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800887 @Override
888 public InterfaceConfiguration getInterfaceConfig(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800889 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Luke Huang14f75442018-08-15 19:22:54 +0800890 final InterfaceConfigurationParcel result;
Kenny Roota80ce062010-06-01 13:23:53 -0700891 try {
Luke Huang14f75442018-08-15 19:22:54 +0800892 result = mNetdService.interfaceGetCfg(iface);
893 } catch (RemoteException | ServiceSpecificException e) {
894 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700895 }
San Mehated4fc8a2010-01-22 12:28:36 -0800896
San Mehated4fc8a2010-01-22 12:28:36 -0800897 try {
Luke Huang14f75442018-08-15 19:22:54 +0800898 final InterfaceConfiguration cfg = InterfaceConfiguration.fromParcel(result);
899 return cfg;
900 } catch (IllegalArgumentException iae) {
901 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae);
San Mehated4fc8a2010-01-22 12:28:36 -0800902 }
San Mehated4fc8a2010-01-22 12:28:36 -0800903 }
904
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800905 @Override
906 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800907 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800908 LinkAddress linkAddr = cfg.getLinkAddress();
Robert Greenwalt2d2afd12011-02-01 15:30:46 -0800909 if (linkAddr == null || linkAddr.getAddress() == null) {
910 throw new IllegalStateException("Null LinkAddress given");
Robert Greenwalted126402011-01-28 15:34:55 -0800911 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800912
Luke Huang14f75442018-08-15 19:22:54 +0800913 final InterfaceConfigurationParcel cfgParcel = cfg.toParcel(iface);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800914
Kenny Roota80ce062010-06-01 13:23:53 -0700915 try {
Luke Huang14f75442018-08-15 19:22:54 +0800916 mNetdService.interfaceSetCfg(cfgParcel);
917 } catch (RemoteException | ServiceSpecificException e) {
918 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -0700919 }
San Mehat873f2142010-01-14 10:25:07 -0800920 }
921
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800922 @Override
923 public void setInterfaceDown(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800924 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800925 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800926 ifcg.setInterfaceDown();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800927 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700928 }
929
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800930 @Override
931 public void setInterfaceUp(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800932 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800933 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
Jeff Sharkeyddba1062011-11-29 18:37:04 -0800934 ifcg.setInterfaceUp();
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800935 setInterfaceConfig(iface, ifcg);
Irfan Sheriff7244c972011-08-05 20:40:45 -0700936 }
937
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800938 @Override
939 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800940 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sheriff73293612011-09-14 12:31:56 -0700941 try {
Luke Huang14f75442018-08-15 19:22:54 +0800942 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable);
943 } catch (RemoteException | ServiceSpecificException e) {
944 throw new IllegalStateException(e);
Irfan Sheriff73293612011-09-14 12:31:56 -0700945 }
946 }
947
Irfan Sherifff5600612011-06-16 10:26:28 -0700948 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
949 IPv6 addresses on interface down, but we need to do full clean up here */
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800950 @Override
951 public void clearInterfaceAddresses(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800952 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Irfan Sherifff5600612011-06-16 10:26:28 -0700953 try {
Luke Huang14f75442018-08-15 19:22:54 +0800954 mNetdService.interfaceClearAddrs(iface);
955 } catch (RemoteException | ServiceSpecificException e) {
956 throw new IllegalStateException(e);
Irfan Sherifff5600612011-06-16 10:26:28 -0700957 }
958 }
959
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800960 @Override
961 public void enableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800962 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700963 try {
Luke Huang14f75442018-08-15 19:22:54 +0800964 mNetdService.interfaceSetEnableIPv6(iface, true);
965 } catch (RemoteException | ServiceSpecificException e) {
966 throw new IllegalStateException(e);
repo sync7960d9f2011-09-29 12:40:02 -0700967 }
968 }
969
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800970 @Override
Joel Scherpelz2db10742017-06-07 15:38:38 +0900971 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
972 try {
973 mNetdService.setIPv6AddrGenMode(iface, mode);
974 } catch (RemoteException e) {
975 throw e.rethrowAsRuntimeException();
976 }
977 }
978
979 @Override
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800980 public void disableIpv6(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800981 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
repo sync7960d9f2011-09-29 12:40:02 -0700982 try {
Luke Huang14f75442018-08-15 19:22:54 +0800983 mNetdService.interfaceSetEnableIPv6(iface, false);
984 } catch (RemoteException | ServiceSpecificException e) {
985 throw new IllegalStateException(e);
repo sync7960d9f2011-09-29 12:40:02 -0700986 }
987 }
988
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800989 @Override
Sreeram Ramachandranb2829fa2014-04-15 19:07:12 -0700990 public void addRoute(int netId, RouteInfo route) {
Luke Huang8a462ec2018-08-24 20:33:16 +0800991 modifyRoute(MODIFY_OPERATION_ADD, netId, route);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700992 }
993
Jeff Sharkeyaf75c332011-11-18 12:41:12 -0800994 @Override
Sreeram Ramachandranb2829fa2014-04-15 19:07:12 -0700995 public void removeRoute(int netId, RouteInfo route) {
Luke Huang8a462ec2018-08-24 20:33:16 +0800996 modifyRoute(MODIFY_OPERATION_REMOVE, netId, route);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700997 }
998
Luke Huang8a462ec2018-08-24 20:33:16 +0800999 private void modifyRoute(boolean add, int netId, RouteInfo route) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001000 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwalt3b28e9a2011-11-02 14:37:19 -07001001
Luke Huang8a462ec2018-08-24 20:33:16 +08001002 final String ifName = route.getInterface();
1003 final String dst = route.getDestination().toString();
1004 final String nextHop;
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +09001005
1006 switch (route.getType()) {
1007 case RouteInfo.RTN_UNICAST:
1008 if (route.hasGateway()) {
Luke Huang8a462ec2018-08-24 20:33:16 +08001009 nextHop = route.getGateway().getHostAddress();
1010 } else {
1011 nextHop = INetd.NEXTHOP_NONE;
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +09001012 }
1013 break;
1014 case RouteInfo.RTN_UNREACHABLE:
Luke Huang8a462ec2018-08-24 20:33:16 +08001015 nextHop = INetd.NEXTHOP_UNREACHABLE;
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +09001016 break;
1017 case RouteInfo.RTN_THROW:
Luke Huang8a462ec2018-08-24 20:33:16 +08001018 nextHop = INetd.NEXTHOP_THROW;
1019 break;
1020 default:
1021 nextHop = INetd.NEXTHOP_NONE;
Lorenzo Colitti4b0f8e62014-09-19 01:49:05 +09001022 break;
Sreeram Ramachandran1fbcb272014-05-22 16:30:48 -07001023 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001024 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08001025 if (add) {
1026 mNetdService.networkAddRoute(netId, ifName, dst, nextHop);
1027 } else {
1028 mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop);
1029 }
1030 } catch (RemoteException | ServiceSpecificException e) {
1031 throw new IllegalStateException(e);
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -07001032 }
1033 }
1034
1035 private ArrayList<String> readRouteList(String filename) {
1036 FileInputStream fstream = null;
Christopher Wiley212b95f2016-08-02 11:38:57 -07001037 ArrayList<String> list = new ArrayList<>();
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -07001038
1039 try {
1040 fstream = new FileInputStream(filename);
1041 DataInputStream in = new DataInputStream(fstream);
1042 BufferedReader br = new BufferedReader(new InputStreamReader(in));
1043 String s;
1044
1045 // throw away the title line
1046
1047 while (((s = br.readLine()) != null) && (s.length() != 0)) {
1048 list.add(s);
1049 }
1050 } catch (IOException ex) {
1051 // return current list, possibly empty
1052 } finally {
1053 if (fstream != null) {
1054 try {
1055 fstream.close();
1056 } catch (IOException ex) {}
1057 }
1058 }
1059
1060 return list;
1061 }
1062
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001063 @Override
sy.yun9d9b74a2013-09-02 05:24:09 +09001064 public void setMtu(String iface, int mtu) {
1065 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1066
sy.yun9d9b74a2013-09-02 05:24:09 +09001067 try {
Luke Huang14f75442018-08-15 19:22:54 +08001068 mNetdService.interfaceSetMtu(iface, mtu);
1069 } catch (RemoteException | ServiceSpecificException e) {
1070 throw new IllegalStateException(e);
sy.yun9d9b74a2013-09-02 05:24:09 +09001071 }
1072 }
1073
1074 @Override
San Mehat873f2142010-01-14 10:25:07 -08001075 public void shutdown() {
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001076 // TODO: remove from aidl if nobody calls externally
1077 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
San Mehat873f2142010-01-14 10:25:07 -08001078
Felipe Leme03e689d2016-03-02 16:17:38 -08001079 Slog.i(TAG, "Shutting down");
San Mehat873f2142010-01-14 10:25:07 -08001080 }
1081
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001082 @Override
San Mehat873f2142010-01-14 10:25:07 -08001083 public boolean getIpForwardingEnabled() throws IllegalStateException{
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001084 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -08001085
Kenny Roota80ce062010-06-01 13:23:53 -07001086 try {
Luke Huang4db488b2018-08-16 15:37:31 +08001087 final boolean isEnabled = mNetdService.ipfwdEnabled();
1088 return isEnabled;
1089 } catch (RemoteException | ServiceSpecificException e) {
1090 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001091 }
San Mehat873f2142010-01-14 10:25:07 -08001092 }
1093
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001094 @Override
1095 public void setIpForwardingEnabled(boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001096 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001097 try {
Luke Huang4db488b2018-08-16 15:37:31 +08001098 if (enable) {
1099 mNetdService.ipfwdEnableForwarding("tethering");
1100 } else {
1101 mNetdService.ipfwdDisableForwarding("tethering");
1102 }
1103 } catch (RemoteException | ServiceSpecificException e) {
1104 throw new IllegalStateException(e);
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001105 }
San Mehat873f2142010-01-14 10:25:07 -08001106 }
1107
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001108 @Override
1109 public void startTethering(String[] dhcpRange) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001110 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Robert Greenwaltbfb7bfa2010-03-24 16:03:21 -07001111 // an odd number of addrs will fail
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001112
Kenny Roota80ce062010-06-01 13:23:53 -07001113 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001114 mNetdService.tetherStart(dhcpRange);
1115 } catch (RemoteException | ServiceSpecificException e) {
1116 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001117 }
San Mehat873f2142010-01-14 10:25:07 -08001118 }
1119
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001120 @Override
1121 public void stopTethering() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001122 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001123 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001124 mNetdService.tetherStop();
1125 } catch (RemoteException | ServiceSpecificException e) {
1126 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001127 }
San Mehat873f2142010-01-14 10:25:07 -08001128 }
1129
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001130 @Override
1131 public boolean isTetheringStarted() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001132 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat873f2142010-01-14 10:25:07 -08001133
Kenny Roota80ce062010-06-01 13:23:53 -07001134 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001135 final boolean isEnabled = mNetdService.tetherIsEnabled();
1136 return isEnabled;
1137 } catch (RemoteException | ServiceSpecificException e) {
1138 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001139 }
San Mehat873f2142010-01-14 10:25:07 -08001140 }
Matthew Xiefe19f122012-07-12 16:03:32 -07001141
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001142 @Override
1143 public void tetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001144 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001145 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001146 mNetdService.tetherInterfaceAdd(iface);
1147 } catch (RemoteException | ServiceSpecificException e) {
1148 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001149 }
Christopher Wiley212b95f2016-08-02 11:38:57 -07001150 List<RouteInfo> routes = new ArrayList<>();
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07001151 // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
1152 // suitable to use as a route destination.
1153 routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface));
1154 addInterfaceToLocalNetwork(iface, routes);
San Mehat873f2142010-01-14 10:25:07 -08001155 }
1156
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001157 @Override
San Mehat873f2142010-01-14 10:25:07 -08001158 public void untetherInterface(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001159 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001160 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001161 mNetdService.tetherInterfaceRemove(iface);
1162 } catch (RemoteException | ServiceSpecificException e) {
1163 throw new IllegalStateException(e);
Erik Kline1f4278a2016-08-16 16:46:33 +09001164 } finally {
1165 removeInterfaceFromLocalNetwork(iface);
Kenny Roota80ce062010-06-01 13:23:53 -07001166 }
San Mehat873f2142010-01-14 10:25:07 -08001167 }
1168
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001169 @Override
1170 public String[] listTetheredInterfaces() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001171 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001172 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +08001173 return mNetdService.tetherInterfaceList();
Luke Huang4a32bf42018-08-21 19:09:45 +08001174 } catch (RemoteException | ServiceSpecificException e) {
1175 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001176 }
San Mehat873f2142010-01-14 10:25:07 -08001177 }
1178
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001179 @Override
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001180 public void setDnsForwarders(Network network, String[] dns) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001181 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001182
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001183 int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001184
San Mehat873f2142010-01-14 10:25:07 -08001185 try {
Luke Huang4a32bf42018-08-21 19:09:45 +08001186 mNetdService.tetherDnsSet(netId, dns);
1187 } catch (RemoteException | ServiceSpecificException e) {
1188 throw new IllegalStateException(e);
San Mehat873f2142010-01-14 10:25:07 -08001189 }
1190 }
1191
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001192 @Override
1193 public String[] getDnsForwarders() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001194 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001195 try {
Luke Huang1b4f92f2018-12-12 15:59:31 +08001196 return mNetdService.tetherDnsList();
Luke Huang4a32bf42018-08-21 19:09:45 +08001197 } catch (RemoteException | ServiceSpecificException e) {
1198 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001199 }
San Mehat873f2142010-01-14 10:25:07 -08001200 }
1201
jiaguo1da35f72014-01-09 16:39:59 +08001202 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
Christopher Wiley212b95f2016-08-02 11:38:57 -07001203 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size());
jiaguo1da35f72014-01-09 16:39:59 +08001204 for (InterfaceAddress ia : addresses) {
1205 if (!ia.getAddress().isLinkLocalAddress())
1206 filtered.add(ia);
1207 }
1208 return filtered;
1209 }
1210
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001211 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) {
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001212 try {
Luke Huang4db488b2018-08-16 15:37:31 +08001213 if (add) {
1214 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface);
1215 } else {
1216 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface);
1217 }
1218 } catch (RemoteException | ServiceSpecificException e) {
1219 throw new IllegalStateException(e);
Lorenzo Colitti35e36db2015-02-26 01:25:36 +09001220 }
1221 }
1222
1223 @Override
1224 public void startInterfaceForwarding(String fromIface, String toIface) {
1225 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1226 modifyInterfaceForward(true, fromIface, toIface);
1227 }
1228
1229 @Override
1230 public void stopInterfaceForwarding(String fromIface, String toIface) {
1231 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1232 modifyInterfaceForward(false, fromIface, toIface);
1233 }
1234
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001235 @Override
1236 public void enableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001237 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001238 try {
Luke Huanga31e0732018-10-22 13:23:10 +09001239 mNetdService.tetherAddForward(internalInterface, externalInterface);
1240 } catch (RemoteException | ServiceSpecificException e) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001241 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001242 }
San Mehat873f2142010-01-14 10:25:07 -08001243 }
1244
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001245 @Override
1246 public void disableNat(String internalInterface, String externalInterface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001247 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001248 try {
Luke Huanga31e0732018-10-22 13:23:10 +09001249 mNetdService.tetherRemoveForward(internalInterface, externalInterface);
1250 } catch (RemoteException | ServiceSpecificException e) {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001251 throw new IllegalStateException(e);
Kenny Roota80ce062010-06-01 13:23:53 -07001252 }
San Mehat873f2142010-01-14 10:25:07 -08001253 }
San Mehat72759df2010-01-19 13:50:37 -08001254
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001255 @Override
1256 public String[] listTtys() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001257 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001258 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001259 return NativeDaemonEvent.filterMessageList(
1260 mConnector.executeForList("list_ttys"), TtyListResult);
Kenny Roota80ce062010-06-01 13:23:53 -07001261 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001262 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001263 }
San Mehat72759df2010-01-19 13:50:37 -08001264 }
1265
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001266 @Override
1267 public void attachPppd(
1268 String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001269 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
San Mehat72759df2010-01-19 13:50:37 -08001270 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001271 mConnector.execute("pppd", "attach", tty,
Robert Greenwalte5903732011-02-22 16:00:42 -08001272 NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
1273 NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
1274 NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001275 NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
Kenny Roota80ce062010-06-01 13:23:53 -07001276 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001277 throw e.rethrowAsParcelableException();
San Mehat72759df2010-01-19 13:50:37 -08001278 }
1279 }
1280
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001281 @Override
1282 public void detachPppd(String tty) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001283 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Kenny Roota80ce062010-06-01 13:23:53 -07001284 try {
Jeff Sharkeyba2896e2011-11-30 18:13:54 -08001285 mConnector.execute("pppd", "detach", tty);
Kenny Roota80ce062010-06-01 13:23:53 -07001286 } catch (NativeDaemonConnectorException e) {
Jeff Sharkey276642b2011-12-01 11:24:24 -08001287 throw e.rethrowAsParcelableException();
Kenny Roota80ce062010-06-01 13:23:53 -07001288 }
San Mehat72759df2010-01-19 13:50:37 -08001289 }
Robert Greenwaltce1200d2010-02-18 11:25:54 -08001290
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001291 @Override
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001292 public void addIdleTimer(String iface, int timeout, final int type) {
Haoyu Bai04124232012-06-28 15:26:19 -07001293 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1294
1295 if (DBG) Slog.d(TAG, "Adding idletimer");
1296
1297 synchronized (mIdleTimerLock) {
1298 IdleTimerParams params = mActiveIdleTimers.get(iface);
1299 if (params != null) {
1300 // the interface already has idletimer, update network count
1301 params.networkCount++;
1302 return;
1303 }
1304
1305 try {
Luke Huanga62d0492018-07-27 20:08:21 +08001306 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
1307 } catch (RemoteException | ServiceSpecificException e) {
1308 throw new IllegalStateException(e);
Haoyu Bai04124232012-06-28 15:26:19 -07001309 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001310 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
1311
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001312 // Networks start up.
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001313 if (ConnectivityManager.isNetworkTypeMobile(type)) {
1314 mNetworkActive = false;
1315 }
Lorenzo Colittid8bc8292019-01-24 13:28:50 +09001316 mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity(
1317 type, true /* isActive */, SystemClock.elapsedRealtimeNanos(), -1, false));
Haoyu Bai04124232012-06-28 15:26:19 -07001318 }
1319 }
1320
1321 @Override
1322 public void removeIdleTimer(String iface) {
1323 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1324
1325 if (DBG) Slog.d(TAG, "Removing idletimer");
1326
1327 synchronized (mIdleTimerLock) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08001328 final IdleTimerParams params = mActiveIdleTimers.get(iface);
Haoyu Bai04124232012-06-28 15:26:19 -07001329 if (params == null || --(params.networkCount) > 0) {
1330 return;
1331 }
1332
1333 try {
Luke Huanga62d0492018-07-27 20:08:21 +08001334 mNetdService.idletimerRemoveInterface(iface,
1335 params.timeout, Integer.toString(params.type));
1336 } catch (RemoteException | ServiceSpecificException e) {
1337 throw new IllegalStateException(e);
Haoyu Bai04124232012-06-28 15:26:19 -07001338 }
1339 mActiveIdleTimers.remove(iface);
Lorenzo Colittid8bc8292019-01-24 13:28:50 +09001340 mDaemonHandler.post(() -> mNetworkObserverRegistry.notifyInterfaceClassActivity(
1341 params.type, false /* isActive */, SystemClock.elapsedRealtimeNanos(), -1,
1342 false));
Haoyu Bai04124232012-06-28 15:26:19 -07001343 }
1344 }
1345
1346 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001347 public NetworkStats getNetworkStatsSummaryDev() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001348 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001349 try {
1350 return mStatsFactory.readNetworkStatsSummaryDev();
1351 } catch (IOException e) {
1352 throw new IllegalStateException(e);
1353 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001354 }
1355
1356 @Override
1357 public NetworkStats getNetworkStatsSummaryXt() {
1358 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001359 try {
1360 return mStatsFactory.readNetworkStatsSummaryXt();
1361 } catch (IOException e) {
1362 throw new IllegalStateException(e);
1363 }
Jeff Sharkeyae2c1812011-10-04 13:11:40 -07001364 }
1365
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001366 @Override
Jeff Sharkey9a13f362011-04-26 16:25:36 -07001367 public NetworkStats getNetworkStatsDetail() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001368 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001369 try {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08001370 return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001371 } catch (IOException e) {
1372 throw new IllegalStateException(e);
1373 }
San Mehat91cac642010-03-31 14:31:36 -07001374 }
1375
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001376 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001377 public void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001378 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001379
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001380 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001381 if (mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001382 throw new IllegalStateException("iface " + iface + " already has quota");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001383 }
1384
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001385 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001386 // TODO: support quota shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001387 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes);
1388
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001389 mActiveQuotas.put(iface, quotaBytes);
Luke Huangc7bea8662018-08-07 16:04:26 +08001390 } catch (RemoteException | ServiceSpecificException e) {
1391 throw new IllegalStateException(e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001392 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001393
1394 synchronized (mTetheringStatsProviders) {
1395 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1396 try {
1397 provider.setInterfaceQuota(iface, quotaBytes);
1398 } catch (RemoteException e) {
1399 Log.e(TAG, "Problem setting tethering data limit on provider " +
1400 mTetheringStatsProviders.get(provider) + ": " + e);
1401 }
1402 }
1403 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001404 }
1405 }
1406
1407 @Override
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001408 public void removeInterfaceQuota(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001409 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001410
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001411 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001412 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001413 // TODO: eventually consider throwing
1414 return;
1415 }
1416
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001417 mActiveQuotas.remove(iface);
1418 mActiveAlerts.remove(iface);
Jeff Sharkey38ddeaa2011-11-08 13:04:22 -08001419
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001420 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001421 // TODO: support quota shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001422 mNetdService.bandwidthRemoveInterfaceQuota(iface);
1423 } catch (RemoteException | ServiceSpecificException e) {
1424 throw new IllegalStateException(e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001425 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001426
1427 synchronized (mTetheringStatsProviders) {
1428 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1429 try {
1430 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED);
1431 } catch (RemoteException e) {
1432 Log.e(TAG, "Problem removing tethering data limit on provider " +
1433 mTetheringStatsProviders.get(provider) + ": " + e);
1434 }
1435 }
1436 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001437 }
1438 }
1439
1440 @Override
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001441 public void setInterfaceAlert(String iface, long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001442 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001443
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001444 // quick sanity check
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001445 if (!mActiveQuotas.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001446 throw new IllegalStateException("setting alert requires existing quota on iface");
1447 }
1448
1449 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001450 if (mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001451 throw new IllegalStateException("iface " + iface + " already has alert");
1452 }
1453
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001454 try {
1455 // TODO: support alert shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001456 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001457 mActiveAlerts.put(iface, alertBytes);
Luke Huangc7bea8662018-08-07 16:04:26 +08001458 } catch (RemoteException | ServiceSpecificException e) {
1459 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001460 }
1461 }
1462 }
1463
1464 @Override
1465 public void removeInterfaceAlert(String iface) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001466 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001467
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001468 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001469 if (!mActiveAlerts.containsKey(iface)) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001470 // TODO: eventually consider throwing
1471 return;
1472 }
1473
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001474 try {
1475 // TODO: support alert shared across interfaces
Luke Huangc7bea8662018-08-07 16:04:26 +08001476 mNetdService.bandwidthRemoveInterfaceAlert(iface);
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001477 mActiveAlerts.remove(iface);
Luke Huangc7bea8662018-08-07 16:04:26 +08001478 } catch (RemoteException | ServiceSpecificException e) {
1479 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001480 }
1481 }
1482 }
1483
1484 @Override
1485 public void setGlobalAlert(long alertBytes) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001486 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001487
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001488 try {
Luke Huangc7bea8662018-08-07 16:04:26 +08001489 mNetdService.bandwidthSetGlobalAlert(alertBytes);
1490 } catch (RemoteException | ServiceSpecificException e) {
1491 throw new IllegalStateException(e);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001492 }
1493 }
1494
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001495 private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001496 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001497
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07001498 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001499 boolean oldEnable;
1500 SparseBooleanArray quotaList;
1501 synchronized (mRulesLock) {
1502 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered;
1503 oldEnable = quotaList.get(uid, false);
1504 }
Felipe Leme65be3022016-03-22 14:53:13 -07001505 if (oldEnable == enable) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001506 // TODO: eventually consider throwing
1507 return;
1508 }
1509
Felipe Leme29e72ea2016-09-08 13:26:55 -07001510 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001511 try {
Luke Huangc7bea8662018-08-07 16:04:26 +08001512 if (blacklist) {
1513 if (enable) {
1514 mNetdService.bandwidthAddNaughtyApp(uid);
1515 } else {
1516 mNetdService.bandwidthRemoveNaughtyApp(uid);
1517 }
1518 } else {
1519 if (enable) {
1520 mNetdService.bandwidthAddNiceApp(uid);
1521 } else {
1522 mNetdService.bandwidthRemoveNiceApp(uid);
1523 }
1524 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001525 synchronized (mRulesLock) {
1526 if (enable) {
1527 quotaList.put(uid, true);
1528 } else {
1529 quotaList.delete(uid);
1530 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001531 }
Luke Huangc7bea8662018-08-07 16:04:26 +08001532 } catch (RemoteException | ServiceSpecificException e) {
1533 throw new IllegalStateException(e);
Felipe Leme29e72ea2016-09-08 13:26:55 -07001534 } finally {
1535 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001536 }
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001537 }
1538 }
1539
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001540 @Override
Felipe Leme65be3022016-03-22 14:53:13 -07001541 public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001542 setUidOnMeteredNetworkList(uid, true, enable);
Felipe Leme65be3022016-03-22 14:53:13 -07001543 }
1544
1545 @Override
1546 public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001547 setUidOnMeteredNetworkList(uid, false, enable);
Felipe Leme65be3022016-03-22 14:53:13 -07001548 }
1549
1550 @Override
1551 public boolean setDataSaverModeEnabled(boolean enable) {
Sehee Parka9139bc2017-12-22 13:54:05 +09001552 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
1553
Felipe Leme65be3022016-03-22 14:53:13 -07001554 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
1555 synchronized (mQuotaLock) {
1556 if (mDataSaverMode == enable) {
1557 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
1558 return true;
1559 }
Felipe Leme29e72ea2016-09-08 13:26:55 -07001560 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver");
Felipe Leme65be3022016-03-22 14:53:13 -07001561 try {
1562 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
1563 if (changed) {
1564 mDataSaverMode = enable;
1565 } else {
1566 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
1567 }
1568 return changed;
1569 } catch (RemoteException e) {
1570 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
1571 return false;
Felipe Leme29e72ea2016-09-08 13:26:55 -07001572 } finally {
1573 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Leme65be3022016-03-22 14:53:13 -07001574 }
1575 }
1576 }
1577
1578 @Override
Robin Lee17e61832016-05-09 13:46:28 +01001579 public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)
1580 throws ServiceSpecificException {
Rubin Xu2ea6c552018-01-11 10:59:19 +00001581 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
Robin Lee17e61832016-05-09 13:46:28 +01001582 try {
1583 mNetdService.networkRejectNonSecureVpn(add, uidRanges);
1584 } catch (ServiceSpecificException e) {
1585 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1586 + ": netd command failed", e);
1587 throw e;
1588 } catch (RemoteException e) {
1589 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1590 + ": netd command failed", e);
1591 throw e.rethrowAsRuntimeException();
1592 }
1593 }
1594
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001595 private void applyUidCleartextNetworkPolicy(int uid, int policy) {
Luke Huang473eb872018-07-26 17:33:14 +08001596 final int policyValue;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001597 switch (policy) {
1598 case StrictMode.NETWORK_POLICY_ACCEPT:
Luke Huang473eb872018-07-26 17:33:14 +08001599 policyValue = INetd.PENALTY_POLICY_ACCEPT;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001600 break;
1601 case StrictMode.NETWORK_POLICY_LOG:
Luke Huang473eb872018-07-26 17:33:14 +08001602 policyValue = INetd.PENALTY_POLICY_LOG;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001603 break;
1604 case StrictMode.NETWORK_POLICY_REJECT:
Luke Huang473eb872018-07-26 17:33:14 +08001605 policyValue = INetd.PENALTY_POLICY_REJECT;
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001606 break;
1607 default:
1608 throw new IllegalArgumentException("Unknown policy " + policy);
1609 }
1610
1611 try {
Luke Huang473eb872018-07-26 17:33:14 +08001612 mNetdService.strictUidCleartextPenalty(uid, policyValue);
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001613 mUidCleartextPolicy.put(uid, policy);
Luke Huang473eb872018-07-26 17:33:14 +08001614 } catch (RemoteException | ServiceSpecificException e) {
1615 throw new IllegalStateException(e);
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001616 }
1617 }
1618
Robin Lee17e61832016-05-09 13:46:28 +01001619 @Override
Jeff Sharkey605eb792014-11-04 13:34:06 -08001620 public void setUidCleartextNetworkPolicy(int uid, int policy) {
1621 if (Binder.getCallingUid() != uid) {
1622 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1623 }
1624
1625 synchronized (mQuotaLock) {
1626 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1627 if (oldPolicy == policy) {
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001628 // This also ensures we won't needlessly apply an ACCEPT policy if we've just
1629 // enabled strict and the underlying iptables rules are empty.
Jeff Sharkey605eb792014-11-04 13:34:06 -08001630 return;
1631 }
1632
Luke Huang473eb872018-07-26 17:33:14 +08001633 // TODO: remove this code after removing prepareNativeDaemon()
Jeff Sharkey605eb792014-11-04 13:34:06 -08001634 if (!mStrictEnabled) {
1635 // Module isn't enabled yet; stash the requested policy away to
1636 // apply later once the daemon is connected.
1637 mUidCleartextPolicy.put(uid, policy);
1638 return;
1639 }
1640
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001641 // netd does not keep state on strict mode policies, and cannot replace a non-accept
1642 // policy without deleting it first. Rather than add state to netd, just always send
1643 // it an accept policy when switching between two non-accept policies.
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001644 // TODO: consider keeping state in netd so we can simplify this code.
Lorenzo Colitti8c253ad2017-07-19 00:23:44 +09001645 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT &&
1646 policy != StrictMode.NETWORK_POLICY_ACCEPT) {
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001647 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT);
Jeff Sharkey605eb792014-11-04 13:34:06 -08001648 }
Lorenzo Colitti26364f12017-08-20 11:54:57 +09001649
1650 applyUidCleartextNetworkPolicy(uid, policy);
Jeff Sharkey605eb792014-11-04 13:34:06 -08001651 }
1652 }
1653
1654 @Override
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001655 public boolean isBandwidthControlEnabled() {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001656 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Luke Huang56a03a02018-09-07 12:02:16 +08001657 return true;
Jeff Sharkey63d27a92011-08-03 17:04:22 -07001658 }
1659
1660 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001661 public NetworkStats getNetworkStatsUidDetail(int uid, String[] ifaces) {
Jeff Sharkey4529bb62011-12-14 10:31:54 -08001662 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001663 try {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001664 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, TAG_ALL, null);
Jeff Sharkey9a2c2a62013-01-14 16:48:51 -08001665 } catch (IOException e) {
1666 throw new IllegalStateException(e);
1667 }
Jeff Sharkeyeedcb952011-05-17 14:55:15 -07001668 }
1669
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001670 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
1671 @Override
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001672 public NetworkStats getTetherStats(int how) {
1673 // We only need to return per-UID stats. Per-device stats are already counted by
1674 // interface counters.
1675 if (how != STATS_PER_UID) {
1676 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
1677 }
1678
Luke Huang13b79e82018-09-26 14:53:42 +08001679 final TetherStatsParcel[] tetherStatsVec;
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001680 try {
Luke Huang13b79e82018-09-26 14:53:42 +08001681 tetherStatsVec = mNetdService.tetherGetStats();
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001682 } catch (RemoteException | ServiceSpecificException e) {
1683 throw new IllegalStateException("problem parsing tethering stats: ", e);
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001684 }
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001685
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001686 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
Luke Huang13b79e82018-09-26 14:53:42 +08001687 tetherStatsVec.length);
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001688 final NetworkStats.Entry entry = new NetworkStats.Entry();
1689
Luke Huang13b79e82018-09-26 14:53:42 +08001690 for (TetherStatsParcel tetherStats : tetherStatsVec) {
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001691 try {
Luke Huang13b79e82018-09-26 14:53:42 +08001692 entry.iface = tetherStats.iface;
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001693 entry.uid = UID_TETHERING;
1694 entry.set = SET_DEFAULT;
1695 entry.tag = TAG_NONE;
Luke Huang13b79e82018-09-26 14:53:42 +08001696 entry.rxBytes = tetherStats.rxBytes;
1697 entry.rxPackets = tetherStats.rxPackets;
1698 entry.txBytes = tetherStats.txBytes;
1699 entry.txPackets = tetherStats.txPackets;
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001700 stats.combineValues(entry);
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001701 } catch (ArrayIndexOutOfBoundsException e) {
Luke Huang13b79e82018-09-26 14:53:42 +08001702 throw new IllegalStateException("invalid tethering stats " + e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001703 }
1704 }
Lorenzo Colitti563dc452017-09-01 17:12:34 +09001705
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001706 return stats;
1707 }
Lorenzo Colitti50b60fc2017-08-11 13:47:49 +09001708
1709 @Override
1710 public void setInterfaceQuota(String iface, long quotaBytes) {
1711 // Do nothing. netd is already informed of quota changes in setInterfaceQuota.
1712 }
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001713 }
1714
1715 @Override
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001716 public NetworkStats getNetworkStatsTethering(int how) {
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001717 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1718
1719 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1720 synchronized (mTetheringStatsProviders) {
1721 for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
1722 try {
Lorenzo Colittif1912ca2017-08-17 19:23:08 +09001723 stats.combineAllValues(provider.getTetherStats(how));
Lorenzo Colitti07f13042017-07-10 19:06:57 +09001724 } catch (RemoteException e) {
1725 Log.e(TAG, "Problem reading tethering stats from " +
1726 mTetheringStatsProviders.get(provider) + ": " + e);
1727 }
1728 }
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001729 }
Jeff Sharkeye4984be2013-09-10 21:03:27 -07001730 return stats;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001731 }
1732
Jeff Sharkeyaf75c332011-11-18 12:41:12 -08001733 @Override
Erik Kline1742fe12017-12-13 19:40:49 +09001734 public void setDnsConfigurationForNetwork(int netId, String[] servers, String[] domains,
Erik Klinee5dac902018-03-04 21:01:01 +09001735 int[] params, String tlsHostname, String[] tlsServers) {
Pierre Imai8e48e672016-04-21 13:30:43 +09001736 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1737
Ben Schwartz6ec28df2017-10-02 13:08:06 -04001738 final String[] tlsFingerprints = new String[0];
Pierre Imai8e48e672016-04-21 13:30:43 +09001739 try {
Erik Kline1742fe12017-12-13 19:40:49 +09001740 mNetdService.setResolverConfiguration(
Erik Klinee5dac902018-03-04 21:01:01 +09001741 netId, servers, domains, params, tlsHostname, tlsServers, tlsFingerprints);
Pierre Imai8e48e672016-04-21 13:30:43 +09001742 } catch (RemoteException e) {
1743 throw new RuntimeException(e);
1744 }
1745 }
1746
1747 @Override
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04001748 public void addVpnUidRanges(int netId, UidRange[] ranges) {
Chad Brubaker3277620a2013-06-12 13:37:30 -07001749 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Luke Huang8a462ec2018-08-24 20:33:16 +08001750
1751 try {
1752 mNetdService.networkAddUidRanges(netId, ranges);
1753 } catch (RemoteException | ServiceSpecificException e) {
1754 throw new IllegalStateException(e);
Chad Brubaker3277620a2013-06-12 13:37:30 -07001755 }
1756 }
1757
1758 @Override
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04001759 public void removeVpnUidRanges(int netId, UidRange[] ranges) {
Chad Brubaker3277620a2013-06-12 13:37:30 -07001760 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Luke Huang8a462ec2018-08-24 20:33:16 +08001761 try {
1762 mNetdService.networkRemoveUidRanges(netId, ranges);
1763 } catch (RemoteException | ServiceSpecificException e) {
1764 throw new IllegalStateException(e);
Chad Brubakercca54c42013-06-27 17:41:38 -07001765 }
1766 }
1767
1768 @Override
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001769 public void setFirewallEnabled(boolean enabled) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001770 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001771 try {
Luke Huanga241db92018-07-31 20:15:24 +08001772 mNetdService.firewallSetFirewallType(
1773 enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001774 mFirewallEnabled = enabled;
Luke Huanga241db92018-07-31 20:15:24 +08001775 } catch (RemoteException | ServiceSpecificException e) {
1776 throw new IllegalStateException(e);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001777 }
1778 }
1779
1780 @Override
1781 public boolean isFirewallEnabled() {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001782 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001783 return mFirewallEnabled;
1784 }
1785
1786 @Override
Jeff Sharkey2c092982012-08-24 11:44:40 -07001787 public void setFirewallInterfaceRule(String iface, boolean allow) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001788 enforceSystemUid();
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001789 Preconditions.checkState(mFirewallEnabled);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001790 try {
Luke Huanga241db92018-07-31 20:15:24 +08001791 mNetdService.firewallSetInterfaceRule(iface,
1792 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
1793 } catch (RemoteException | ServiceSpecificException e) {
1794 throw new IllegalStateException(e);
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001795 }
1796 }
1797
Lorenzo Colitti3fef7232016-04-29 18:00:03 +09001798 private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001799 // UID ranges to close sockets on.
1800 UidRange[] ranges;
1801 // UID ranges whose sockets we won't touch.
1802 int[] exemptUids;
1803
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001804 int numUids = 0;
Luke Huanga241db92018-07-31 20:15:24 +08001805 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001806 if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
1807 // Close all sockets on all non-system UIDs...
1808 ranges = new UidRange[] {
1809 // TODO: is there a better way of finding all existing users? If so, we could
1810 // specify their ranges here.
1811 new UidRange(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
1812 };
1813 // ... except for the UIDs that have allow rules.
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001814 synchronized (mRulesLock) {
1815 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1816 exemptUids = new int[rules.size()];
1817 for (int i = 0; i < exemptUids.length; i++) {
1818 if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
1819 exemptUids[numUids] = rules.keyAt(i);
1820 numUids++;
1821 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001822 }
1823 }
1824 // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length.
1825 // But the code does not guarantee this in any way, and at least in one case - if we add
1826 // a UID rule to the firewall, and then disable the firewall - the chains can contain
1827 // the wrong type of rule. In this case, don't close connections that we shouldn't.
1828 //
1829 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and
1830 // fix setFirewallEnabled to grab mQuotaLock and clear rules.
1831 if (numUids != exemptUids.length) {
1832 exemptUids = Arrays.copyOf(exemptUids, numUids);
1833 }
1834 } else {
1835 // Close sockets for every UID that has a deny rule...
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001836 synchronized (mRulesLock) {
1837 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1838 ranges = new UidRange[rules.size()];
1839 for (int i = 0; i < ranges.length; i++) {
1840 if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_DENY) {
1841 int uid = rules.keyAt(i);
1842 ranges[numUids] = new UidRange(uid, uid);
1843 numUids++;
1844 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001845 }
1846 }
1847 // As above; usually numUids == ranges.length, but not always.
1848 if (numUids != ranges.length) {
1849 ranges = Arrays.copyOf(ranges, numUids);
1850 }
1851 // ... with no exceptions.
1852 exemptUids = new int[0];
1853 }
1854
1855 try {
1856 mNetdService.socketDestroy(ranges, exemptUids);
1857 } catch(RemoteException | ServiceSpecificException e) {
1858 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e);
1859 }
1860 }
1861
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001862 @Override
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001863 public void setFirewallChainEnabled(int chain, boolean enable) {
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07001864 enforceSystemUid();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001865 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001866 synchronized (mRulesLock) {
1867 if (getFirewallChainState(chain) == enable) {
1868 // All is the same, nothing to do. This relies on the fact that netd has child
1869 // chains default detached.
1870 return;
1871 }
1872 setFirewallChainState(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001873 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001874
Luke Huang615e1022018-10-25 11:54:05 +09001875 final String chainName = getFirewallChainName(chain);
Luke Huanga241db92018-07-31 20:15:24 +08001876 if (chain == FIREWALL_CHAIN_NONE) {
Luke Huang615e1022018-10-25 11:54:05 +09001877 throw new IllegalArgumentException("Bad child chain: " + chainName);
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001878 }
1879
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001880 try {
Luke Huanga241db92018-07-31 20:15:24 +08001881 mNetdService.firewallEnableChildChain(chain, enable);
1882 } catch (RemoteException | ServiceSpecificException e) {
1883 throw new IllegalStateException(e);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001884 }
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001885
1886 // Close any sockets that were opened by the affected UIDs. This has to be done after
1887 // disabling network connectivity, in case they react to the socket close by reopening
1888 // the connection and race with the iptables commands that enable the firewall. All
1889 // whitelist and blacklist chains allow RSTs through.
1890 if (enable) {
Luke Huang615e1022018-10-25 11:54:05 +09001891 closeSocketsForFirewallChainLocked(chain, chainName);
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09001892 }
Amith Yamasani15e472352015-04-24 19:06:07 -07001893 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001894 }
1895
Luke Huanga241db92018-07-31 20:15:24 +08001896 private String getFirewallChainName(int chain) {
1897 switch (chain) {
1898 case FIREWALL_CHAIN_STANDBY:
1899 return FIREWALL_CHAIN_NAME_STANDBY;
1900 case FIREWALL_CHAIN_DOZABLE:
1901 return FIREWALL_CHAIN_NAME_DOZABLE;
1902 case FIREWALL_CHAIN_POWERSAVE:
1903 return FIREWALL_CHAIN_NAME_POWERSAVE;
1904 default:
1905 throw new IllegalArgumentException("Bad child chain: " + chain);
1906 }
1907 }
1908
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001909 private int getFirewallType(int chain) {
1910 switch (chain) {
1911 case FIREWALL_CHAIN_STANDBY:
1912 return FIREWALL_TYPE_BLACKLIST;
1913 case FIREWALL_CHAIN_DOZABLE:
1914 return FIREWALL_TYPE_WHITELIST;
Felipe Leme011b98f2016-02-10 17:28:31 -08001915 case FIREWALL_CHAIN_POWERSAVE:
1916 return FIREWALL_TYPE_WHITELIST;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001917 default:
1918 return isFirewallEnabled() ? FIREWALL_TYPE_WHITELIST : FIREWALL_TYPE_BLACKLIST;
1919 }
1920 }
1921
1922 @Override
1923 public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
1924 enforceSystemUid();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001925 synchronized (mQuotaLock) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001926 synchronized (mRulesLock) {
1927 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1928 SparseIntArray newRules = new SparseIntArray();
1929 // apply new set of rules
1930 for (int index = uids.length - 1; index >= 0; --index) {
1931 int uid = uids[index];
1932 int rule = rules[index];
1933 updateFirewallUidRuleLocked(chain, uid, rule);
1934 newRules.put(uid, rule);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001935 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001936 // collect the rules to remove.
1937 SparseIntArray rulesToRemove = new SparseIntArray();
1938 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
1939 int uid = uidFirewallRules.keyAt(index);
1940 if (newRules.indexOfKey(uid) < 0) {
1941 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
1942 }
1943 }
1944 // remove dead rules
1945 for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
1946 int uid = rulesToRemove.keyAt(index);
1947 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
1948 }
Felipe Lemea701cad2016-05-12 09:58:14 -07001949 }
1950 try {
1951 switch (chain) {
1952 case FIREWALL_CHAIN_DOZABLE:
1953 mNetdService.firewallReplaceUidChain("fw_dozable", true, uids);
1954 break;
1955 case FIREWALL_CHAIN_STANDBY:
1956 mNetdService.firewallReplaceUidChain("fw_standby", false, uids);
1957 break;
1958 case FIREWALL_CHAIN_POWERSAVE:
1959 mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
1960 break;
1961 case FIREWALL_CHAIN_NONE:
1962 default:
1963 Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
1964 }
1965 } catch (RemoteException e) {
1966 Slog.w(TAG, "Error flushing firewall chain " + chain, e);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07001967 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001968 }
1969 }
1970
1971 @Override
1972 public void setFirewallUidRule(int chain, int uid, int rule) {
1973 enforceSystemUid();
Felipe Lemea701cad2016-05-12 09:58:14 -07001974 synchronized (mQuotaLock) {
1975 setFirewallUidRuleLocked(chain, uid, rule);
1976 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07001977 }
1978
Felipe Lemea701cad2016-05-12 09:58:14 -07001979 private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
1980 if (updateFirewallUidRuleLocked(chain, uid, rule)) {
Luke Huanga241db92018-07-31 20:15:24 +08001981 final int ruleType = getFirewallRuleType(chain, rule);
Amith Yamasani15e472352015-04-24 19:06:07 -07001982 try {
Luke Huanga241db92018-07-31 20:15:24 +08001983 mNetdService.firewallSetUidRule(chain, uid, ruleType);
1984 } catch (RemoteException | ServiceSpecificException e) {
1985 throw new IllegalStateException(e);
Amith Yamasani15e472352015-04-24 19:06:07 -07001986 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07001987 }
1988 }
1989
Felipe Lemea701cad2016-05-12 09:58:14 -07001990 // TODO: now that netd supports batching, NMS should not keep these data structures anymore...
1991 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) {
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001992 synchronized (mRulesLock) {
1993 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
Felipe Lemea701cad2016-05-12 09:58:14 -07001994
Sudheer Shanka62f5c172017-03-17 16:25:55 -07001995 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
1996 if (DBG) {
1997 Slog.d(TAG, "oldRule = " + oldUidFirewallRule
1998 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain);
1999 }
2000 if (oldUidFirewallRule == rule) {
2001 if (DBG) Slog.d(TAG, "!!!!! Skipping change");
2002 // TODO: eventually consider throwing
2003 return false;
2004 }
Felipe Lemea701cad2016-05-12 09:58:14 -07002005
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002006 String ruleName = getFirewallRuleName(chain, rule);
2007 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule);
Felipe Lemea701cad2016-05-12 09:58:14 -07002008
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002009 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
2010 uidFirewallRules.delete(uid);
2011 } else {
2012 uidFirewallRules.put(uid, rule);
2013 }
2014 return !ruleName.equals(oldRuleName);
Felipe Lemea701cad2016-05-12 09:58:14 -07002015 }
Felipe Lemea701cad2016-05-12 09:58:14 -07002016 }
2017
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07002018 private @NonNull String getFirewallRuleName(int chain, int rule) {
2019 String ruleName;
2020 if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
2021 if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
2022 ruleName = "allow";
2023 } else {
2024 ruleName = "deny";
2025 }
2026 } else { // Blacklist mode
2027 if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) {
2028 ruleName = "deny";
2029 } else {
2030 ruleName = "allow";
2031 }
2032 }
2033 return ruleName;
2034 }
2035
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002036 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002037 switch (chain) {
2038 case FIREWALL_CHAIN_STANDBY:
2039 return mUidFirewallStandbyRules;
2040 case FIREWALL_CHAIN_DOZABLE:
2041 return mUidFirewallDozableRules;
Felipe Leme011b98f2016-02-10 17:28:31 -08002042 case FIREWALL_CHAIN_POWERSAVE:
2043 return mUidFirewallPowerSaveRules;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002044 case FIREWALL_CHAIN_NONE:
2045 return mUidFirewallRules;
2046 default:
2047 throw new IllegalArgumentException("Unknown chain:" + chain);
2048 }
2049 }
2050
Luke Huanga241db92018-07-31 20:15:24 +08002051 private int getFirewallRuleType(int chain, int rule) {
Luke Huang615e1022018-10-25 11:54:05 +09002052 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
2053 return getFirewallType(chain) == FIREWALL_TYPE_WHITELIST
2054 ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002055 }
Luke Huang615e1022018-10-25 11:54:05 +09002056 return rule;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002057 }
2058
Jeff Sharkeyf56e2432012-09-06 17:54:29 -07002059 private static void enforceSystemUid() {
2060 final int uid = Binder.getCallingUid();
2061 if (uid != Process.SYSTEM_UID) {
2062 throw new SecurityException("Only available to AID_SYSTEM");
2063 }
2064 }
2065
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07002066 @Override
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002067 public void registerNetworkActivityListener(INetworkActivityListener listener) {
2068 mNetworkActivityListeners.register(listener);
2069 }
2070
2071 @Override
2072 public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
2073 mNetworkActivityListeners.unregister(listener);
2074 }
2075
2076 @Override
2077 public boolean isNetworkActive() {
2078 synchronized (mNetworkActivityListeners) {
2079 return mNetworkActive || mActiveIdleTimers.isEmpty();
2080 }
2081 }
2082
2083 private void reportNetworkActive() {
2084 final int length = mNetworkActivityListeners.beginBroadcast();
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07002085 try {
2086 for (int i = 0; i < length; i++) {
2087 try {
2088 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
Felipe Leme03e689d2016-03-02 16:17:38 -08002089 } catch (RemoteException | RuntimeException e) {
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07002090 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002091 }
Robert Greenwalt2c9f5472014-04-21 14:50:28 -07002092 } finally {
2093 mNetworkActivityListeners.finishBroadcast();
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002094 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002095 }
2096
Mattias Falk8b47b362011-08-23 14:15:13 +02002097 /** {@inheritDoc} */
Jeff Sharkey7b4596f2013-02-25 10:55:29 -08002098 @Override
Jeff Sharkeyfa23c5a2011-08-09 21:44:24 -07002099 public void monitor() {
2100 if (mConnector != null) {
2101 mConnector.monitor();
2102 }
2103 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07002104
2105 @Override
2106 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002107 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Sharkey47eb1022011-08-25 17:48:52 -07002108
Robert Greenwalt470fd722012-01-18 12:51:15 -08002109 pw.println("NetworkManagementService NativeDaemonConnector Log:");
2110 mConnector.dump(fd, pw, args);
2111 pw.println();
2112
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07002113 pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
2114 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
2115 pw.print("mNetworkActive="); pw.println(mNetworkActive);
Jeff Sharkey47eb1022011-08-25 17:48:52 -07002116
2117 synchronized (mQuotaLock) {
Jeff Sharkeyb24a7852012-05-01 15:19:37 -07002118 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
2119 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
Felipe Leme65be3022016-03-22 14:53:13 -07002120 pw.print("Data saver mode: "); pw.println(mDataSaverMode);
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002121 synchronized (mRulesLock) {
2122 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
2123 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
2124 }
Jeff Sharkey47eb1022011-08-25 17:48:52 -07002125 }
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07002126
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002127 synchronized (mRulesLock) {
Felipe Leme011b98f2016-02-10 17:28:31 -08002128 dumpUidFirewallRule(pw, "", mUidFirewallRules);
Amith Yamasani15e472352015-04-24 19:06:07 -07002129
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002130 pw.print("UID firewall standby chain enabled: "); pw.println(
2131 getFirewallChainState(FIREWALL_CHAIN_STANDBY));
Felipe Leme011b98f2016-02-10 17:28:31 -08002132 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002133
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002134 pw.print("UID firewall dozable chain enabled: "); pw.println(
2135 getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
Felipe Leme011b98f2016-02-10 17:28:31 -08002136 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
Felipe Leme011b98f2016-02-10 17:28:31 -08002137
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002138 pw.println("UID firewall powersave chain enabled: " +
2139 getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
Felipe Leme011b98f2016-02-10 17:28:31 -08002140 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07002141 }
2142
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002143 synchronized (mIdleTimerLock) {
2144 pw.println("Idle timers:");
2145 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
2146 pw.print(" "); pw.print(ent.getKey()); pw.println(":");
2147 IdleTimerParams params = ent.getValue();
2148 pw.print(" timeout="); pw.print(params.timeout);
2149 pw.print(" type="); pw.print(params.type);
2150 pw.print(" networkCount="); pw.println(params.networkCount);
2151 }
2152 }
2153
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -07002154 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
Felipe Leme65be3022016-03-22 14:53:13 -07002155 pw.print("Netd service status: " );
2156 if (mNetdService == null) {
2157 pw.println("disconnected");
2158 } else {
2159 try {
2160 final boolean alive = mNetdService.isAlive();
2161 pw.println(alive ? "alive": "dead");
2162 } catch (RemoteException e) {
2163 pw.println("unreachable");
2164 }
2165 }
2166 }
2167
2168 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
2169 pw.print("UID bandwith control ");
2170 pw.print(name);
2171 pw.print(" rule: [");
2172 final int size = list.size();
2173 for (int i = 0; i < size; i++) {
2174 pw.print(list.keyAt(i));
2175 if (i < size - 1) pw.print(",");
2176 }
2177 pw.println("]");
Jeff Sharkey47eb1022011-08-25 17:48:52 -07002178 }
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002179
Felipe Leme011b98f2016-02-10 17:28:31 -08002180 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
Lorenzo Colitti4cb42402016-04-24 12:52:00 +09002181 pw.print("UID firewall ");
Felipe Leme011b98f2016-02-10 17:28:31 -08002182 pw.print(name);
2183 pw.print(" rule: [");
2184 final int size = rules.size();
2185 for (int i = 0; i < size; i++) {
2186 pw.print(rules.keyAt(i));
2187 pw.print(":");
2188 pw.print(rules.valueAt(i));
2189 if (i < size - 1) pw.print(",");
2190 }
2191 pw.println("]");
2192 }
2193
Robert Greenwalt568891d2014-04-04 13:38:00 -07002194 @Override
Luke Huang8a462ec2018-08-24 20:33:16 +08002195 public void createPhysicalNetwork(int netId, int permission) {
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002196 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2197
2198 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002199 mNetdService.networkCreatePhysical(netId, permission);
2200 } catch (RemoteException | ServiceSpecificException e) {
2201 throw new IllegalStateException(e);
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002202 }
2203 }
2204
Robert Greenwalt568891d2014-04-04 13:38:00 -07002205 @Override
ckenbed368e2018-12-05 20:32:30 +09002206 public void createVirtualNetwork(int netId, boolean secure) {
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002207 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2208
2209 try {
ckenbed368e2018-12-05 20:32:30 +09002210 mNetdService.networkCreateVpn(netId, secure);
Luke Huang8a462ec2018-08-24 20:33:16 +08002211 } catch (RemoteException | ServiceSpecificException e) {
2212 throw new IllegalStateException(e);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002213 }
2214 }
2215
2216 @Override
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002217 public void removeNetwork(int netId) {
Erik Kline33d8e5c2018-01-15 17:05:07 +09002218 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002219
2220 try {
Erik Kline33d8e5c2018-01-15 17:05:07 +09002221 mNetdService.networkDestroy(netId);
2222 } catch (ServiceSpecificException e) {
2223 Log.w(TAG, "removeNetwork(" + netId + "): ", e);
2224 throw e;
2225 } catch (RemoteException e) {
2226 Log.w(TAG, "removeNetwork(" + netId + "): ", e);
2227 throw e.rethrowAsRuntimeException();
Robert Greenwalt9ba9c582014-03-19 17:56:12 -07002228 }
2229 }
Robert Greenwalt568891d2014-04-04 13:38:00 -07002230
2231 @Override
Paul Jensen992f2522014-04-28 10:33:11 -04002232 public void addInterfaceToNetwork(String iface, int netId) {
Luke Huang8a462ec2018-08-24 20:33:16 +08002233 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
Paul Jensen992f2522014-04-28 10:33:11 -04002234 }
2235
2236 @Override
2237 public void removeInterfaceFromNetwork(String iface, int netId) {
Luke Huang8a462ec2018-08-24 20:33:16 +08002238 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002239 }
Paul Jensen992f2522014-04-28 10:33:11 -04002240
Luke Huang8a462ec2018-08-24 20:33:16 +08002241 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002242 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Paul Jensen992f2522014-04-28 10:33:11 -04002243 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002244 if (add) {
2245 mNetdService.networkAddInterface(netId, iface);
2246 } else {
2247 mNetdService.networkRemoveInterface(netId, iface);
2248 }
2249 } catch (RemoteException | ServiceSpecificException e) {
2250 throw new IllegalStateException(e);
Paul Jensen992f2522014-04-28 10:33:11 -04002251 }
2252 }
2253
2254 @Override
Robert Greenwalt913c8952014-04-07 17:36:35 -07002255 public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
Robert Greenwalt568891d2014-04-04 13:38:00 -07002256 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2257
Sreeram Ramachandrancc91c7b2014-06-03 18:41:43 -07002258 final LinkAddress la = routeInfo.getDestinationLinkAddress();
Luke Huang8a462ec2018-08-24 20:33:16 +08002259 final String ifName = routeInfo.getInterface();
2260 final String dst = la.toString();
2261 final String nextHop;
Robert Greenwalt568891d2014-04-04 13:38:00 -07002262
Luke Huang8a462ec2018-08-24 20:33:16 +08002263 if (routeInfo.hasGateway()) {
2264 nextHop = routeInfo.getGateway().getHostAddress();
2265 } else {
2266 nextHop = "";
2267 }
Robert Greenwalt568891d2014-04-04 13:38:00 -07002268 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002269 mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
2270 } catch (RemoteException | ServiceSpecificException e) {
2271 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002272 }
2273 }
2274
2275 @Override
Sreeram Ramachandranf047f2a2014-04-15 16:04:26 -07002276 public void setDefaultNetId(int netId) {
Robert Greenwalt568891d2014-04-04 13:38:00 -07002277 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2278
2279 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002280 mNetdService.networkSetDefault(netId);
2281 } catch (RemoteException | ServiceSpecificException e) {
2282 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002283 }
2284 }
2285
2286 @Override
2287 public void clearDefaultNetId() {
2288 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2289
2290 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002291 mNetdService.networkClearDefault();
2292 } catch (RemoteException | ServiceSpecificException e) {
2293 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002294 }
2295 }
2296
2297 @Override
Luke Huang8a462ec2018-08-24 20:33:16 +08002298 public void setNetworkPermission(int netId, int permission) {
Paul Jensen487ffe72015-07-24 15:57:11 -04002299 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2300
2301 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002302 mNetdService.networkSetPermissionForNetwork(netId, permission);
2303 } catch (RemoteException | ServiceSpecificException e) {
2304 throw new IllegalStateException(e);
Paul Jensen487ffe72015-07-24 15:57:11 -04002305 }
2306 }
2307
Luke Huang8a462ec2018-08-24 20:33:16 +08002308 private int parsePermission(String permission) {
2309 if (permission.equals("NETWORK")) {
2310 return INetd.PERMISSION_NETWORK;
2311 }
2312 if (permission.equals("SYSTEM")) {
2313 return INetd.PERMISSION_SYSTEM;
2314 }
2315 return INetd.PERMISSION_NONE;
2316 }
Paul Jensen487ffe72015-07-24 15:57:11 -04002317
2318 @Override
Sreeram Ramachandrane4a05af2014-09-24 09:16:19 -07002319 public void setPermission(String permission, int[] uids) {
Robert Greenwalt568891d2014-04-04 13:38:00 -07002320 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2321
Luke Huang8a462ec2018-08-24 20:33:16 +08002322 try {
2323 mNetdService.networkSetPermissionForUser(parsePermission(permission), uids);
2324 } catch (RemoteException | ServiceSpecificException e) {
2325 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002326 }
2327 }
2328
2329 @Override
2330 public void clearPermission(int[] uids) {
2331 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2332
Luke Huang8a462ec2018-08-24 20:33:16 +08002333 try {
2334 mNetdService.networkClearPermissionForUser(uids);
2335 } catch (RemoteException | ServiceSpecificException e) {
2336 throw new IllegalStateException(e);
Robert Greenwalt568891d2014-04-04 13:38:00 -07002337 }
2338 }
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002339
2340 @Override
2341 public void allowProtect(int uid) {
2342 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2343
2344 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002345 mNetdService.networkSetProtectAllow(uid);
2346 } catch (RemoteException | ServiceSpecificException e) {
2347 throw new IllegalStateException(e);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002348 }
2349 }
2350
2351 @Override
2352 public void denyProtect(int uid) {
2353 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2354
2355 try {
Luke Huang8a462ec2018-08-24 20:33:16 +08002356 mNetdService.networkSetProtectDeny(uid);
2357 } catch (RemoteException | ServiceSpecificException e) {
2358 throw new IllegalStateException(e);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04002359 }
2360 }
2361
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002362 @Override
2363 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
Luke Huang706d7ab2018-10-16 15:42:15 +08002364 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002365
2366 for (RouteInfo route : routes) {
2367 if (!route.isDefaultRoute()) {
Luke Huang706d7ab2018-10-16 15:42:15 +08002368 modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, route);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002369 }
2370 }
2371 }
2372
2373 @Override
2374 public void removeInterfaceFromLocalNetwork(String iface) {
Luke Huang706d7ab2018-10-16 15:42:15 +08002375 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface);
Sreeram Ramachandrana77760d2014-07-17 17:09:07 -07002376 }
Erik Kline6599ee82016-07-17 21:28:39 +09002377
2378 @Override
2379 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) {
2380 int failures = 0;
2381
2382 for (RouteInfo route : routes) {
2383 try {
Luke Huang706d7ab2018-10-16 15:42:15 +08002384 modifyRoute(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, route);
Erik Kline6599ee82016-07-17 21:28:39 +09002385 } catch (IllegalStateException e) {
2386 failures++;
2387 }
2388 }
2389
2390 return failures;
2391 }
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002392
Sudheer Shankab8f23162017-08-04 13:30:10 -07002393 @Override
2394 public boolean isNetworkRestricted(int uid) {
2395 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2396 return isNetworkRestrictedInternal(uid);
2397 }
2398
2399 private boolean isNetworkRestrictedInternal(int uid) {
2400 synchronized (mRulesLock) {
2401 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
2402 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
2403 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
2404 return true;
2405 }
2406 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
2407 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
2408 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
2409 return true;
2410 }
2411 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
2412 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
2413 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
2414 return true;
2415 }
2416 if (mUidRejectOnMetered.get(uid)) {
2417 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
2418 + " in the background");
2419 return true;
2420 }
2421 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
2422 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
2423 return true;
2424 }
2425 return false;
2426 }
2427 }
2428
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002429 private void setFirewallChainState(int chain, boolean state) {
2430 synchronized (mRulesLock) {
2431 mFirewallChainStates.put(chain, state);
2432 }
2433 }
2434
2435 private boolean getFirewallChainState(int chain) {
2436 synchronized (mRulesLock) {
2437 return mFirewallChainStates.get(chain);
2438 }
2439 }
2440
2441 @VisibleForTesting
2442 class LocalService extends NetworkManagementInternal {
2443 @Override
2444 public boolean isNetworkRestrictedForUid(int uid) {
Sudheer Shankab8f23162017-08-04 13:30:10 -07002445 return isNetworkRestrictedInternal(uid);
Sudheer Shanka62f5c172017-03-17 16:25:55 -07002446 }
2447 }
2448
2449 @VisibleForTesting
2450 Injector getInjector() {
2451 return new Injector();
2452 }
2453
2454 @VisibleForTesting
2455 class Injector {
2456 void setDataSaverMode(boolean dataSaverMode) {
2457 mDataSaverMode = dataSaverMode;
2458 }
2459
2460 void setFirewallChainState(int chain, boolean state) {
2461 NetworkManagementService.this.setFirewallChainState(chain, state);
2462 }
2463
2464 void setFirewallRule(int chain, int uid, int rule) {
2465 synchronized (mRulesLock) {
2466 getUidFirewallRulesLR(chain).put(uid, rule);
2467 }
2468 }
2469
2470 void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) {
2471 synchronized (mRulesLock) {
2472 if (blacklist) {
2473 mUidRejectOnMetered.put(uid, enable);
2474 } else {
2475 mUidAllowOnMetered.put(uid, enable);
2476 }
2477 }
2478 }
2479
2480 void reset() {
2481 synchronized (mRulesLock) {
2482 setDataSaverMode(false);
2483 final int[] chains = {
2484 FIREWALL_CHAIN_DOZABLE,
2485 FIREWALL_CHAIN_STANDBY,
2486 FIREWALL_CHAIN_POWERSAVE
2487 };
2488 for (int chain : chains) {
2489 setFirewallChainState(chain, false);
2490 getUidFirewallRulesLR(chain).clear();
2491 }
2492 mUidAllowOnMetered.clear();
2493 mUidRejectOnMetered.clear();
2494 }
2495 }
2496 }
San Mehat873f2142010-01-14 10:25:07 -08002497}