blob: 36ba610085e19ada4b880aa30ecbf427d9c0c9c5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 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
Haoyu Baidb3c8672012-06-20 14:29:57 -070019import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
Chalard Jeanb552c462018-02-21 18:43:54 +090020import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +000021import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
22import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
23import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
24import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
25import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
26import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
27import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
28import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
Jeff Sharkey961e3042011-08-29 16:02:57 -070029import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Paul Jensen31a94f42015-02-13 14:18:39 -050030import static android.net.ConnectivityManager.NETID_UNSET;
Xiao Maed25f9c2019-06-12 16:31:14 +090031import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
Lorenzo Colitti7bbe3ee2017-08-24 22:35:10 +090032import static android.net.ConnectivityManager.TYPE_ETHERNET;
Robert Greenwalt12e67352014-05-13 21:41:06 -070033import static android.net.ConnectivityManager.TYPE_NONE;
Sreeram Ramachandran60c0c0d2014-10-30 14:55:29 -070034import static android.net.ConnectivityManager.TYPE_VPN;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -070035import static android.net.ConnectivityManager.getNetworkTypeName;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -070036import static android.net.ConnectivityManager.isNetworkTypeValid;
lucaslin783f2212019-10-22 18:27:33 +080037import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
Chiachang Wang8ea15c962019-05-23 16:29:30 +080038import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
39import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
Paul Jensen3d194ea2015-06-16 14:27:36 -040040import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +090041import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
Lorenzo Colitti8deb3412015-05-14 17:07:20 +090042import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
43import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
44import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
Jeff Sharkey72f9c422017-10-27 17:22:59 -060045import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
Chalard Jean804b8fb2018-01-30 22:41:41 +090046import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
Chalard Jeandda156a2018-01-10 21:19:32 +090047import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
lucasline252a742019-03-12 13:08:03 +080048import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
Lorenzo Colitti8deb3412015-05-14 17:07:20 +090049import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
Chalard Jean52638ac42020-01-14 22:46:36 +090050import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Chalard Jean09c48e42020-03-25 10:33:55 +000051import static android.net.NetworkCapabilities.TRANSPORT_TEST;
Jeff Sharkey72f9c422017-10-27 17:22:59 -060052import static android.net.NetworkCapabilities.TRANSPORT_VPN;
junyulai05986c62018-08-07 19:50:45 +080053import static android.net.NetworkPolicyManager.RULE_NONE;
54import static android.net.NetworkPolicyManager.uidRulesToString;
Lorenzo Colitti80986d92019-03-22 00:28:28 +090055import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -070056import static android.os.Process.INVALID_UID;
57import static android.system.OsConstants.IPPROTO_TCP;
58import static android.system.OsConstants.IPPROTO_UDP;
Jeff Sharkey72f9c422017-10-27 17:22:59 -060059
Cody Kestinga75e26b2020-01-05 14:06:39 -080060import static java.util.Map.Entry;
61
Chalard Jean09c48e42020-03-25 10:33:55 +000062import android.Manifest;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000063import android.annotation.NonNull;
Wenchao Tongf5ea3402015-03-04 13:26:38 -080064import android.annotation.Nullable;
Cody Kestinga75e26b2020-01-05 14:06:39 -080065import android.app.AppOpsManager;
Dianne Hackborne0e413e2015-12-09 17:22:26 -080066import android.app.BroadcastOptions;
Lorenzo Colitti0b599062016-08-22 22:36:19 +090067import android.app.NotificationManager;
Wink Savilleab9321d2013-06-29 21:10:57 -070068import android.app.PendingIntent;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070069import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.content.ContentResolver;
71import android.content.Context;
72import android.content.Intent;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070073import android.content.IntentFilter;
Mark Chien44592d12020-03-27 16:53:45 +000074import android.content.pm.PackageManager;
Robert Greenwalte182bfe2013-07-16 12:06:09 -070075import android.content.res.Configuration;
Robert Greenwalt434203a2010-10-11 16:00:27 -070076import android.database.ContentObserver;
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +090077import android.net.CaptivePortal;
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +090078import android.net.CaptivePortalData;
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -070079import android.net.ConnectionInfo;
Cody Kestinga75e26b2020-01-05 14:06:39 -080080import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
Cody Kesting4f49f142020-01-06 16:55:35 -080081import android.net.ConnectivityDiagnosticsManager.DataStallReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.net.ConnectivityManager;
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +000083import android.net.DataStallReportParcelable;
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +090084import android.net.ICaptivePortal;
Cody Kesting5aadb8b2019-12-17 12:55:28 -080085import android.net.IConnectivityDiagnosticsCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.net.IConnectivityManager;
Luke Huang65914772019-03-16 00:31:46 +080087import android.net.IDnsResolver;
dalyk7301aa42018-03-05 12:42:22 -050088import android.net.IIpConnectivityMetrics;
Luke Huang674660f2018-09-27 19:33:11 +080089import android.net.INetd;
dalyk7301aa42018-03-05 12:42:22 -050090import android.net.INetdEventCallback;
Haoyu Baidb3c8672012-06-20 14:29:57 -070091import android.net.INetworkManagementEventObserver;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +090092import android.net.INetworkMonitor;
93import android.net.INetworkMonitorCallbacks;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -070094import android.net.INetworkPolicyListener;
95import android.net.INetworkPolicyManager;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070096import android.net.INetworkStatsService;
junyulai7c469172019-01-16 20:23:34 +080097import android.net.ISocketKeepaliveCallback;
Lorenzo Colitti6998fa82019-01-08 10:04:25 +090098import android.net.InetAddresses;
Xiao Mad91ec092019-04-10 19:01:52 +090099import android.net.IpMemoryStore;
Lorenzo Colitti6998fa82019-01-08 10:04:25 +0900100import android.net.IpPrefix;
Jaikumar Ganesh15c74392010-12-21 22:31:44 -0800101import android.net.LinkProperties;
Charles He36738632017-05-15 17:07:18 +0100102import android.net.MatchAllNetworkSpecifier;
junyulai215b8772019-01-15 11:32:44 +0800103import android.net.NattSocketKeepalive;
Robert Greenwalt9ba9c582014-03-19 17:56:12 -0700104import android.net.Network;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700105import android.net.NetworkAgent;
Lorenzo Colittid9696562020-01-12 22:28:37 +0900106import android.net.NetworkAgentConfig;
Robert Greenwalte049c232014-04-11 15:53:27 -0700107import android.net.NetworkCapabilities;
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700108import android.net.NetworkConfig;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.net.NetworkInfo;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700110import android.net.NetworkInfo.DetailedState;
Lorenzo Colittiac955b32019-05-31 15:41:29 +0900111import android.net.NetworkMonitorManager;
Jeff Sharkey75d31892018-01-18 22:01:59 +0900112import android.net.NetworkPolicyManager;
Lorenzo Colittiae5cb712020-01-08 00:04:09 +0900113import android.net.NetworkProvider;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700114import android.net.NetworkQuotaInfo;
Robert Greenwalte049c232014-04-11 15:53:27 -0700115import android.net.NetworkRequest;
Etan Cohen859748f2017-04-03 17:42:34 -0700116import android.net.NetworkSpecifier;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900117import android.net.NetworkStack;
Remi NGUYEN VAN5db454c2019-02-14 18:04:20 +0900118import android.net.NetworkStackClient;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700119import android.net.NetworkState;
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +0000120import android.net.NetworkTestResultParcelable;
Robert Greenwalt585ac0f2010-08-27 09:24:29 -0700121import android.net.NetworkUtils;
Ricky Wai44dcbde2018-01-23 04:09:45 +0000122import android.net.NetworkWatchlistManager;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900123import android.net.PrivateDnsConfigParcel;
Jason Monk207900c2014-04-25 15:00:09 -0400124import android.net.ProxyInfo;
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700125import android.net.RouteInfo;
Lorenzo Colittid86407b2020-03-18 07:52:25 +0000126import android.net.RouteInfoParcel;
junyulai06835112019-01-03 18:50:15 +0800127import android.net.SocketKeepalive;
markchien0df2ebc42019-09-30 14:40:57 +0800128import android.net.TetheringManager;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400129import android.net.UidRange;
Jason Monk602b2322013-07-03 17:04:33 -0400130import android.net.Uri;
Benedict Wong418017e2019-11-06 00:20:15 -0800131import android.net.VpnManager;
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600132import android.net.VpnService;
Hugo Benichicfddd682016-05-31 16:28:06 +0900133import android.net.metrics.IpConnectivityLog;
Hugo Benichicc92c6e2016-04-21 15:02:38 +0900134import android.net.metrics.NetworkEvent;
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -0700135import android.net.netlink.InetDiagMessage;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900136import android.net.shared.PrivateDnsConfig;
Lorenzo Colittid86407b2020-03-18 07:52:25 +0000137import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
Aaron Huang94df39a2019-12-17 00:33:18 +0800138import android.net.util.LinkPropertiesUtils.CompareResult;
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +0900139import android.net.util.MultinetworkPolicyTracker;
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +0900140import android.net.util.NetdService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141import android.os.Binder;
Dianne Hackborne0e413e2015-12-09 17:22:26 -0800142import android.os.Build;
Robert Greenwalta848c1c2014-09-30 16:50:07 -0700143import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144import android.os.Handler;
Wink Savillebb08caf2010-09-02 19:23:52 -0700145import android.os.HandlerThread;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700146import android.os.IBinder;
Chia-chi Yehc9338302011-05-11 16:35:13 -0700147import android.os.INetworkManagementService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148import android.os.Looper;
149import android.os.Message;
Robert Greenwalt665e1ae2012-08-21 19:27:00 -0700150import android.os.Messenger;
Chia-chi Yehff3bdca2011-05-23 17:26:46 -0700151import android.os.ParcelFileDescriptor;
Hugo Benichidba33db2017-03-23 22:40:44 +0900152import android.os.Parcelable;
Cody Kestinga75e26b2020-01-05 14:06:39 -0800153import android.os.PersistableBundle;
Robert Greenwalt14f2ef42010-06-15 12:19:37 -0700154import android.os.PowerManager;
Jeff Sharkeyf56e2432012-09-06 17:54:29 -0700155import android.os.Process;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700156import android.os.RemoteException;
Jeremy Klein36c7aa02016-01-22 14:11:45 -0800157import android.os.ResultReceiver;
Lorenzo Colitti7bbe3ee2017-08-24 22:35:10 +0900158import android.os.ServiceManager;
Hugo Benichicb883232017-05-11 13:16:17 +0900159import android.os.ServiceSpecificException;
mswest46386886f2018-03-12 10:34:34 -0700160import android.os.ShellCallback;
161import android.os.ShellCommand;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900162import android.os.SystemClock;
Anil Admal4661b742019-04-05 10:06:37 -0700163import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700164import android.os.UserHandle;
Julia Reynoldsfc6b2a02014-06-24 10:56:55 -0400165import android.os.UserManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166import android.provider.Settings;
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700167import android.security.Credentials;
Jeff Sharkey82f85212012-08-24 11:17:25 -0700168import android.security.KeyStore;
Wink Savilleab9321d2013-06-29 21:10:57 -0700169import android.telephony.TelephonyManager;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700170import android.text.TextUtils;
Chalard Jeanf213ca12018-01-16 18:43:05 +0900171import android.util.ArraySet;
Robert Greenwalt22b4c6a2015-06-23 15:03:33 -0700172import android.util.LocalLog;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600173import android.util.Log;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900174import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800175import android.util.Slog;
Chad Brubaker4ca19e82013-06-14 11:16:51 -0700176import android.util.SparseArray;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700177import android.util.SparseIntArray;
Robert Greenwalte182bfe2013-07-16 12:06:09 -0700178import android.util.Xml;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179
Wink Savilleab9321d2013-06-29 21:10:57 -0700180import com.android.internal.R;
Jason Monk602b2322013-07-03 17:04:33 -0400181import com.android.internal.annotations.GuardedBy;
Paul Jensen67b0b072015-06-10 11:22:17 -0400182import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700183import com.android.internal.app.IBatteryStats;
Remi NGUYEN VANde602212019-01-30 15:22:01 +0900184import com.android.internal.logging.MetricsLogger;
Chia-chi Yeh2e467642011-07-04 03:23:12 -0700185import com.android.internal.net.LegacyVpnInfo;
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -0700186import com.android.internal.net.VpnConfig;
Wenchao Tongf5ea3402015-03-04 13:26:38 -0800187import com.android.internal.net.VpnInfo;
Jeff Sharkey82f85212012-08-24 11:17:25 -0700188import com.android.internal.net.VpnProfile;
Erik Kline3f8306b2018-05-01 16:51:44 +0900189import com.android.internal.util.ArrayUtils;
Robert Greenwalte049c232014-04-11 15:53:27 -0700190import com.android.internal.util.AsyncChannel;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600191import com.android.internal.util.DumpUtils;
Jeff Sharkeye6e61972012-09-14 13:47:51 -0700192import com.android.internal.util.IndentingPrintWriter;
Cody Kestinga75e26b2020-01-05 14:06:39 -0800193import com.android.internal.util.LocationPermissionChecker;
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +0900194import com.android.internal.util.MessageUtils;
Robert Greenwalte182bfe2013-07-16 12:06:09 -0700195import com.android.internal.util.XmlUtils;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700196import com.android.server.am.BatteryStatsService;
Chalard Jeand5603302019-05-30 14:58:29 +0900197import com.android.server.connectivity.AutodestructReference;
John Spurlockbf991a82013-06-24 14:20:23 -0400198import com.android.server.connectivity.DataConnectionStats;
Erik Kline1742fe12017-12-13 19:40:49 +0900199import com.android.server.connectivity.DnsManager;
dalyk7301aa42018-03-05 12:42:22 -0500200import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
Hugo Benichi64901e52017-10-19 14:42:40 +0900201import com.android.server.connectivity.IpConnectivityMetrics;
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900202import com.android.server.connectivity.KeepaliveTracker;
Charles He36738632017-05-15 17:07:18 +0100203import com.android.server.connectivity.LingerMonitor;
Christopher Wiley497c1472016-10-11 13:26:03 -0700204import com.android.server.connectivity.MockableSystemProperties;
Lorenzo Colittid260ef22018-01-24 17:35:07 +0900205import com.android.server.connectivity.MultipathPolicyTracker;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700206import com.android.server.connectivity.NetworkAgentInfo;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600207import com.android.server.connectivity.NetworkDiagnostics;
Lorenzo Colittif3ae2ee2016-08-22 16:30:00 +0900208import com.android.server.connectivity.NetworkNotificationManager;
209import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
Chalard Jean7a5e51f2019-12-10 22:16:53 +0900210import com.android.server.connectivity.NetworkRanker;
Sreeram Ramachandrane4a05af2014-09-24 09:16:19 -0700211import com.android.server.connectivity.PermissionMonitor;
Chalard Jean52c2aa72018-06-07 16:44:04 +0900212import com.android.server.connectivity.ProxyTracker;
Chia-chi Yehff3bdca2011-05-23 17:26:46 -0700213import com.android.server.connectivity.Vpn;
dalyk7301aa42018-03-05 12:42:22 -0500214import com.android.server.net.BaseNetdEventCallback;
Jeff Sharkey216c1812012-08-05 14:29:23 -0700215import com.android.server.net.BaseNetworkObserver;
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700216import com.android.server.net.LockdownVpnTracker;
Hugo Benichi938ab4f2017-02-11 17:04:43 +0900217import com.android.server.net.NetworkPolicyManagerInternal;
Vishnu Nair5c010902017-10-26 10:08:50 -0700218import com.android.server.utils.PriorityDump;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600219
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700220import com.google.android.collect.Lists;
Jeff Sharkeyfb878b62012-07-26 18:32:30 -0700221
Robert Greenwalte182bfe2013-07-16 12:06:09 -0700222import org.xmlpull.v1.XmlPullParser;
223import org.xmlpull.v1.XmlPullParserException;
224
225import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226import java.io.FileDescriptor;
Robert Greenwalte182bfe2013-07-16 12:06:09 -0700227import java.io.FileNotFoundException;
228import java.io.FileReader;
Irfan Sheriffd649c122010-06-09 15:39:36 -0700229import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230import java.io.PrintWriter;
Wink Savillec9822c52011-07-14 12:23:28 -0700231import java.net.Inet4Address;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700232import java.net.InetAddress;
233import java.net.UnknownHostException;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700234import java.util.ArrayList;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700235import java.util.Arrays;
Robert Greenwalt47f69fe2010-06-15 15:43:39 -0700236import java.util.Collection;
Cody Kesting201fc132020-01-17 11:58:36 -0800237import java.util.Collections;
Hugo Benichia2a917c2018-09-03 08:19:02 +0900238import java.util.Comparator;
junyulai05986c62018-08-07 19:50:45 +0800239import java.util.ConcurrentModificationException;
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700240import java.util.HashMap;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700241import java.util.HashSet;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700242import java.util.List;
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -0700243import java.util.Map;
Robert Greenwalta848c1c2014-09-30 16:50:07 -0700244import java.util.Objects;
Chalard Jeanf213ca12018-01-16 18:43:05 +0900245import java.util.Set;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600246import java.util.SortedSet;
Chalard Jeanbf1170c2019-12-10 21:07:02 +0900247import java.util.StringJoiner;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600248import java.util.TreeSet;
Lorenzo Colittiae5cb712020-01-08 00:04:09 +0900249import java.util.concurrent.atomic.AtomicInteger;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251/**
252 * @hide
253 */
Jeremy Joslin46e3ac82014-11-05 10:32:09 -0800254public class ConnectivityService extends IConnectivityManager.Stub
255 implements PendingIntent.OnFinished {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900256 private static final String TAG = ConnectivityService.class.getSimpleName();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257
Chalard Jean4133a122018-06-04 13:33:12 +0900258 private static final String DIAG_ARG = "--diag";
Erik Kline7747fd42017-05-12 16:52:48 +0900259 public static final String SHORT_ARG = "--short";
Hugo Benichi14683812018-09-03 08:32:56 +0900260 private static final String NETWORK_ARG = "networks";
261 private static final String REQUEST_ARG = "requests";
Erik Kline7747fd42017-05-12 16:52:48 +0900262
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +0900263 private static final boolean DBG = true;
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +0900264 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
265 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +0900267 private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700268
Niklas Lindgrenafc5f9b2018-12-07 11:08:04 +0100269 /**
270 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
271 * by OEMs for configuration purposes, as this value is overridden by
272 * Settings.Global.CAPTIVE_PORTAL_HTTP_URL.
273 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
274 * (preferably via runtime resource overlays).
275 */
276 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
277 "http://connectivitycheck.gstatic.com/generate_204";
278
Jeff Sharkey899223b2012-08-04 15:24:58 -0700279 // TODO: create better separation between radio types and network types
280
Robert Greenwalt42acef32009-08-12 16:08:25 -0700281 // how long to wait before switching back to a radio's default network
282 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
283 // system property that can override the above value
284 private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
285 "android.telephony.apn-restore";
286
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900287 // How long to wait before putting up a "This network doesn't have an Internet connection,
288 // connect anyway?" dialog after the user selects a network that doesn't validate.
289 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
290
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900291 // Default to 30s linger time-out. Modifiable only for testing.
292 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
293 private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
294 @VisibleForTesting
295 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it.
296
Jeremy Joslin79294842014-12-03 17:15:28 -0800297 // How long to delay to removal of a pending intent based request.
298 // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
299 private final int mReleasePendingIntentDelayMs;
300
Lorenzo Colitti42cdf572017-03-21 18:54:11 +0900301 private MockableSystemProperties mSystemProperties;
302
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000303 @VisibleForTesting
304 protected final PermissionMonitor mPermissionMonitor;
Sreeram Ramachandrane4a05af2014-09-24 09:16:19 -0700305
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700306 private KeyStore mKeyStore;
Jeff Sharkey82f85212012-08-24 11:17:25 -0700307
Chalard Jeanfb0c87e2018-04-18 19:18:58 +0900308 @VisibleForTesting
Chad Brubaker4ca19e82013-06-14 11:16:51 -0700309 @GuardedBy("mVpns")
Chalard Jean4133a122018-06-04 13:33:12 +0900310 protected final SparseArray<Vpn> mVpns = new SparseArray<>();
Chia-chi Yehff3bdca2011-05-23 17:26:46 -0700311
Hugo Benichi69744342017-11-27 10:57:16 +0900312 // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by
313 // a direct call to LockdownVpnTracker.isEnabled().
314 @GuardedBy("mVpns")
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700315 private boolean mLockdownEnabled;
Hugo Benichi69744342017-11-27 10:57:16 +0900316 @GuardedBy("mVpns")
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700317 private LockdownVpnTracker mLockdownTracker;
318
junyulai05986c62018-08-07 19:50:45 +0800319 /**
320 * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
321 * handler thread, they don't need a lock.
322 */
323 private SparseIntArray mUidRules = new SparseIntArray();
324 /** Flag indicating if background data is restricted. */
325 private boolean mRestrictBackground;
326
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900327 private final Context mContext;
328 private final Dependencies mDeps;
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700329 // 0 is full bad, 100 is full good
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700330 private int mDefaultInetConditionPublished = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331
Luke Huang4e25ec62018-09-27 16:58:23 +0800332 private INetworkManagementService mNMS;
Chenbo Feng7f14dbc2018-11-08 17:36:21 -0800333 @VisibleForTesting
Luke Huang65914772019-03-16 00:31:46 +0800334 protected IDnsResolver mDnsResolver;
335 @VisibleForTesting
Chenbo Feng7f14dbc2018-11-08 17:36:21 -0800336 protected INetd mNetd;
Jeff Sharkey69736342014-12-08 14:50:12 -0800337 private INetworkStatsService mStatsService;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700338 private INetworkPolicyManager mPolicyManager;
Hugo Benichi938ab4f2017-02-11 17:04:43 +0900339 private NetworkPolicyManagerInternal mPolicyManagerInternal;
Robert Greenwalt59b1a4e2011-05-10 15:05:02 -0700340
Benedict Wonga341fbc2018-11-09 14:45:34 -0800341 /**
342 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
343 * instances.
344 */
345 @GuardedBy("mTNSLock")
346 private TestNetworkService mTNS;
347
348 private final Object mTNSLock = new Object();
349
Robert Greenwalt3f05bf42014-08-06 12:00:25 -0700350 private String mCurrentTcpBufferSizes;
351
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +0900352 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
Lorenzo Colittib57578ca2016-07-01 01:53:25 +0900353 new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
354 NetworkAgentInfo.class });
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +0900355
Paul Jensenb10e37f2014-11-25 12:33:08 -0500356 private enum ReapUnvalidatedNetworks {
Paul Jensen85cf78e2015-06-25 13:25:07 -0400357 // Tear down networks that have no chance (e.g. even if validated) of becoming
358 // the highest scoring network satisfying a NetworkRequest. This should be passed when
Paul Jensenb10e37f2014-11-25 12:33:08 -0500359 // all networks have been rematched against all NetworkRequests.
360 REAP,
Paul Jensen85cf78e2015-06-25 13:25:07 -0400361 // Don't reap networks. This should be passed when some networks have not yet been
362 // rematched against all NetworkRequests.
Paul Jensenb10e37f2014-11-25 12:33:08 -0500363 DONT_REAP
Chalard Jean4133a122018-06-04 13:33:12 +0900364 }
Paul Jensenb10e37f2014-11-25 12:33:08 -0500365
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +0900366 private enum UnneededFor {
367 LINGER, // Determine whether this network is unneeded and should be lingered.
368 TEARDOWN, // Determine whether this network is unneeded and should be torn down.
369 }
370
Robert Greenwalt8dcc28b2010-09-23 10:05:56 -0700371 /**
Robert Greenwaltf3331232010-09-24 14:32:21 -0700372 * used internally to clear a wakelock when transitioning
Robert Greenwalt27711812014-06-25 16:45:57 -0700373 * from one net to another. Clear happens when we get a new
374 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
375 * after a timeout if no network is found (typically 1 min).
Robert Greenwaltf3331232010-09-24 14:32:21 -0700376 */
Jeff Sharkey4c628eb2012-07-23 13:19:46 -0700377 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
Robert Greenwaltf3331232010-09-24 14:32:21 -0700378
Robert Greenwalt434203a2010-10-11 16:00:27 -0700379 /**
380 * used internally to reload global proxy settings
381 */
Jeff Sharkey4c628eb2012-07-23 13:19:46 -0700382 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700383
Robert Greenwaltd55a6b42011-03-25 13:09:25 -0700384 /**
Jason Monkdecd2952013-10-10 14:02:51 -0400385 * PAC manager has received new port.
386 */
387 private static final int EVENT_PROXY_HAS_CHANGED = 16;
388
Robert Greenwalte049c232014-04-11 15:53:27 -0700389 /**
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900390 * used internally when registering NetworkProviders
391 * obj = NetworkProviderInfo
Robert Greenwalte049c232014-04-11 15:53:27 -0700392 */
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900393 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17;
Robert Greenwalte049c232014-04-11 15:53:27 -0700394
Robert Greenwalt7b816022014-04-18 15:25:25 -0700395 /**
396 * used internally when registering NetworkAgents
397 * obj = Messenger
398 */
399 private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
400
Robert Greenwalt9258c642014-03-26 16:47:06 -0700401 /**
402 * used to add a network request
403 * includes a NetworkRequestInfo
404 */
405 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
406
407 /**
408 * indicates a timeout period is over - check if we had a network yet or not
Erik Klineacdd6392016-07-07 16:50:58 +0900409 * and if not, call the timeout callback (but leave the request live until they
Robert Greenwalt9258c642014-03-26 16:47:06 -0700410 * cancel it.
411 * includes a NetworkRequestInfo
412 */
413 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
414
415 /**
416 * used to add a network listener - no request
417 * includes a NetworkRequestInfo
418 */
419 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
420
421 /**
422 * used to remove a network request, either a listener or a real request
Paul Jensen7ecb42f2014-05-16 14:31:12 -0400423 * arg1 = UID of caller
424 * obj = NetworkRequest
Robert Greenwalt9258c642014-03-26 16:47:06 -0700425 */
426 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
427
Robert Greenwalta67be032014-05-16 15:49:14 -0700428 /**
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900429 * used internally when registering NetworkProviders
Robert Greenwalta67be032014-05-16 15:49:14 -0700430 * obj = Messenger
431 */
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900432 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23;
Robert Greenwalta67be032014-05-16 15:49:14 -0700433
Robert Greenwalt27711812014-06-25 16:45:57 -0700434 /**
435 * used internally to expire a wakelock when transitioning
436 * from one net to another. Expire happens when we fail to find
437 * a new network (typically after 1 minute) -
438 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
439 * a replacement network.
440 */
441 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
442
Robert Greenwaltfb68f8f2014-08-13 13:43:32 -0700443 /**
444 * Used internally to indicate the system is ready.
445 */
446 private static final int EVENT_SYSTEM_READY = 25;
447
Jeremy Joslin46e3ac82014-11-05 10:32:09 -0800448 /**
449 * used to add a network request with a pending intent
Paul Jensen694f2b82015-06-17 14:15:39 -0400450 * obj = NetworkRequestInfo
Jeremy Joslin46e3ac82014-11-05 10:32:09 -0800451 */
452 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
453
454 /**
455 * used to remove a pending intent and its associated network request.
456 * arg1 = UID of caller
457 * obj = PendingIntent
458 */
459 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
460
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900461 /**
462 * used to specify whether a network should be used even if unvalidated.
463 * arg1 = whether to accept the network if it's unvalidated (1 or 0)
464 * arg2 = whether to remember this choice in the future (1 or 0)
465 * obj = network
466 */
467 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
468
469 /**
470 * used to ask the user to confirm a connection to an unvalidated network.
471 * obj = network
472 */
473 private static final int EVENT_PROMPT_UNVALIDATED = 29;
Robert Greenwalta67be032014-05-16 15:49:14 -0700474
Erik Klineda4bfa82015-04-30 12:58:40 +0900475 /**
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -0700476 * used internally to (re)configure always-on networks.
Erik Klineda4bfa82015-04-30 12:58:40 +0900477 */
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -0700478 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
Erik Klineda4bfa82015-04-30 12:58:40 +0900479
Paul Jensen694f2b82015-06-17 14:15:39 -0400480 /**
481 * used to add a network listener with a pending intent
482 * obj = NetworkRequestInfo
483 */
484 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
485
Hugo Benichi1c51d7a2017-04-06 17:22:18 +0900486 /**
487 * used to specify whether a network should not be penalized when it becomes unvalidated.
488 */
489 private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
490
491 /**
492 * used to trigger revalidation of a network.
493 */
494 private static final int EVENT_REVALIDATE_NETWORK = 36;
495
Erik Klinea24d4592018-01-11 21:07:29 +0900496 // Handle changes in Private DNS settings.
497 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
498
dalyk7301aa42018-03-05 12:42:22 -0500499 // Handle private DNS validation status updates.
500 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
501
junyulai05986c62018-08-07 19:50:45 +0800502 /**
503 * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
504 */
505 private static final int EVENT_UID_RULES_CHANGED = 39;
506
507 /**
508 * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
509 */
510 private static final int EVENT_DATA_SAVER_CHANGED = 40;
511
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900512 /**
513 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
514 * been tested.
Cody Kestinga75e26b2020-01-05 14:06:39 -0800515 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor.
516 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link
517 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null.
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900518 */
Chalard Jeanafdecd52019-09-26 18:03:47 +0900519 private static final int EVENT_NETWORK_TESTED = 41;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900520
521 /**
522 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
523 * config was resolved.
524 * obj = PrivateDnsConfig
525 * arg2 = netid
526 */
Chalard Jeanafdecd52019-09-26 18:03:47 +0900527 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900528
529 /**
530 * Request ConnectivityService display provisioning notification.
531 * arg1 = Whether to make the notification visible.
532 * arg2 = NetID.
533 * obj = Intent to be launched when notification selected by user, null if !arg1.
534 */
Chalard Jeanafdecd52019-09-26 18:03:47 +0900535 private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900536
537 /**
lucasline252a742019-03-12 13:08:03 +0800538 * Used to specify whether a network should be used even if connectivity is partial.
539 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
540 * false)
541 * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
542 * obj = network
543 */
lucaslin8c407bd2020-02-20 16:42:27 +0800544 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
lucasline252a742019-03-12 13:08:03 +0800545
546 /**
lucaslin783f2212019-10-22 18:27:33 +0800547 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
548 * Both of the arguments are bitmasks, and the value of bits come from
549 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
550 * arg1 = A bitmask to describe which probes are completed.
551 * arg2 = A bitmask to describe which probes are successful.
552 */
lucaslin8c407bd2020-02-20 16:42:27 +0800553 public static final int EVENT_PROBE_STATUS_CHANGED = 45;
lucaslin783f2212019-10-22 18:27:33 +0800554
555 /**
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +0900556 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
557 * arg1 = unused
558 * arg2 = netId
559 * obj = captive portal data
560 */
lucaslin8c407bd2020-02-20 16:42:27 +0800561 private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +0900562
563 /**
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900564 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
565 * should be shown.
566 */
Chalard Jeanafdecd52019-09-26 18:03:47 +0900567 private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900568
569 /**
570 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
571 * should be hidden.
572 */
Chalard Jeanafdecd52019-09-26 18:03:47 +0900573 private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +0900574
Hugo Benichiaf52d7a2017-03-30 10:46:05 +0900575 private static String eventName(int what) {
576 return sMagicDecoderRing.get(what, Integer.toString(what));
577 }
578
Luke Huang65914772019-03-16 00:31:46 +0800579 private static IDnsResolver getDnsResolver() {
580 return IDnsResolver.Stub
581 .asInterface(ServiceManager.getService("dnsresolver"));
582 }
583
Cody Kesting63e4e002019-12-18 10:57:50 -0800584 /** Handler thread used for all of the handlers below. */
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900585 @VisibleForTesting
586 protected final HandlerThread mHandlerThread;
Jeff Sharkey4c628eb2012-07-23 13:19:46 -0700587 /** Handler used for internal events. */
Robert Greenwalt7b816022014-04-18 15:25:25 -0700588 final private InternalHandler mHandler;
Jeff Sharkey4c628eb2012-07-23 13:19:46 -0700589 /** Handler used for incoming {@link NetworkStateTracker} events. */
Robert Greenwalt7b816022014-04-18 15:25:25 -0700590 final private NetworkStateTrackerHandler mTrackerHandler;
Cody Kesting63e4e002019-12-18 10:57:50 -0800591 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */
592 @VisibleForTesting
593 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
594
Erik Kline1742fe12017-12-13 19:40:49 +0900595 private final DnsManager mDnsManager;
Chalard Jean7a5e51f2019-12-10 22:16:53 +0900596 private final NetworkRanker mNetworkRanker;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700597
Mike Lockwood0f79b542009-08-14 14:18:49 -0400598 private boolean mSystemReady;
Dianne Hackborn1c633fc2009-12-08 19:45:14 -0800599 private Intent mInitialBroadcast;
Mike Lockwood0f79b542009-08-14 14:18:49 -0400600
Robert Greenwalt14f2ef42010-06-15 12:19:37 -0700601 private PowerManager.WakeLock mNetTransitionWakeLock;
Robert Greenwalt14f2ef42010-06-15 12:19:37 -0700602 private int mNetTransitionWakeLockTimeout;
Jeremy Joslin46e3ac82014-11-05 10:32:09 -0800603 private final PowerManager.WakeLock mPendingIntentWakeLock;
Robert Greenwalt14f2ef42010-06-15 12:19:37 -0700604
Chalard Jean52c2aa72018-06-07 16:44:04 +0900605 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
606 // the world when it changes.
Irina Dumitrescu044a4362018-12-05 16:19:47 +0000607 @VisibleForTesting
608 protected final ProxyTracker mProxyTracker;
Jason Monk602b2322013-07-03 17:04:33 -0400609
Erik Klineda4bfa82015-04-30 12:58:40 +0900610 final private SettingsObserver mSettingsObserver;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700611
Julia Reynoldsfc6b2a02014-06-24 10:56:55 -0400612 private UserManager mUserManager;
613
Chalard Jean4133a122018-06-04 13:33:12 +0900614 private NetworkConfig[] mNetConfigs;
615 private int mNetworksDefined;
Robert Greenwalt42acef32009-08-12 16:08:25 -0700616
Robert Greenwalt50393202011-06-21 17:26:14 -0700617 // the set of network types that can only be enabled by system/sig apps
Chalard Jean4133a122018-06-04 13:33:12 +0900618 private List mProtectedNetworks;
Robert Greenwalt50393202011-06-21 17:26:14 -0700619
Valentin Iftimec86ebba2019-09-24 13:32:13 +0200620 private Set<String> mWolSupportedInterfaces;
621
Roshan Piuse38acab2020-01-16 12:17:17 -0800622 private final TelephonyManager mTelephonyManager;
Cody Kestinga75e26b2020-01-05 14:06:39 -0800623 private final AppOpsManager mAppOpsManager;
624
625 private final LocationPermissionChecker mLocationPermissionChecker;
John Spurlockbf991a82013-06-24 14:20:23 -0400626
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900627 private KeepaliveTracker mKeepaliveTracker;
Lorenzo Colittif3ae2ee2016-08-22 16:30:00 +0900628 private NetworkNotificationManager mNotifier;
Lorenzo Colitti5526f9c2016-08-22 16:46:40 +0900629 private LingerMonitor mLingerMonitor;
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900630
Robert Greenwalt34524f02014-05-18 16:22:10 -0700631 // sequence number of NetworkRequests
632 private int mNextNetworkRequestId = 1;
633
Lorenzo Colittiae5cb712020-01-08 00:04:09 +0900634 // Sequence number for NetworkProvider IDs.
635 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
636 NetworkProvider.FIRST_PROVIDER_ID);
637
Erik Kline7523eb32015-07-09 18:24:03 +0900638 // NetworkRequest activity String log entries.
639 private static final int MAX_NETWORK_REQUEST_LOGS = 20;
640 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
641
Hugo Benichic2ae2872016-07-11 11:05:12 +0900642 // NetworkInfo blocked and unblocked String log entries
Hugo Benichiaf52d7a2017-03-30 10:46:05 +0900643 private static final int MAX_NETWORK_INFO_LOGS = 40;
Hugo Benichic2ae2872016-07-11 11:05:12 +0900644 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
645
Hugo Benichiaf52d7a2017-03-30 10:46:05 +0900646 private static final int MAX_WAKELOCK_LOGS = 20;
647 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
Hugo Benichi26bcfa12017-09-05 13:25:07 +0900648 private int mTotalWakelockAcquisitions = 0;
649 private int mTotalWakelockReleases = 0;
650 private long mTotalWakelockDurationMs = 0;
651 private long mMaxWakelockDurationMs = 0;
652 private long mLastWakeLockAcquireTimestamp = 0;
Hugo Benichiaf52d7a2017-03-30 10:46:05 +0900653
Hugo Benichif9fdf872016-07-28 17:53:06 +0900654 private final IpConnectivityLog mMetricsLog;
Hugo Benichicfddd682016-05-31 16:28:06 +0900655
Nathan Haroldfd45e5f2018-07-30 13:38:01 -0700656 @GuardedBy("mBandwidthRequests")
657 private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
658
Erik Kline065ab6e2016-10-02 18:02:14 +0900659 @VisibleForTesting
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +0900660 final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
Erik Kline065ab6e2016-10-02 18:02:14 +0900661
Lorenzo Colittid260ef22018-01-24 17:35:07 +0900662 @VisibleForTesting
663 final MultipathPolicyTracker mMultipathPolicyTracker;
664
Cody Kesting63e4e002019-12-18 10:57:50 -0800665 @VisibleForTesting
Cody Kesting4600fa52020-03-05 10:46:02 -0800666 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
667 new HashMap<>();
Cody Kesting63e4e002019-12-18 10:57:50 -0800668
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700669 /**
670 * Implements support for the legacy "one network per network type" model.
671 *
672 * We used to have a static array of NetworkStateTrackers, one for each
673 * network type, but that doesn't work any more now that we can have,
674 * for example, more that one wifi network. This class stores all the
675 * NetworkAgentInfo objects that support a given type, but the legacy
676 * API will only see the first one.
677 *
678 * It serves two main purposes:
679 *
680 * 1. Provide information about "the network for a given type" (since this
681 * API only supports one).
682 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
683 * the first network for a given type changes, or if the default network
684 * changes.
685 */
Chalard Jean612522b2019-04-10 23:07:55 +0900686 @VisibleForTesting
687 static class LegacyTypeTracker {
Lorenzo Colittia793a672014-07-31 23:20:17 +0900688
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +0900689 private static final boolean DBG = true;
Lorenzo Colittia793a672014-07-31 23:20:17 +0900690 private static final boolean VDBG = false;
Lorenzo Colittia793a672014-07-31 23:20:17 +0900691
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700692 /**
693 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
694 * Each list holds references to all NetworkAgentInfos that are used to
695 * satisfy requests for that network type.
696 *
697 * This array is built out at startup such that an unsupported network
698 * doesn't get an ArrayList instance, making this a tristate:
699 * unsupported, supported but not active and active.
700 *
701 * The actual lists are populated when we scan the network types that
702 * are supported on this device.
Hugo Benichi78caa2582016-06-21 09:48:07 +0900703 *
704 * Threading model:
705 * - addSupportedType() is only called in the constructor
706 * - add(), update(), remove() are only called from the ConnectivityService handler thread.
707 * They are therefore not thread-safe with respect to each other.
708 * - getNetworkForType() can be called at any time on binder threads. It is synchronized
709 * on mTypeLists to be thread-safe with respect to a concurrent remove call.
710 * - dump is thread-safe with respect to concurrent add and remove calls.
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700711 */
Hugo Benichi78caa2582016-06-21 09:48:07 +0900712 private final ArrayList<NetworkAgentInfo> mTypeLists[];
Chalard Jean612522b2019-04-10 23:07:55 +0900713 @NonNull
714 private final ConnectivityService mService;
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700715
Chalard Jean612522b2019-04-10 23:07:55 +0900716 LegacyTypeTracker(@NonNull ConnectivityService service) {
717 mService = service;
718 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700719 }
720
721 public void addSupportedType(int type) {
722 if (mTypeLists[type] != null) {
723 throw new IllegalStateException(
724 "legacy list for type " + type + "already initialized");
725 }
Chalard Jean4133a122018-06-04 13:33:12 +0900726 mTypeLists[type] = new ArrayList<>();
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700727 }
728
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700729 public boolean isTypeSupported(int type) {
730 return isNetworkTypeValid(type) && mTypeLists[type] != null;
731 }
732
733 public NetworkAgentInfo getNetworkForType(int type) {
Hugo Benichi78caa2582016-06-21 09:48:07 +0900734 synchronized (mTypeLists) {
735 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
736 return mTypeLists[type].get(0);
737 }
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700738 }
Hugo Benichi78caa2582016-06-21 09:48:07 +0900739 return null;
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700740 }
741
Robert Greenwalt8d482522015-06-24 13:23:42 -0700742 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900743 boolean isDefaultNetwork) {
Lorenzo Colittia793a672014-07-31 23:20:17 +0900744 if (DBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +0900745 log("Sending " + state
746 + " broadcast for type " + type + " " + nai.toShortString()
747 + " isDefaultNetwork=" + isDefaultNetwork);
Lorenzo Colittia793a672014-07-31 23:20:17 +0900748 }
749 }
750
751 /** Adds the given network to the specified legacy type list. */
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700752 public void add(int type, NetworkAgentInfo nai) {
753 if (!isTypeSupported(type)) {
754 return; // Invalid network type.
755 }
756 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
757
758 ArrayList<NetworkAgentInfo> list = mTypeLists[type];
759 if (list.contains(nai)) {
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700760 return;
761 }
Hugo Benichi78caa2582016-06-21 09:48:07 +0900762 synchronized (mTypeLists) {
763 list.add(nai);
764 }
Lorenzo Colitti061f4152014-09-28 16:08:06 +0900765
766 // Send a broadcast if this is the first network of its type or if it's the default.
Chalard Jean612522b2019-04-10 23:07:55 +0900767 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
Hugo Benichi78caa2582016-06-21 09:48:07 +0900768 if ((list.size() == 1) || isDefaultNetwork) {
Robert Greenwalt8d482522015-06-24 13:23:42 -0700769 maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
Chalard Jean612522b2019-04-10 23:07:55 +0900770 mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700771 }
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700772 }
773
Lorenzo Colittia793a672014-07-31 23:20:17 +0900774 /** Removes the given network from the specified legacy type list. */
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900775 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
Lorenzo Colittia793a672014-07-31 23:20:17 +0900776 ArrayList<NetworkAgentInfo> list = mTypeLists[type];
777 if (list == null || list.isEmpty()) {
778 return;
779 }
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900780 final boolean wasFirstNetwork = list.get(0).equals(nai);
Lorenzo Colittia793a672014-07-31 23:20:17 +0900781
Hugo Benichi78caa2582016-06-21 09:48:07 +0900782 synchronized (mTypeLists) {
783 if (!list.remove(nai)) {
784 return;
785 }
Lorenzo Colittia793a672014-07-31 23:20:17 +0900786 }
787
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900788 if (wasFirstNetwork || wasDefault) {
Chalard Jean72102e52019-04-11 14:09:07 +0900789 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
790 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
Lorenzo Colittia793a672014-07-31 23:20:17 +0900791 }
792
793 if (!list.isEmpty() && wasFirstNetwork) {
794 if (DBG) log("Other network available for type " + type +
795 ", sending connected broadcast");
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900796 final NetworkAgentInfo replacement = list.get(0);
Chalard Jean72102e52019-04-11 14:09:07 +0900797 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
798 mService.isDefaultNetwork(replacement));
799 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
Lorenzo Colittia793a672014-07-31 23:20:17 +0900800 }
801 }
802
803 /** Removes the given network from all legacy type lists. */
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900804 public void remove(NetworkAgentInfo nai, boolean wasDefault) {
805 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700806 for (int type = 0; type < mTypeLists.length; type++) {
Lorenzo Colitticc917ce2015-05-01 00:30:10 +0900807 remove(type, nai, wasDefault);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700808 }
809 }
Robert Greenwaltd49ac332014-07-30 16:31:24 -0700810
Robert Greenwalt8d482522015-06-24 13:23:42 -0700811 // send out another legacy broadcast - currently only used for suspend/unsuspend
812 // toggle
813 public void update(NetworkAgentInfo nai) {
Chalard Jean612522b2019-04-10 23:07:55 +0900814 final boolean isDefault = mService.isDefaultNetwork(nai);
Robert Greenwalt8d482522015-06-24 13:23:42 -0700815 final DetailedState state = nai.networkInfo.getDetailedState();
816 for (int type = 0; type < mTypeLists.length; type++) {
817 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
Robert Greenwalt3ac71b72015-07-10 16:00:36 -0700818 final boolean contains = (list != null && list.contains(nai));
Hugo Benichi78caa2582016-06-21 09:48:07 +0900819 final boolean isFirst = contains && (nai == list.get(0));
820 if (isFirst || contains && isDefault) {
Robert Greenwalt8d482522015-06-24 13:23:42 -0700821 maybeLogBroadcast(nai, state, type, isDefault);
Chalard Jean612522b2019-04-10 23:07:55 +0900822 mService.sendLegacyNetworkBroadcast(nai, state, type);
Robert Greenwalt8d482522015-06-24 13:23:42 -0700823 }
824 }
825 }
826
Robert Greenwaltd49ac332014-07-30 16:31:24 -0700827 public void dump(IndentingPrintWriter pw) {
Lorenzo Colittie3805462015-06-03 11:18:24 +0900828 pw.println("mLegacyTypeTracker:");
829 pw.increaseIndent();
830 pw.print("Supported types:");
Robert Greenwaltd49ac332014-07-30 16:31:24 -0700831 for (int type = 0; type < mTypeLists.length; type++) {
Lorenzo Colittie3805462015-06-03 11:18:24 +0900832 if (mTypeLists[type] != null) pw.print(" " + type);
Robert Greenwaltd49ac332014-07-30 16:31:24 -0700833 }
Lorenzo Colittie3805462015-06-03 11:18:24 +0900834 pw.println();
835 pw.println("Current state:");
836 pw.increaseIndent();
Hugo Benichi78caa2582016-06-21 09:48:07 +0900837 synchronized (mTypeLists) {
838 for (int type = 0; type < mTypeLists.length; type++) {
839 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
840 for (NetworkAgentInfo nai : mTypeLists[type]) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +0900841 pw.println(type + " " + nai.toShortString());
Hugo Benichi78caa2582016-06-21 09:48:07 +0900842 }
Lorenzo Colittie3805462015-06-03 11:18:24 +0900843 }
844 }
845 pw.decreaseIndent();
846 pw.decreaseIndent();
847 pw.println();
Robert Greenwaltd49ac332014-07-30 16:31:24 -0700848 }
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700849 }
Chalard Jean612522b2019-04-10 23:07:55 +0900850 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -0700851
Vishnu Nair5c010902017-10-26 10:08:50 -0700852 /**
853 * Helper class which parses out priority arguments and dumps sections according to their
854 * priority. If priority arguments are omitted, function calls the legacy dump command.
855 */
856 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
857 @Override
858 public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
859 doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
860 doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
861 }
862
863 @Override
864 public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
865 doDump(fd, pw, args, asProto);
866 }
867
868 @Override
869 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
870 doDump(fd, pw, args, asProto);
871 }
872 };
873
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900874 /**
875 * Dependencies of ConnectivityService, for injection in tests.
876 */
877 @VisibleForTesting
878 public static class Dependencies {
879 /**
880 * Get system properties to use in ConnectivityService.
881 */
882 public MockableSystemProperties getSystemProperties() {
883 return new MockableSystemProperties();
884 }
885
886 /**
887 * Create a HandlerThread to use in ConnectivityService.
888 */
889 public HandlerThread makeHandlerThread() {
890 return new HandlerThread("ConnectivityServiceThread");
891 }
892
893 /**
894 * Get a reference to the NetworkStackClient.
895 */
896 public NetworkStackClient getNetworkStack() {
897 return NetworkStackClient.getInstance();
898 }
899
900 /**
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900901 * @see ProxyTracker
902 */
903 public ProxyTracker makeProxyTracker(@NonNull Context context,
904 @NonNull Handler connServiceHandler) {
905 return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED);
906 }
907
908 /**
909 * @see NetIdManager
910 */
911 public NetIdManager makeNetIdManager() {
912 return new NetIdManager();
913 }
914
915 /**
916 * @see NetworkUtils#queryUserAccess(int, int)
917 */
918 public boolean queryUserAccess(int uid, int netId) {
919 return NetworkUtils.queryUserAccess(uid, netId);
920 }
921
922 /**
923 * @see MultinetworkPolicyTracker
924 */
925 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
926 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) {
927 return new MultinetworkPolicyTracker(c, h, r);
928 }
929
930 /**
931 * @see ServiceManager#checkService(String)
932 */
933 public boolean hasService(@NonNull String name) {
934 return ServiceManager.checkService(name) != null;
935 }
936
937 /**
938 * @see IpConnectivityMetrics.Logger
939 */
940 public IpConnectivityMetrics.Logger getMetricsLogger() {
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +0000941 return Objects.requireNonNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900942 "no IpConnectivityMetrics service");
943 }
944
945 /**
946 * @see IpConnectivityMetrics
947 */
948 public IIpConnectivityMetrics getIpConnectivityMetrics() {
949 return IIpConnectivityMetrics.Stub.asInterface(
950 ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
951 }
Chalard Jean587758b2019-11-29 16:41:50 +0900952
953 public IBatteryStats getBatteryStatsService() {
954 return BatteryStatsService.getService();
955 }
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900956 }
957
Jeff Sharkey899223b2012-08-04 15:24:58 -0700958 public ConnectivityService(Context context, INetworkManagementService netManager,
Robert Greenwalt6831f1d2014-07-27 12:06:40 -0700959 INetworkStatsService statsService, INetworkPolicyManager policyManager) {
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900960 this(context, netManager, statsService, policyManager, getDnsResolver(),
961 new IpConnectivityLog(), NetdService.getInstance(), new Dependencies());
Hugo Benichif9fdf872016-07-28 17:53:06 +0900962 }
963
964 @VisibleForTesting
965 protected ConnectivityService(Context context, INetworkManagementService netManager,
966 INetworkStatsService statsService, INetworkPolicyManager policyManager,
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900967 IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) {
Wink Savilleed9c02b2010-12-03 12:01:38 -0800968 if (DBG) log("ConnectivityService starting up");
Robert Greenwaltde8383c2010-01-14 17:47:58 -0800969
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +0000970 mDeps = Objects.requireNonNull(deps, "missing Dependencies");
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900971 mSystemProperties = mDeps.getSystemProperties();
972 mNetIdManager = mDeps.makeNetIdManager();
Roshan Piuse38acab2020-01-16 12:17:17 -0800973 mContext = Objects.requireNonNull(context, "missing Context");
Lorenzo Colitti42cdf572017-03-21 18:54:11 +0900974
Hugo Benichif9fdf872016-07-28 17:53:06 +0900975 mMetricsLog = logger;
Chalard Jeandda156a2018-01-10 21:19:32 +0900976 mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
Chalard Jean7a5e51f2019-12-10 22:16:53 +0900977 mNetworkRanker = new NetworkRanker();
Lorenzo Colittib35d40d2016-07-01 13:19:21 +0900978 NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
Erik Kline7523eb32015-07-09 18:24:03 +0900979 mNetworkRequests.put(mDefaultRequest, defaultNRI);
980 mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
Erik Klineda4bfa82015-04-30 12:58:40 +0900981
Chalard Jeandda156a2018-01-10 21:19:32 +0900982 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +0900983 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
Robert Greenwalte049c232014-04-11 15:53:27 -0700984
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -0700985 // The default WiFi request is a background request so that apps using WiFi are
986 // migrated to a better network (typically ethernet) when one comes up, instead
987 // of staying on WiFi forever.
988 mDefaultWifiRequest = createDefaultInternetRequestForTransport(
989 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
990
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +0900991 mHandlerThread = mDeps.makeHandlerThread();
Lorenzo Colittie58961a2015-08-07 20:17:27 +0900992 mHandlerThread.start();
993 mHandler = new InternalHandler(mHandlerThread.getLooper());
994 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
Cody Kesting63e4e002019-12-18 10:57:50 -0800995 mConnectivityDiagnosticsHandler =
996 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
Wink Savillebb08caf2010-09-02 19:23:52 -0700997
Jeremy Joslin79294842014-12-03 17:15:28 -0800998 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
999 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
1000
Lorenzo Colitti42cdf572017-03-21 18:54:11 +09001001 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09001002
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +00001003 mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
1004 mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
1005 mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
1006 mPolicyManagerInternal = Objects.requireNonNull(
Hugo Benichi938ab4f2017-02-11 17:04:43 +09001007 LocalServices.getService(NetworkPolicyManagerInternal.class),
1008 "missing NetworkPolicyManagerInternal");
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +00001009 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09001010 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09001011
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00001012 mNetd = netd;
Jeff Sharkey82f85212012-08-24 11:17:25 -07001013 mKeyStore = KeyStore.getInstance();
Wink Savilleab9321d2013-06-29 21:10:57 -07001014 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Cody Kestinga75e26b2020-01-05 14:06:39 -08001015 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1016 mLocationPermissionChecker = new LocationPermissionChecker(mContext);
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07001017
junyulai05986c62018-08-07 19:50:45 +08001018 // To ensure uid rules are synchronized with Network Policy, register for
1019 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
1020 // reading existing policy from disk.
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001021 try {
Hugo Benichi938ab4f2017-02-11 17:04:43 +09001022 mPolicyManager.registerListener(mPolicyListener);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001023 } catch (RemoteException e) {
1024 // ouch, no rules updates means some processes may never get network
Felipe Lemed31a97f2016-05-06 14:53:50 -07001025 loge("unable to register INetworkPolicyListener" + e);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001026 }
1027
1028 final PowerManager powerManager = (PowerManager) context.getSystemService(
1029 Context.POWER_SERVICE);
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07001030 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1031 mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
1032 com.android.internal.R.integer.config_networkTransitionTimeout);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08001033 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07001034
Robert Greenwaltd55a6b42011-03-25 13:09:25 -07001035 mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
Robert Greenwalt5154ae762009-10-30 14:17:42 -07001036
Wink Saville51f456f2013-04-23 14:26:51 -07001037 // TODO: What is the "correct" way to do determine if this is a wifi only device?
Lorenzo Colitti42cdf572017-03-21 18:54:11 +09001038 boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false);
Wink Saville51f456f2013-04-23 14:26:51 -07001039 log("wifiOnly=" + wifiOnly);
Robert Greenwalt5154ae762009-10-30 14:17:42 -07001040 String[] naStrings = context.getResources().getStringArray(
1041 com.android.internal.R.array.networkAttributes);
1042 for (String naString : naStrings) {
1043 try {
Robert Greenwaltd55a6b42011-03-25 13:09:25 -07001044 NetworkConfig n = new NetworkConfig(naString);
Wink Saville5e56bc52013-07-29 15:00:57 -07001045 if (VDBG) log("naString=" + naString + " config=" + n);
Wink Saville975c8482011-04-07 14:23:45 -07001046 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
Wink Savilleed9c02b2010-12-03 12:01:38 -08001047 loge("Error in networkAttributes - ignoring attempt to define type " +
Wink Saville975c8482011-04-07 14:23:45 -07001048 n.type);
Robert Greenwalt5154ae762009-10-30 14:17:42 -07001049 continue;
Robert Greenwalt42acef32009-08-12 16:08:25 -07001050 }
Wink Saville51f456f2013-04-23 14:26:51 -07001051 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
1052 log("networkAttributes - ignoring mobile as this dev is wifiOnly " +
1053 n.type);
1054 continue;
1055 }
Wink Saville975c8482011-04-07 14:23:45 -07001056 if (mNetConfigs[n.type] != null) {
Wink Savilleed9c02b2010-12-03 12:01:38 -08001057 loge("Error in networkAttributes - ignoring attempt to redefine type " +
Wink Saville975c8482011-04-07 14:23:45 -07001058 n.type);
Robert Greenwalt5154ae762009-10-30 14:17:42 -07001059 continue;
1060 }
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07001061 mLegacyTypeTracker.addSupportedType(n.type);
Robert Greenwalt12e67352014-05-13 21:41:06 -07001062
Wink Saville975c8482011-04-07 14:23:45 -07001063 mNetConfigs[n.type] = n;
Robert Greenwalt5154ae762009-10-30 14:17:42 -07001064 mNetworksDefined++;
1065 } catch(Exception e) {
1066 // ignore it - leave the entry null
Robert Greenwalt42acef32009-08-12 16:08:25 -07001067 }
1068 }
Sreeram Ramachandran60c0c0d2014-10-30 14:55:29 -07001069
1070 // Forcibly add TYPE_VPN as a supported type, if it has not already been added via config.
1071 if (mNetConfigs[TYPE_VPN] == null) {
1072 // mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we
1073 // don't need to add TYPE_VPN to mNetConfigs.
1074 mLegacyTypeTracker.addSupportedType(TYPE_VPN);
1075 mNetworksDefined++; // used only in the log() statement below.
1076 }
1077
Lorenzo Colitti7bbe3ee2017-08-24 22:35:10 +09001078 // Do the same for Ethernet, since it's often not specified in the configs, although many
1079 // devices can use it via USB host adapters.
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09001080 if (mNetConfigs[TYPE_ETHERNET] == null && mDeps.hasService(Context.ETHERNET_SERVICE)) {
Lorenzo Colitti7bbe3ee2017-08-24 22:35:10 +09001081 mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET);
1082 mNetworksDefined++;
1083 }
1084
Wink Saville5e56bc52013-07-29 15:00:57 -07001085 if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
Robert Greenwalt42acef32009-08-12 16:08:25 -07001086
Robert Greenwalt50393202011-06-21 17:26:14 -07001087 mProtectedNetworks = new ArrayList<Integer>();
1088 int[] protectedNetworks = context.getResources().getIntArray(
1089 com.android.internal.R.array.config_protectedNetworks);
1090 for (int p : protectedNetworks) {
1091 if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
1092 mProtectedNetworks.add(p);
1093 } else {
1094 if (DBG) loge("Ignoring protectedNetwork " + p);
1095 }
1096 }
1097
Valentin Iftimec86ebba2019-09-24 13:32:13 +02001098 mWolSupportedInterfaces = new ArraySet(
1099 mContext.getResources().getStringArray(
1100 com.android.internal.R.array.config_wakeonlan_supported_interfaces));
1101
soma, kawata0f1cd1d2019-05-23 09:30:40 +09001102 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1103
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00001104 mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
Sreeram Ramachandrane4a05af2014-09-24 09:16:19 -07001105
Varun Anand4fa80e82019-02-06 10:13:38 -08001106 // Set up the listener for user state for creating user VPNs.
1107 // Should run on mHandler to avoid any races.
Chad Brubaker4ca19e82013-06-14 11:16:51 -07001108 IntentFilter intentFilter = new IntentFilter();
Robin Lee323f29d2016-05-04 16:38:06 +01001109 intentFilter.addAction(Intent.ACTION_USER_STARTED);
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -07001110 intentFilter.addAction(Intent.ACTION_USER_STOPPED);
Fyodor Kupolov1c363152015-09-02 13:27:21 -07001111 intentFilter.addAction(Intent.ACTION_USER_ADDED);
1112 intentFilter.addAction(Intent.ACTION_USER_REMOVED);
Robin Lee89e7a692016-02-29 14:38:17 +00001113 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
Chad Brubaker4ca19e82013-06-14 11:16:51 -07001114 mContext.registerReceiverAsUser(
Varun Anand4fa80e82019-02-06 10:13:38 -08001115 mIntentReceiver,
1116 UserHandle.ALL,
1117 intentFilter,
1118 null /* broadcastPermission */,
1119 mHandler);
Robin Lee95204e02017-01-27 11:59:22 +00001120 mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM,
1121 new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
Lorenzo Colitti13c9fde2013-03-15 04:22:37 +09001122
junyulai2454b692018-11-01 17:16:31 +08001123 // Listen to package add and removal events for all users.
1124 intentFilter = new IntentFilter();
1125 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
junyulaiefb04d32018-11-12 22:39:30 +08001126 intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
junyulai2454b692018-11-01 17:16:31 +08001127 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1128 intentFilter.addDataScheme("package");
1129 mContext.registerReceiverAsUser(
Varun Anand4fa80e82019-02-06 10:13:38 -08001130 mIntentReceiver,
1131 UserHandle.ALL,
1132 intentFilter,
1133 null /* broadcastPermission */,
1134 mHandler);
junyulai2454b692018-11-01 17:16:31 +08001135
Chia-chi Yeh008ff392011-05-23 15:08:29 -07001136 try {
Luke Huang4e25ec62018-09-27 16:58:23 +08001137 mNMS.registerObserver(mDataActivityObserver);
Chia-chi Yeh008ff392011-05-23 15:08:29 -07001138 } catch (RemoteException e) {
1139 loge("Error registering observer :" + e);
1140 }
1141
Erik Klineda4bfa82015-04-30 12:58:40 +09001142 mSettingsObserver = new SettingsObserver(mContext, mHandler);
1143 registerSettingsCallbacks();
Robert Greenwaltb7090d62010-12-02 11:31:00 -08001144
Remi NGUYEN VANf9354792019-08-27 20:21:58 +09001145 final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext, mHandler);
Chalard Jean4133a122018-06-04 13:33:12 +09001146 dataConnectionStats.startMonitoring();
Jason Monk602b2322013-07-03 17:04:33 -04001147
junyulai0c666972019-03-04 22:45:36 +08001148 mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
Lorenzo Colitti0b599062016-08-22 22:36:19 +09001149 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
1150 mContext.getSystemService(NotificationManager.class));
Lorenzo Colitti84e6f1232016-08-29 14:03:11 +09001151
1152 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
1153 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
1154 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
1155 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
1156 Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
1157 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
1158 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
Lorenzo Colitti2618c1b2016-09-16 23:43:38 +09001159
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09001160 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
Erik Kline065ab6e2016-10-02 18:02:14 +09001161 mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +09001162 mMultinetworkPolicyTracker.start();
Erik Kline1742fe12017-12-13 19:40:49 +09001163
Lorenzo Colittid260ef22018-01-24 17:35:07 +09001164 mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
1165
Luke Huang65914772019-03-16 00:31:46 +08001166 mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
Erik Klinea24d4592018-01-11 21:07:29 +09001167 registerPrivateDnsSettingsCallbacks();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 }
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07001169
Chalard Jean26400492018-04-18 20:18:38 +09001170 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
1171 final NetworkCapabilities netCap = new NetworkCapabilities();
1172 netCap.addCapability(NET_CAPABILITY_INTERNET);
Chalard Jean26400492018-04-18 20:18:38 +09001173 netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
1174 netCap.setSingleUid(uid);
1175 return netCap;
1176 }
1177
Chalard Jeandda156a2018-01-10 21:19:32 +09001178 private NetworkRequest createDefaultInternetRequestForTransport(
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09001179 int transportType, NetworkRequest.Type type) {
Erik Kline72302902018-06-14 17:36:40 +09001180 final NetworkCapabilities netCap = new NetworkCapabilities();
Lorenzo Colitti8deb3412015-05-14 17:07:20 +09001181 netCap.addCapability(NET_CAPABILITY_INTERNET);
Roshan Piuse38acab2020-01-16 12:17:17 -08001182 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
Erik Klineda4bfa82015-04-30 12:58:40 +09001183 if (transportType > -1) {
1184 netCap.addTransportType(transportType);
1185 }
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09001186 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
Erik Klineda4bfa82015-04-30 12:58:40 +09001187 }
1188
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09001189 // Used only for testing.
1190 // TODO: Delete this and either:
Erik Kline736353a2018-03-21 07:18:33 -07001191 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09001192 // changing ContentResolver to make registerContentObserver non-final).
1193 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
1194 // by subclassing SettingsObserver.
1195 @VisibleForTesting
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001196 void updateAlwaysOnNetworks() {
1197 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
Lorenzo Colitti762ea7a2016-06-05 21:00:23 +09001198 }
1199
Erik Kline736353a2018-03-21 07:18:33 -07001200 // See FakeSettingsProvider comment above.
1201 @VisibleForTesting
1202 void updatePrivateDnsSettings() {
1203 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1204 }
1205
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001206 private void handleAlwaysOnNetworkRequest(
1207 NetworkRequest networkRequest, String settingName, boolean defaultValue) {
Hugo Benichiab7d2e62017-04-21 15:07:12 +09001208 final boolean enable = toBool(Settings.Global.getInt(
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001209 mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
1210 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
Erik Klineda4bfa82015-04-30 12:58:40 +09001211 if (enable == isEnabled) {
1212 return; // Nothing to do.
1213 }
1214
1215 if (enable) {
1216 handleRegisterNetworkRequest(new NetworkRequestInfo(
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001217 null, networkRequest, new Binder()));
Erik Klineda4bfa82015-04-30 12:58:40 +09001218 } else {
Etan Cohenddb720a2019-01-08 12:09:18 -08001219 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
1220 /* callOnUnavailable */ false);
Erik Klineda4bfa82015-04-30 12:58:40 +09001221 }
1222 }
1223
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001224 private void handleConfigureAlwaysOnNetworks() {
1225 handleAlwaysOnNetworkRequest(
1226 mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true);
1227 handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED,
1228 false);
1229 }
1230
Erik Klineda4bfa82015-04-30 12:58:40 +09001231 private void registerSettingsCallbacks() {
1232 // Watch for global HTTP proxy changes.
1233 mSettingsObserver.observe(
1234 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
1235 EVENT_APPLY_GLOBAL_HTTP_PROXY);
1236
1237 // Watch for whether or not to keep mobile data always on.
1238 mSettingsObserver.observe(
1239 Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON),
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07001240 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1241
1242 // Watch for whether or not to keep wifi always on.
1243 mSettingsObserver.observe(
1244 Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED),
1245 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
Erik Klineda4bfa82015-04-30 12:58:40 +09001246 }
1247
Erik Klinea24d4592018-01-11 21:07:29 +09001248 private void registerPrivateDnsSettingsCallbacks() {
Erik Kline736353a2018-03-21 07:18:33 -07001249 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
1250 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
Erik Klinea24d4592018-01-11 21:07:29 +09001251 }
1252 }
1253
Robert Greenwalt34524f02014-05-18 16:22:10 -07001254 private synchronized int nextNetworkRequestId() {
1255 return mNextNetworkRequestId++;
1256 }
1257
Chalard Jeanc0982912018-06-07 16:11:34 +09001258 private NetworkState getFilteredNetworkState(int networkType, int uid) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001259 if (mLegacyTypeTracker.isTypeSupported(networkType)) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001260 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1261 final NetworkState state;
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001262 if (nai != null) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001263 state = nai.getNetworkState();
1264 state.networkInfo.setType(networkType);
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001265 } else {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001266 final NetworkInfo info = new NetworkInfo(networkType, 0,
1267 getNetworkTypeName(networkType), "");
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001268 info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
1269 info.setIsAvailable(true);
Jeff Sharkey62262162017-12-04 15:52:01 -07001270 final NetworkCapabilities capabilities = new NetworkCapabilities();
1271 capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
1272 !info.isRoaming());
1273 state = new NetworkState(info, new LinkProperties(), capabilities,
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001274 null, null, null);
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001275 }
Chalard Jeanc0982912018-06-07 16:11:34 +09001276 filterNetworkStateForUid(state, uid, false);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001277 return state;
1278 } else {
1279 return NetworkState.EMPTY;
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001280 }
Paul Jensen7ccd3df2014-08-29 09:54:01 -04001281 }
1282
junyulai4a192e22018-06-13 15:00:37 +08001283 @VisibleForTesting
1284 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001285 if (network == null) {
1286 return null;
1287 }
Erik Kline736353a2018-03-21 07:18:33 -07001288 return getNetworkAgentInfoForNetId(network.netId);
1289 }
1290
1291 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001292 synchronized (mNetworkForNetId) {
Erik Kline736353a2018-03-21 07:18:33 -07001293 return mNetworkForNetId.get(netId);
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001294 }
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001295 }
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001296
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001297 private Network[] getVpnUnderlyingNetworks(int uid) {
Hugo Benichi69744342017-11-27 10:57:16 +09001298 synchronized (mVpns) {
1299 if (!mLockdownEnabled) {
1300 int user = UserHandle.getUserId(uid);
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001301 Vpn vpn = mVpns.get(user);
1302 if (vpn != null && vpn.appliesToUid(uid)) {
1303 return vpn.getUnderlyingNetworks();
1304 }
1305 }
1306 }
1307 return null;
1308 }
1309
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001310 private NetworkState getUnfilteredActiveNetworkState(int uid) {
Paul Jensen85cf78e2015-06-25 13:25:07 -04001311 NetworkAgentInfo nai = getDefaultNetwork();
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08001312
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001313 final Network[] networks = getVpnUnderlyingNetworks(uid);
1314 if (networks != null) {
1315 // getUnderlyingNetworks() returns:
1316 // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
1317 // empty array => the VPN explicitly said "no default network".
1318 // non-empty array => the VPN specified one or more default networks; we use the
1319 // first one.
1320 if (networks.length > 0) {
1321 nai = getNetworkAgentInfoForNetwork(networks[0]);
1322 } else {
1323 nai = null;
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08001324 }
1325 }
1326
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001327 if (nai != null) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001328 return nai.getNetworkState();
1329 } else {
1330 return NetworkState.EMPTY;
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001331 }
Paul Jensen7ccd3df2014-08-29 09:54:01 -04001332 }
1333
1334 /**
1335 * Check if UID should be blocked from using the network with the given LinkProperties.
1336 */
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001337 private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
1338 boolean ignoreBlocked) {
1339 // Networks aren't blocked when ignoring blocked status
Hugo Benichi938ab4f2017-02-11 17:04:43 +09001340 if (ignoreBlocked) {
1341 return false;
1342 }
Robin Lee17e61832016-05-09 13:46:28 +01001343 synchronized (mVpns) {
1344 final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
junyulai8ed89152018-10-25 10:56:17 +08001345 if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
Robin Lee17e61832016-05-09 13:46:28 +01001346 return true;
1347 }
1348 }
Robert Greenwalt12e67352014-05-13 21:41:06 -07001349 final String iface = (lp == null ? "" : lp.getInterfaceName());
Hugo Benichi938ab4f2017-02-11 17:04:43 +09001350 return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001351 }
1352
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09001353 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
Hugo Benichic2ae2872016-07-11 11:05:12 +09001354 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
1355 return;
1356 }
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09001357 final boolean blocked;
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09001358 synchronized (mBlockedAppUids) {
1359 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09001360 blocked = true;
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09001361 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09001362 blocked = false;
1363 } else {
1364 return;
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09001365 }
1366 }
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09001367 String action = blocked ? "BLOCKED" : "UNBLOCKED";
1368 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
1369 mNetworkInfoBlockingLogs.log(action + " " + uid);
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09001370 }
1371
junyulai05986c62018-08-07 19:50:45 +08001372 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
1373 boolean blocked) {
1374 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
1375 return;
1376 }
Junyu Laibf55f0e2020-06-02 09:52:38 +00001377 final String action = blocked ? "BLOCKED" : "UNBLOCKED";
1378 mNetworkInfoBlockingLogs.log(String.format(
1379 "%s %d(%d) on netId %d", action, nri.mUid, nri.request.requestId, net.netId));
junyulai05986c62018-08-07 19:50:45 +08001380 }
1381
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001382 /**
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001383 * Apply any relevant filters to {@link NetworkState} for the given UID. For
1384 * example, this may mark the network as {@link DetailedState#BLOCKED} based
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001385 * on {@link #isNetworkWithLinkPropertiesBlocked}.
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001386 */
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001387 private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001388 if (state == null || state.networkInfo == null || state.linkProperties == null) return;
1389
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001390 if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001391 state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001392 }
Hugo Benichi69744342017-11-27 10:57:16 +09001393 synchronized (mVpns) {
1394 if (mLockdownTracker != null) {
1395 mLockdownTracker.augmentNetworkInfo(state.networkInfo);
1396 }
Jeff Sharkey69ddab42012-08-25 00:05:46 -07001397 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001398 }
1399
1400 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 * Return NetworkInfo for the active (i.e., connected) network interface.
1402 * It is assumed that at most one network is active at a time. If more
1403 * than one is active, it is indeterminate which will be returned.
Robert Greenwalt86e9e552009-07-16 17:21:39 -07001404 * @return the info for the active network, or {@code null} if none is
1405 * active
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 */
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001407 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 public NetworkInfo getActiveNetworkInfo() {
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001409 enforceAccessPermission();
1410 final int uid = Binder.getCallingUid();
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001411 final NetworkState state = getUnfilteredActiveNetworkState(uid);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001412 filterNetworkStateForUid(state, uid, false);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001413 maybeLogBlockedNetworkInfo(state.networkInfo, uid);
1414 return state.networkInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 }
1416
Paul Jensen31a94f42015-02-13 14:18:39 -05001417 @Override
1418 public Network getActiveNetwork() {
1419 enforceAccessPermission();
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001420 return getActiveNetworkForUidInternal(Binder.getCallingUid(), false);
Robin Leed2baf792016-03-24 12:07:00 +00001421 }
1422
1423 @Override
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001424 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
paulhu59148b72019-08-12 16:25:11 +08001425 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001426 return getActiveNetworkForUidInternal(uid, ignoreBlocked);
Robin Leed2baf792016-03-24 12:07:00 +00001427 }
1428
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001429 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
Paul Jensen31a94f42015-02-13 14:18:39 -05001430 final int user = UserHandle.getUserId(uid);
1431 int vpnNetId = NETID_UNSET;
1432 synchronized (mVpns) {
1433 final Vpn vpn = mVpns.get(user);
Chalard Jean26400492018-04-18 20:18:38 +09001434 // TODO : now that capabilities contain the UID, the appliesToUid test should
1435 // be removed as the satisfying test below should be enough.
Paul Jensen31a94f42015-02-13 14:18:39 -05001436 if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
1437 }
1438 NetworkAgentInfo nai;
1439 if (vpnNetId != NETID_UNSET) {
Erik Kline736353a2018-03-21 07:18:33 -07001440 nai = getNetworkAgentInfoForNetId(vpnNetId);
Chalard Jean26400492018-04-18 20:18:38 +09001441 if (nai != null) {
1442 final NetworkCapabilities requiredCaps =
1443 createDefaultNetworkCapabilitiesForUid(uid);
1444 if (requiredCaps.satisfiedByNetworkCapabilities(nai.networkCapabilities)) {
1445 return nai.network;
1446 }
1447 }
Paul Jensen31a94f42015-02-13 14:18:39 -05001448 }
1449 nai = getDefaultNetwork();
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001450 if (nai != null
1451 && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) {
1452 nai = null;
1453 }
Paul Jensen31a94f42015-02-13 14:18:39 -05001454 return nai != null ? nai.network : null;
1455 }
1456
Lorenzo Colitti18660282016-07-04 12:55:44 +09001457 // Public because it's used by mLockdownTracker.
Jeff Sharkey69ddab42012-08-25 00:05:46 -07001458 public NetworkInfo getActiveNetworkInfoUnfiltered() {
1459 enforceAccessPermission();
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001460 final int uid = Binder.getCallingUid();
1461 NetworkState state = getUnfilteredActiveNetworkState(uid);
1462 return state.networkInfo;
Jeff Sharkey69ddab42012-08-25 00:05:46 -07001463 }
1464
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001465 @Override
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001466 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
paulhu59148b72019-08-12 16:25:11 +08001467 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001468 final NetworkState state = getUnfilteredActiveNetworkState(uid);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001469 filterNetworkStateForUid(state, uid, ignoreBlocked);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001470 return state.networkInfo;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001471 }
1472
1473 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 public NetworkInfo getNetworkInfo(int networkType) {
1475 enforceAccessPermission();
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001476 final int uid = Binder.getCallingUid();
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001477 if (getVpnUnderlyingNetworks(uid) != null) {
1478 // A VPN is active, so we may need to return one of its underlying networks. This
1479 // information is not available in LegacyTypeTracker, so we have to get it from
1480 // getUnfilteredActiveNetworkState.
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001481 final NetworkState state = getUnfilteredActiveNetworkState(uid);
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001482 if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001483 filterNetworkStateForUid(state, uid, false);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001484 return state.networkInfo;
Lorenzo Colittid6a79802015-02-05 13:57:17 +09001485 }
1486 }
Chalard Jeanc0982912018-06-07 16:11:34 +09001487 final NetworkState state = getFilteredNetworkState(networkType, uid);
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001488 return state.networkInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 }
1490
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001491 @Override
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001492 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001493 enforceAccessPermission();
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001494 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001495 if (nai != null) {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001496 final NetworkState state = nai.getNetworkState();
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001497 filterNetworkStateForUid(state, uid, ignoreBlocked);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001498 return state.networkInfo;
1499 } else {
1500 return null;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001501 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001502 }
1503
1504 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 public NetworkInfo[] getAllNetworkInfo() {
1506 enforceAccessPermission();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001507 final ArrayList<NetworkInfo> result = Lists.newArrayList();
Paul Jensenf9ee0e52014-09-19 11:14:12 -04001508 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
1509 networkType++) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001510 NetworkInfo info = getNetworkInfo(networkType);
1511 if (info != null) {
1512 result.add(info);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001515 return result.toArray(new NetworkInfo[result.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 }
1517
Robert Greenwalt9b2886e2011-08-31 11:46:42 -07001518 @Override
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001519 public Network getNetworkForType(int networkType) {
1520 enforceAccessPermission();
1521 final int uid = Binder.getCallingUid();
Chalard Jeanc0982912018-06-07 16:11:34 +09001522 NetworkState state = getFilteredNetworkState(networkType, uid);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001523 if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001524 return state.network;
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001525 }
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001526 return null;
Lorenzo Colittib57edc52014-08-22 17:10:50 -07001527 }
1528
1529 @Override
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001530 public Network[] getAllNetworks() {
1531 enforceAccessPermission();
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001532 synchronized (mNetworkForNetId) {
Paul Jensene75b9e32015-04-06 11:54:53 -04001533 final Network[] result = new Network[mNetworkForNetId.size()];
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001534 for (int i = 0; i < mNetworkForNetId.size(); i++) {
Paul Jensene75b9e32015-04-06 11:54:53 -04001535 result[i] = mNetworkForNetId.valueAt(i).network;
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001536 }
Paul Jensene75b9e32015-04-06 11:54:53 -04001537 return result;
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001538 }
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001539 }
1540
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001541 @Override
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001542 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
1543 int userId, String callingPackageName) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001544 // The basic principle is: if an app's traffic could possibly go over a
1545 // network, without the app doing anything multinetwork-specific,
1546 // (hence, by "default"), then include that network's capabilities in
1547 // the array.
1548 //
1549 // In the normal case, app traffic only goes over the system's default
1550 // network connection, so that's the only network returned.
1551 //
1552 // With a VPN in force, some app traffic may go into the VPN, and thus
1553 // over whatever underlying networks the VPN specifies, while other app
1554 // traffic may go over the system default network (e.g.: a split-tunnel
1555 // VPN, or an app disallowed by the VPN), so the set of networks
1556 // returned includes the VPN's underlying networks and the system
1557 // default.
1558 enforceAccessPermission();
1559
Chalard Jean4133a122018-06-04 13:33:12 +09001560 HashMap<Network, NetworkCapabilities> result = new HashMap<>();
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001561
1562 NetworkAgentInfo nai = getDefaultNetwork();
Lorenzo Colitti76f67792015-05-14 17:28:27 +09001563 NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001564 if (nc != null) {
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001565 result.put(
1566 nai.network,
1567 maybeSanitizeLocationInfoForCaller(
1568 nc, Binder.getCallingUid(), callingPackageName));
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001569 }
1570
Hugo Benichi69744342017-11-27 10:57:16 +09001571 synchronized (mVpns) {
1572 if (!mLockdownEnabled) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001573 Vpn vpn = mVpns.get(userId);
1574 if (vpn != null) {
1575 Network[] networks = vpn.getUnderlyingNetworks();
1576 if (networks != null) {
1577 for (Network network : networks) {
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001578 nc = getNetworkCapabilitiesInternal(network);
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001579 if (nc != null) {
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001580 result.put(
1581 network,
1582 maybeSanitizeLocationInfoForCaller(
1583 nc, Binder.getCallingUid(), callingPackageName));
Lorenzo Colitti403aa262014-11-28 11:21:30 +09001584 }
1585 }
1586 }
1587 }
1588 }
1589 }
1590
1591 NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
1592 out = result.values().toArray(out);
1593 return out;
1594 }
1595
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001596 @Override
Robert Greenwalt9b2886e2011-08-31 11:46:42 -07001597 public boolean isNetworkSupported(int networkType) {
1598 enforceAccessPermission();
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001599 return mLegacyTypeTracker.isTypeSupported(networkType);
Robert Greenwalt9b2886e2011-08-31 11:46:42 -07001600 }
1601
Robert Greenwaltd192dad2010-09-14 09:18:02 -07001602 /**
1603 * Return LinkProperties for the active (i.e., connected) default
1604 * network interface. It is assumed that at most one default network
1605 * is active at a time. If more than one is active, it is indeterminate
1606 * which will be returned.
1607 * @return the ip properties for the active network, or {@code null} if
1608 * none is active
1609 */
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001610 @Override
Robert Greenwaltd192dad2010-09-14 09:18:02 -07001611 public LinkProperties getActiveLinkProperties() {
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001612 enforceAccessPermission();
1613 final int uid = Binder.getCallingUid();
1614 NetworkState state = getUnfilteredActiveNetworkState(uid);
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001615 if (state.linkProperties == null) return null;
1616 return linkPropertiesRestrictedForCallerPermissions(state.linkProperties,
1617 Binder.getCallingPid(), uid);
Robert Greenwaltd192dad2010-09-14 09:18:02 -07001618 }
1619
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001620 @Override
Robert Greenwalt9258c642014-03-26 16:47:06 -07001621 public LinkProperties getLinkPropertiesForType(int networkType) {
Robert Greenwaltd192dad2010-09-14 09:18:02 -07001622 enforceAccessPermission();
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08001623 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001624 final LinkProperties lp = getLinkProperties(nai);
1625 if (lp == null) return null;
1626 return linkPropertiesRestrictedForCallerPermissions(
1627 lp, Binder.getCallingPid(), Binder.getCallingUid());
Robert Greenwaltd192dad2010-09-14 09:18:02 -07001628 }
1629
Robert Greenwalt12e67352014-05-13 21:41:06 -07001630 // TODO - this should be ALL networks
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001631 @Override
Robert Greenwalt9258c642014-03-26 16:47:06 -07001632 public LinkProperties getLinkProperties(Network network) {
1633 enforceAccessPermission();
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001634 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network));
1635 if (lp == null) return null;
1636 return linkPropertiesRestrictedForCallerPermissions(
1637 lp, Binder.getCallingPid(), Binder.getCallingUid());
Hugo Benichi0fd4af92017-04-06 16:01:44 +09001638 }
1639
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001640 @Nullable
1641 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) {
Hugo Benichi0fd4af92017-04-06 16:01:44 +09001642 if (nai == null) {
1643 return null;
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001644 }
Hugo Benichi0fd4af92017-04-06 16:01:44 +09001645 synchronized (nai) {
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001646 return nai.linkProperties;
Hugo Benichi0fd4af92017-04-06 16:01:44 +09001647 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07001648 }
1649
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001650 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
1651 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
1652 }
1653
Lorenzo Colitti76f67792015-05-14 17:28:27 +09001654 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001655 if (nai == null) return null;
1656 synchronized (nai) {
1657 if (nai.networkCapabilities == null) return null;
1658 return networkCapabilitiesRestrictedForCallerPermissions(
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001659 nai.networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid());
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001660 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07001661 }
1662
1663 @Override
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001664 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName) {
1665 mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackageName);
Lorenzo Colitti76f67792015-05-14 17:28:27 +09001666 enforceAccessPermission();
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001667 return maybeSanitizeLocationInfoForCaller(
1668 getNetworkCapabilitiesInternal(network),
1669 Binder.getCallingUid(), callingPackageName);
Lorenzo Colitti76f67792015-05-14 17:28:27 +09001670 }
1671
Qingxi Li7cf06622020-01-17 17:54:27 -08001672 @VisibleForTesting
1673 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
Chalard Jeanb552c462018-02-21 18:43:54 +09001674 NetworkCapabilities nc, int callerPid, int callerUid) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001675 final NetworkCapabilities newNc = new NetworkCapabilities(nc);
Chalard Jean26400492018-04-18 20:18:38 +09001676 if (!checkSettingsPermission(callerPid, callerUid)) {
1677 newNc.setUids(null);
1678 newNc.setSSID(null);
1679 }
Etan Cohen836ad572018-12-30 17:59:59 -08001680 if (newNc.getNetworkSpecifier() != null) {
1681 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
1682 }
Cody Kestingf7ac9962020-03-16 18:15:28 -07001683 newNc.setAdministratorUids(new int[0]);
Qingxi Li7cf06622020-01-17 17:54:27 -08001684
Chalard Jeanb03a6222018-04-11 21:09:10 +09001685 return newNc;
Chalard Jeanf19db372018-01-26 19:24:40 +09001686 }
1687
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001688 @VisibleForTesting
1689 @Nullable
1690 NetworkCapabilities maybeSanitizeLocationInfoForCaller(
1691 @Nullable NetworkCapabilities nc, int callerUid, @NonNull String callerPkgName) {
1692 if (nc == null) {
1693 return null;
1694 }
1695 final NetworkCapabilities newNc = new NetworkCapabilities(nc);
1696 if (callerUid != newNc.getOwnerUid()) {
1697 newNc.setOwnerUid(INVALID_UID);
1698 return newNc;
1699 }
1700
Benedict Wong26d23782020-06-15 17:54:29 +00001701 // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
1702 if (nc.hasTransport(TRANSPORT_VPN)) {
1703 // Owner UIDs already checked above. No need to re-check.
1704 return newNc;
1705 }
1706
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001707 Binder.withCleanCallingIdentity(
1708 () -> {
1709 if (!mLocationPermissionChecker.checkLocationPermission(
1710 callerPkgName, null /* featureId */, callerUid, null /* message */)) {
1711 // Caller does not have the requisite location permissions. Reset the
1712 // owner's UID in the NetworkCapabilities.
1713 newNc.setOwnerUid(INVALID_UID);
1714 }
1715 }
1716 );
1717
1718 return newNc;
Qingxi Li7cf06622020-01-17 17:54:27 -08001719 }
1720
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001721 private LinkProperties linkPropertiesRestrictedForCallerPermissions(
1722 LinkProperties lp, int callerPid, int callerUid) {
1723 if (lp == null) return new LinkProperties();
1724
1725 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
1726 final boolean needsSanitization =
1727 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null);
1728 if (!needsSanitization) {
1729 return new LinkProperties(lp);
1730 }
1731
1732 if (checkSettingsPermission(callerPid, callerUid)) {
Automerger Merge Worker0acf9102020-03-17 16:02:25 +00001733 return new LinkProperties(lp, true /* parcelSensitiveFields */);
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09001734 }
1735
1736 final LinkProperties newLp = new LinkProperties(lp);
1737 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the
1738 // object gets parceled.
1739 newLp.setCaptivePortalApiUrl(null);
1740 newLp.setCaptivePortalData(null);
1741 return newLp;
1742 }
1743
Roshan Piuse38acab2020-01-16 12:17:17 -08001744 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
1745 int callerUid, String callerPackageName) {
Chalard Jeanb552c462018-02-21 18:43:54 +09001746 if (!checkSettingsPermission()) {
Roshan Piuse38acab2020-01-16 12:17:17 -08001747 nc.setSingleUid(callerUid);
Chalard Jeanb552c462018-02-21 18:43:54 +09001748 }
Roshan Piuse38acab2020-01-16 12:17:17 -08001749 nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
Cody Kestingf7ac9962020-03-16 18:15:28 -07001750 nc.setAdministratorUids(new int[0]);
Qingxi Li7cf06622020-01-17 17:54:27 -08001751
1752 // Clear owner UID; this can never come from an app.
1753 nc.setOwnerUid(INVALID_UID);
Chalard Jeanb552c462018-02-21 18:43:54 +09001754 }
1755
Chalard Jean26aa91a2018-03-20 19:13:57 +09001756 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
1757 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(Binder.getCallingUid())) {
1758 nc.addCapability(NET_CAPABILITY_FOREGROUND);
1759 }
1760 }
1761
Lorenzo Colitti76f67792015-05-14 17:28:27 +09001762 @Override
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001763 public NetworkState[] getAllNetworkState() {
paulhu59148b72019-08-12 16:25:11 +08001764 // This contains IMSI details, so make sure the caller is privileged.
1765 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey32566012014-12-02 18:30:14 -08001766
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001767 final ArrayList<NetworkState> result = Lists.newArrayList();
Jeff Sharkey32566012014-12-02 18:30:14 -08001768 for (Network network : getAllNetworks()) {
1769 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
1770 if (nai != null) {
Chalard Jeanf19db372018-01-26 19:24:40 +09001771 // TODO (b/73321673) : NetworkState contains a copy of the
1772 // NetworkCapabilities, which may contain UIDs of apps to which the
1773 // network applies. Should the UIDs be cleared so as not to leak or
1774 // interfere ?
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -06001775 result.add(nai.getNetworkState());
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001776 }
1777 }
1778 return result.toArray(new NetworkState[result.size()]);
1779 }
1780
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07001781 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001782 @Deprecated
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07001783 public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001784 Log.w(TAG, "Shame on UID " + Binder.getCallingUid()
1785 + " for calling the hidden API getNetworkQuotaInfo(). Shame!");
1786 return new NetworkQuotaInfo();
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07001787 }
1788
Jeff Sharkey9f7cbf02012-04-12 18:34:54 -07001789 @Override
1790 public boolean isActiveNetworkMetered() {
1791 enforceAccessPermission();
Jeff Sharkey9f7cbf02012-04-12 18:34:54 -07001792
Qingxi Li9c5d8b92020-01-08 12:51:49 -08001793 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork());
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001794 if (caps != null) {
1795 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1796 } else {
1797 // Always return the most conservative value
1798 return true;
1799 }
Jeff Sharkey5f4dafb2012-04-30 15:47:05 -07001800 }
1801
Jeff Sharkey216c1812012-08-05 14:29:23 -07001802 private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
1803 @Override
Ashish Sharma0535a9f2014-03-12 18:42:23 -07001804 public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
Haoyu Baidb3c8672012-06-20 14:29:57 -07001805 int deviceType = Integer.parseInt(label);
Ashish Sharma0535a9f2014-03-12 18:42:23 -07001806 sendDataActivityBroadcast(deviceType, active, tsNanos);
Haoyu Baidb3c8672012-06-20 14:29:57 -07001807 }
Jeff Sharkey216c1812012-08-05 14:29:23 -07001808 };
Haoyu Baidb3c8672012-06-20 14:29:57 -07001809
Robert Greenwalt9c75d4a2009-09-27 17:27:04 -07001810 /**
Lorenzo Colitti2e31a7c2018-09-28 11:31:55 +09001811 * Ensures that the system cannot call a particular method.
1812 */
1813 private boolean disallowedBecauseSystemCaller() {
1814 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
Anil Admal4661b742019-04-05 10:06:37 -07001815 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
1816 // for devices launched with Q and above. However, existing devices upgrading to Q and
1817 // above must continued to be supported for few more releases.
1818 if (isSystem(Binder.getCallingUid()) && SystemProperties.getInt(
1819 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
Lorenzo Colitti2e31a7c2018-09-28 11:31:55 +09001820 log("This method exists only for app backwards compatibility"
1821 + " and must not be called by system services.");
1822 return true;
1823 }
1824 return false;
1825 }
1826
1827 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 * Ensure that a network route exists to deliver traffic to the specified
1829 * host via the specified network interface.
Robert Greenwalt86e9e552009-07-16 17:21:39 -07001830 * @param networkType the type of the network over which traffic to the
1831 * specified host is to be routed
1832 * @param hostAddress the IP address of the host to which the route is
1833 * desired
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001834 * @return {@code true} on success, {@code false} on failure
1835 */
Lorenzo Colitti18660282016-07-04 12:55:44 +09001836 @Override
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001837 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
Lorenzo Colitti2e31a7c2018-09-28 11:31:55 +09001838 if (disallowedBecauseSystemCaller()) {
1839 return false;
1840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841 enforceChangePermission();
Robert Greenwalt50393202011-06-21 17:26:14 -07001842 if (mProtectedNetworks.contains(networkType)) {
paulhu59148b72019-08-12 16:25:11 +08001843 enforceConnectivityRestrictedNetworksPermission();
Robert Greenwalt50393202011-06-21 17:26:14 -07001844 }
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001845
Chad Brubakerc0234532014-02-14 13:24:29 -08001846 InetAddress addr;
1847 try {
1848 addr = InetAddress.getByAddress(hostAddress);
1849 } catch (UnknownHostException e) {
1850 if (DBG) log("requestRouteToHostAddress got " + e.toString());
1851 return false;
1852 }
Robert Greenwalt50393202011-06-21 17:26:14 -07001853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
Robert Greenwalt8beff952011-12-13 15:26:02 -08001855 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 return false;
1857 }
Robert Greenwalt2d370702014-06-03 17:22:11 -07001858
1859 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1860 if (nai == null) {
1861 if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
1862 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
1863 } else {
1864 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
1865 }
1866 return false;
Ken Mixter151d3032013-11-07 22:08:24 -08001867 }
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001868
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001869 DetailedState netState;
1870 synchronized (nai) {
1871 netState = nai.networkInfo.getDetailedState();
1872 }
Robert Greenwalt2d370702014-06-03 17:22:11 -07001873
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001874 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
Robert Greenwalt58d4c592011-08-02 17:18:41 -07001875 if (VDBG) {
Wink Savilleab9321d2013-06-29 21:10:57 -07001876 log("requestRouteToHostAddress on down network "
1877 + "(" + networkType + ") - dropped"
Robert Greenwalt2d370702014-06-03 17:22:11 -07001878 + " netState=" + netState);
Robert Greenwalt8206ff32009-09-10 15:06:20 -07001879 }
1880 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 }
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001882
Sreeram Ramachandran515350a2014-05-22 16:30:48 -07001883 final int uid = Binder.getCallingUid();
Robert Greenwalt8beff952011-12-13 15:26:02 -08001884 final long token = Binder.clearCallingIdentity();
Robert Greenwalt47f69fe2010-06-15 15:43:39 -07001885 try {
Paul Jensenbcc76d32014-07-11 08:17:29 -04001886 LinkProperties lp;
1887 int netId;
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07001888 synchronized (nai) {
1889 lp = nai.linkProperties;
1890 netId = nai.network.netId;
1891 }
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001892 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
Wink Savilleab9321d2013-06-29 21:10:57 -07001893 if (DBG) log("requestRouteToHostAddress ok=" + ok);
1894 return ok;
Robert Greenwalt8beff952011-12-13 15:26:02 -08001895 } finally {
1896 Binder.restoreCallingIdentity(token);
1897 }
Irfan Sheriffd649c122010-06-09 15:39:36 -07001898 }
1899
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001900 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
Lorenzo Colittif83d90c2013-03-15 13:58:38 +09001901 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
Robert Greenwaltad55d352011-07-22 11:55:33 -07001902 if (bestRoute == null) {
Lorenzo Colittif83d90c2013-03-15 13:58:38 +09001903 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
Robert Greenwaltad55d352011-07-22 11:55:33 -07001904 } else {
Lorenzo Colittif83d90c2013-03-15 13:58:38 +09001905 String iface = bestRoute.getInterface();
Robert Greenwaltad55d352011-07-22 11:55:33 -07001906 if (bestRoute.getGateway().equals(addr)) {
1907 // if there is no better route, add the implied hostroute for our gateway
Lorenzo Colittie1671352013-03-08 12:30:44 -08001908 bestRoute = RouteInfo.makeHostRoute(addr, iface);
Robert Greenwaltad55d352011-07-22 11:55:33 -07001909 } else {
1910 // if we will connect to this through another route, add a direct route
1911 // to it's gateway
Lorenzo Colittie1671352013-03-08 12:30:44 -08001912 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
Robert Greenwaltad55d352011-07-22 11:55:33 -07001913 }
1914 }
Lorenzo Colittiaa281e22015-09-04 13:12:42 +09001915 if (DBG) log("Adding legacy route " + bestRoute +
1916 " for UID/PID " + uid + "/" + Binder.getCallingPid());
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001917 try {
Luke Huang4e25ec62018-09-27 16:58:23 +08001918 mNMS.addLegacyRouteForNetId(netId, bestRoute, uid);
Sreeram Ramachandran03666c72014-07-19 23:21:46 -07001919 } catch (Exception e) {
1920 // never crash - catch them all
1921 if (DBG) loge("Exception trying to add a route: " + e);
Robert Greenwalt8beff952011-12-13 15:26:02 -08001922 return false;
1923 }
Robert Greenwalt0a46db52011-07-14 14:28:05 -07001924 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 }
1926
dalyk7301aa42018-03-05 12:42:22 -05001927 @VisibleForTesting
1928 protected final INetdEventCallback mNetdEventCallback = new BaseNetdEventCallback() {
1929 @Override
1930 public void onPrivateDnsValidationEvent(int netId, String ipAddress,
1931 String hostname, boolean validated) {
1932 try {
1933 mHandler.sendMessage(mHandler.obtainMessage(
1934 EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
1935 new PrivateDnsValidationUpdate(netId,
1936 InetAddress.parseNumericAddress(ipAddress),
1937 hostname, validated)));
1938 } catch (IllegalArgumentException e) {
1939 loge("Error parsing ip address in validation event");
1940 }
1941 }
Chiachang Wang7a70a7e2018-11-27 18:00:05 +08001942
1943 @Override
1944 public void onDnsEvent(int netId, int eventType, int returnCode, String hostname,
1945 String[] ipAddresses, int ipAddressesCount, long timestamp, int uid) {
1946 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
1947 // Netd event only allow registrants from system. Each NetworkMonitor thread is under
1948 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
1949 // event callback for certain nai. e.g. cellular. Register here to pass to
1950 // NetworkMonitor instead.
Remi NGUYEN VANd68c0252019-02-04 10:25:11 +09001951 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allow one
1952 // callback from each caller type. Need to re-factor NetdEventListenerService to allow
1953 // multiple NetworkMonitor registrants.
Chiachang Wang7a70a7e2018-11-27 18:00:05 +08001954 if (nai != null && nai.satisfies(mDefaultRequest)) {
Lorenzo Colittiac955b32019-05-31 15:41:29 +09001955 nai.networkMonitor().notifyDnsResponse(returnCode);
Chiachang Wang7a70a7e2018-11-27 18:00:05 +08001956 }
1957 }
Lorenzo Colitti6998fa82019-01-08 10:04:25 +09001958
1959 @Override
1960 public void onNat64PrefixEvent(int netId, boolean added,
1961 String prefixString, int prefixLength) {
1962 mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength));
1963 }
dalyk7301aa42018-03-05 12:42:22 -05001964 };
1965
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09001966 private void registerNetdEventCallback() {
1967 final IIpConnectivityMetrics ipConnectivityMetrics = mDeps.getIpConnectivityMetrics();
Chalard Jean4133a122018-06-04 13:33:12 +09001968 if (ipConnectivityMetrics == null) {
dalyk7301aa42018-03-05 12:42:22 -05001969 Slog.wtf(TAG, "Missing IIpConnectivityMetrics");
Chalard Jean4133a122018-06-04 13:33:12 +09001970 return;
dalyk7301aa42018-03-05 12:42:22 -05001971 }
1972
1973 try {
Chalard Jean4133a122018-06-04 13:33:12 +09001974 ipConnectivityMetrics.addNetdEventCallback(
dalyk7301aa42018-03-05 12:42:22 -05001975 INetdEventCallback.CALLBACK_CALLER_CONNECTIVITY_SERVICE,
1976 mNetdEventCallback);
1977 } catch (Exception e) {
1978 loge("Error registering netd callback: " + e);
1979 }
1980 }
1981
Jeff Sharkey75d31892018-01-18 22:01:59 +09001982 private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001983 @Override
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001984 public void onUidRulesChanged(int uid, int uidRules) {
junyulai05986c62018-08-07 19:50:45 +08001985 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001986 }
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001987 @Override
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08001988 public void onRestrictBackgroundChanged(boolean restrictBackground) {
junyulai05986c62018-08-07 19:50:45 +08001989 // caller is NPMS, since we only register with them
1990 if (LOGD_BLOCKED_NETWORKINFO) {
1991 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
1992 }
1993 mHandler.sendMessage(mHandler.obtainMessage(
1994 EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08001995 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07001996 };
1997
junyulai05986c62018-08-07 19:50:45 +08001998 void handleUidRulesChanged(int uid, int newRules) {
1999 // skip update when we've already applied rules
2000 final int oldRules = mUidRules.get(uid, RULE_NONE);
2001 if (oldRules == newRules) return;
2002
2003 maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
2004
2005 if (newRules == RULE_NONE) {
2006 mUidRules.delete(uid);
2007 } else {
2008 mUidRules.put(uid, newRules);
2009 }
2010 }
2011
2012 void handleRestrictBackgroundChanged(boolean restrictBackground) {
2013 if (mRestrictBackground == restrictBackground) return;
2014
2015 for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
2016 final boolean curMetered = nai.networkCapabilities.isMetered();
2017 maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
2018 restrictBackground);
2019 }
2020
2021 mRestrictBackground = restrictBackground;
2022 }
2023
2024 private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
2025 boolean isBackgroundRestricted) {
2026 synchronized (mVpns) {
2027 final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
2028 // Because the return value of this function depends on the list of UIDs the
2029 // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
2030 // list all state depending on the return value of this function has to be recomputed.
2031 // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
2032 // send the necessary onBlockedStatusChanged callbacks.
junyulai8ed89152018-10-25 10:56:17 +08002033 if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
junyulai05986c62018-08-07 19:50:45 +08002034 return true;
2035 }
2036 }
2037
Chalard Jeanafdecd52019-09-26 18:03:47 +09002038 return NetworkPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
junyulai05986c62018-08-07 19:50:45 +08002039 isNetworkMetered, isBackgroundRestricted);
2040 }
2041
Robin Lee3b3dd942015-05-12 18:14:58 +01002042 /**
2043 * Require that the caller is either in the same user or has appropriate permission to interact
2044 * across users.
2045 *
2046 * @param userId Target user for whatever operation the current IPC is supposed to perform.
2047 */
2048 private void enforceCrossUserPermission(int userId) {
2049 if (userId == UserHandle.getCallingUserId()) {
2050 // Not a cross-user call.
2051 return;
2052 }
2053 mContext.enforceCallingOrSelfPermission(
2054 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2055 "ConnectivityService");
2056 }
2057
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002058 private boolean checkAnyPermissionOf(String... permissions) {
Lorenzo Colittif5845d12018-10-09 18:55:11 +09002059 for (String permission : permissions) {
2060 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002061 return true;
Lorenzo Colittif5845d12018-10-09 18:55:11 +09002062 }
2063 }
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002064 return false;
2065 }
2066
paulhu3d67f532019-03-22 16:35:06 +08002067 private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
2068 for (String permission : permissions) {
2069 if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
2070 return true;
2071 }
2072 }
2073 return false;
2074 }
2075
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002076 private void enforceAnyPermissionOf(String... permissions) {
2077 if (!checkAnyPermissionOf(permissions)) {
2078 throw new SecurityException("Requires one of the following permissions: "
2079 + String.join(", ", permissions) + ".");
2080 }
Lorenzo Colittif5845d12018-10-09 18:55:11 +09002081 }
2082
Paul Jensen7ccd3df2014-08-29 09:54:01 -04002083 private void enforceInternetPermission() {
2084 mContext.enforceCallingOrSelfPermission(
2085 android.Manifest.permission.INTERNET,
2086 "ConnectivityService");
2087 }
2088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002089 private void enforceAccessPermission() {
Robert Greenwalt86e9e552009-07-16 17:21:39 -07002090 mContext.enforceCallingOrSelfPermission(
2091 android.Manifest.permission.ACCESS_NETWORK_STATE,
2092 "ConnectivityService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
2094
2095 private void enforceChangePermission() {
Lorenzo Colittid5427052015-10-15 16:29:00 +09002096 ConnectivityManager.enforceChangePermission(mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 }
2098
Charles He36738632017-05-15 17:07:18 +01002099 private void enforceSettingsPermission() {
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002100 enforceAnyPermissionOf(
Charles He36738632017-05-15 17:07:18 +01002101 android.Manifest.permission.NETWORK_SETTINGS,
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002102 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Charles He36738632017-05-15 17:07:18 +01002103 }
2104
paulhu59148b72019-08-12 16:25:11 +08002105 private void enforceNetworkFactoryPermission() {
Automerger Merge Worker8a8e8a12020-03-04 18:04:01 +00002106 enforceAnyPermissionOf(
paulhu59148b72019-08-12 16:25:11 +08002107 android.Manifest.permission.NETWORK_FACTORY,
Automerger Merge Worker8a8e8a12020-03-04 18:04:01 +00002108 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
paulhu59148b72019-08-12 16:25:11 +08002109 }
2110
Aaron Huang7dcb8182020-04-17 05:11:01 +00002111 private void enforceNetworkFactoryOrSettingsPermission() {
2112 enforceAnyPermissionOf(
2113 android.Manifest.permission.NETWORK_SETTINGS,
2114 android.Manifest.permission.NETWORK_FACTORY,
2115 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2116 }
2117
2118 private void enforceNetworkFactoryOrTestNetworksPermission() {
2119 enforceAnyPermissionOf(
2120 android.Manifest.permission.MANAGE_TEST_NETWORKS,
2121 android.Manifest.permission.NETWORK_FACTORY,
2122 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2123 }
2124
Chalard Jeanb552c462018-02-21 18:43:54 +09002125 private boolean checkSettingsPermission() {
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002126 return checkAnyPermissionOf(
2127 android.Manifest.permission.NETWORK_SETTINGS,
2128 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Chalard Jeanb552c462018-02-21 18:43:54 +09002129 }
2130
2131 private boolean checkSettingsPermission(int pid, int uid) {
2132 return PERMISSION_GRANTED == mContext.checkPermission(
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002133 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
2134 || PERMISSION_GRANTED == mContext.checkPermission(
2135 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
Chalard Jeanb552c462018-02-21 18:43:54 +09002136 }
2137
Pavel Grafova462bcb2019-01-25 08:50:06 +00002138 private void enforceControlAlwaysOnVpnPermission() {
2139 mContext.enforceCallingOrSelfPermission(
2140 android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
2141 "ConnectivityService");
2142 }
2143
paulhu59148b72019-08-12 16:25:11 +08002144 private void enforceNetworkStackOrSettingsPermission() {
2145 enforceAnyPermissionOf(
2146 android.Manifest.permission.NETWORK_SETTINGS,
2147 android.Manifest.permission.NETWORK_STACK,
2148 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2149 }
2150
Lorenzo Colittif5845d12018-10-09 18:55:11 +09002151 private void enforceNetworkStackSettingsOrSetup() {
2152 enforceAnyPermissionOf(
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002153 android.Manifest.permission.NETWORK_SETTINGS,
2154 android.Manifest.permission.NETWORK_SETUP_WIZARD,
Pavel Grafova462bcb2019-01-25 08:50:06 +00002155 android.Manifest.permission.NETWORK_STACK,
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002156 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Pavel Grafova462bcb2019-01-25 08:50:06 +00002157 }
2158
Edward Savage-Jonesaffb2292019-11-26 13:18:08 +01002159 private void enforceAirplaneModePermission() {
2160 enforceAnyPermissionOf(
2161 android.Manifest.permission.NETWORK_AIRPLANE_MODE,
2162 android.Manifest.permission.NETWORK_SETTINGS,
2163 android.Manifest.permission.NETWORK_SETUP_WIZARD,
2164 android.Manifest.permission.NETWORK_STACK,
2165 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2166 }
2167
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07002168 private boolean checkNetworkStackPermission() {
Remi NGUYEN VANdd29f202019-01-31 16:42:12 +09002169 return checkAnyPermissionOf(
2170 android.Manifest.permission.NETWORK_STACK,
2171 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07002172 }
2173
Cody Kestinga75e26b2020-01-05 14:06:39 -08002174 private boolean checkNetworkStackPermission(int pid, int uid) {
2175 return checkAnyPermissionOf(pid, uid,
2176 android.Manifest.permission.NETWORK_STACK,
2177 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2178 }
2179
paulhu3d67f532019-03-22 16:35:06 +08002180 private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
2181 return checkAnyPermissionOf(pid, uid,
2182 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
Chalard Jean3b2a81b2020-04-13 19:10:13 +00002183 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
2184 android.Manifest.permission.NETWORK_SETTINGS);
paulhu3d67f532019-03-22 16:35:06 +08002185 }
2186
Hugo Benichi514da602016-07-19 15:59:27 +09002187 private void enforceConnectivityRestrictedNetworksPermission() {
2188 try {
2189 mContext.enforceCallingOrSelfPermission(
2190 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
2191 "ConnectivityService");
2192 return;
2193 } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
paulhu59148b72019-08-12 16:25:11 +08002194 // TODO: Remove this fallback check after all apps have declared
2195 // CONNECTIVITY_USE_RESTRICTED_NETWORKS.
2196 mContext.enforceCallingOrSelfPermission(
2197 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2198 "ConnectivityService");
Hugo Benichi514da602016-07-19 15:59:27 +09002199 }
2200
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09002201 private void enforceKeepalivePermission() {
Lorenzo Colitti7914ce52015-09-08 13:21:48 +09002202 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09002203 }
2204
Lorenzo Colitti18660282016-07-04 12:55:44 +09002205 // Public because it's used by mLockdownTracker.
Jeff Sharkey69ddab42012-08-25 00:05:46 -07002206 public void sendConnectedBroadcast(NetworkInfo info) {
paulhu59148b72019-08-12 16:25:11 +08002207 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey961e3042011-08-29 16:02:57 -07002208 sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
Robert Greenwalt1e9aac22010-09-15 17:36:33 -07002209 }
2210
2211 private void sendInetConditionBroadcast(NetworkInfo info) {
2212 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
2213 }
2214
Wink Saville628b0852011-08-04 15:01:58 -07002215 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
Hugo Benichi69744342017-11-27 10:57:16 +09002216 synchronized (mVpns) {
2217 if (mLockdownTracker != null) {
2218 info = new NetworkInfo(info);
2219 mLockdownTracker.augmentNetworkInfo(info);
2220 }
Jeff Sharkey69ddab42012-08-25 00:05:46 -07002221 }
2222
Robert Greenwalt1e9aac22010-09-15 17:36:33 -07002223 Intent intent = new Intent(bcastType);
Irfan Sheriff9538bdd2012-09-20 09:32:41 -07002224 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
Jeff Sharkey75fbb4b2012-08-06 11:41:50 -07002225 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 if (info.isFailover()) {
2227 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
2228 info.setFailover(false);
2229 }
2230 if (info.getReason() != null) {
2231 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
2232 }
2233 if (info.getExtraInfo() != null) {
Robert Greenwalt86e9e552009-07-16 17:21:39 -07002234 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
2235 info.getExtraInfo());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 }
Robert Greenwaltd7085fc2010-09-08 15:24:47 -07002237 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
Wink Saville628b0852011-08-04 15:01:58 -07002238 return intent;
2239 }
2240
2241 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
2242 sendStickyBroadcast(makeGeneralIntent(info, bcastType));
2243 }
2244
Ashish Sharma0535a9f2014-03-12 18:42:23 -07002245 private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
Haoyu Baidb3c8672012-06-20 14:29:57 -07002246 Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
2247 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
2248 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
Ashish Sharma0535a9f2014-03-12 18:42:23 -07002249 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
Dianne Hackbornfd8bf5c2012-09-04 18:48:37 -07002250 final long ident = Binder.clearCallingIdentity();
2251 try {
2252 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
2253 RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null);
2254 } finally {
2255 Binder.restoreCallingIdentity(ident);
2256 }
Haoyu Baidb3c8672012-06-20 14:29:57 -07002257 }
2258
Mike Lockwood0f79b542009-08-14 14:18:49 -04002259 private void sendStickyBroadcast(Intent intent) {
Hugo Benichi20035e02017-04-26 14:53:28 +09002260 synchronized (this) {
Chalard Jeanb9d45fd2018-06-08 14:24:49 +09002261 if (!mSystemReady
2262 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08002263 mInitialBroadcast = new Intent(intent);
Mike Lockwood0f79b542009-08-14 14:18:49 -04002264 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08002265 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09002266 if (VDBG) {
Jeff Sharkey961e3042011-08-29 16:02:57 -07002267 log("sendStickyBroadcast: action=" + intent.getAction());
Wink Saville628b0852011-08-04 15:01:58 -07002268 }
2269
Dianne Hackborne0e413e2015-12-09 17:22:26 -08002270 Bundle options = null;
Dianne Hackbornfd8bf5c2012-09-04 18:48:37 -07002271 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002272 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
Robert Greenwalte94a6ff2015-09-01 08:23:04 -07002273 final NetworkInfo ni = intent.getParcelableExtra(
2274 ConnectivityManager.EXTRA_NETWORK_INFO);
Automerger Merge Workerd40f64b2020-03-19 02:48:22 +00002275 final BroadcastOptions opts = BroadcastOptions.makeBasic();
2276 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
2277 options = opts.toBundle();
Chalard Jean587758b2019-11-29 16:41:50 +09002278 final IBatteryStats bs = mDeps.getBatteryStatsService();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002279 try {
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002280 bs.noteConnectivityChanged(intent.getIntExtra(
2281 ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
Chalard Jean4133a122018-06-04 13:33:12 +09002282 ni.getState().toString());
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002283 } catch (RemoteException e) {
2284 }
Chad Brubakerac925012018-03-08 10:37:09 -08002285 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002286 }
Dianne Hackbornfd8bf5c2012-09-04 18:48:37 -07002287 try {
Dianne Hackborne0e413e2015-12-09 17:22:26 -08002288 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL, options);
Dianne Hackbornfd8bf5c2012-09-04 18:48:37 -07002289 } finally {
2290 Binder.restoreCallingIdentity(ident);
2291 }
Mike Lockwood0f79b542009-08-14 14:18:49 -04002292 }
2293 }
2294
Remi NGUYEN VANbb592532019-06-20 18:29:36 +09002295 /**
2296 * Called when the system is ready and ConnectivityService can initialize remaining components.
2297 */
2298 @VisibleForTesting
2299 public void systemReady() {
paulhuf2d73702019-11-19 17:55:31 +08002300 // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady
2301 // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be
2302 // populated first to ensure that listening network request which is sent by
2303 // MultipathPolicyTracker won't be added NET_CAPABILITY_FOREGROUND capability.
2304 mPermissionMonitor.startMonitoring();
Chalard Jean655ad152018-06-08 12:47:42 +09002305 mProxyTracker.loadGlobalProxy();
dalyk7301aa42018-03-05 12:42:22 -05002306 registerNetdEventCallback();
Wink Saville948282b2013-08-29 08:55:16 -07002307
Hugo Benichi20035e02017-04-26 14:53:28 +09002308 synchronized (this) {
Mike Lockwood0f79b542009-08-14 14:18:49 -04002309 mSystemReady = true;
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08002310 if (mInitialBroadcast != null) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07002311 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08002312 mInitialBroadcast = null;
Mike Lockwood0f79b542009-08-14 14:18:49 -04002313 }
2314 }
Jeff Sharkey69ddab42012-08-25 00:05:46 -07002315
Robin Lee244ce8e2016-01-05 18:03:46 +00002316 // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
2317 // for user to unlock device too.
2318 updateLockdownVpn();
Robert Greenwaltfb68f8f2014-08-13 13:43:32 -07002319
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07002320 // Create network requests for always-on networks.
2321 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
Erik Klineda4bfa82015-04-30 12:58:40 +09002322
Robert Greenwaltfb68f8f2014-08-13 13:43:32 -07002323 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 }
2325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 /**
Robert Greenwalt7b816022014-04-18 15:25:25 -07002327 * Setup data activity tracking for the given network.
Haoyu Bai04124232012-06-28 15:26:19 -07002328 *
2329 * Every {@code setupDataActivityTracking} should be paired with a
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002330 * {@link #removeDataActivityTracking} for cleanup.
Haoyu Bai04124232012-06-28 15:26:19 -07002331 */
Robert Greenwalt7b816022014-04-18 15:25:25 -07002332 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
2333 final String iface = networkAgent.linkProperties.getInterfaceName();
Haoyu Bai04124232012-06-28 15:26:19 -07002334
2335 final int timeout;
Chalard Jeanafdecd52019-09-26 18:03:47 +09002336 final int type;
Haoyu Bai04124232012-06-28 15:26:19 -07002337
Robert Greenwalt7b816022014-04-18 15:25:25 -07002338 if (networkAgent.networkCapabilities.hasTransport(
2339 NetworkCapabilities.TRANSPORT_CELLULAR)) {
Jeff Brownbf6f6f92012-09-25 15:03:20 -07002340 timeout = Settings.Global.getInt(mContext.getContentResolver(),
2341 Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
Adam Lesinskied6160d2015-08-18 11:47:07 -07002342 10);
Haoyu Bai04124232012-06-28 15:26:19 -07002343 type = ConnectivityManager.TYPE_MOBILE;
Robert Greenwalt7b816022014-04-18 15:25:25 -07002344 } else if (networkAgent.networkCapabilities.hasTransport(
2345 NetworkCapabilities.TRANSPORT_WIFI)) {
Jeff Brownbf6f6f92012-09-25 15:03:20 -07002346 timeout = Settings.Global.getInt(mContext.getContentResolver(),
2347 Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
Adam Lesinski06f46cb2015-06-23 13:42:53 -07002348 15);
Robert Greenwalt7b816022014-04-18 15:25:25 -07002349 type = ConnectivityManager.TYPE_WIFI;
Haoyu Bai04124232012-06-28 15:26:19 -07002350 } else {
Chalard Jeanafdecd52019-09-26 18:03:47 +09002351 return; // do not track any other networks
Haoyu Bai04124232012-06-28 15:26:19 -07002352 }
2353
Chalard Jeanafdecd52019-09-26 18:03:47 +09002354 if (timeout > 0 && iface != null) {
Haoyu Bai04124232012-06-28 15:26:19 -07002355 try {
Luke Huang4e25ec62018-09-27 16:58:23 +08002356 mNMS.addIdleTimer(iface, timeout, type);
Robert Greenwaltd9cb2f32014-03-19 14:26:28 -07002357 } catch (Exception e) {
2358 // You shall not crash!
2359 loge("Exception in setupDataActivityTracking " + e);
Haoyu Bai04124232012-06-28 15:26:19 -07002360 }
2361 }
2362 }
2363
2364 /**
2365 * Remove data activity tracking when network disconnects.
2366 */
Robert Greenwalt7b816022014-04-18 15:25:25 -07002367 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
2368 final String iface = networkAgent.linkProperties.getInterfaceName();
2369 final NetworkCapabilities caps = networkAgent.networkCapabilities;
Haoyu Bai04124232012-06-28 15:26:19 -07002370
Robert Greenwalt7b816022014-04-18 15:25:25 -07002371 if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
2372 caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
Haoyu Bai04124232012-06-28 15:26:19 -07002373 try {
Chalard Jean4d660112018-06-04 16:52:49 +09002374 // the call fails silently if no idle timer setup for this interface
Luke Huang4e25ec62018-09-27 16:58:23 +08002375 mNMS.removeIdleTimer(iface);
Robert Greenwaltd9cb2f32014-03-19 14:26:28 -07002376 } catch (Exception e) {
2377 loge("Exception in removeDataActivityTracking " + e);
Haoyu Bai04124232012-06-28 15:26:19 -07002378 }
2379 }
2380 }
2381
2382 /**
Chiachang Wanga6093042018-09-28 22:42:48 +08002383 * Update data activity tracking when network state is updated.
2384 */
2385 private void updateDataActivityTracking(NetworkAgentInfo newNetwork,
2386 NetworkAgentInfo oldNetwork) {
2387 if (newNetwork != null) {
2388 setupDataActivityTracking(newNetwork);
2389 }
2390 if (oldNetwork != null) {
2391 removeDataActivityTracking(oldNetwork);
2392 }
2393 }
2394 /**
Chalard Jean4d660112018-06-04 16:52:49 +09002395 * Reads the network specific MTU size from resources.
sy.yun9d9b74a2013-09-02 05:24:09 +09002396 * and set it on it's iface.
2397 */
Robert Greenwalt7b816022014-04-18 15:25:25 -07002398 private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
2399 final String iface = newLp.getInterfaceName();
2400 final int mtu = newLp.getMtu();
Pierre Imai54f0d9e2016-02-08 16:01:40 +09002401 if (oldLp == null && mtu == 0) {
2402 // Silently ignore unset MTU value.
2403 return;
2404 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07002405 if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
2406 if (VDBG) log("identical MTU - not setting");
2407 return;
2408 }
paulhud9736de2019-03-08 16:35:20 +08002409 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09002410 if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
Robert Greenwalt7b816022014-04-18 15:25:25 -07002411 return;
2412 }
sy.yun9d9b74a2013-09-02 05:24:09 +09002413
w1997615afd812014-08-05 15:18:11 -07002414 // Cannot set MTU without interface name
2415 if (TextUtils.isEmpty(iface)) {
2416 loge("Setting MTU size with null iface.");
2417 return;
2418 }
2419
Robert Greenwalt7b816022014-04-18 15:25:25 -07002420 try {
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09002421 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
Luke Huang4e25ec62018-09-27 16:58:23 +08002422 mNMS.setMtu(iface, mtu);
Robert Greenwalt7b816022014-04-18 15:25:25 -07002423 } catch (Exception e) {
2424 Slog.e(TAG, "exception in setMtu()" + e);
2425 }
2426 }
Irfan Sheriffd649c122010-06-09 15:39:36 -07002427
Chenbo Feng7f14dbc2018-11-08 17:36:21 -08002428 @VisibleForTesting
2429 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
Paul Jensend7b6ca92015-05-13 14:05:12 -04002430
lucaslin041a1af2018-11-28 19:27:52 +08002431 private void updateTcpBufferSizes(String tcpBufferSizes) {
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07002432 String[] values = null;
2433 if (tcpBufferSizes != null) {
2434 values = tcpBufferSizes.split(",");
2435 }
2436
2437 if (values == null || values.length != 6) {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07002438 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07002439 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
2440 values = tcpBufferSizes.split(",");
2441 }
2442
2443 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
2444
2445 try {
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09002446 if (VDBG || DDBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes);
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07002447
Chenbo Feng7f14dbc2018-11-08 17:36:21 -08002448 String rmemValues = String.join(" ", values[0], values[1], values[2]);
2449 String wmemValues = String.join(" ", values[3], values[4], values[5]);
2450 mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07002451 mCurrentTcpBufferSizes = tcpBufferSizes;
Chenbo Feng7f14dbc2018-11-08 17:36:21 -08002452 } catch (RemoteException | ServiceSpecificException e) {
Robert Greenwalt3f05bf42014-08-06 12:00:25 -07002453 loge("Can't set TCP buffer sizes:" + e);
Irfan Sheriffd649c122010-06-09 15:39:36 -07002454 }
JP Abgrall32d1ac4d2014-02-21 12:05:20 -08002455
JP Abgrall32d1ac4d2014-02-21 12:05:20 -08002456 Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
Lorenzo Colitti42cdf572017-03-21 18:54:11 +09002457 Settings.Global.TCP_DEFAULT_INIT_RWND,
2458 mSystemProperties.getInt("net.tcp.default_init_rwnd", 0));
JP Abgrall32d1ac4d2014-02-21 12:05:20 -08002459 final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
2460 if (rwndValue != 0) {
Lorenzo Colitti42cdf572017-03-21 18:54:11 +09002461 mSystemProperties.set(sysctlKey, rwndValue.toString());
JP Abgrall32d1ac4d2014-02-21 12:05:20 -08002462 }
Irfan Sheriffd649c122010-06-09 15:39:36 -07002463 }
2464
Robert Greenwalt562cc542014-05-15 18:07:26 -07002465 @Override
2466 public int getRestoreDefaultNetworkDelay(int networkType) {
Lorenzo Colitti42cdf572017-03-21 18:54:11 +09002467 String restoreDefaultNetworkDelayStr = mSystemProperties.get(
Robert Greenwalt42acef32009-08-12 16:08:25 -07002468 NETWORK_RESTORE_DELAY_PROP_NAME);
2469 if(restoreDefaultNetworkDelayStr != null &&
2470 restoreDefaultNetworkDelayStr.length() != 0) {
2471 try {
Narayan Kamatha09b4d22016-04-15 18:32:45 +01002472 return Integer.parseInt(restoreDefaultNetworkDelayStr);
Robert Greenwalt42acef32009-08-12 16:08:25 -07002473 } catch (NumberFormatException e) {
2474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 }
Robert Greenwaltf2102f72011-05-03 19:02:44 -07002476 // if the system property isn't set, use the value for the apn type
2477 int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2478
2479 if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2480 (mNetConfigs[networkType] != null)) {
2481 ret = mNetConfigs[networkType].restoreTime;
2482 }
2483 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 }
2485
Lorenzo Colitti5ff640d2016-03-03 17:53:46 +09002486 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
2487 final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
2488 final long DIAG_TIME_MS = 5000;
Hugo Benichia2a917c2018-09-03 08:19:02 +09002489 for (NetworkAgentInfo nai : networksSortedById()) {
Lorenzo Colitti5ff640d2016-03-03 17:53:46 +09002490 // Start gathering diagnostic information.
2491 netDiags.add(new NetworkDiagnostics(
2492 nai.network,
2493 new LinkProperties(nai.linkProperties), // Must be a copy.
2494 DIAG_TIME_MS));
2495 }
2496
2497 for (NetworkDiagnostics netDiag : netDiags) {
2498 pw.println();
2499 netDiag.waitForMeasurements();
2500 netDiag.dump(pw);
2501 }
2502 }
2503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 @Override
Chalard Jeanafdecd52019-09-26 18:03:47 +09002505 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
2506 @Nullable String[] args) {
Vishnu Nair5c010902017-10-26 10:08:50 -07002507 PriorityDump.dump(mPriorityDumper, fd, writer, args);
2508 }
2509
2510 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002511 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002512 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Vishnu Nair5c010902017-10-26 10:08:50 -07002513 if (asProto) return;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002514
Erik Kline3f8306b2018-05-01 16:51:44 +09002515 if (ArrayUtils.contains(args, DIAG_ARG)) {
Lorenzo Colitti5ff640d2016-03-03 17:53:46 +09002516 dumpNetworkDiagnostics(pw);
2517 return;
Hugo Benichi14683812018-09-03 08:32:56 +09002518 } else if (ArrayUtils.contains(args, NETWORK_ARG)) {
2519 dumpNetworks(pw);
2520 return;
2521 } else if (ArrayUtils.contains(args, REQUEST_ARG)) {
2522 dumpNetworkRequests(pw);
2523 return;
Lorenzo Colitti5ff640d2016-03-03 17:53:46 +09002524 }
Erik Kline379747a2015-06-05 17:47:34 +09002525
Lorenzo Colitti6654b082020-01-10 00:40:28 +09002526 pw.print("NetworkProviders for:");
2527 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
2528 pw.print(" " + npi.name);
Robert Greenwalta67be032014-05-16 15:49:14 -07002529 }
Lorenzo Colittie3805462015-06-03 11:18:24 +09002530 pw.println();
Robert Greenwalta67be032014-05-16 15:49:14 -07002531 pw.println();
2532
Paul Jensen85cf78e2015-06-25 13:25:07 -04002533 final NetworkAgentInfo defaultNai = getDefaultNetwork();
Robert Greenwaltc9c90c72014-05-13 15:36:27 -07002534 pw.print("Active default network: ");
2535 if (defaultNai == null) {
2536 pw.println("none");
2537 } else {
2538 pw.println(defaultNai.network.netId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 }
Dianne Hackborn77b987f2014-02-26 16:20:52 -08002540 pw.println();
2541
Robert Greenwaltc9c90c72014-05-13 15:36:27 -07002542 pw.println("Current Networks:");
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002543 pw.increaseIndent();
Hugo Benichi14683812018-09-03 08:32:56 +09002544 dumpNetworks(pw);
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002545 pw.decreaseIndent();
Robert Greenwaltc9c90c72014-05-13 15:36:27 -07002546 pw.println();
Robert Greenwaltb9285352009-12-21 18:24:07 -08002547
junyulai05986c62018-08-07 19:50:45 +08002548 pw.print("Restrict background: ");
2549 pw.println(mRestrictBackground);
2550 pw.println();
2551
2552 pw.println("Status for known UIDs:");
2553 pw.increaseIndent();
2554 final int size = mUidRules.size();
2555 for (int i = 0; i < size; i++) {
2556 // Don't crash if the array is modified while dumping in bugreports.
2557 try {
2558 final int uid = mUidRules.keyAt(i);
2559 final int uidRules = mUidRules.get(uid, RULE_NONE);
2560 pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
2561 } catch (ArrayIndexOutOfBoundsException e) {
2562 pw.println(" ArrayIndexOutOfBoundsException");
2563 } catch (ConcurrentModificationException e) {
2564 pw.println(" ConcurrentModificationException");
2565 }
2566 }
2567 pw.println();
2568 pw.decreaseIndent();
2569
Robert Greenwaltc9c90c72014-05-13 15:36:27 -07002570 pw.println("Network Requests:");
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002571 pw.increaseIndent();
Hugo Benichi14683812018-09-03 08:32:56 +09002572 dumpNetworkRequests(pw);
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002573 pw.decreaseIndent();
Hugo Benichi14683812018-09-03 08:32:56 +09002574 pw.println();
Robert Greenwalt2a091d72010-02-11 18:18:40 -08002575
Robert Greenwaltd49ac332014-07-30 16:31:24 -07002576 mLegacyTypeTracker.dump(pw);
Robert Greenwaltd49ac332014-07-30 16:31:24 -07002577
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09002578 pw.println();
markchien0df2ebc42019-09-30 14:40:57 +08002579 mKeepaliveTracker.dump(pw);
Robert Greenwalt4e8dfef2010-09-20 14:35:25 -07002580
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09002581 pw.println();
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09002582 dumpAvoidBadWifiSettings(pw);
Lorenzo Colitti5ff640d2016-03-03 17:53:46 +09002583
Lorenzo Colittid260ef22018-01-24 17:35:07 +09002584 pw.println();
2585 mMultipathPolicyTracker.dump(pw);
2586
Erik Kline3f8306b2018-05-01 16:51:44 +09002587 if (ArrayUtils.contains(args, SHORT_ARG) == false) {
Robert Greenwalt22b4c6a2015-06-23 15:03:33 -07002588 pw.println();
Erik Kline7523eb32015-07-09 18:24:03 +09002589 pw.println("mNetworkRequestInfoLogs (most recent first):");
2590 pw.increaseIndent();
2591 mNetworkRequestInfoLogs.reverseDump(fd, pw, args);
2592 pw.decreaseIndent();
Hugo Benichic2ae2872016-07-11 11:05:12 +09002593
2594 pw.println();
2595 pw.println("mNetworkInfoBlockingLogs (most recent first):");
2596 pw.increaseIndent();
2597 mNetworkInfoBlockingLogs.reverseDump(fd, pw, args);
2598 pw.decreaseIndent();
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09002599
2600 pw.println();
2601 pw.println("NetTransition WakeLock activity (most recent first):");
2602 pw.increaseIndent();
Hugo Benichi26bcfa12017-09-05 13:25:07 +09002603 pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
2604 pw.println("total releases: " + mTotalWakelockReleases);
2605 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
2606 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
2607 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
2608 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
2609 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
2610 }
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09002611 mWakelockLogs.reverseDump(fd, pw, args);
Nathan Haroldfd45e5f2018-07-30 13:38:01 -07002612
2613 pw.println();
2614 pw.println("bandwidth update requests (by uid):");
2615 pw.increaseIndent();
2616 synchronized (mBandwidthRequests) {
2617 for (int i = 0; i < mBandwidthRequests.size(); i++) {
2618 pw.println("[" + mBandwidthRequests.keyAt(i)
2619 + "]: " + mBandwidthRequests.valueAt(i));
2620 }
2621 }
2622 pw.decreaseIndent();
2623
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09002624 pw.decreaseIndent();
Robert Greenwalt22b4c6a2015-06-23 15:03:33 -07002625 }
Remi NGUYEN VANa25379f2019-02-18 11:20:28 +09002626
2627 pw.println();
2628 pw.println("NetworkStackClient logs:");
2629 pw.increaseIndent();
2630 NetworkStackClient.getInstance().dump(pw);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00002631 pw.decreaseIndent();
2632
2633 pw.println();
2634 pw.println("Permission Monitor:");
2635 pw.increaseIndent();
2636 mPermissionMonitor.dump(pw);
2637 pw.decreaseIndent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 }
2639
Hugo Benichi14683812018-09-03 08:32:56 +09002640 private void dumpNetworks(IndentingPrintWriter pw) {
2641 for (NetworkAgentInfo nai : networksSortedById()) {
2642 pw.println(nai.toString());
2643 pw.increaseIndent();
2644 pw.println(String.format(
2645 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
2646 nai.numForegroundNetworkRequests(),
2647 nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
2648 nai.numBackgroundNetworkRequests(),
2649 nai.numNetworkRequests()));
2650 pw.increaseIndent();
2651 for (int i = 0; i < nai.numNetworkRequests(); i++) {
2652 pw.println(nai.requestAt(i).toString());
2653 }
2654 pw.decreaseIndent();
2655 pw.println("Lingered:");
2656 pw.increaseIndent();
2657 nai.dumpLingerTimers(pw);
2658 pw.decreaseIndent();
2659 pw.decreaseIndent();
2660 }
2661 }
2662
2663 private void dumpNetworkRequests(IndentingPrintWriter pw) {
2664 for (NetworkRequestInfo nri : requestsSortedById()) {
2665 pw.println(nri.toString());
2666 }
2667 }
2668
Hugo Benichia2a917c2018-09-03 08:19:02 +09002669 /**
2670 * Return an array of all current NetworkAgentInfos sorted by network id.
2671 */
2672 private NetworkAgentInfo[] networksSortedById() {
2673 NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
2674 networks = mNetworkAgentInfos.values().toArray(networks);
2675 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.netId));
2676 return networks;
2677 }
2678
2679 /**
2680 * Return an array of all current NetworkRequest sorted by request id.
2681 */
2682 private NetworkRequestInfo[] requestsSortedById() {
2683 NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
2684 requests = mNetworkRequests.values().toArray(requests);
2685 Arrays.sort(requests, Comparator.comparingInt(nri -> nri.request.requestId));
2686 return requests;
2687 }
2688
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002689 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
Paul Jensenad50a1f2014-09-05 12:06:44 -04002690 if (nai.network == null) return false;
Sreeram Ramachandran21b5ee32014-11-12 22:31:52 -08002691 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
Robert Greenwalt73ed9d82014-08-19 18:58:04 -07002692 if (officialNai != null && officialNai.equals(nai)) return true;
2693 if (officialNai != null || VDBG) {
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09002694 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
Robert Greenwalt73ed9d82014-08-19 18:58:04 -07002695 " - " + nai);
2696 }
2697 return false;
2698 }
2699
Robert Greenwalt42acef32009-08-12 16:08:25 -07002700 // must be stateless - things change under us.
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07002701 private class NetworkStateTrackerHandler extends Handler {
2702 public NetworkStateTrackerHandler(Looper looper) {
Wink Savillebb08caf2010-09-02 19:23:52 -07002703 super(looper);
2704 }
2705
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002706 private boolean maybeHandleAsyncChannelMessage(Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 switch (msg.what) {
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002708 default:
2709 return false;
Robert Greenwalte049c232014-04-11 15:53:27 -07002710 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
Robert Greenwalt7b816022014-04-18 15:25:25 -07002711 handleAsyncChannelHalfConnect(msg);
2712 break;
2713 }
2714 case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
2715 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2716 if (nai != null) nai.asyncChannel.disconnect();
2717 break;
2718 }
2719 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
2720 handleAsyncChannelDisconnected(msg);
2721 break;
2722 }
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002723 }
2724 return true;
2725 }
2726
2727 private void maybeHandleNetworkAgentMessage(Message msg) {
2728 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2729 if (nai == null) {
2730 if (VDBG) {
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09002731 log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002732 }
2733 return;
2734 }
2735
2736 switch (msg.what) {
Robert Greenwalt7b816022014-04-18 15:25:25 -07002737 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
Chalard Jean09c48e42020-03-25 10:33:55 +00002738 NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
lucasline252a742019-03-12 13:08:03 +08002739 if (networkCapabilities.hasConnectivityManagedCapability()) {
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002740 Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
Robert Greenwalte049c232014-04-11 15:53:27 -07002741 }
Chalard Jean09c48e42020-03-25 10:33:55 +00002742 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
2743 // Make sure the original object is not mutated. NetworkAgent normally
2744 // makes a copy of the capabilities when sending the message through
2745 // the Messenger, but if this ever changes, not making a defensive copy
2746 // here will give attack vectors to clients using this code path.
2747 networkCapabilities = new NetworkCapabilities(networkCapabilities);
Cody Kesting0d8d6ac2020-05-12 18:47:10 +00002748 networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
Chalard Jean09c48e42020-03-25 10:33:55 +00002749 }
Hugo Benichif15b2822016-09-15 18:18:48 +09002750 updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
Robert Greenwalte049c232014-04-11 15:53:27 -07002751 break;
2752 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07002753 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00002754 LinkProperties newLp = (LinkProperties) msg.obj;
2755 processLinkPropertiesFromAgent(nai, newLp);
2756 handleUpdateLinkProperties(nai, newLp);
Robert Greenwalt7b816022014-04-18 15:25:25 -07002757 break;
2758 }
2759 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002760 NetworkInfo info = (NetworkInfo) msg.obj;
Robert Greenwalt7b816022014-04-18 15:25:25 -07002761 updateNetworkInfo(nai, info);
2762 break;
2763 }
Robert Greenwalt55691b82014-05-27 13:20:24 -07002764 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
Automerger Merge Worker3d40f5782020-03-08 06:07:47 +00002765 updateNetworkScore(nai, msg.arg1);
Robert Greenwalt55691b82014-05-27 13:20:24 -07002766 break;
2767 }
Robert Greenwalte73cc462014-09-07 16:50:01 -07002768 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
Lorenzo Colitti091de3f2019-06-04 14:37:26 +09002769 if (nai.everConnected) {
2770 loge("ERROR: cannot call explicitlySelected on already-connected network");
Paul Jensen4b9b2be2014-09-26 10:10:22 -04002771 }
Lorenzo Colittid9696562020-01-12 22:28:37 +09002772 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
2773 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
lucasline252a742019-03-12 13:08:03 +08002774 // Mark the network as temporarily accepting partial connectivity so that it
2775 // will be validated (and possibly become default) even if it only provides
2776 // partial internet access. Note that if user connects to partial connectivity
2777 // and choose "don't ask again", then wifi disconnected by some reasons(maybe
2778 // out of wifi coverage) and if the same wifi is available again, the device
2779 // will auto connect to this wifi even though the wifi has "no internet".
2780 // TODO: Evaluate using a separate setting in IpMemoryStore.
Lorenzo Colittid9696562020-01-12 22:28:37 +09002781 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2);
Robert Greenwalte73cc462014-09-07 16:50:01 -07002782 break;
2783 }
junyulai06835112019-01-03 18:50:15 +08002784 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
2785 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg);
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09002786 break;
2787 }
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002788 }
2789 }
2790
2791 private boolean maybeHandleNetworkMonitorMessage(Message msg) {
2792 switch (msg.what) {
2793 default:
2794 return false;
lucaslin783f2212019-10-22 18:27:33 +08002795 case EVENT_PROBE_STATUS_CHANGED: {
2796 final Integer netId = (Integer) msg.obj;
2797 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
2798 if (nai == null) {
2799 break;
2800 }
2801 final boolean probePrivateDnsCompleted =
2802 ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
2803 final boolean privateDnsBroken =
2804 ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
2805 if (probePrivateDnsCompleted) {
2806 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
2807 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
2808 final int oldScore = nai.getCurrentScore();
2809 updateCapabilities(oldScore, nai, nai.networkCapabilities);
2810 }
2811 // Only show the notification when the private DNS is broken and the
2812 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid.
Lorenzo Colittid9696562020-01-12 22:28:37 +09002813 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) {
lucaslin783f2212019-10-22 18:27:33 +08002814 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN);
2815 }
Lorenzo Colittid9696562020-01-12 22:28:37 +09002816 nai.networkAgentConfig.hasShownBroken = privateDnsBroken;
lucaslin783f2212019-10-22 18:27:33 +08002817 } else if (nai.networkCapabilities.isPrivateDnsBroken()) {
2818 // If probePrivateDnsCompleted is false but nai.networkCapabilities says
2819 // private DNS is broken, it means this network is being reevaluated.
2820 // Either probing private DNS is not necessary any more or it hasn't been
2821 // done yet. In either case, the networkCapabilities should be updated to
2822 // reflect the new status.
2823 nai.networkCapabilities.setPrivateDnsBroken(false);
2824 final int oldScore = nai.getCurrentScore();
2825 updateCapabilities(oldScore, nai, nai.networkCapabilities);
Lorenzo Colittid9696562020-01-12 22:28:37 +09002826 nai.networkAgentConfig.hasShownBroken = false;
lucaslin783f2212019-10-22 18:27:33 +08002827 }
2828 break;
2829 }
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09002830 case EVENT_NETWORK_TESTED: {
Cody Kestinga75e26b2020-01-05 14:06:39 -08002831 final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
2832
2833 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId);
Erik Klinea24d4592018-01-11 21:07:29 +09002834 if (nai == null) break;
2835
Cody Kestinga75e26b2020-01-05 14:06:39 -08002836 handleNetworkTested(nai, results.mTestResult,
2837 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl);
Robert Greenwalt7b816022014-04-18 15:25:25 -07002838 break;
2839 }
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09002840 case EVENT_PROVISIONING_NOTIFICATION: {
Lorenzo Colittif6673d02015-05-21 16:17:05 +09002841 final int netId = msg.arg2;
Hugo Benichiab7d2e62017-04-21 15:07:12 +09002842 final boolean visible = toBool(msg.arg1);
Erik Kline736353a2018-03-21 07:18:33 -07002843 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
Calvin Onbe96da12016-10-11 15:10:46 -07002844 // If captive portal status has changed, update capabilities or disconnect.
Paul Jensen3d194ea2015-06-16 14:27:36 -04002845 if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
Hugo Benichif15b2822016-09-15 18:18:48 +09002846 final int oldScore = nai.getCurrentScore();
Paul Jensen3d194ea2015-06-16 14:27:36 -04002847 nai.lastCaptivePortalDetected = visible;
2848 nai.everCaptivePortalDetected |= visible;
Calvin Onbe96da12016-10-11 15:10:46 -07002849 if (nai.lastCaptivePortalDetected &&
2850 Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09002851 if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
Calvin Onbe96da12016-10-11 15:10:46 -07002852 nai.asyncChannel.sendMessage(
2853 NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
2854 teardownUnneededNetwork(nai);
2855 break;
2856 }
Hugo Benichif15b2822016-09-15 18:18:48 +09002857 updateCapabilities(oldScore, nai, nai.networkCapabilities);
Paul Jensen3d194ea2015-06-16 14:27:36 -04002858 }
2859 if (!visible) {
lucaslind2e045e02019-01-24 15:55:30 +08002860 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
lucasline252a742019-03-12 13:08:03 +08002861 // notifications belong to the same network may be cleared unexpectedly.
lucaslind2e045e02019-01-24 15:55:30 +08002862 mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
2863 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
Paul Jensenfdc4e4a2014-07-15 12:07:36 -04002864 } else {
Paul Jensen5df4bec2014-08-25 22:45:39 -04002865 if (nai == null) {
2866 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
2867 break;
2868 }
Lorenzo Colittid9696562020-01-12 22:28:37 +09002869 if (!nai.networkAgentConfig.provisioningNotificationDisabled) {
Lorenzo Colitti5526f9c2016-08-22 16:46:40 +09002870 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
Lorenzo Colittid9696562020-01-12 22:28:37 +09002871 (PendingIntent) msg.obj,
2872 nai.networkAgentConfig.explicitlySelected);
fionaxu1bf6ec22016-05-23 16:33:16 -07002873 }
Paul Jensen869868be2014-05-15 10:33:05 -04002874 }
Paul Jensen869868be2014-05-15 10:33:05 -04002875 break;
2876 }
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09002877 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
Erik Kline736353a2018-03-21 07:18:33 -07002878 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
Erik Klinea24d4592018-01-11 21:07:29 +09002879 if (nai == null) break;
2880
Erik Kline736353a2018-03-21 07:18:33 -07002881 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
Erik Klinea24d4592018-01-11 21:07:29 +09002882 break;
2883 }
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +09002884 case EVENT_CAPPORT_DATA_CHANGED: {
2885 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
2886 if (nai == null) break;
2887 handleCaptivePortalDataUpdate(nai, (CaptivePortalData) msg.obj);
2888 break;
2889 }
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07002890 }
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002891 return true;
2892 }
2893
Cody Kestinga75e26b2020-01-05 14:06:39 -08002894 private void handleNetworkTested(
2895 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
2896 final boolean wasPartial = nai.partialConnectivity;
2897 nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
2898 final boolean partialConnectivityChanged =
2899 (wasPartial != nai.partialConnectivity);
2900
2901 final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
2902 final boolean wasValidated = nai.lastValidated;
2903 final boolean wasDefault = isDefaultNetwork(nai);
Cody Kestinga75e26b2020-01-05 14:06:39 -08002904
2905 if (DBG) {
2906 final String logMsg = !TextUtils.isEmpty(redirectUrl)
2907 ? " with redirect to " + redirectUrl
2908 : "";
Chalard Jeanbf1170c2019-12-10 21:07:02 +09002909 log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
Cody Kestinga75e26b2020-01-05 14:06:39 -08002910 }
2911 if (valid != nai.lastValidated) {
2912 if (wasDefault) {
2913 mDeps.getMetricsLogger()
2914 .defaultNetworkMetrics().logDefaultNetworkValidity(
2915 SystemClock.elapsedRealtime(), valid);
2916 }
2917 final int oldScore = nai.getCurrentScore();
2918 nai.lastValidated = valid;
2919 nai.everValidated |= valid;
2920 updateCapabilities(oldScore, nai, nai.networkCapabilities);
2921 // If score has changed, rebroadcast to NetworkProviders. b/17726566
2922 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
2923 if (valid) {
2924 handleFreshlyValidatedNetwork(nai);
2925 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
2926 // LOST_INTERNET notifications if network becomes valid.
2927 mNotifier.clearNotification(nai.network.netId,
2928 NotificationType.NO_INTERNET);
2929 mNotifier.clearNotification(nai.network.netId,
2930 NotificationType.LOST_INTERNET);
2931 mNotifier.clearNotification(nai.network.netId,
2932 NotificationType.PARTIAL_CONNECTIVITY);
2933 mNotifier.clearNotification(nai.network.netId,
2934 NotificationType.PRIVATE_DNS_BROKEN);
2935 // If network becomes valid, the hasShownBroken should be reset for
2936 // that network so that the notification will be fired when the private
2937 // DNS is broken again.
2938 nai.networkAgentConfig.hasShownBroken = false;
2939 }
2940 } else if (partialConnectivityChanged) {
2941 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
2942 }
2943 updateInetCondition(nai);
2944 // Let the NetworkAgent know the state of its network
2945 Bundle redirectUrlBundle = new Bundle();
2946 redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
2947 // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
2948 nai.asyncChannel.sendMessage(
2949 NetworkAgent.CMD_REPORT_NETWORK_STATUS,
2950 (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
2951 0, redirectUrlBundle);
2952
2953 // If NetworkMonitor detects partial connectivity before
2954 // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
2955 // immediately. Re-notify partial connectivity silently if no internet
2956 // notification already there.
2957 if (!wasPartial && nai.partialConnectivity) {
2958 // Remove delayed message if there is a pending message.
2959 mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
2960 handlePromptUnvalidated(nai.network);
2961 }
2962
2963 if (wasValidated && !nai.lastValidated) {
2964 handleNetworkUnvalidated(nai);
2965 }
2966 }
2967
Calvin Onbe96da12016-10-11 15:10:46 -07002968 private int getCaptivePortalMode() {
2969 return Settings.Global.getInt(mContext.getContentResolver(),
2970 Settings.Global.CAPTIVE_PORTAL_MODE,
2971 Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
2972 }
2973
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09002974 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
2975 switch (msg.what) {
2976 default:
2977 return false;
2978 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
2979 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
2980 if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
2981 handleLingerComplete(nai);
2982 }
2983 break;
2984 }
2985 }
2986 return true;
2987 }
2988
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002989 @Override
2990 public void handleMessage(Message msg) {
Etan Cohenddb720a2019-01-08 12:09:18 -08002991 if (!maybeHandleAsyncChannelMessage(msg)
2992 && !maybeHandleNetworkMonitorMessage(msg)
Remi NGUYEN VANd0658b62020-01-14 19:48:18 +09002993 && !maybeHandleNetworkAgentInfoMessage(msg)) {
Lorenzo Colitti9b0c8fd2016-04-05 17:52:16 +09002994 maybeHandleNetworkAgentMessage(msg);
2995 }
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07002996 }
2997 }
2998
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09002999 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
Chalard Jeand5603302019-05-30 14:58:29 +09003000 private final int mNetId;
3001 private final AutodestructReference<NetworkAgentInfo> mNai;
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003002
3003 private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
Chalard Jeand5603302019-05-30 14:58:29 +09003004 mNetId = nai.network.netId;
Chalard Jeanafdecd52019-09-26 18:03:47 +09003005 mNai = new AutodestructReference<>(nai);
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003006 }
3007
3008 @Override
3009 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
3010 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
Chalard Jeand5603302019-05-30 14:58:29 +09003011 new Pair<>(mNai.getAndDestroy(), networkMonitor)));
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003012 }
3013
3014 @Override
3015 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00003016 // Legacy version of notifyNetworkTestedWithExtras.
3017 // Would only be called if the system has a NetworkStack module older than the
3018 // framework, which does not happen in practice.
Remi NGUYEN VANbf8dcf32020-04-27 08:08:57 +00003019 Slog.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
Cody Kestinga75e26b2020-01-05 14:06:39 -08003020 }
3021
3022 @Override
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00003023 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
Remi NGUYEN VANbf8dcf32020-04-27 08:08:57 +00003024 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
3025 // the same looper so messages will be processed in sequence.
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00003026 final Message msg = mTrackerHandler.obtainMessage(
3027 EVENT_NETWORK_TESTED,
3028 new NetworkTestedResults(
3029 mNetId, p.result, p.timestampMillis, p.redirectUrl));
Cody Kestinga75e26b2020-01-05 14:06:39 -08003030 mTrackerHandler.sendMessage(msg);
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00003031
3032 // Invoke ConnectivityReport generation for this Network test event.
3033 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId);
3034 if (nai == null) return;
3035 final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
3036 ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED,
3037 new ConnectivityReportEvent(p.timestampMillis, nai));
3038
3039 final PersistableBundle extras = new PersistableBundle();
3040 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, p.result);
3041 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded);
3042 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted);
3043
3044 m.setData(new Bundle(extras));
3045 mConnectivityDiagnosticsHandler.sendMessage(m);
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003046 }
3047
3048 @Override
3049 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
3050 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3051 EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
Chalard Jeand5603302019-05-30 14:58:29 +09003052 0, mNetId, PrivateDnsConfig.fromParcel(config)));
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003053 }
3054
3055 @Override
lucaslin783f2212019-10-22 18:27:33 +08003056 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
3057 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3058 EVENT_PROBE_STATUS_CHANGED,
3059 probesCompleted, probesSucceeded, new Integer(mNetId)));
3060 }
3061
3062 @Override
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +09003063 public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
3064 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3065 EVENT_CAPPORT_DATA_CHANGED,
3066 0, mNetId, data));
3067 }
3068
3069 @Override
Remi NGUYEN VAN9c5d9642019-02-07 21:29:57 +09003070 public void showProvisioningNotification(String action, String packageName) {
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003071 final Intent intent = new Intent(action);
Remi NGUYEN VAN9c5d9642019-02-07 21:29:57 +09003072 intent.setPackage(packageName);
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003073
3074 final PendingIntent pendingIntent;
3075 // Only the system server can register notifications with package "android"
3076 final long token = Binder.clearCallingIdentity();
3077 try {
3078 pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
3079 } finally {
3080 Binder.restoreCallingIdentity(token);
3081 }
3082 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
3083 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
Chalard Jeand5603302019-05-30 14:58:29 +09003084 mNetId, pendingIntent));
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003085 }
3086
3087 @Override
3088 public void hideProvisioningNotification() {
3089 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
Chalard Jeand5603302019-05-30 14:58:29 +09003090 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003091 }
Remi NGUYEN VAN1232fe32019-04-05 15:15:48 +09003092
3093 @Override
Remi NGUYEN VAN24d8a332020-04-24 12:19:37 +00003094 public void notifyDataStallSuspected(DataStallReportParcelable p) {
Cody Kesting2fa510c82020-05-18 18:57:14 +00003095 ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
Cody Kesting4f49f142020-01-06 16:55:35 -08003096 }
3097
3098 @Override
Remi NGUYEN VAN1232fe32019-04-05 15:15:48 +09003099 public int getInterfaceVersion() {
3100 return this.VERSION;
3101 }
Paul Trautrimaf2e0822020-01-23 14:55:57 +09003102
3103 @Override
3104 public String getInterfaceHash() {
3105 return this.HASH;
3106 }
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003107 }
3108
Cody Kesting2fa510c82020-05-18 18:57:14 +00003109 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
Cody Kesting56c22b72020-05-22 00:28:02 +00003110 log("Data stall detected with methods: " + p.detectionMethod);
3111
Cody Kesting2fa510c82020-05-18 18:57:14 +00003112 final PersistableBundle extras = new PersistableBundle();
Cody Kesting56c22b72020-05-22 00:28:02 +00003113 int detectionMethod = 0;
3114 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
3115 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
3116 detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
3117 }
3118 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
3119 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
3120 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
3121 p.tcpMetricsCollectionPeriodMillis);
3122 detectionMethod |= DETECTION_METHOD_TCP_METRICS;
Cody Kesting2fa510c82020-05-18 18:57:14 +00003123 }
3124
Automerger Merge Worker42f81352020-05-12 18:48:04 +00003125 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
Cody Kesting2fa510c82020-05-18 18:57:14 +00003126 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
Cody Kesting56c22b72020-05-22 00:28:02 +00003127 p.timestampMillis);
Automerger Merge Worker42f81352020-05-12 18:48:04 +00003128 msg.setData(new Bundle(extras));
3129
3130 // NetworkStateTrackerHandler currently doesn't take any actions based on data
3131 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
3132 // the cost of going through two handlers.
3133 mConnectivityDiagnosticsHandler.sendMessage(msg);
3134 }
3135
Cody Kesting56c22b72020-05-22 00:28:02 +00003136 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
3137 return (p.detectionMethod & detectionMethod) != 0;
3138 }
3139
Lorenzo Colitti80986d92019-03-22 00:28:28 +09003140 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
3141 return isPrivateDnsValidationRequired(nai.networkCapabilities);
Erik Kline736353a2018-03-21 07:18:33 -07003142 }
3143
Erik Klinec6d00222018-06-26 18:53:43 +09003144 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
3145 if (nai == null) return;
3146 // If the Private DNS mode is opportunistic, reprogram the DNS servers
3147 // in order to restart a validation pass from within netd.
3148 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
3149 if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
3150 updateDnses(nai.linkProperties, null, nai.network.netId);
3151 }
3152 }
3153
Erik Klinea24d4592018-01-11 21:07:29 +09003154 private void handlePrivateDnsSettingsChanged() {
3155 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
3156
3157 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
Erik Kline736353a2018-03-21 07:18:33 -07003158 handlePerNetworkPrivateDnsConfig(nai, cfg);
Lorenzo Colitti80986d92019-03-22 00:28:28 +09003159 if (networkRequiresPrivateDnsValidation(nai)) {
dalyk7301aa42018-03-05 12:42:22 -05003160 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3161 }
Erik Klinea24d4592018-01-11 21:07:29 +09003162 }
3163 }
3164
Erik Kline736353a2018-03-21 07:18:33 -07003165 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
3166 // Private DNS only ever applies to networks that might provide
3167 // Internet access and therefore also require validation.
Lorenzo Colitti80986d92019-03-22 00:28:28 +09003168 if (!networkRequiresPrivateDnsValidation(nai)) return;
Erik Klinea24d4592018-01-11 21:07:29 +09003169
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09003170 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
Erik Kline736353a2018-03-21 07:18:33 -07003171 // schedule DNS resolutions. If a DNS resolution is required the
3172 // result will be sent back to us.
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003173 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
Erik Kline736353a2018-03-21 07:18:33 -07003174
3175 // With Private DNS bypass support, we can proceed to update the
3176 // Private DNS config immediately, even if we're in strict mode
3177 // and have not yet resolved the provider name into a set of IPs.
3178 updatePrivateDns(nai, cfg);
3179 }
3180
3181 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
3182 mDnsManager.updatePrivateDns(nai.network, newCfg);
Erik Klinea24d4592018-01-11 21:07:29 +09003183 updateDnses(nai.linkProperties, null, nai.network.netId);
Erik Klinea24d4592018-01-11 21:07:29 +09003184 }
3185
dalyk7301aa42018-03-05 12:42:22 -05003186 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
3187 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
3188 if (nai == null) {
3189 return;
3190 }
3191 mDnsManager.updatePrivateDnsValidation(update);
3192 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3193 }
3194
Lorenzo Colitti6998fa82019-01-08 10:04:25 +09003195 private void handleNat64PrefixEvent(int netId, boolean added, String prefixString,
3196 int prefixLength) {
3197 NetworkAgentInfo nai = mNetworkForNetId.get(netId);
3198 if (nai == null) return;
3199
3200 log(String.format("NAT64 prefix %s on netId %d: %s/%d",
3201 (added ? "added" : "removed"), netId, prefixString, prefixLength));
3202
3203 IpPrefix prefix = null;
3204 if (added) {
3205 try {
3206 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString),
3207 prefixLength);
3208 } catch (IllegalArgumentException e) {
3209 loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength);
3210 return;
3211 }
3212 }
3213
Lorenzo Colitti06dcc322020-04-02 15:24:59 +00003214 nai.clatd.setNat64PrefixFromDns(prefix);
Lorenzo Colitti6998fa82019-01-08 10:04:25 +09003215 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3216 }
3217
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +09003218 private void handleCaptivePortalDataUpdate(@NonNull final NetworkAgentInfo nai,
3219 @Nullable final CaptivePortalData data) {
3220 nai.captivePortalData = data;
3221 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
3222 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
3223 }
3224
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003225 /**
3226 * Updates the linger state from the network requests inside the NAI.
3227 * @param nai the agent info to update
3228 * @param now the timestamp of the event causing this update
3229 * @return whether the network was lingered as a result of this update
3230 */
3231 private boolean updateLingerState(@NonNull final NetworkAgentInfo nai, final long now) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09003232 // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
3233 // 2. If the network was lingering and there are now requests, unlinger it.
3234 // 3. If this network is unneeded (which implies it is not lingering), and there is at least
3235 // one lingered request, start lingering.
3236 nai.updateLingerTimer();
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003237 if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003238 if (DBG) log("Unlingering " + nai.toShortString());
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09003239 nai.unlinger();
3240 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003241 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) {
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003242 if (DBG) {
3243 final int lingerTime = (int) (nai.getLingerExpiry() - now);
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003244 log("Lingering " + nai.toShortString() + " for " + lingerTime + "ms");
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003245 }
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09003246 nai.linger();
3247 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003248 return true;
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09003249 }
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003250 return false;
Paul Jensen0cc17322014-11-25 15:26:53 -05003251 }
3252
Robert Greenwalt7b816022014-04-18 15:25:25 -07003253 private void handleAsyncChannelHalfConnect(Message msg) {
Chalard Jean11293a92019-11-05 14:40:23 +09003254 ensureRunningOnConnectivityServiceThread();
3255 final AsyncChannel ac = (AsyncChannel) msg.obj;
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003256 if (mNetworkProviderInfos.containsKey(msg.replyTo)) {
Robert Greenwalt7b816022014-04-18 15:25:25 -07003257 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
3258 if (VDBG) log("NetworkFactory connected");
Etan Cohenddb720a2019-01-08 12:09:18 -08003259 // Finish setting up the full connection
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003260 NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo);
3261 npi.completeConnection();
3262 sendAllRequestsToProvider(npi);
Robert Greenwalt7b816022014-04-18 15:25:25 -07003263 } else {
3264 loge("Error connecting NetworkFactory");
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003265 mNetworkProviderInfos.remove(msg.obj);
Robert Greenwalt7b816022014-04-18 15:25:25 -07003266 }
3267 } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
3268 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
3269 if (VDBG) log("NetworkAgent connected");
3270 // A network agent has requested a connection. Establish the connection.
3271 mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
3272 sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
3273 } else {
3274 loge("Error connecting NetworkAgent");
Robert Greenwalt12e67352014-05-13 21:41:06 -07003275 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
Robert Greenwalt9258c642014-03-26 16:47:06 -07003276 if (nai != null) {
Lorenzo Colitticc917ce2015-05-01 00:30:10 +09003277 final boolean wasDefault = isDefaultNetwork(nai);
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07003278 synchronized (mNetworkForNetId) {
3279 mNetworkForNetId.remove(nai.network.netId);
3280 }
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09003281 mNetIdManager.releaseNetId(nai.network.netId);
Lorenzo Colittia793a672014-07-31 23:20:17 +09003282 // Just in case.
Lorenzo Colitticc917ce2015-05-01 00:30:10 +09003283 mLegacyTypeTracker.remove(nai, wasDefault);
Robert Greenwalt9258c642014-03-26 16:47:06 -07003284 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07003285 }
3286 }
3287 }
Paul Jensen0cc17322014-11-25 15:26:53 -05003288
Chalard Jean392971c2018-05-11 20:19:20 +09003289 // This is a no-op if it's called with a message designating a network that has
3290 // already been destroyed, because its reference will not be found in the relevant
3291 // maps.
Robert Greenwalt7b816022014-04-18 15:25:25 -07003292 private void handleAsyncChannelDisconnected(Message msg) {
3293 NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
3294 if (nai != null) {
Chalard Jean392971c2018-05-11 20:19:20 +09003295 disconnectAndDestroyNetwork(nai);
Paul Jensen62d30802015-06-17 14:42:30 -04003296 } else {
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003297 NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo);
3298 if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name);
Robert Greenwalt7b816022014-04-18 15:25:25 -07003299 }
3300 }
3301
Chalard Jean392971c2018-05-11 20:19:20 +09003302 // Destroys a network, remove references to it from the internal state managed by
3303 // ConnectivityService, free its interfaces and clean up.
3304 // Must be called on the Handler thread.
3305 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
Chalard Jean11293a92019-11-05 14:40:23 +09003306 ensureRunningOnConnectivityServiceThread();
Chalard Jean392971c2018-05-11 20:19:20 +09003307 if (DBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003308 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
Chalard Jean392971c2018-05-11 20:19:20 +09003309 }
lucaslinf80b83b2019-02-12 15:30:13 +08003310 // Clear all notifications of this network.
3311 mNotifier.clearNotification(nai.network.netId);
Chalard Jean392971c2018-05-11 20:19:20 +09003312 // A network agent has disconnected.
3313 // TODO - if we move the logic to the network agent (have them disconnect
3314 // because they lost all their requests or because their score isn't good)
3315 // then they would disconnect organically, report their new state and then
3316 // disconnect the channel.
3317 if (nai.networkInfo.isConnected()) {
3318 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
3319 null, null);
3320 }
3321 final boolean wasDefault = isDefaultNetwork(nai);
3322 if (wasDefault) {
3323 mDefaultInetConditionPublished = 0;
3324 // Log default network disconnection before required book-keeping.
3325 // Let rematchAllNetworksAndRequests() below record a new default network event
3326 // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
3327 // whose timestamps tell how long it takes to recover a default network.
3328 long now = SystemClock.elapsedRealtime();
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09003329 mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
Chalard Jean392971c2018-05-11 20:19:20 +09003330 }
3331 notifyIfacesChangedForNetworkStats();
3332 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
3333 // by other networks that are already connected. Perhaps that can be done by
3334 // sending all CALLBACK_LOST messages (for requests, not listens) at the end
3335 // of rematchAllNetworksAndRequests
3336 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
junyulai06835112019-01-03 18:50:15 +08003337 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
Chalard Jean392971c2018-05-11 20:19:20 +09003338 for (String iface : nai.linkProperties.getAllInterfaceNames()) {
3339 // Disable wakeup packet monitoring for each interface.
3340 wakeupModifyInterface(iface, nai.networkCapabilities, false);
3341 }
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003342 nai.networkMonitor().notifyNetworkDisconnected();
Chalard Jean392971c2018-05-11 20:19:20 +09003343 mNetworkAgentInfos.remove(nai.messenger);
Lorenzo Colittid593e292019-02-19 13:21:56 +09003344 nai.clatd.update();
Chalard Jean392971c2018-05-11 20:19:20 +09003345 synchronized (mNetworkForNetId) {
3346 // Remove the NetworkAgent, but don't mark the netId as
3347 // available until we've told netd to delete it below.
3348 mNetworkForNetId.remove(nai.network.netId);
3349 }
3350 // Remove all previously satisfied requests.
3351 for (int i = 0; i < nai.numNetworkRequests(); i++) {
3352 NetworkRequest request = nai.requestAt(i);
Chalard Jean68602592019-11-05 15:07:09 +09003353 final NetworkRequestInfo nri = mNetworkRequests.get(request);
Chalard Jeancf904232019-11-05 15:10:49 +09003354 final NetworkAgentInfo currentNetwork = nri.mSatisfier;
Chalard Jean392971c2018-05-11 20:19:20 +09003355 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
Chalard Jeancf904232019-11-05 15:10:49 +09003356 nri.mSatisfier = null;
Chalard Jean05ab6812018-05-02 21:14:54 +09003357 sendUpdatedScoreToFactories(request, null);
Chalard Jean392971c2018-05-11 20:19:20 +09003358 }
3359 }
3360 nai.clearLingerState();
3361 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
Chalard Jeancf904232019-11-05 15:10:49 +09003362 mDefaultNetworkNai = null;
Chiachang Wanga6093042018-09-28 22:42:48 +08003363 updateDataActivityTracking(null /* newNetwork */, nai);
Chalard Jean392971c2018-05-11 20:19:20 +09003364 notifyLockdownVpn(nai);
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003365 ensureNetworkTransitionWakelock(nai.toShortString());
Chalard Jean392971c2018-05-11 20:19:20 +09003366 }
3367 mLegacyTypeTracker.remove(nai, wasDefault);
3368 if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
3369 updateAllVpnsCapabilities();
3370 }
Chalard Jean1a4548c2019-11-07 18:54:49 +09003371 rematchAllNetworksAndRequests();
Chalard Jean392971c2018-05-11 20:19:20 +09003372 mLingerMonitor.noteDisconnect(nai);
3373 if (nai.created) {
3374 // Tell netd to clean up the configuration for this network
3375 // (routing rules, DNS, etc).
3376 // This may be slow as it requires a lot of netd shelling out to ip and
3377 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
3378 // after we've rematched networks with requests which should make a potential
3379 // fallback network the default or requested a new network from the
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003380 // NetworkProviders, so network traffic isn't interrupted for an unnecessarily
Chalard Jean392971c2018-05-11 20:19:20 +09003381 // long time.
Luke Huanga24d5d82019-04-09 18:41:49 +08003382 destroyNativeNetwork(nai);
Chalard Jean392971c2018-05-11 20:19:20 +09003383 mDnsManager.removeNetwork(nai.network);
3384 }
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09003385 mNetIdManager.releaseNetId(nai.network.netId);
Chalard Jean392971c2018-05-11 20:19:20 +09003386 }
3387
Luke Huanga24d5d82019-04-09 18:41:49 +08003388 private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
3389 try {
3390 // This should never fail. Specifying an already in use NetID will cause failure.
3391 if (networkAgent.isVPN()) {
3392 mNetd.networkCreateVpn(networkAgent.network.netId,
Lorenzo Colittid9696562020-01-12 22:28:37 +09003393 (networkAgent.networkAgentConfig == null
3394 || !networkAgent.networkAgentConfig.allowBypass));
Luke Huanga24d5d82019-04-09 18:41:49 +08003395 } else {
3396 mNetd.networkCreatePhysical(networkAgent.network.netId,
3397 getNetworkPermission(networkAgent.networkCapabilities));
3398 }
3399 mDnsResolver.createNetworkCache(networkAgent.network.netId);
chenbruce5d955622020-02-20 14:28:31 +08003400 mDnsManager.updateTransportsForNetwork(networkAgent.network.netId,
3401 networkAgent.networkCapabilities.getTransportTypes());
Luke Huanga24d5d82019-04-09 18:41:49 +08003402 return true;
3403 } catch (RemoteException | ServiceSpecificException e) {
3404 loge("Error creating network " + networkAgent.network.netId + ": "
3405 + e.getMessage());
3406 return false;
3407 }
3408 }
3409
3410 private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
3411 try {
3412 mNetd.networkDestroy(networkAgent.network.netId);
3413 mDnsResolver.destroyNetworkCache(networkAgent.network.netId);
3414 } catch (RemoteException | ServiceSpecificException e) {
3415 loge("Exception destroying network: " + e);
3416 }
3417 }
3418
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003419 // If this method proves to be too slow then we can maintain a separate
3420 // pendingIntent => NetworkRequestInfo map.
3421 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
3422 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
3423 Intent intent = pendingIntent.getIntent();
3424 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
3425 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
3426 if (existingPendingIntent != null &&
3427 existingPendingIntent.getIntent().filterEquals(intent)) {
3428 return entry.getValue();
3429 }
3430 }
3431 return null;
3432 }
3433
3434 private void handleRegisterNetworkRequestWithIntent(Message msg) {
3435 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
3436
3437 NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent);
3438 if (existingRequest != null) { // remove the existing request.
3439 if (DBG) log("Replacing " + existingRequest.request + " with "
3440 + nri.request + " because their intents matched.");
Etan Cohenddb720a2019-01-08 12:09:18 -08003441 handleReleaseNetworkRequest(existingRequest.request, getCallingUid(),
3442 /* callOnUnavailable */ false);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003443 }
Erik Klineda4bfa82015-04-30 12:58:40 +09003444 handleRegisterNetworkRequest(nri);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003445 }
3446
Erik Klineda4bfa82015-04-30 12:58:40 +09003447 private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
Chalard Jean11293a92019-11-05 14:40:23 +09003448 ensureRunningOnConnectivityServiceThread();
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003449 mNetworkRequests.put(nri.request, nri);
Erik Kline7523eb32015-07-09 18:24:03 +09003450 mNetworkRequestInfoLogs.log("REGISTER " + nri);
Lorenzo Colittif4a45f42016-07-18 18:17:08 +09003451 if (nri.request.isListen()) {
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09003452 for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09003453 if (nri.request.networkCapabilities.hasSignalStrength() &&
3454 network.satisfiesImmutableCapabilitiesOf(nri.request)) {
3455 updateSignalStrengthThresholds(network, "REGISTER", nri.request);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09003456 }
3457 }
3458 }
Chalard Jean1a4548c2019-11-07 18:54:49 +09003459 rematchAllNetworksAndRequests();
Chalard Jeancf904232019-11-05 15:10:49 +09003460 if (nri.request.isRequest() && nri.mSatisfier == null) {
Chalard Jean05ab6812018-05-02 21:14:54 +09003461 sendUpdatedScoreToFactories(nri.request, null);
Robert Greenwalt9258c642014-03-26 16:47:06 -07003462 }
3463 }
3464
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003465 private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent,
3466 int callingUid) {
3467 NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
3468 if (nri != null) {
Etan Cohenddb720a2019-01-08 12:09:18 -08003469 handleReleaseNetworkRequest(nri.request, callingUid, /* callOnUnavailable */ false);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08003470 }
3471 }
3472
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003473 // Determines whether the network is the best (or could become the best, if it validated), for
3474 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
3475 // on the value of reason:
3476 //
3477 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
3478 // then it should be torn down.
3479 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
3480 // then it should be lingered.
3481 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
Chalard Jean11293a92019-11-05 14:40:23 +09003482 ensureRunningOnConnectivityServiceThread();
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003483 final int numRequests;
3484 switch (reason) {
3485 case TEARDOWN:
3486 numRequests = nai.numRequestNetworkRequests();
3487 break;
3488 case LINGER:
3489 numRequests = nai.numForegroundNetworkRequests();
3490 break;
3491 default:
3492 Slog.wtf(TAG, "Invalid reason. Cannot happen.");
3493 return true;
3494 }
3495
3496 if (!nai.everConnected || nai.isVPN() || nai.isLingering() || numRequests > 0) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09003497 return false;
3498 }
Paul Jensene0988542015-06-25 15:30:08 -04003499 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003500 if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) {
3501 // Background requests don't affect lingering.
3502 continue;
3503 }
3504
Paul Jensene0988542015-06-25 15:30:08 -04003505 // If this Network is already the highest scoring Network for a request, or if
3506 // there is hope for it to become one if it validated, then it is needed.
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09003507 if (nri.request.isRequest() && nai.satisfies(nri.request) &&
Chalard Jeanfb830762020-02-20 07:32:12 +00003508 (nai.isSatisfyingRequest(nri.request.requestId) ||
3509 // Note that this catches two important cases:
3510 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
3511 // is currently satisfying the request. This is desirable when
3512 // cellular ends up validating but WiFi does not.
3513 // 2. Unvalidated WiFi will not be reaped when validated cellular
3514 // is currently satisfying the request. This is desirable when
3515 // WiFi ends up validating and out scoring cellular.
3516 nri.mSatisfier.getCurrentScore()
3517 < nai.getCurrentScoreAsValidated())) {
Paul Jensene0988542015-06-25 15:30:08 -04003518 return false;
Paul Jensen99364842014-12-09 11:43:45 -05003519 }
3520 }
Paul Jensene0988542015-06-25 15:30:08 -04003521 return true;
Paul Jensen99364842014-12-09 11:43:45 -05003522 }
3523
Erik Klineacdd6392016-07-07 16:50:58 +09003524 private NetworkRequestInfo getNriForAppRequest(
3525 NetworkRequest request, int callingUid, String requestedOperation) {
3526 final NetworkRequestInfo nri = mNetworkRequests.get(request);
3527
Robert Greenwalt9258c642014-03-26 16:47:06 -07003528 if (nri != null) {
Roshan Piuse896c6d2019-10-04 06:33:37 -07003529 if (Process.SYSTEM_UID != callingUid && Process.NETWORK_STACK_UID != callingUid
3530 && nri.mUid != callingUid) {
Erik Klineacdd6392016-07-07 16:50:58 +09003531 log(String.format("UID %d attempted to %s for unowned request %s",
3532 callingUid, requestedOperation, nri));
3533 return null;
Paul Jensen7ecb42f2014-05-16 14:31:12 -04003534 }
Erik Klineacdd6392016-07-07 16:50:58 +09003535 }
3536
3537 return nri;
3538 }
3539
Erik Kline57faba92015-11-25 12:49:38 +09003540 private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
Chalard Jean11293a92019-11-05 14:40:23 +09003541 ensureRunningOnConnectivityServiceThread();
Hugo Benichidba33db2017-03-23 22:40:44 +09003542 if (mNetworkRequests.get(nri.request) == null) {
3543 return;
Erik Kline57faba92015-11-25 12:49:38 +09003544 }
Chalard Jeancf904232019-11-05 15:10:49 +09003545 if (nri.mSatisfier != null) {
Hugo Benichidba33db2017-03-23 22:40:44 +09003546 return;
3547 }
3548 if (VDBG || (DBG && nri.request.isRequest())) {
3549 log("releasing " + nri.request + " (timeout)");
3550 }
3551 handleRemoveNetworkRequest(nri);
3552 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
Erik Kline57faba92015-11-25 12:49:38 +09003553 }
3554
Etan Cohenddb720a2019-01-08 12:09:18 -08003555 private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid,
3556 boolean callOnUnavailable) {
Hugo Benichidba33db2017-03-23 22:40:44 +09003557 final NetworkRequestInfo nri =
3558 getNriForAppRequest(request, callingUid, "release NetworkRequest");
3559 if (nri == null) {
3560 return;
Erik Kline57faba92015-11-25 12:49:38 +09003561 }
Hugo Benichidba33db2017-03-23 22:40:44 +09003562 if (VDBG || (DBG && nri.request.isRequest())) {
3563 log("releasing " + nri.request + " (release request)");
3564 }
3565 handleRemoveNetworkRequest(nri);
Etan Cohenddb720a2019-01-08 12:09:18 -08003566 if (callOnUnavailable) {
3567 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
3568 }
Erik Kline57faba92015-11-25 12:49:38 +09003569 }
Erik Klineacdd6392016-07-07 16:50:58 +09003570
Hugo Benichidba33db2017-03-23 22:40:44 +09003571 private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
Chalard Jean11293a92019-11-05 14:40:23 +09003572 ensureRunningOnConnectivityServiceThread();
3573
Erik Klineacdd6392016-07-07 16:50:58 +09003574 nri.unlinkDeathRecipient();
Erik Kline57faba92015-11-25 12:49:38 +09003575 mNetworkRequests.remove(nri.request);
Erik Kline33d8e5c2018-01-15 17:05:07 +09003576
Cody Kesting63e4e002019-12-18 10:57:50 -08003577 decrementNetworkRequestPerUidCount(nri);
Erik Kline33d8e5c2018-01-15 17:05:07 +09003578
Erik Klineacdd6392016-07-07 16:50:58 +09003579 mNetworkRequestInfoLogs.log("RELEASE " + nri);
3580 if (nri.request.isRequest()) {
3581 boolean wasKept = false;
Chalard Jeancf904232019-11-05 15:10:49 +09003582 final NetworkAgentInfo nai = nri.mSatisfier;
Erik Klineacdd6392016-07-07 16:50:58 +09003583 if (nai != null) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09003584 boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
Erik Klineacdd6392016-07-07 16:50:58 +09003585 nai.removeRequest(nri.request.requestId);
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09003586 if (VDBG || DDBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003587 log(" Removing from current network " + nai.toShortString()
3588 + ", leaving " + nai.numNetworkRequests() + " requests.");
Erik Klineacdd6392016-07-07 16:50:58 +09003589 }
3590 // If there are still lingered requests on this network, don't tear it down,
3591 // but resume lingering instead.
Chalard Jeanb4429fe2019-12-04 18:49:18 +09003592 final long now = SystemClock.elapsedRealtime();
3593 if (updateLingerState(nai, now)) {
3594 notifyNetworkLosing(nai, now);
3595 }
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09003596 if (unneeded(nai, UnneededFor.TEARDOWN)) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003597 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting");
Erik Klineacdd6392016-07-07 16:50:58 +09003598 teardownUnneededNetwork(nai);
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04003599 } else {
Erik Klineacdd6392016-07-07 16:50:58 +09003600 wasKept = true;
3601 }
Chalard Jeancf904232019-11-05 15:10:49 +09003602 nri.mSatisfier = null;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09003603 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
3604 // Went from foreground to background.
Lorenzo Colittib8167f62016-09-15 22:47:08 +09003605 updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09003606 }
Erik Klineacdd6392016-07-07 16:50:58 +09003607 }
3608
Erik Klineacdd6392016-07-07 16:50:58 +09003609 // Maintain the illusion. When this request arrived, we might have pretended
3610 // that a network connected to serve it, even though the network was already
3611 // connected. Now that this request has gone away, we might have to pretend
3612 // that the network disconnected. LegacyTypeTracker will generate that
3613 // phantom disconnect for this type.
3614 if (nri.request.legacyType != TYPE_NONE && nai != null) {
3615 boolean doRemove = true;
3616 if (wasKept) {
3617 // check if any of the remaining requests for this network are for the
3618 // same legacy type - if so, don't remove the nai
3619 for (int i = 0; i < nai.numNetworkRequests(); i++) {
3620 NetworkRequest otherRequest = nai.requestAt(i);
3621 if (otherRequest.legacyType == nri.request.legacyType &&
3622 otherRequest.isRequest()) {
3623 if (DBG) log(" still have other legacy request - leaving");
3624 doRemove = false;
Robert Greenwalt51481852015-01-08 14:43:31 -08003625 }
3626 }
Robert Greenwalt4456cf32014-08-24 22:52:10 -07003627 }
3628
Erik Klineacdd6392016-07-07 16:50:58 +09003629 if (doRemove) {
3630 mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
Robert Greenwalt9258c642014-03-26 16:47:06 -07003631 }
3632 }
Erik Klineacdd6392016-07-07 16:50:58 +09003633
Lorenzo Colitti6654b082020-01-10 00:40:28 +09003634 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
3635 npi.cancelRequest(nri.request);
Erik Klineacdd6392016-07-07 16:50:58 +09003636 }
3637 } else {
3638 // listens don't have a singular affectedNetwork. Check all networks to see
3639 // if this listen request applies and remove it.
3640 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
3641 nai.removeRequest(nri.request.requestId);
3642 if (nri.request.networkCapabilities.hasSignalStrength() &&
3643 nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
3644 updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
3645 }
3646 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07003647 }
3648 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07003649
Cody Kesting63e4e002019-12-18 10:57:50 -08003650 private void decrementNetworkRequestPerUidCount(final NetworkRequestInfo nri) {
3651 synchronized (mUidToNetworkRequestCount) {
3652 final int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
3653 if (requests < 1) {
3654 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid);
3655 } else if (requests == 1) {
3656 mUidToNetworkRequestCount.removeAt(mUidToNetworkRequestCount.indexOfKey(nri.mUid));
3657 } else {
3658 mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
3659 }
3660 }
3661 }
3662
Lorenzo Colitti18660282016-07-04 12:55:44 +09003663 @Override
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003664 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
lucasline252a742019-03-12 13:08:03 +08003665 enforceNetworkStackSettingsOrSetup();
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003666 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
Hugo Benichiab7d2e62017-04-21 15:07:12 +09003667 encodeBool(accept), encodeBool(always), network));
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003668 }
3669
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003670 @Override
lucasline252a742019-03-12 13:08:03 +08003671 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
3672 enforceNetworkStackSettingsOrSetup();
3673 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
3674 encodeBool(accept), encodeBool(always), network));
3675 }
3676
3677 @Override
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003678 public void setAvoidUnvalidated(Network network) {
lucasline252a742019-03-12 13:08:03 +08003679 enforceNetworkStackSettingsOrSetup();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003680 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
3681 }
3682
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003683 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
3684 if (DBG) log("handleSetAcceptUnvalidated network=" + network +
3685 " accept=" + accept + " always=" + always);
3686
3687 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3688 if (nai == null) {
3689 // Nothing to do.
3690 return;
3691 }
3692
3693 if (nai.everValidated) {
Lorenzo Colittif6673d02015-05-21 16:17:05 +09003694 // The network validated while the dialog box was up. Take no action.
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003695 return;
3696 }
3697
Lorenzo Colittid9696562020-01-12 22:28:37 +09003698 if (!nai.networkAgentConfig.explicitlySelected) {
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003699 Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
3700 }
3701
Lorenzo Colittid9696562020-01-12 22:28:37 +09003702 if (accept != nai.networkAgentConfig.acceptUnvalidated) {
3703 nai.networkAgentConfig.acceptUnvalidated = accept;
lucasline252a742019-03-12 13:08:03 +08003704 // If network becomes partial connectivity and user already accepted to use this
3705 // network, we should respect the user's option and don't need to popup the
3706 // PARTIAL_CONNECTIVITY notification to user again.
Lorenzo Colittid9696562020-01-12 22:28:37 +09003707 nai.networkAgentConfig.acceptPartialConnectivity = accept;
Chalard Jean1a4548c2019-11-07 18:54:49 +09003708 rematchAllNetworksAndRequests();
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003709 sendUpdatedScoreToFactories(nai);
3710 }
3711
3712 if (always) {
3713 nai.asyncChannel.sendMessage(
Hugo Benichiab7d2e62017-04-21 15:07:12 +09003714 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003715 }
3716
Lorenzo Colittif6673d02015-05-21 16:17:05 +09003717 if (!accept) {
Paul Jensenf95d2202015-07-13 15:19:51 -04003718 // Tell the NetworkAgent to not automatically reconnect to the network.
3719 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
Chalard Jean4d660112018-06-04 16:52:49 +09003720 // Teardown the network.
Paul Jensenf95d2202015-07-13 15:19:51 -04003721 teardownUnneededNetwork(nai);
Lorenzo Colittif6673d02015-05-21 16:17:05 +09003722 }
3723
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003724 }
3725
lucasline252a742019-03-12 13:08:03 +08003726 private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
3727 boolean always) {
3728 if (DBG) {
3729 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
3730 + " always=" + always);
3731 }
3732
3733 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3734 if (nai == null) {
3735 // Nothing to do.
3736 return;
3737 }
3738
3739 if (nai.lastValidated) {
3740 // The network validated while the dialog box was up. Take no action.
3741 return;
3742 }
3743
Lorenzo Colittid9696562020-01-12 22:28:37 +09003744 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) {
3745 nai.networkAgentConfig.acceptPartialConnectivity = accept;
lucasline252a742019-03-12 13:08:03 +08003746 }
3747
3748 // TODO: Use the current design or save the user choice into IpMemoryStore.
3749 if (always) {
3750 nai.asyncChannel.sendMessage(
3751 NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
3752 }
3753
3754 if (!accept) {
3755 // Tell the NetworkAgent to not automatically reconnect to the network.
3756 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
3757 // Tear down the network.
3758 teardownUnneededNetwork(nai);
3759 } else {
lucaslin43338992019-03-20 18:21:59 +08003760 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
3761 // result in a partial connectivity result which will be processed by
3762 // maybeHandleNetworkMonitorMessage.
Chiachang Wang8ea15c962019-05-23 16:29:30 +08003763 //
3764 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
3765 // per network. Therefore, NetworkMonitor may still do https probe.
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003766 nai.networkMonitor().setAcceptPartialConnectivity();
lucasline252a742019-03-12 13:08:03 +08003767 }
3768 }
3769
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003770 private void handleSetAvoidUnvalidated(Network network) {
3771 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3772 if (nai == null || nai.lastValidated) {
3773 // Nothing to do. The network either disconnected or revalidated.
3774 return;
3775 }
3776 if (!nai.avoidUnvalidated) {
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003777 nai.avoidUnvalidated = true;
Chalard Jean1a4548c2019-11-07 18:54:49 +09003778 rematchAllNetworksAndRequests();
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003779 sendUpdatedScoreToFactories(nai);
3780 }
3781 }
3782
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003783 private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09003784 if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09003785 mHandler.sendMessageDelayed(
3786 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
3787 PROMPT_UNVALIDATED_DELAY_MS);
3788 }
3789
Lorenzo Colitti4734cdb2017-04-27 14:30:21 +09003790 @Override
3791 public void startCaptivePortalApp(Network network) {
paulhu59148b72019-08-12 16:25:11 +08003792 enforceNetworkStackOrSettingsPermission();
Lorenzo Colitti4734cdb2017-04-27 14:30:21 +09003793 mHandler.post(() -> {
3794 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3795 if (nai == null) return;
3796 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003797 nai.networkMonitor().launchCaptivePortalApp();
Lorenzo Colitti4734cdb2017-04-27 14:30:21 +09003798 });
3799 }
3800
Remi NGUYEN VANdc483562019-02-04 11:32:20 +09003801 /**
3802 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
3803 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003804 * @param network Network on which the captive portal was detected.
Remi NGUYEN VANdc483562019-02-04 11:32:20 +09003805 * @param appExtras Bundle to use as intent extras for the captive portal application.
3806 * Must be treated as opaque to avoid preventing the captive portal app to
3807 * update its arguments.
3808 */
3809 @Override
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003810 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
paulhu98525602019-05-14 14:17:44 +08003811 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
3812 "ConnectivityService");
Remi NGUYEN VANdc483562019-02-04 11:32:20 +09003813
3814 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
3815 appIntent.putExtras(appExtras);
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003816 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
3817 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
Remi NGUYEN VANdc483562019-02-04 11:32:20 +09003818 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
3819
3820 Binder.withCleanCallingIdentity(() ->
3821 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
3822 }
3823
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003824 private class CaptivePortalImpl extends ICaptivePortal.Stub {
3825 private final Network mNetwork;
3826
3827 private CaptivePortalImpl(Network network) {
3828 mNetwork = network;
3829 }
3830
3831 @Override
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003832 public void appResponse(final int response) {
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003833 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
3834 enforceSettingsPermission();
3835 }
3836
Chiachang Wang207b6cf2020-01-09 13:50:55 +08003837 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003838 if (nm == null) return;
Lorenzo Colittiac955b32019-05-31 15:41:29 +09003839 nm.notifyCaptivePortalAppFinished(response);
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003840 }
3841
3842 @Override
Chiachang Wang207b6cf2020-01-09 13:50:55 +08003843 public void appRequest(final int request) {
3844 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
3845 if (nm == null) return;
3846
3847 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) {
Chiachang Wanga1b80582020-02-12 18:08:16 +08003848 checkNetworkStackPermission();
Chiachang Wang207b6cf2020-01-09 13:50:55 +08003849 nm.forceReevaluation(Binder.getCallingUid());
3850 }
3851 }
3852
3853 @Nullable
3854 private NetworkMonitorManager getNetworkMonitorManager(final Network network) {
3855 // getNetworkAgentInfoForNetwork is thread-safe
3856 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3857 if (nai == null) return null;
3858
3859 // nai.networkMonitor() is thread-safe
3860 return nai.networkMonitor();
3861 }
3862
3863 @Override
Remi NGUYEN VANcfff01e2019-02-13 20:58:59 +09003864 public void logEvent(int eventId, String packageName) {
3865 enforceSettingsPermission();
3866
3867 new MetricsLogger().action(eventId, packageName);
3868 }
3869 }
3870
Hugo Benichic8e9e122016-09-14 23:23:08 +00003871 public boolean avoidBadWifi() {
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +09003872 return mMultinetworkPolicyTracker.getAvoidBadWifi();
Lorenzo Colitti2618c1b2016-09-16 23:43:38 +09003873 }
3874
Remi NGUYEN VANe2365d62019-03-22 11:14:13 +09003875 /**
3876 * Return whether the device should maintain continuous, working connectivity by switching away
3877 * from WiFi networks having no connectivity.
3878 * @see MultinetworkPolicyTracker#getAvoidBadWifi()
3879 */
3880 public boolean shouldAvoidBadWifi() {
Remi NGUYEN VAN97f69c22019-01-20 20:35:06 +09003881 if (!checkNetworkStackPermission()) {
3882 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
3883 }
3884 return avoidBadWifi();
3885 }
3886
Chalard Jean9bcd4222020-02-20 07:39:31 +00003887
Erik Kline065ab6e2016-10-02 18:02:14 +09003888 private void rematchForAvoidBadWifiUpdate() {
Chalard Jean1a4548c2019-11-07 18:54:49 +09003889 rematchAllNetworksAndRequests();
Erik Kline065ab6e2016-10-02 18:02:14 +09003890 for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) {
3891 if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
3892 sendUpdatedScoreToFactories(nai);
3893 }
3894 }
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09003895 }
3896
Erik Kline065ab6e2016-10-02 18:02:14 +09003897 // TODO: Evaluate whether this is of interest to other consumers of
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +09003898 // MultinetworkPolicyTracker and worth moving out of here.
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09003899 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +09003900 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09003901 if (!configRestrict) {
3902 pw.println("Bad Wi-Fi avoidance: unrestricted");
3903 return;
3904 }
3905
3906 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
3907 pw.increaseIndent();
3908 pw.println("Config restrict: " + configRestrict);
3909
Lorenzo Colitti58ebe1c2017-01-24 09:41:36 +09003910 final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09003911 String description;
3912 // Can't use a switch statement because strings are legal case labels, but null is not.
3913 if ("0".equals(value)) {
3914 description = "get stuck";
3915 } else if (value == null) {
3916 description = "prompt";
3917 } else if ("1".equals(value)) {
3918 description = "avoid";
3919 } else {
3920 description = value + " (?)";
3921 }
3922 pw.println("User setting: " + description);
3923 pw.println("Network overrides:");
3924 pw.increaseIndent();
Hugo Benichia2a917c2018-09-03 08:19:02 +09003925 for (NetworkAgentInfo nai : networksSortedById()) {
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09003926 if (nai.avoidUnvalidated) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09003927 pw.println(nai.toShortString());
Lorenzo Colitti29bd3842016-09-20 16:03:27 +09003928 }
3929 }
3930 pw.decreaseIndent();
3931 pw.decreaseIndent();
3932 }
3933
lucaslind2e045e02019-01-24 15:55:30 +08003934 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003935 final String action;
Lorenzo Colitti938457e2019-06-05 16:08:37 +09003936 final boolean highPriority;
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003937 switch (type) {
3938 case NO_INTERNET:
3939 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
Lorenzo Colitti938457e2019-06-05 16:08:37 +09003940 // High priority because it is only displayed for explicitly selected networks.
3941 highPriority = true;
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003942 break;
lucaslin783f2212019-10-22 18:27:33 +08003943 case PRIVATE_DNS_BROKEN:
3944 action = Settings.ACTION_WIRELESS_SETTINGS;
3945 // High priority because we should let user know why there is no internet.
3946 highPriority = true;
3947 break;
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003948 case LOST_INTERNET:
3949 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
Lorenzo Colitti938457e2019-06-05 16:08:37 +09003950 // High priority because it could help the user avoid unexpected data usage.
3951 highPriority = true;
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003952 break;
lucasline252a742019-03-12 13:08:03 +08003953 case PARTIAL_CONNECTIVITY:
3954 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
Lorenzo Colitti938457e2019-06-05 16:08:37 +09003955 // Don't bother the user with a high-priority notification if the network was not
3956 // explicitly selected by the user.
Lorenzo Colittid9696562020-01-12 22:28:37 +09003957 highPriority = nai.networkAgentConfig.explicitlySelected;
lucasline252a742019-03-12 13:08:03 +08003958 break;
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003959 default:
3960 Slog.wtf(TAG, "Unknown notification type " + type);
3961 return;
3962 }
3963
3964 Intent intent = new Intent(action);
lucaslin8c407bd2020-02-20 16:42:27 +08003965 if (type != NotificationType.PRIVATE_DNS_BROKEN) {
lucaslind2e045e02019-01-24 15:55:30 +08003966 intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
3967 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3968 intent.setClassName("com.android.settings",
3969 "com.android.settings.wifi.WifiNoInternetDialog");
3970 }
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003971
3972 PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
3973 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
Lorenzo Colitti938457e2019-06-05 16:08:37 +09003974
3975 mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority);
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09003976 }
3977
Lorenzo Colittiec2c7ec2019-06-04 19:29:50 +09003978 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
3979 // Don't prompt if the network is validated, and don't prompt on captive portals
3980 // because we're already prompting the user to sign in.
3981 if (nai.everValidated || nai.everCaptivePortalDetected) {
3982 return false;
3983 }
3984
3985 // If a network has partial connectivity, always prompt unless the user has already accepted
3986 // partial connectivity and selected don't ask again. This ensures that if the device
3987 // automatically connects to a network that has partial Internet access, the user will
3988 // always be able to use it, either because they've already chosen "don't ask again" or
3989 // because we have prompt them.
Lorenzo Colittid9696562020-01-12 22:28:37 +09003990 if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) {
Lorenzo Colittiec2c7ec2019-06-04 19:29:50 +09003991 return true;
3992 }
3993
3994 // If a network has no Internet access, only prompt if the network was explicitly selected
3995 // and if the user has not already told us to use the network regardless of whether it
3996 // validated or not.
Lorenzo Colittid9696562020-01-12 22:28:37 +09003997 if (nai.networkAgentConfig.explicitlySelected
3998 && !nai.networkAgentConfig.acceptUnvalidated) {
Lorenzo Colittiec2c7ec2019-06-04 19:29:50 +09003999 return true;
4000 }
4001
4002 return false;
4003 }
4004
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004005 private void handlePromptUnvalidated(Network network) {
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09004006 if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004007 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4008
Lorenzo Colittiec2c7ec2019-06-04 19:29:50 +09004009 if (nai == null || !shouldPromptUnvalidated(nai)) {
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004010 return;
4011 }
Lorenzo Colitti22991332019-05-30 16:24:31 +09004012
4013 // Stop automatically reconnecting to this network in the future. Automatically connecting
4014 // to a network that provides no or limited connectivity is not useful, because the user
4015 // cannot use that network except through the notification shown by this method, and the
4016 // notification is only shown if the network is explicitly selected by the user.
4017 nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
4018
lucasline252a742019-03-12 13:08:03 +08004019 // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
4020 // NetworkMonitor detects the network is partial connectivity. Need to change the design to
4021 // popup the notification immediately when the network is partial connectivity.
4022 if (nai.partialConnectivity) {
lucaslin975b7d32019-03-21 11:59:22 +08004023 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
lucasline252a742019-03-12 13:08:03 +08004024 } else {
4025 showNetworkNotification(nai, NotificationType.NO_INTERNET);
4026 }
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09004027 }
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004028
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09004029 private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
4030 NetworkCapabilities nc = nai.networkCapabilities;
Chalard Jeanbf1170c2019-12-10 21:07:02 +09004031 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc);
fionaxu1bf6ec22016-05-23 16:33:16 -07004032
lucasline252a742019-03-12 13:08:03 +08004033 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
4034 return;
4035 }
4036
4037 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
lucaslind2e045e02019-01-24 15:55:30 +08004038 showNetworkNotification(nai, NotificationType.LOST_INTERNET);
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09004039 }
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004040 }
4041
Lorenzo Colitti2de49252017-01-24 18:08:41 +09004042 @Override
4043 public int getMultipathPreference(Network network) {
4044 enforceAccessPermission();
4045
4046 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Jeff Sharkey43d2a172017-07-12 10:50:42 -06004047 if (nai != null && nai.networkCapabilities
4048 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
Lorenzo Colitti2de49252017-01-24 18:08:41 +09004049 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
4050 }
4051
Lorenzo Colittid260ef22018-01-24 17:35:07 +09004052 Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
4053 if (networkPreference != null) {
4054 return networkPreference;
4055 }
4056
Lorenzo Colitti2de49252017-01-24 18:08:41 +09004057 return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
4058 }
4059
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09004060 @Override
4061 public NetworkRequest getDefaultRequest() {
4062 return mDefaultRequest;
4063 }
4064
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07004065 private class InternalHandler extends Handler {
4066 public InternalHandler(Looper looper) {
4067 super(looper);
4068 }
4069
4070 @Override
4071 public void handleMessage(Message msg) {
Jeff Sharkey4c628eb2012-07-23 13:19:46 -07004072 switch (msg.what) {
Robert Greenwalt27711812014-06-25 16:45:57 -07004073 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
Sreeram Ramachandranb1486ae2013-08-27 11:41:19 -07004074 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
Hugo Benichi4c31b342017-03-30 23:18:10 +09004075 handleReleaseNetworkTransitionWakelock(msg.what);
Robert Greenwalt057d5e92010-09-09 14:05:10 -07004076 break;
Sreeram Ramachandranb1486ae2013-08-27 11:41:19 -07004077 }
Sreeram Ramachandranb1486ae2013-08-27 11:41:19 -07004078 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
Chalard Jeanb9d45fd2018-06-08 14:24:49 +09004079 mProxyTracker.loadDeprecatedGlobalHttpProxy();
Robert Greenwaltd55a6b42011-03-25 13:09:25 -07004080 break;
4081 }
Jason Monkdecd2952013-10-10 14:02:51 -04004082 case EVENT_PROXY_HAS_CHANGED: {
Jason Monk207900c2014-04-25 15:00:09 -04004083 handleApplyDefaultProxy((ProxyInfo)msg.obj);
Jason Monkdecd2952013-10-10 14:02:51 -04004084 break;
4085 }
Lorenzo Colitti6654b082020-01-10 00:40:28 +09004086 case EVENT_REGISTER_NETWORK_PROVIDER: {
4087 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj);
Robert Greenwalta67be032014-05-16 15:49:14 -07004088 break;
4089 }
Lorenzo Colitti6654b082020-01-10 00:40:28 +09004090 case EVENT_UNREGISTER_NETWORK_PROVIDER: {
4091 handleUnregisterNetworkProvider((Messenger) msg.obj);
Robert Greenwalte049c232014-04-11 15:53:27 -07004092 break;
4093 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07004094 case EVENT_REGISTER_NETWORK_AGENT: {
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09004095 final Pair<NetworkAgentInfo, INetworkMonitor> arg =
4096 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
4097 handleRegisterNetworkAgent(arg.first, arg.second);
Robert Greenwalt7b816022014-04-18 15:25:25 -07004098 break;
4099 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07004100 case EVENT_REGISTER_NETWORK_REQUEST:
4101 case EVENT_REGISTER_NETWORK_LISTENER: {
Erik Klineda4bfa82015-04-30 12:58:40 +09004102 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
Robert Greenwalt9258c642014-03-26 16:47:06 -07004103 break;
4104 }
Paul Jensen694f2b82015-06-17 14:15:39 -04004105 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
4106 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08004107 handleRegisterNetworkRequestWithIntent(msg);
4108 break;
4109 }
Erik Kline57faba92015-11-25 12:49:38 +09004110 case EVENT_TIMEOUT_NETWORK_REQUEST: {
4111 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
4112 handleTimedOutNetworkRequest(nri);
4113 break;
4114 }
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08004115 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
4116 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
4117 break;
4118 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07004119 case EVENT_RELEASE_NETWORK_REQUEST: {
Etan Cohenddb720a2019-01-08 12:09:18 -08004120 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
4121 /* callOnUnavailable */ false);
Robert Greenwalt9258c642014-03-26 16:47:06 -07004122 break;
4123 }
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004124 case EVENT_SET_ACCEPT_UNVALIDATED: {
Hugo Benichiab7d2e62017-04-21 15:07:12 +09004125 Network network = (Network) msg.obj;
4126 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004127 break;
4128 }
lucasline252a742019-03-12 13:08:03 +08004129 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
4130 Network network = (Network) msg.obj;
4131 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
4132 toBool(msg.arg2));
4133 break;
4134 }
Lorenzo Colitti165c51c2016-09-19 01:00:19 +09004135 case EVENT_SET_AVOID_UNVALIDATED: {
4136 handleSetAvoidUnvalidated((Network) msg.obj);
4137 break;
4138 }
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09004139 case EVENT_PROMPT_UNVALIDATED: {
4140 handlePromptUnvalidated((Network) msg.obj);
4141 break;
4142 }
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07004143 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
4144 handleConfigureAlwaysOnNetworks();
Erik Klineda4bfa82015-04-30 12:58:40 +09004145 break;
4146 }
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09004147 // Sent by KeepaliveTracker to process an app request on the state machine thread.
junyulai06835112019-01-03 18:50:15 +08004148 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: {
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09004149 mKeepaliveTracker.handleStartKeepalive(msg);
4150 break;
4151 }
4152 // Sent by KeepaliveTracker to process an app request on the state machine thread.
junyulai06835112019-01-03 18:50:15 +08004153 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09004154 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
4155 int slot = msg.arg1;
4156 int reason = msg.arg2;
4157 mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
4158 break;
4159 }
Robert Greenwaltfb68f8f2014-08-13 13:43:32 -07004160 case EVENT_SYSTEM_READY: {
Lorenzo Colittid260ef22018-01-24 17:35:07 +09004161 mMultipathPolicyTracker.start();
Robert Greenwaltfb68f8f2014-08-13 13:43:32 -07004162 break;
4163 }
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004164 case EVENT_REVALIDATE_NETWORK: {
Hugo Benichiab7d2e62017-04-21 15:07:12 +09004165 handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004166 break;
4167 }
Erik Klinea24d4592018-01-11 21:07:29 +09004168 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
4169 handlePrivateDnsSettingsChanged();
4170 break;
dalyk7301aa42018-03-05 12:42:22 -05004171 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
4172 handlePrivateDnsValidationUpdate(
4173 (PrivateDnsValidationUpdate) msg.obj);
4174 break;
junyulai05986c62018-08-07 19:50:45 +08004175 case EVENT_UID_RULES_CHANGED:
4176 handleUidRulesChanged(msg.arg1, msg.arg2);
4177 break;
4178 case EVENT_DATA_SAVER_CHANGED:
4179 handleRestrictBackgroundChanged(toBool(msg.arg1));
4180 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 }
4182 }
4183 }
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08004184
Lorenzo Colitti18660282016-07-04 12:55:44 +09004185 @Override
markchienae8aa642019-12-16 20:15:20 +08004186 @Deprecated
Robert Greenwalt5a735062010-03-02 17:25:02 -08004187 public int getLastTetherError(String iface) {
markchienae8aa642019-12-16 20:15:20 +08004188 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4189 Context.TETHERING_SERVICE);
4190 return tm.getLastTetherError(iface);
Robert Greenwalt2a091d72010-02-11 18:18:40 -08004191 }
4192
Lorenzo Colitti18660282016-07-04 12:55:44 +09004193 @Override
markchienae8aa642019-12-16 20:15:20 +08004194 @Deprecated
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08004195 public String[] getTetherableIfaces() {
markchienae8aa642019-12-16 20:15:20 +08004196 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4197 Context.TETHERING_SERVICE);
4198 return tm.getTetherableIfaces();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08004199 }
4200
Lorenzo Colitti18660282016-07-04 12:55:44 +09004201 @Override
markchienae8aa642019-12-16 20:15:20 +08004202 @Deprecated
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08004203 public String[] getTetheredIfaces() {
markchienae8aa642019-12-16 20:15:20 +08004204 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4205 Context.TETHERING_SERVICE);
4206 return tm.getTetheredIfaces();
Robert Greenwaltd0e18ff2010-01-26 11:40:34 -08004207 }
Robert Greenwalt2a091d72010-02-11 18:18:40 -08004208
markchienae8aa642019-12-16 20:15:20 +08004209
Lorenzo Colitti18660282016-07-04 12:55:44 +09004210 @Override
markchienae8aa642019-12-16 20:15:20 +08004211 @Deprecated
Robert Greenwalt5a735062010-03-02 17:25:02 -08004212 public String[] getTetheringErroredIfaces() {
markchienae8aa642019-12-16 20:15:20 +08004213 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4214 Context.TETHERING_SERVICE);
4215
4216 return tm.getTetheringErroredIfaces();
Robert Greenwalt5a735062010-03-02 17:25:02 -08004217 }
4218
Lorenzo Colitti18660282016-07-04 12:55:44 +09004219 @Override
markchienae8aa642019-12-16 20:15:20 +08004220 @Deprecated
4221 public String[] getTetherableUsbRegexs() {
4222 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4223 Context.TETHERING_SERVICE);
4224
4225 return tm.getTetherableUsbRegexs();
Robert Greenwalt9c7e2c22014-06-23 14:53:42 -07004226 }
4227
Udam Saini0e94c362017-06-07 12:06:28 -07004228 @Override
markchienae8aa642019-12-16 20:15:20 +08004229 @Deprecated
4230 public String[] getTetherableWifiRegexs() {
4231 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
4232 Context.TETHERING_SERVICE);
4233 return tm.getTetherableWifiRegexs();
markchien26299ed2019-02-27 14:56:11 +08004234 }
4235
Robert Greenwalt17c3e0f2014-07-02 09:59:16 -07004236 // Called when we lose the default network and have no replacement yet.
4237 // This will automatically be cleared after X seconds or a new default network
4238 // becomes CONNECTED, whichever happens first. The timer is started by the
4239 // first caller and not restarted by subsequent callers.
Hugo Benichi4c31b342017-03-30 23:18:10 +09004240 private void ensureNetworkTransitionWakelock(String forWhom) {
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07004241 synchronized (this) {
Hugo Benichi4c31b342017-03-30 23:18:10 +09004242 if (mNetTransitionWakeLock.isHeld()) {
4243 return;
4244 }
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07004245 mNetTransitionWakeLock.acquire();
Hugo Benichi26bcfa12017-09-05 13:25:07 +09004246 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
4247 mTotalWakelockAcquisitions++;
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07004248 }
Hugo Benichi4c31b342017-03-30 23:18:10 +09004249 mWakelockLogs.log("ACQUIRE for " + forWhom);
4250 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
4251 mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout);
Robert Greenwalt14f2ef42010-06-15 12:19:37 -07004252 }
Robert Greenwaltca4306c2010-09-09 13:15:32 -07004253
Hugo Benichi4c31b342017-03-30 23:18:10 +09004254 // Called when we gain a new default network to release the network transition wakelock in a
4255 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
4256 // message is cancelled.
4257 private void scheduleReleaseNetworkTransitionWakelock() {
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09004258 synchronized (this) {
Hugo Benichi4c31b342017-03-30 23:18:10 +09004259 if (!mNetTransitionWakeLock.isHeld()) {
4260 return; // expiry message released the lock first.
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09004261 }
4262 }
Hugo Benichi4c31b342017-03-30 23:18:10 +09004263 // Cancel self timeout on wakelock hold.
4264 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
4265 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
4266 mHandler.sendMessageDelayed(msg, 1000);
4267 }
4268
4269 // Called when either message of ensureNetworkTransitionWakelock or
4270 // scheduleReleaseNetworkTransitionWakelock is processed.
4271 private void handleReleaseNetworkTransitionWakelock(int eventId) {
4272 String event = eventName(eventId);
4273 synchronized (this) {
4274 if (!mNetTransitionWakeLock.isHeld()) {
4275 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
4276 Slog.w(TAG, "expected Net Transition WakeLock to be held");
4277 return;
4278 }
4279 mNetTransitionWakeLock.release();
Hugo Benichi26bcfa12017-09-05 13:25:07 +09004280 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
4281 mTotalWakelockDurationMs += lockDuration;
4282 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
4283 mTotalWakelockReleases++;
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09004284 }
Hugo Benichi4c31b342017-03-30 23:18:10 +09004285 mWakelockLogs.log(String.format("RELEASE (%s)", event));
Hugo Benichiaf52d7a2017-03-30 10:46:05 +09004286 }
4287
Robert Greenwaltd7085fc2010-09-08 15:24:47 -07004288 // 100 percent is full good, 0 is full bad.
Lorenzo Colitti18660282016-07-04 12:55:44 +09004289 @Override
Robert Greenwaltd7085fc2010-09-08 15:24:47 -07004290 public void reportInetCondition(int networkType, int percentage) {
Robert Greenwaltbf4eed72014-08-06 21:32:18 -07004291 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
Lorenzo Colitti0831f662015-02-11 07:39:20 +09004292 if (nai == null) return;
Paul Jensenbfd17b72015-04-07 12:43:13 -04004293 reportNetworkConnectivity(nai.network, percentage > 50);
Robert Greenwalt8dcc28b2010-09-23 10:05:56 -07004294 }
4295
Lorenzo Colitti18660282016-07-04 12:55:44 +09004296 @Override
Paul Jensenbfd17b72015-04-07 12:43:13 -04004297 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
Paul Jensen7ccd3df2014-08-29 09:54:01 -04004298 enforceAccessPermission();
4299 enforceInternetPermission();
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004300 final int uid = Binder.getCallingUid();
Hugo Benichiab7d2e62017-04-21 15:07:12 +09004301 final int connectivityInfo = encodeBool(hasConnectivity);
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004302 mHandler.sendMessage(
4303 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
Cody Kesting1e5ab9b2020-01-07 11:18:54 -08004304
4305 final NetworkAgentInfo nai;
4306 if (network == null) {
4307 nai = getDefaultNetwork();
4308 } else {
4309 nai = getNetworkAgentInfoForNetwork(network);
4310 }
4311 if (nai != null) {
4312 mConnectivityDiagnosticsHandler.sendMessage(
4313 mConnectivityDiagnosticsHandler.obtainMessage(
4314 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
4315 connectivityInfo, 0, nai));
4316 }
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004317 }
Paul Jensen7ccd3df2014-08-29 09:54:01 -04004318
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004319 private void handleReportNetworkConnectivity(
4320 Network network, int uid, boolean hasConnectivity) {
Hugo Benichi0fd4af92017-04-06 16:01:44 +09004321 final NetworkAgentInfo nai;
Paul Jensenbfd17b72015-04-07 12:43:13 -04004322 if (network == null) {
4323 nai = getDefaultNetwork();
4324 } else {
4325 nai = getNetworkAgentInfoForNetwork(network);
4326 }
Paul Jensen4e8050e2015-06-25 10:28:34 -04004327 if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
4328 nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
4329 return;
4330 }
Paul Jensenbfd17b72015-04-07 12:43:13 -04004331 // Revalidate if the app report does not match our current validated state.
Hugo Benichi0fd4af92017-04-06 16:01:44 +09004332 if (hasConnectivity == nai.lastValidated) {
4333 return;
4334 }
Paul Jensenbfd17b72015-04-07 12:43:13 -04004335 if (DBG) {
Hugo Benichi1c51d7a2017-04-06 17:22:18 +09004336 int netid = nai.network.netId;
4337 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
Paul Jensenbfd17b72015-04-07 12:43:13 -04004338 }
Hugo Benichi0fd4af92017-04-06 16:01:44 +09004339 // Validating a network that has not yet connected could result in a call to
4340 // rematchNetworkAndRequests() which is not meant to work on such networks.
4341 if (!nai.everConnected) {
4342 return;
Paul Jensen7ccd3df2014-08-29 09:54:01 -04004343 }
Hugo Benichi0fd4af92017-04-06 16:01:44 +09004344 LinkProperties lp = getLinkProperties(nai);
4345 if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
4346 return;
4347 }
Lorenzo Colittiac955b32019-05-31 15:41:29 +09004348 nai.networkMonitor().forceReevaluation(uid);
Robert Greenwalt9258c642014-03-26 16:47:06 -07004349 }
4350
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004351 /**
4352 * Returns information about the proxy a certain network is using. If given a null network, it
4353 * it will return the proxy for the bound network for the caller app or the default proxy if
4354 * none.
4355 *
4356 * @param network the network we want to get the proxy information for.
4357 * @return Proxy information if a network has a proxy configured, or otherwise null.
4358 */
Lorenzo Colitti18660282016-07-04 12:55:44 +09004359 @Override
Paul Jensencee9b512015-05-06 07:32:40 -04004360 public ProxyInfo getProxyForNetwork(Network network) {
Chalard Jean5afbc832018-06-07 18:02:37 +09004361 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
Paul Jensencee9b512015-05-06 07:32:40 -04004362 if (globalProxy != null) return globalProxy;
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004363 if (network == null) {
4364 // Get the network associated with the calling UID.
4365 final Network activeNetwork = getActiveNetworkForUidInternal(Binder.getCallingUid(),
4366 true);
4367 if (activeNetwork == null) {
4368 return null;
4369 }
4370 return getLinkPropertiesProxyInfo(activeNetwork);
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09004371 } else if (mDeps.queryUserAccess(Binder.getCallingUid(), network.netId)) {
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004372 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
4373 // caller may not have.
4374 return getLinkPropertiesProxyInfo(network);
4375 }
4376 // No proxy info available if the calling UID does not have network access.
4377 return null;
4378 }
4379
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004380
4381 private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
Paul Jensencee9b512015-05-06 07:32:40 -04004382 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4383 if (nai == null) return null;
4384 synchronized (nai) {
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004385 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
4386 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
Paul Jensencee9b512015-05-06 07:32:40 -04004387 }
4388 }
4389
Chalard Jean3c443fc2018-06-07 18:37:59 +09004390 @Override
4391 public void setGlobalProxy(final ProxyInfo proxyProperties) {
paulhu59148b72019-08-12 16:25:11 +08004392 NetworkStack.checkNetworkStackPermission(mContext);
Chalard Jean3c443fc2018-06-07 18:37:59 +09004393 mProxyTracker.setGlobalProxy(proxyProperties);
Robert Greenwalt434203a2010-10-11 16:00:27 -07004394 }
4395
Chalard Jean5afbc832018-06-07 18:02:37 +09004396 @Override
4397 @Nullable
Jason Monk207900c2014-04-25 15:00:09 -04004398 public ProxyInfo getGlobalProxy() {
Chalard Jean5afbc832018-06-07 18:02:37 +09004399 return mProxyTracker.getGlobalProxy();
Robert Greenwalt434203a2010-10-11 16:00:27 -07004400 }
4401
Jason Monk207900c2014-04-25 15:00:09 -04004402 private void handleApplyDefaultProxy(ProxyInfo proxy) {
Jason Monk602b2322013-07-03 17:04:33 -04004403 if (proxy != null && TextUtils.isEmpty(proxy.getHost())
Geoffrey Borggaard79adc952014-11-20 14:35:32 -05004404 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
Chia-chi Yeh4c12a472011-10-03 15:34:04 -07004405 proxy = null;
4406 }
Chalard Jeandaab8f92018-06-08 12:20:15 +09004407 mProxyTracker.setDefaultProxy(proxy);
Robert Greenwalt434203a2010-10-11 16:00:27 -07004408 }
4409
Irina Dumitrescu044a4362018-12-05 16:19:47 +00004410 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
4411 // when any network changes proxy.
4412 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
4413 // multi-network world where an app might be bound to a non-default network.
Chalard Jean4133a122018-06-04 13:33:12 +09004414 private void updateProxy(LinkProperties newLp, LinkProperties oldLp) {
Paul Jensene0bef712014-12-10 15:12:18 -05004415 ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
4416 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
4417
Chalard Jean4949dd72018-06-07 17:41:29 +09004418 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
Chalard Jeanb50a2762018-06-08 19:46:44 +09004419 mProxyTracker.sendProxyBroadcast();
Paul Jensene0bef712014-12-10 15:12:18 -05004420 }
4421 }
4422
Robert Greenwalt434203a2010-10-11 16:00:27 -07004423 private static class SettingsObserver extends ContentObserver {
Erik Klineda4bfa82015-04-30 12:58:40 +09004424 final private HashMap<Uri, Integer> mUriEventMap;
4425 final private Context mContext;
4426 final private Handler mHandler;
4427
4428 SettingsObserver(Context context, Handler handler) {
4429 super(null);
Chalard Jean4133a122018-06-04 13:33:12 +09004430 mUriEventMap = new HashMap<>();
Erik Klineda4bfa82015-04-30 12:58:40 +09004431 mContext = context;
Robert Greenwalt434203a2010-10-11 16:00:27 -07004432 mHandler = handler;
Robert Greenwalt434203a2010-10-11 16:00:27 -07004433 }
4434
Erik Klineda4bfa82015-04-30 12:58:40 +09004435 void observe(Uri uri, int what) {
4436 mUriEventMap.put(uri, what);
4437 final ContentResolver resolver = mContext.getContentResolver();
4438 resolver.registerContentObserver(uri, false, this);
Robert Greenwalt434203a2010-10-11 16:00:27 -07004439 }
4440
4441 @Override
4442 public void onChange(boolean selfChange) {
Erik Klineda4bfa82015-04-30 12:58:40 +09004443 Slog.wtf(TAG, "Should never be reached.");
4444 }
4445
4446 @Override
4447 public void onChange(boolean selfChange, Uri uri) {
4448 final Integer what = mUriEventMap.get(uri);
4449 if (what != null) {
Chalard Jeanafdecd52019-09-26 18:03:47 +09004450 mHandler.obtainMessage(what).sendToTarget();
Erik Klineda4bfa82015-04-30 12:58:40 +09004451 } else {
4452 loge("No matching event to send for URI=" + uri);
4453 }
Robert Greenwalt434203a2010-10-11 16:00:27 -07004454 }
4455 }
Wink Savilleed9c02b2010-12-03 12:01:38 -08004456
Jeff Sharkeyfb878b62012-07-26 18:32:30 -07004457 private static void log(String s) {
Wink Savilleed9c02b2010-12-03 12:01:38 -08004458 Slog.d(TAG, s);
4459 }
4460
Jeff Sharkeyfb878b62012-07-26 18:32:30 -07004461 private static void loge(String s) {
Wink Savilleed9c02b2010-12-03 12:01:38 -08004462 Slog.e(TAG, s);
4463 }
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004464
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004465 private static void loge(String s, Throwable t) {
4466 Slog.e(TAG, s, t);
4467 }
4468
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004469 /**
Jeff Davidson11008a72014-11-20 13:12:46 -08004470 * Prepare for a VPN application.
Robin Lee3b3dd942015-05-12 18:14:58 +01004471 * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
4472 * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
4473 *
4474 * @param oldPackage Package name of the application which currently controls VPN, which will
4475 * be replaced. If there is no such application, this should should either be
4476 * {@code null} or {@link VpnConfig.LEGACY_VPN}.
4477 * @param newPackage Package name of the application which should gain control of VPN, or
4478 * {@code null} to disable.
4479 * @param userId User for whom to prepare the new VPN.
4480 *
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004481 * @hide
4482 */
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004483 @Override
Robin Lee3b3dd942015-05-12 18:14:58 +01004484 public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
4485 int userId) {
4486 enforceCrossUserPermission(userId);
Robin Lee3b3dd942015-05-12 18:14:58 +01004487
Hugo Benichi20035e02017-04-26 14:53:28 +09004488 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09004489 throwIfLockdownEnabled();
Robin Lee47283452015-06-01 10:57:03 -07004490 Vpn vpn = mVpns.get(userId);
4491 if (vpn != null) {
Benedict Wong418017e2019-11-06 00:20:15 -08004492 return vpn.prepare(oldPackage, newPackage, VpnManager.TYPE_VPN_SERVICE);
Robin Lee47283452015-06-01 10:57:03 -07004493 } else {
4494 return false;
4495 }
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004496 }
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004497 }
4498
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004499 /**
Benedict Wong418017e2019-11-06 00:20:15 -08004500 * Set whether the VPN package has the ability to launch VPNs without user intervention. This
4501 * method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn}
4502 * class. If the caller is not {@code userId}, {@link
4503 * android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
Robin Lee3b3dd942015-05-12 18:14:58 +01004504 *
4505 * @param packageName The package for which authorization state should change.
4506 * @param userId User for whom {@code packageName} is installed.
4507 * @param authorized {@code true} if this app should be able to start a VPN connection without
Benedict Wong418017e2019-11-06 00:20:15 -08004508 * explicit user approval, {@code false} if not.
4509 * @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN
4510 * permissions should be granted. When unauthorizing an app, {@link
4511 * VpnManager.TYPE_VPN_NONE} should be used.
Jeff Davidson05542602014-08-11 14:07:27 -07004512 * @hide
4513 */
4514 @Override
Benedict Wong418017e2019-11-06 00:20:15 -08004515 public void setVpnPackageAuthorization(
4516 String packageName, int userId, @VpnManager.VpnType int vpnType) {
Robin Lee3b3dd942015-05-12 18:14:58 +01004517 enforceCrossUserPermission(userId);
4518
Hugo Benichi20035e02017-04-26 14:53:28 +09004519 synchronized (mVpns) {
Robin Lee47283452015-06-01 10:57:03 -07004520 Vpn vpn = mVpns.get(userId);
4521 if (vpn != null) {
Benedict Wong418017e2019-11-06 00:20:15 -08004522 vpn.setPackageAuthorization(packageName, vpnType);
Robin Lee47283452015-06-01 10:57:03 -07004523 }
Jeff Davidson05542602014-08-11 14:07:27 -07004524 }
4525 }
4526
4527 /**
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004528 * Configure a TUN interface and return its file descriptor. Parameters
4529 * are encoded and opaque to this class. This method is used by VpnBuilder
Chia-chi Yeh2e467642011-07-04 03:23:12 -07004530 * and not available in ConnectivityManager. Permissions are checked in
4531 * Vpn class.
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004532 * @hide
4533 */
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004534 @Override
Chia-chi Yeh04ba25c2011-06-15 17:07:27 -07004535 public ParcelFileDescriptor establishVpn(VpnConfig config) {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004536 int user = UserHandle.getUserId(Binder.getCallingUid());
Hugo Benichi20035e02017-04-26 14:53:28 +09004537 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09004538 throwIfLockdownEnabled();
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004539 return mVpns.get(user).establish(config);
4540 }
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004541 }
4542
Chia-chi Yeh77fd4852011-07-02 17:15:00 -07004543 /**
Benedict Wongb4b925f2019-11-05 12:56:25 -08004544 * Stores the given VPN profile based on the provisioning package name.
4545 *
4546 * <p>If there is already a VPN profile stored for the provisioning package, this call will
4547 * overwrite the profile.
4548 *
4549 * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
4550 * exclusively by the Settings app, and passed into the platform at startup time.
4551 *
4552 * @return {@code true} if user consent has already been granted, {@code false} otherwise.
4553 * @hide
4554 */
4555 @Override
4556 public boolean provisionVpnProfile(@NonNull VpnProfile profile, @NonNull String packageName) {
4557 final int user = UserHandle.getUserId(Binder.getCallingUid());
4558 synchronized (mVpns) {
4559 return mVpns.get(user).provisionVpnProfile(packageName, profile, mKeyStore);
4560 }
4561 }
4562
4563 /**
4564 * Deletes the stored VPN profile for the provisioning package
4565 *
4566 * <p>If there are no profiles for the given package, this method will silently succeed.
4567 *
4568 * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
4569 * exclusively by the Settings app, and passed into the platform at startup time.
4570 *
4571 * @hide
4572 */
4573 @Override
4574 public void deleteVpnProfile(@NonNull String packageName) {
4575 final int user = UserHandle.getUserId(Binder.getCallingUid());
4576 synchronized (mVpns) {
4577 mVpns.get(user).deleteVpnProfile(packageName, mKeyStore);
4578 }
4579 }
4580
4581 /**
4582 * Starts the VPN based on the stored profile for the given package
4583 *
4584 * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
4585 * exclusively by the Settings app, and passed into the platform at startup time.
4586 *
4587 * @throws IllegalArgumentException if no profile was found for the given package name.
4588 * @hide
4589 */
4590 @Override
4591 public void startVpnProfile(@NonNull String packageName) {
4592 final int user = UserHandle.getUserId(Binder.getCallingUid());
4593 synchronized (mVpns) {
4594 throwIfLockdownEnabled();
4595 mVpns.get(user).startVpnProfile(packageName, mKeyStore);
4596 }
4597 }
4598
4599 /**
4600 * Stops the Platform VPN if the provided package is running one.
4601 *
4602 * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
4603 * exclusively by the Settings app, and passed into the platform at startup time.
4604 *
4605 * @hide
4606 */
4607 @Override
4608 public void stopVpnProfile(@NonNull String packageName) {
4609 final int user = UserHandle.getUserId(Binder.getCallingUid());
4610 synchronized (mVpns) {
4611 mVpns.get(user).stopVpnProfile(packageName);
4612 }
4613 }
4614
4615 /**
Jeff Sharkey82f85212012-08-24 11:17:25 -07004616 * Start legacy VPN, controlling native daemons as needed. Creates a
4617 * secondary thread to perform connection work, returning quickly.
Chia-chi Yeh77fd4852011-07-02 17:15:00 -07004618 */
4619 @Override
Jeff Sharkey82f85212012-08-24 11:17:25 -07004620 public void startLegacyVpn(VpnProfile profile) {
Hugo Benichi69744342017-11-27 10:57:16 +09004621 int user = UserHandle.getUserId(Binder.getCallingUid());
Jeff Sharkey82f85212012-08-24 11:17:25 -07004622 final LinkProperties egress = getActiveLinkProperties();
4623 if (egress == null) {
4624 throw new IllegalStateException("Missing active network connection");
4625 }
Hugo Benichi20035e02017-04-26 14:53:28 +09004626 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09004627 throwIfLockdownEnabled();
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004628 mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
4629 }
Chia-chi Yeh2e467642011-07-04 03:23:12 -07004630 }
4631
4632 /**
4633 * Return the information of the ongoing legacy VPN. This method is used
4634 * by VpnSettings and not available in ConnectivityManager. Permissions
4635 * are checked in Vpn class.
Chia-chi Yeh2e467642011-07-04 03:23:12 -07004636 */
4637 @Override
Robin Lee3eed5ec2015-07-07 12:28:13 -07004638 public LegacyVpnInfo getLegacyVpnInfo(int userId) {
4639 enforceCrossUserPermission(userId);
Hung-ying Tyan44c8c5c2015-07-29 12:39:21 +08004640
Hugo Benichi20035e02017-04-26 14:53:28 +09004641 synchronized (mVpns) {
Robin Lee3eed5ec2015-07-07 12:28:13 -07004642 return mVpns.get(userId).getLegacyVpnInfo();
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004643 }
Chia-chi Yeh77fd4852011-07-02 17:15:00 -07004644 }
4645
Chia-chi Yehff3bdca2011-05-23 17:26:46 -07004646 /**
Varun Anandd33cbc62019-02-07 14:13:13 -08004647 * Return the information of all ongoing VPNs.
4648 *
4649 * <p>This method is used to update NetworkStatsService.
4650 *
4651 * <p>Must be called on the handler thread.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08004652 */
Varun Anandd33cbc62019-02-07 14:13:13 -08004653 private VpnInfo[] getAllVpnInfo() {
4654 ensureRunningOnConnectivityServiceThread();
Hugo Benichi20035e02017-04-26 14:53:28 +09004655 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09004656 if (mLockdownEnabled) {
4657 return new VpnInfo[0];
4658 }
4659
Wenchao Tongf5ea3402015-03-04 13:26:38 -08004660 List<VpnInfo> infoList = new ArrayList<>();
4661 for (int i = 0; i < mVpns.size(); i++) {
4662 VpnInfo info = createVpnInfo(mVpns.valueAt(i));
4663 if (info != null) {
4664 infoList.add(info);
4665 }
4666 }
4667 return infoList.toArray(new VpnInfo[infoList.size()]);
4668 }
4669 }
4670
4671 /**
4672 * @return VPN information for accounting, or null if we can't retrieve all required
Benedict Wonga84d9fa2019-06-12 17:46:15 +00004673 * information, e.g underlying ifaces.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08004674 */
4675 @Nullable
4676 private VpnInfo createVpnInfo(Vpn vpn) {
4677 VpnInfo info = vpn.getVpnInfo();
4678 if (info == null) {
4679 return null;
4680 }
4681 Network[] underlyingNetworks = vpn.getUnderlyingNetworks();
4682 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
4683 // the underlyingNetworks list.
4684 if (underlyingNetworks == null) {
Benedict Wonga84d9fa2019-06-12 17:46:15 +00004685 NetworkAgentInfo defaultNai = getDefaultNetwork();
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00004686 if (defaultNai != null) {
Benedict Wonga84d9fa2019-06-12 17:46:15 +00004687 underlyingNetworks = new Network[] { defaultNai.network };
Wenchao Tongf5ea3402015-03-04 13:26:38 -08004688 }
4689 }
Benedict Wonga84d9fa2019-06-12 17:46:15 +00004690 if (underlyingNetworks != null && underlyingNetworks.length > 0) {
4691 List<String> interfaces = new ArrayList<>();
4692 for (Network network : underlyingNetworks) {
4693 LinkProperties lp = getLinkProperties(network);
4694 if (lp != null) {
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00004695 for (String iface : lp.getAllInterfaceNames()) {
4696 if (!TextUtils.isEmpty(iface)) {
4697 interfaces.add(iface);
4698 }
4699 }
Benedict Wonga84d9fa2019-06-12 17:46:15 +00004700 }
4701 }
4702 if (!interfaces.isEmpty()) {
4703 info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
4704 }
4705 }
4706 return info.underlyingIfaces == null ? null : info;
Wenchao Tongf5ea3402015-03-04 13:26:38 -08004707 }
4708
4709 /**
Robin Lee3b3dd942015-05-12 18:14:58 +01004710 * Returns the information of the ongoing VPN for {@code userId}. This method is used by
4711 * VpnDialogs and not available in ConnectivityManager.
Chad Brubakerbf6ff2c2013-07-16 18:59:12 -07004712 * Permissions are checked in Vpn class.
4713 * @hide
4714 */
4715 @Override
Robin Lee3b3dd942015-05-12 18:14:58 +01004716 public VpnConfig getVpnConfig(int userId) {
4717 enforceCrossUserPermission(userId);
Hugo Benichi20035e02017-04-26 14:53:28 +09004718 synchronized (mVpns) {
Robin Lee47283452015-06-01 10:57:03 -07004719 Vpn vpn = mVpns.get(userId);
4720 if (vpn != null) {
4721 return vpn.getVpnConfig();
4722 } else {
4723 return null;
4724 }
Chad Brubakerbf6ff2c2013-07-16 18:59:12 -07004725 }
4726 }
4727
Chalard Jean6b65ec72018-05-18 22:02:56 +09004728 /**
4729 * Ask all VPN objects to recompute and update their capabilities.
4730 *
4731 * When underlying networks change, VPNs may have to update capabilities to reflect things
4732 * like the metered bit, their transports, and so on. This asks the VPN objects to update
4733 * their capabilities, and as this will cause them to send messages to the ConnectivityService
4734 * handler thread through their agent, this is asynchronous. When the capabilities objects
4735 * are computed they will be up-to-date as they are computed synchronously from here and
4736 * this is running on the ConnectivityService thread.
Chalard Jean6b65ec72018-05-18 22:02:56 +09004737 */
4738 private void updateAllVpnsCapabilities() {
Varun Anand4fa80e82019-02-06 10:13:38 -08004739 Network defaultNetwork = getNetwork(getDefaultNetwork());
Chalard Jean6b65ec72018-05-18 22:02:56 +09004740 synchronized (mVpns) {
4741 for (int i = 0; i < mVpns.size(); i++) {
4742 final Vpn vpn = mVpns.valueAt(i);
Varun Anand4fa80e82019-02-06 10:13:38 -08004743 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
4744 updateVpnCapabilities(vpn, nc);
Chalard Jean6b65ec72018-05-18 22:02:56 +09004745 }
4746 }
4747 }
4748
Varun Anand4fa80e82019-02-06 10:13:38 -08004749 private void updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc) {
4750 ensureRunningOnConnectivityServiceThread();
4751 NetworkAgentInfo vpnNai = getNetworkAgentInfoForNetId(vpn.getNetId());
4752 if (vpnNai == null || nc == null) {
4753 return;
4754 }
4755 updateCapabilities(vpnNai.getCurrentScore(), vpnNai, nc);
4756 }
4757
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004758 @Override
4759 public boolean updateLockdownVpn() {
Jeff Sharkey3671b1e2013-01-31 17:22:26 -08004760 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
4761 Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
4762 return false;
4763 }
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004764
Hugo Benichi69744342017-11-27 10:57:16 +09004765 synchronized (mVpns) {
4766 // Tear down existing lockdown if profile was removed
4767 mLockdownEnabled = LockdownVpnTracker.isEnabled();
4768 if (mLockdownEnabled) {
4769 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
4770 if (profileTag == null) {
4771 Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore");
4772 return false;
4773 }
4774 String profileName = new String(profileTag);
4775 final VpnProfile profile = VpnProfile.decode(
4776 profileName, mKeyStore.get(Credentials.VPN + profileName));
4777 if (profile == null) {
4778 Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName);
4779 setLockdownTracker(null);
4780 return true;
4781 }
4782 int user = UserHandle.getUserId(Binder.getCallingUid());
Robin Lee18566c12016-03-14 13:08:48 +00004783 Vpn vpn = mVpns.get(user);
4784 if (vpn == null) {
4785 Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
4786 return false;
4787 }
junyulai465088e2019-08-30 16:44:45 +08004788 setLockdownTracker(new LockdownVpnTracker(mContext, this, mHandler, vpn, profile));
Hugo Benichi69744342017-11-27 10:57:16 +09004789 } else {
4790 setLockdownTracker(null);
Chad Brubaker4ca19e82013-06-14 11:16:51 -07004791 }
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004792 }
4793
4794 return true;
4795 }
4796
4797 /**
4798 * Internally set new {@link LockdownVpnTracker}, shutting down any existing
4799 * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
4800 */
Hugo Benichi69744342017-11-27 10:57:16 +09004801 @GuardedBy("mVpns")
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004802 private void setLockdownTracker(LockdownVpnTracker tracker) {
4803 // Shutdown any existing tracker
4804 final LockdownVpnTracker existing = mLockdownTracker;
junyulai05986c62018-08-07 19:50:45 +08004805 // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
4806 // necessary onBlockedStatusChanged callbacks.
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004807 mLockdownTracker = null;
4808 if (existing != null) {
4809 existing.shutdown();
4810 }
4811
Robin Leec3736bc2017-03-10 16:19:54 +00004812 if (tracker != null) {
4813 mLockdownTracker = tracker;
4814 mLockdownTracker.init();
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004815 }
4816 }
4817
Benedict Wongb4b925f2019-11-05 12:56:25 -08004818 /**
4819 * Throws if there is any currently running, always-on Legacy VPN.
4820 *
4821 * <p>The LockdownVpnTracker and mLockdownEnabled both track whether an always-on Legacy VPN is
4822 * running across the entire system. Tracking for app-based VPNs is done on a per-user,
4823 * per-package basis in Vpn.java
4824 */
Hugo Benichi69744342017-11-27 10:57:16 +09004825 @GuardedBy("mVpns")
Jeff Sharkey69ddab42012-08-25 00:05:46 -07004826 private void throwIfLockdownEnabled() {
4827 if (mLockdownEnabled) {
4828 throw new IllegalStateException("Unavailable in lockdown mode");
4829 }
4830 }
Robert Greenwalt665e1ae2012-08-21 19:27:00 -07004831
Robin Lee244ce8e2016-01-05 18:03:46 +00004832 /**
Robin Lee17e61832016-05-09 13:46:28 +01004833 * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform
4834 * some setup and then call {@code establish()} to connect.
Robin Lee244ce8e2016-01-05 18:03:46 +00004835 *
Robin Lee17e61832016-05-09 13:46:28 +01004836 * @return {@code true} if the service was started, the service was already connected, or there
4837 * was no always-on VPN to start. {@code false} otherwise.
Robin Lee244ce8e2016-01-05 18:03:46 +00004838 */
Robin Lee17e61832016-05-09 13:46:28 +01004839 private boolean startAlwaysOnVpn(int userId) {
Robin Lee17e61832016-05-09 13:46:28 +01004840 synchronized (mVpns) {
4841 Vpn vpn = mVpns.get(userId);
4842 if (vpn == null) {
Chalard Jean4d660112018-06-04 16:52:49 +09004843 // Shouldn't happen as all code paths that point here should have checked the Vpn
Robin Lee17e61832016-05-09 13:46:28 +01004844 // exists already.
4845 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration");
4846 return false;
4847 }
Robin Lee244ce8e2016-01-05 18:03:46 +00004848
Benedict Wongb570e862020-01-17 19:33:55 -08004849 return vpn.startAlwaysOnVpn(mKeyStore);
Robin Lee244ce8e2016-01-05 18:03:46 +00004850 }
4851 }
4852
4853 @Override
Charles He36738632017-05-15 17:07:18 +01004854 public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
4855 enforceSettingsPermission();
4856 enforceCrossUserPermission(userId);
4857
4858 synchronized (mVpns) {
4859 Vpn vpn = mVpns.get(userId);
4860 if (vpn == null) {
4861 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4862 return false;
4863 }
Benedict Wongb570e862020-01-17 19:33:55 -08004864 return vpn.isAlwaysOnPackageSupported(packageName, mKeyStore);
Charles He36738632017-05-15 17:07:18 +01004865 }
4866 }
4867
4868 @Override
Pavel Grafova462bcb2019-01-25 08:50:06 +00004869 public boolean setAlwaysOnVpnPackage(
4870 int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist) {
4871 enforceControlAlwaysOnVpnPermission();
Robin Lee244ce8e2016-01-05 18:03:46 +00004872 enforceCrossUserPermission(userId);
4873
Robin Lee244ce8e2016-01-05 18:03:46 +00004874 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09004875 // Can't set always-on VPN if legacy VPN is already in lockdown mode.
4876 if (LockdownVpnTracker.isEnabled()) {
4877 return false;
4878 }
4879
Robin Lee244ce8e2016-01-05 18:03:46 +00004880 Vpn vpn = mVpns.get(userId);
4881 if (vpn == null) {
4882 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4883 return false;
4884 }
Benedict Wongb570e862020-01-17 19:33:55 -08004885 if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownWhitelist, mKeyStore)) {
Robin Lee244ce8e2016-01-05 18:03:46 +00004886 return false;
4887 }
Robin Lee17e61832016-05-09 13:46:28 +01004888 if (!startAlwaysOnVpn(userId)) {
Benedict Wongb570e862020-01-17 19:33:55 -08004889 vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
Robin Lee244ce8e2016-01-05 18:03:46 +00004890 return false;
4891 }
4892 }
4893 return true;
4894 }
4895
4896 @Override
4897 public String getAlwaysOnVpnPackage(int userId) {
Pavel Grafova462bcb2019-01-25 08:50:06 +00004898 enforceControlAlwaysOnVpnPermission();
Robin Lee244ce8e2016-01-05 18:03:46 +00004899 enforceCrossUserPermission(userId);
4900
4901 synchronized (mVpns) {
4902 Vpn vpn = mVpns.get(userId);
4903 if (vpn == null) {
4904 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4905 return null;
4906 }
4907 return vpn.getAlwaysOnPackage();
4908 }
4909 }
4910
Wink Savilleab9321d2013-06-29 21:10:57 -07004911 @Override
Pavel Grafova462bcb2019-01-25 08:50:06 +00004912 public boolean isVpnLockdownEnabled(int userId) {
4913 enforceControlAlwaysOnVpnPermission();
4914 enforceCrossUserPermission(userId);
4915
4916 synchronized (mVpns) {
4917 Vpn vpn = mVpns.get(userId);
4918 if (vpn == null) {
4919 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4920 return false;
4921 }
4922 return vpn.getLockdown();
4923 }
4924 }
4925
4926 @Override
4927 public List<String> getVpnLockdownWhitelist(int userId) {
4928 enforceControlAlwaysOnVpnPermission();
4929 enforceCrossUserPermission(userId);
4930
4931 synchronized (mVpns) {
4932 Vpn vpn = mVpns.get(userId);
4933 if (vpn == null) {
4934 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4935 return null;
4936 }
4937 return vpn.getLockdownWhitelist();
4938 }
4939 }
4940
4941 @Override
Wink Saville948282b2013-08-29 08:55:16 -07004942 public int checkMobileProvisioning(int suggestedTimeOutMs) {
Paul Jensen89e0f092014-09-15 15:59:36 -04004943 // TODO: Remove? Any reason to trigger a provisioning check?
4944 return -1;
Wink Saville948282b2013-08-29 08:55:16 -07004945 }
4946
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004947 /** Location to an updatable file listing carrier provisioning urls.
4948 * An example:
4949 *
4950 * <?xml version="1.0" encoding="utf-8"?>
4951 * <provisioningUrls>
4952 * <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&amp;iccid=%1$s&amp;imei=%2$s</provisioningUrl>
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004953 * </provisioningUrls>
4954 */
4955 private static final String PROVISIONING_URL_PATH =
4956 "/data/misc/radio/provisioning_urls.xml";
4957 private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH);
Wink Savilleab9321d2013-06-29 21:10:57 -07004958
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004959 /** XML tag for root element. */
4960 private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
4961 /** XML tag for individual url */
4962 private static final String TAG_PROVISIONING_URL = "provisioningUrl";
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004963 /** XML attribute for mcc */
4964 private static final String ATTR_MCC = "mcc";
4965 /** XML attribute for mnc */
4966 private static final String ATTR_MNC = "mnc";
4967
Paul Jensen434dde82015-06-11 09:43:30 -04004968 private String getProvisioningUrlBaseFromFile() {
Chalard Jeanafdecd52019-09-26 18:03:47 +09004969 XmlPullParser parser;
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004970 Configuration config = mContext.getResources().getConfiguration();
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004971
Chalard Jeanafdecd52019-09-26 18:03:47 +09004972 try (FileReader fileReader = new FileReader(mProvisioningUrlFile)) {
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004973 parser = Xml.newPullParser();
4974 parser.setInput(fileReader);
4975 XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
4976
4977 while (true) {
4978 XmlUtils.nextElement(parser);
4979
4980 String element = parser.getName();
4981 if (element == null) break;
4982
Paul Jensen434dde82015-06-11 09:43:30 -04004983 if (element.equals(TAG_PROVISIONING_URL)) {
Robert Greenwalte182bfe2013-07-16 12:06:09 -07004984 String mcc = parser.getAttributeValue(null, ATTR_MCC);
4985 try {
4986 if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
4987 String mnc = parser.getAttributeValue(null, ATTR_MNC);
4988 if (mnc != null && Integer.parseInt(mnc) == config.mnc) {
4989 parser.next();
4990 if (parser.getEventType() == XmlPullParser.TEXT) {
4991 return parser.getText();
4992 }
4993 }
4994 }
4995 } catch (NumberFormatException e) {
4996 loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e);
4997 }
4998 }
4999 }
5000 return null;
5001 } catch (FileNotFoundException e) {
5002 loge("Carrier Provisioning Urls file not found");
5003 } catch (XmlPullParserException e) {
5004 loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
5005 } catch (IOException e) {
5006 loge("I/O exception reading Carrier Provisioning Urls file: " + e);
Robert Greenwalte182bfe2013-07-16 12:06:09 -07005007 }
5008 return null;
5009 }
5010
Wink Saville42d4f082013-07-20 20:31:59 -07005011 @Override
Robert Greenwalte182bfe2013-07-16 12:06:09 -07005012 public String getMobileProvisioningUrl() {
paulhu59148b72019-08-12 16:25:11 +08005013 enforceSettingsPermission();
Paul Jensen434dde82015-06-11 09:43:30 -04005014 String url = getProvisioningUrlBaseFromFile();
Robert Greenwalte182bfe2013-07-16 12:06:09 -07005015 if (TextUtils.isEmpty(url)) {
5016 url = mContext.getResources().getString(R.string.mobile_provisioning_url);
Wink Saville42d4f082013-07-20 20:31:59 -07005017 log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
Robert Greenwalte182bfe2013-07-16 12:06:09 -07005018 } else {
Wink Saville42d4f082013-07-20 20:31:59 -07005019 log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url);
Robert Greenwalte182bfe2013-07-16 12:06:09 -07005020 }
Wink Saville8cf35602013-07-10 23:00:07 -07005021 // populate the iccid, imei and phone number in the provisioning url.
Wink Savilleab9321d2013-06-29 21:10:57 -07005022 if (!TextUtils.isEmpty(url)) {
Wink Saville8cf35602013-07-10 23:00:07 -07005023 String phoneNumber = mTelephonyManager.getLine1Number();
5024 if (TextUtils.isEmpty(phoneNumber)) {
5025 phoneNumber = "0000000000";
5026 }
Wink Savilleab9321d2013-06-29 21:10:57 -07005027 url = String.format(url,
5028 mTelephonyManager.getSimSerialNumber() /* ICCID */,
5029 mTelephonyManager.getDeviceId() /* IMEI */,
Chalard Jean4d660112018-06-04 16:52:49 +09005030 phoneNumber /* Phone number */);
Wink Savilleab9321d2013-06-29 21:10:57 -07005031 }
5032
Wink Savilleab9321d2013-06-29 21:10:57 -07005033 return url;
5034 }
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005035
Wink Saville948282b2013-08-29 08:55:16 -07005036 @Override
5037 public void setProvisioningNotificationVisible(boolean visible, int networkType,
Paul Jensen89e0f092014-09-15 15:59:36 -04005038 String action) {
paulhu59148b72019-08-12 16:25:11 +08005039 enforceSettingsPermission();
Hugo Benichi16f0a942017-06-20 14:07:59 +09005040 if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
5041 return;
5042 }
Paul Jensen89e0f092014-09-15 15:59:36 -04005043 final long ident = Binder.clearCallingIdentity();
5044 try {
Lorenzo Colitti0b599062016-08-22 22:36:19 +09005045 // Concatenate the range of types onto the range of NetIDs.
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09005046 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
Lorenzo Colitti0b599062016-08-22 22:36:19 +09005047 mNotifier.setProvNotificationVisible(visible, id, action);
Paul Jensen89e0f092014-09-15 15:59:36 -04005048 } finally {
5049 Binder.restoreCallingIdentity(ident);
5050 }
Wink Saville948282b2013-08-29 08:55:16 -07005051 }
Wink Saville7788c612013-08-29 14:57:08 -07005052
Yuhao Zheng5cd1a0e2013-09-09 17:00:04 -07005053 @Override
5054 public void setAirplaneMode(boolean enable) {
Edward Savage-Jonesaffb2292019-11-26 13:18:08 +01005055 enforceAirplaneModePermission();
Yuhao Zheng5cd1a0e2013-09-09 17:00:04 -07005056 final long ident = Binder.clearCallingIdentity();
5057 try {
Yuhao Zheng5530e4b2013-09-11 09:36:41 -07005058 final ContentResolver cr = mContext.getContentResolver();
Hugo Benichiab7d2e62017-04-21 15:07:12 +09005059 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
Yuhao Zheng5530e4b2013-09-11 09:36:41 -07005060 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
5061 intent.putExtra("state", enable);
xinhe98e25fc2014-11-17 11:35:01 -08005062 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Yuhao Zheng5cd1a0e2013-09-09 17:00:04 -07005063 } finally {
5064 Binder.restoreCallingIdentity(ident);
5065 }
5066 }
5067
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005068 private void onUserStart(int userId) {
Hugo Benichi20035e02017-04-26 14:53:28 +09005069 synchronized (mVpns) {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005070 Vpn userVpn = mVpns.get(userId);
5071 if (userVpn != null) {
5072 loge("Starting user already has a VPN");
5073 return;
5074 }
Benedict Wongb570e862020-01-17 19:33:55 -08005075 userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId, mKeyStore);
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005076 mVpns.put(userId, userVpn);
Hugo Benichi69744342017-11-27 10:57:16 +09005077 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
5078 updateLockdownVpn();
5079 }
Robin Lee9a5f4852015-12-17 11:42:22 +00005080 }
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005081 }
5082
5083 private void onUserStop(int userId) {
Hugo Benichi20035e02017-04-26 14:53:28 +09005084 synchronized (mVpns) {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005085 Vpn userVpn = mVpns.get(userId);
5086 if (userVpn == null) {
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -07005087 loge("Stopped user has no VPN");
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005088 return;
5089 }
Robin Lee17e61832016-05-09 13:46:28 +01005090 userVpn.onUserStopped();
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005091 mVpns.delete(userId);
5092 }
5093 }
5094
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005095 private void onUserAdded(int userId) {
junyulai2454b692018-11-01 17:16:31 +08005096 mPermissionMonitor.onUserAdded(userId);
Varun Anand4fa80e82019-02-06 10:13:38 -08005097 Network defaultNetwork = getNetwork(getDefaultNetwork());
Hugo Benichi20035e02017-04-26 14:53:28 +09005098 synchronized (mVpns) {
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005099 final int vpnsSize = mVpns.size();
5100 for (int i = 0; i < vpnsSize; i++) {
5101 Vpn vpn = mVpns.valueAt(i);
5102 vpn.onUserAdded(userId);
Varun Anand4fa80e82019-02-06 10:13:38 -08005103 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
5104 updateVpnCapabilities(vpn, nc);
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005105 }
5106 }
5107 }
5108
5109 private void onUserRemoved(int userId) {
junyulai2454b692018-11-01 17:16:31 +08005110 mPermissionMonitor.onUserRemoved(userId);
Varun Anand4fa80e82019-02-06 10:13:38 -08005111 Network defaultNetwork = getNetwork(getDefaultNetwork());
Hugo Benichi20035e02017-04-26 14:53:28 +09005112 synchronized (mVpns) {
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005113 final int vpnsSize = mVpns.size();
5114 for (int i = 0; i < vpnsSize; i++) {
5115 Vpn vpn = mVpns.valueAt(i);
5116 vpn.onUserRemoved(userId);
Varun Anand4fa80e82019-02-06 10:13:38 -08005117 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
5118 updateVpnCapabilities(vpn, nc);
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005119 }
5120 }
5121 }
5122
junyulai2454b692018-11-01 17:16:31 +08005123 private void onPackageAdded(String packageName, int uid) {
5124 if (TextUtils.isEmpty(packageName) || uid < 0) {
5125 Slog.wtf(TAG, "Invalid package in onPackageAdded: " + packageName + " | " + uid);
5126 return;
5127 }
5128 mPermissionMonitor.onPackageAdded(packageName, uid);
5129 }
5130
junyulaiefb04d32018-11-12 22:39:30 +08005131 private void onPackageReplaced(String packageName, int uid) {
5132 if (TextUtils.isEmpty(packageName) || uid < 0) {
5133 Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
5134 return;
5135 }
5136 final int userId = UserHandle.getUserId(uid);
5137 synchronized (mVpns) {
5138 final Vpn vpn = mVpns.get(userId);
5139 if (vpn == null) {
5140 return;
5141 }
5142 // Legacy always-on VPN won't be affected since the package name is not set.
5143 if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
5144 Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user "
5145 + userId);
Benedict Wongb570e862020-01-17 19:33:55 -08005146 vpn.startAlwaysOnVpn(mKeyStore);
junyulaiefb04d32018-11-12 22:39:30 +08005147 }
5148 }
5149 }
5150
5151 private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
junyulai2454b692018-11-01 17:16:31 +08005152 if (TextUtils.isEmpty(packageName) || uid < 0) {
5153 Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
5154 return;
5155 }
5156 mPermissionMonitor.onPackageRemoved(uid);
junyulaiefb04d32018-11-12 22:39:30 +08005157
5158 final int userId = UserHandle.getUserId(uid);
5159 synchronized (mVpns) {
5160 final Vpn vpn = mVpns.get(userId);
5161 if (vpn == null) {
5162 return;
5163 }
5164 // Legacy always-on VPN won't be affected since the package name is not set.
5165 if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
5166 Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user "
5167 + userId);
Benedict Wongb570e862020-01-17 19:33:55 -08005168 vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
junyulaiefb04d32018-11-12 22:39:30 +08005169 }
5170 }
junyulai2454b692018-11-01 17:16:31 +08005171 }
5172
Robin Lee89e7a692016-02-29 14:38:17 +00005173 private void onUserUnlocked(int userId) {
Hugo Benichi69744342017-11-27 10:57:16 +09005174 synchronized (mVpns) {
5175 // User present may be sent because of an unlock, which might mean an unlocked keystore.
5176 if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
5177 updateLockdownVpn();
5178 } else {
5179 startAlwaysOnVpn(userId);
5180 }
Robin Lee9a5f4852015-12-17 11:42:22 +00005181 }
5182 }
5183
junyulai2454b692018-11-01 17:16:31 +08005184 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005185 @Override
5186 public void onReceive(Context context, Intent intent) {
Varun Anand4fa80e82019-02-06 10:13:38 -08005187 ensureRunningOnConnectivityServiceThread();
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005188 final String action = intent.getAction();
5189 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
junyulai2454b692018-11-01 17:16:31 +08005190 final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
5191 final Uri packageData = intent.getData();
5192 final String packageName =
5193 packageData != null ? packageData.getSchemeSpecificPart() : null;
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005194 if (userId == UserHandle.USER_NULL) return;
5195
Robin Lee323f29d2016-05-04 16:38:06 +01005196 if (Intent.ACTION_USER_STARTED.equals(action)) {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005197 onUserStart(userId);
Amith Yamasaniad2e4bf2016-04-26 14:35:54 -07005198 } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005199 onUserStop(userId);
Fyodor Kupolov1c363152015-09-02 13:27:21 -07005200 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
5201 onUserAdded(userId);
5202 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
5203 onUserRemoved(userId);
Robin Lee89e7a692016-02-29 14:38:17 +00005204 } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
5205 onUserUnlocked(userId);
junyulai2454b692018-11-01 17:16:31 +08005206 } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
5207 onPackageAdded(packageName, uid);
junyulaiefb04d32018-11-12 22:39:30 +08005208 } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
5209 onPackageReplaced(packageName, uid);
junyulai2454b692018-11-01 17:16:31 +08005210 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
junyulaiefb04d32018-11-12 22:39:30 +08005211 final boolean isReplacing = intent.getBooleanExtra(
5212 Intent.EXTRA_REPLACING, false);
5213 onPackageRemoved(packageName, uid, isReplacing);
Chad Brubaker4ca19e82013-06-14 11:16:51 -07005214 }
5215 }
5216 };
Vinit Deshapnde1f12cb52013-08-21 13:09:01 -07005217
Robin Lee95204e02017-01-27 11:59:22 +00005218 private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
5219 @Override
5220 public void onReceive(Context context, Intent intent) {
5221 // Try creating lockdown tracker, since user present usually means
5222 // unlocked keystore.
5223 updateLockdownVpn();
5224 mContext.unregisterReceiver(this);
5225 }
5226 };
5227
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005228 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
Chalard Jean4133a122018-06-04 13:33:12 +09005229 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
Robert Greenwalte049c232014-04-11 15:53:27 -07005230
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04005231 private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
5232 // Map from UID to number of NetworkRequests that UID has filed.
5233 @GuardedBy("mUidToNetworkRequestCount")
5234 private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
5235
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005236 private static class NetworkProviderInfo {
Robert Greenwalta67be032014-05-16 15:49:14 -07005237 public final String name;
5238 public final Messenger messenger;
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005239 private final AsyncChannel mAsyncChannel;
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005240 private final IBinder.DeathRecipient mDeathRecipient;
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005241 public final int providerId;
Robert Greenwalta67be032014-05-16 15:49:14 -07005242
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005243 NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
5244 int providerId, IBinder.DeathRecipient deathRecipient) {
Robert Greenwalta67be032014-05-16 15:49:14 -07005245 this.name = name;
5246 this.messenger = messenger;
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005247 this.providerId = providerId;
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005248 mAsyncChannel = asyncChannel;
5249 mDeathRecipient = deathRecipient;
5250
5251 if ((mAsyncChannel == null) == (mDeathRecipient == null)) {
5252 throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient");
5253 }
5254 }
5255
5256 boolean isLegacyNetworkFactory() {
5257 return mAsyncChannel != null;
5258 }
5259
5260 void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) {
5261 try {
5262 messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj));
5263 } catch (RemoteException e) {
5264 // Remote process died. Ignore; the death recipient will remove this
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005265 // NetworkProviderInfo from mNetworkProviderInfos.
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005266 }
Robert Greenwalta67be032014-05-16 15:49:14 -07005267 }
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005268
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005269 void requestNetwork(NetworkRequest request, int score, int servingProviderId) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005270 if (isLegacyNetworkFactory()) {
5271 mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005272 servingProviderId, request);
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005273 } else {
5274 sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score,
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005275 servingProviderId, request);
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005276 }
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005277 }
5278
5279 void cancelRequest(NetworkRequest request) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005280 if (isLegacyNetworkFactory()) {
5281 mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request);
5282 } else {
5283 sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request);
5284 }
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005285 }
5286
5287 void connect(Context context, Handler handler) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005288 if (isLegacyNetworkFactory()) {
5289 mAsyncChannel.connect(context, handler, messenger);
5290 } else {
5291 try {
5292 messenger.getBinder().linkToDeath(mDeathRecipient, 0);
5293 } catch (RemoteException e) {
5294 mDeathRecipient.binderDied();
5295 }
5296 }
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005297 }
5298
5299 void completeConnection() {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005300 if (isLegacyNetworkFactory()) {
5301 mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
5302 }
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09005303 }
Robert Greenwalta67be032014-05-16 15:49:14 -07005304 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07005305
Lorenzo Colitti1ec11eb2016-07-05 01:22:13 +09005306 private void ensureNetworkRequestHasType(NetworkRequest request) {
5307 if (request.type == NetworkRequest.Type.NONE) {
5308 throw new IllegalArgumentException(
5309 "All NetworkRequests in ConnectivityService must have a type");
5310 }
5311 }
5312
Robert Greenwalt39fa65a2014-07-27 10:56:49 -07005313 /**
5314 * Tracks info about the requester.
5315 * Also used to notice when the calling process dies so we can self-expire
5316 */
Robert Greenwalt9258c642014-03-26 16:47:06 -07005317 private class NetworkRequestInfo implements IBinder.DeathRecipient {
Robert Greenwalt9258c642014-03-26 16:47:06 -07005318 final NetworkRequest request;
Chalard Jean68602592019-11-05 15:07:09 +09005319 // The network currently satisfying this request, or null if none. Must only be touched
5320 // on the handler thread. This only makes sense for network requests and not for listens,
5321 // as defined by NetworkRequest#isRequest(). For listens, this is always null.
5322 @Nullable
5323 NetworkAgentInfo mSatisfier;
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005324 final PendingIntent mPendingIntent;
Jeremy Joslin79294842014-12-03 17:15:28 -08005325 boolean mPendingIntentSent;
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005326 private final IBinder mBinder;
Robert Greenwalt9258c642014-03-26 16:47:06 -07005327 final int mPid;
5328 final int mUid;
5329 final Messenger messenger;
Robert Greenwalt9258c642014-03-26 16:47:06 -07005330
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005331 NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005332 request = r;
Lorenzo Colitti1ec11eb2016-07-05 01:22:13 +09005333 ensureNetworkRequestHasType(request);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005334 mPendingIntent = pi;
5335 messenger = null;
5336 mBinder = null;
5337 mPid = getCallingPid();
5338 mUid = getCallingUid();
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04005339 enforceRequestCountLimit();
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005340 }
5341
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005342 NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
Robert Greenwalt9258c642014-03-26 16:47:06 -07005343 super();
5344 messenger = m;
5345 request = r;
Lorenzo Colitti1ec11eb2016-07-05 01:22:13 +09005346 ensureNetworkRequestHasType(request);
Robert Greenwalt9258c642014-03-26 16:47:06 -07005347 mBinder = binder;
5348 mPid = getCallingPid();
5349 mUid = getCallingUid();
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005350 mPendingIntent = null;
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04005351 enforceRequestCountLimit();
Robert Greenwalt9258c642014-03-26 16:47:06 -07005352
5353 try {
5354 mBinder.linkToDeath(this, 0);
5355 } catch (RemoteException e) {
5356 binderDied();
5357 }
5358 }
5359
Cody Kesting63e4e002019-12-18 10:57:50 -08005360 NetworkRequestInfo(NetworkRequest r) {
5361 this(r, null);
5362 }
5363
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04005364 private void enforceRequestCountLimit() {
5365 synchronized (mUidToNetworkRequestCount) {
5366 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
5367 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
Hugo Benichicb883232017-05-11 13:16:17 +09005368 throw new ServiceSpecificException(
5369 ConnectivityManager.Errors.TOO_MANY_REQUESTS);
Paul Jensen4e1d3fd2016-04-08 13:56:52 -04005370 }
5371 mUidToNetworkRequestCount.put(mUid, networkRequests);
5372 }
5373 }
5374
Robert Greenwalt9258c642014-03-26 16:47:06 -07005375 void unlinkDeathRecipient() {
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005376 if (mBinder != null) {
5377 mBinder.unlinkToDeath(this, 0);
5378 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07005379 }
5380
5381 public void binderDied() {
5382 log("ConnectivityService NetworkRequestInfo binderDied(" +
5383 request + ", " + mBinder + ")");
5384 releaseNetworkRequest(request);
5385 }
Robert Greenwalta67be032014-05-16 15:49:14 -07005386
5387 public String toString() {
Qingxi Li9c5d8b92020-01-08 12:51:49 -08005388 return "uid/pid:" + mUid + "/" + mPid + " " + request
5389 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
Robert Greenwalta67be032014-05-16 15:49:14 -07005390 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07005391 }
5392
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09005393 private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
5394 final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
5395 if (badCapability != null) {
5396 throw new IllegalArgumentException("Cannot request network with " + badCapability);
Paul Jensenbb2e0e92015-06-16 15:11:58 -04005397 }
5398 }
5399
Chalard Jeanafdecd52019-09-26 18:03:47 +09005400 // This checks that the passed capabilities either do not request a
5401 // specific SSID/SignalStrength, or the calling app has permission to do so.
Chalard Jeanb03a6222018-04-11 21:09:10 +09005402 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
Roshan Piuse38acab2020-01-16 12:17:17 -08005403 int callerPid, int callerUid, String callerPackageName) {
Chalard Jeane5e38502020-03-18 15:58:50 +09005404 if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09005405 throw new SecurityException("Insufficient permissions to request a specific SSID");
5406 }
paulhu3d67f532019-03-22 16:35:06 +08005407
5408 if (nc.hasSignalStrength()
5409 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
5410 throw new SecurityException(
5411 "Insufficient permissions to request a specific signal strength");
5412 }
Roshan Piuse38acab2020-01-16 12:17:17 -08005413 mAppOpsManager.checkPackage(callerUid, callerPackageName);
Chalard Jeanb03a6222018-04-11 21:09:10 +09005414 }
5415
Erik Kline9d598e12015-07-13 16:37:51 +09005416 private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
Chalard Jean4133a122018-06-04 13:33:12 +09005417 final SortedSet<Integer> thresholds = new TreeSet<>();
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09005418 synchronized (nai) {
5419 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5420 if (nri.request.networkCapabilities.hasSignalStrength() &&
5421 nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
5422 thresholds.add(nri.request.networkCapabilities.getSignalStrength());
5423 }
5424 }
5425 }
Chalard Jean4133a122018-06-04 13:33:12 +09005426 return new ArrayList<>(thresholds);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09005427 }
5428
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09005429 private void updateSignalStrengthThresholds(
5430 NetworkAgentInfo nai, String reason, NetworkRequest request) {
5431 ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai);
Erik Kline9d598e12015-07-13 16:37:51 +09005432 Bundle thresholds = new Bundle();
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09005433 thresholds.putIntegerArrayList("thresholds", thresholdsArray);
5434
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09005435 if (VDBG || (DBG && !"CONNECT".equals(reason))) {
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09005436 String detail;
5437 if (request != null && request.networkCapabilities.hasSignalStrength()) {
5438 detail = reason + " " + request.networkCapabilities.getSignalStrength();
5439 } else {
5440 detail = reason;
5441 }
5442 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
Chalard Jeanbf1170c2019-12-10 21:07:02 +09005443 detail, Arrays.toString(thresholdsArray.toArray()), nai.toShortString()));
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09005444 }
5445
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09005446 nai.asyncChannel.sendMessage(
5447 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
Erik Kline9d598e12015-07-13 16:37:51 +09005448 0, 0, thresholds);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09005449 }
5450
Etan Cohen859748f2017-04-03 17:42:34 -07005451 private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
5452 if (nc == null) {
5453 return;
5454 }
5455 NetworkSpecifier ns = nc.getNetworkSpecifier();
5456 if (ns == null) {
5457 return;
5458 }
5459 MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
Etan Cohen859748f2017-04-03 17:42:34 -07005460 }
5461
lucaslin783f2212019-10-22 18:27:33 +08005462 private void ensureValid(NetworkCapabilities nc) {
5463 ensureValidNetworkSpecifier(nc);
5464 if (nc.isPrivateDnsBroken()) {
5465 throw new IllegalArgumentException("Can't request broken private DNS");
5466 }
5467 }
5468
Mark Chien44592d12020-03-27 16:53:45 +00005469 private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
5470 final PackageManager pm = mContext.getPackageManager();
5471 final int userId = UserHandle.getCallingUserId();
5472 try {
5473 final int callingVersion = pm.getApplicationInfoAsUser(
5474 callingPackageName, 0 /* flags */, userId).targetSdkVersion;
5475 if (callingVersion < version) return false;
5476 } catch (PackageManager.NameNotFoundException e) { }
5477 return true;
5478 }
5479
Robert Greenwalt9258c642014-03-26 16:47:06 -07005480 @Override
5481 public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005482 Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
5483 @NonNull String callingPackageName) {
markchien97c029e2020-03-18 21:16:15 +08005484 if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
Mark Chien44592d12020-03-27 16:53:45 +00005485 if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
5486 throw new SecurityException("Insufficient permissions to specify legacy type");
5487 }
markchien97c029e2020-03-18 21:16:15 +08005488 }
Roshan Piuse38acab2020-01-16 12:17:17 -08005489 final int callingUid = Binder.getCallingUid();
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005490 final NetworkRequest.Type type = (networkCapabilities == null)
5491 ? NetworkRequest.Type.TRACK_DEFAULT
5492 : NetworkRequest.Type.REQUEST;
Erik Klinea2d29402016-03-16 15:31:39 +09005493 // If the requested networkCapabilities is null, take them instead from
5494 // the default network request. This allows callers to keep track of
5495 // the system default network.
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005496 if (type == NetworkRequest.Type.TRACK_DEFAULT) {
Roshan Piuse38acab2020-01-16 12:17:17 -08005497 networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
Erik Klinea2d29402016-03-16 15:31:39 +09005498 enforceAccessPermission();
5499 } else {
5500 networkCapabilities = new NetworkCapabilities(networkCapabilities);
5501 enforceNetworkRequestPermissions(networkCapabilities);
Lorenzo Colittib60570c2016-07-01 13:20:10 +09005502 // TODO: this is incorrect. We mark the request as metered or not depending on the state
5503 // of the app when the request is filed, but we never change the request if the app
5504 // changes network state. http://b/29964605
5505 enforceMeteredApnPolicy(networkCapabilities);
Erik Klinea2d29402016-03-16 15:31:39 +09005506 }
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09005507 ensureRequestableCapabilities(networkCapabilities);
Chalard Jeanb03a6222018-04-11 21:09:10 +09005508 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005509 Binder.getCallingPid(), callingUid, callingPackageName);
Chalard Jeanb552c462018-02-21 18:43:54 +09005510 // Set the UID range for this request to the single UID of the requester, or to an empty
5511 // set of UIDs if the caller has the appropriate permission and UIDs have not been set.
Chalard Jeandda156a2018-01-10 21:19:32 +09005512 // This will overwrite any allowed UIDs in the requested capabilities. Though there
5513 // are no visible methods to set the UIDs, an app could use reflection to try and get
5514 // networks for other apps so it's essential that the UIDs are overwritten.
Roshan Piuse38acab2020-01-16 12:17:17 -08005515 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
5516 callingUid, callingPackageName);
Robert Greenwalt39fa65a2014-07-27 10:56:49 -07005517
Etan Cohenba07c8c2017-02-05 10:42:27 -08005518 if (timeoutMs < 0) {
Robert Greenwalt9258c642014-03-26 16:47:06 -07005519 throw new IllegalArgumentException("Bad timeout specified");
5520 }
lucaslin783f2212019-10-22 18:27:33 +08005521 ensureValid(networkCapabilities);
Etan Cohenddb9ef02015-11-18 10:56:15 -08005522
Robert Greenwalt39fa65a2014-07-27 10:56:49 -07005523 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005524 nextNetworkRequestId(), type);
5525 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
Erik Kline7523eb32015-07-09 18:24:03 +09005526 if (DBG) log("requestNetwork for " + nri);
Robert Greenwalt9258c642014-03-26 16:47:06 -07005527
5528 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
Robert Greenwalt6078b502014-06-11 16:05:07 -07005529 if (timeoutMs > 0) {
Robert Greenwalt9258c642014-03-26 16:47:06 -07005530 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
Robert Greenwalt6078b502014-06-11 16:05:07 -07005531 nri), timeoutMs);
Robert Greenwalt9258c642014-03-26 16:47:06 -07005532 }
5533 return networkRequest;
5534 }
5535
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005536 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
Lorenzo Colitti76f67792015-05-14 17:28:27 +09005537 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
Hugo Benichi514da602016-07-19 15:59:27 +09005538 enforceConnectivityRestrictedNetworksPermission();
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005539 } else {
5540 enforceChangePermission();
5541 }
5542 }
5543
fenglub15e72b2015-03-20 11:29:56 -07005544 @Override
fengludb571472015-04-21 17:12:05 -07005545 public boolean requestBandwidthUpdate(Network network) {
fenglub15e72b2015-03-20 11:29:56 -07005546 enforceAccessPermission();
5547 NetworkAgentInfo nai = null;
5548 if (network == null) {
5549 return false;
5550 }
5551 synchronized (mNetworkForNetId) {
5552 nai = mNetworkForNetId.get(network.netId);
5553 }
5554 if (nai != null) {
5555 nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
Nathan Haroldfd45e5f2018-07-30 13:38:01 -07005556 synchronized (mBandwidthRequests) {
5557 final int uid = Binder.getCallingUid();
5558 Integer uidReqs = mBandwidthRequests.get(uid);
5559 if (uidReqs == null) {
Chalard Jeanafdecd52019-09-26 18:03:47 +09005560 uidReqs = 0;
Nathan Haroldfd45e5f2018-07-30 13:38:01 -07005561 }
5562 mBandwidthRequests.put(uid, ++uidReqs);
5563 }
fenglub15e72b2015-03-20 11:29:56 -07005564 return true;
5565 }
5566 return false;
5567 }
5568
Felipe Lemeee27cab2016-06-20 16:36:29 -07005569 private boolean isSystem(int uid) {
5570 return uid < Process.FIRST_APPLICATION_UID;
5571 }
fenglub15e72b2015-03-20 11:29:56 -07005572
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005573 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
Felipe Lemeee27cab2016-06-20 16:36:29 -07005574 final int uid = Binder.getCallingUid();
5575 if (isSystem(uid)) {
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005576 // Exemption for system uid.
Felipe Lemeee27cab2016-06-20 16:36:29 -07005577 return;
5578 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005579 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
5580 // Policy already enforced.
5581 return;
5582 }
5583 if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
5584 // If UID is restricted, don't allow them to bring up metered APNs.
5585 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005586 }
5587 }
5588
Robert Greenwalt9258c642014-03-26 16:47:06 -07005589 @Override
5590 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005591 PendingIntent operation, @NonNull String callingPackageName) {
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +00005592 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Roshan Piuse38acab2020-01-16 12:17:17 -08005593 final int callingUid = Binder.getCallingUid();
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005594 networkCapabilities = new NetworkCapabilities(networkCapabilities);
5595 enforceNetworkRequestPermissions(networkCapabilities);
5596 enforceMeteredApnPolicy(networkCapabilities);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09005597 ensureRequestableCapabilities(networkCapabilities);
Chalard Jeanb03a6222018-04-11 21:09:10 +09005598 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005599 Binder.getCallingPid(), callingUid, callingPackageName);
Etan Cohen859748f2017-04-03 17:42:34 -07005600 ensureValidNetworkSpecifier(networkCapabilities);
Roshan Piuse38acab2020-01-16 12:17:17 -08005601 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
5602 callingUid, callingPackageName);
Etan Cohena7434272017-04-03 12:17:51 -07005603
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005604 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005605 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
5606 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
Erik Kline7523eb32015-07-09 18:24:03 +09005607 if (DBG) log("pendingRequest for " + nri);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005608 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
5609 nri));
5610 return networkRequest;
5611 }
5612
Jeremy Joslin79294842014-12-03 17:15:28 -08005613 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
5614 mHandler.sendMessageDelayed(
5615 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
5616 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
5617 }
5618
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005619 @Override
5620 public void releasePendingNetworkRequest(PendingIntent operation) {
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +00005621 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08005622 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
5623 getCallingUid(), 0, operation));
Robert Greenwalt9258c642014-03-26 16:47:06 -07005624 }
5625
Lorenzo Colittifa57c482015-04-22 10:44:49 +09005626 // In order to implement the compatibility measure for pre-M apps that call
5627 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
5628 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
5629 // This ensures it has permission to do so.
5630 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
5631 if (nc == null) {
5632 return false;
5633 }
5634 int[] transportTypes = nc.getTransportTypes();
5635 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
5636 return false;
5637 }
5638 try {
5639 mContext.enforceCallingOrSelfPermission(
5640 android.Manifest.permission.ACCESS_WIFI_STATE,
5641 "ConnectivityService");
5642 } catch (SecurityException e) {
5643 return false;
5644 }
5645 return true;
5646 }
5647
Robert Greenwalt9258c642014-03-26 16:47:06 -07005648 @Override
5649 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005650 Messenger messenger, IBinder binder, @NonNull String callingPackageName) {
5651 final int callingUid = Binder.getCallingUid();
Lorenzo Colittifa57c482015-04-22 10:44:49 +09005652 if (!hasWifiNetworkListenPermission(networkCapabilities)) {
5653 enforceAccessPermission();
5654 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07005655
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09005656 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
Chalard Jeanb03a6222018-04-11 21:09:10 +09005657 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005658 Binder.getCallingPid(), callingUid, callingPackageName);
5659 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Chalard Jean26aa91a2018-03-20 19:13:57 +09005660 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
5661 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
5662 // onLost and onAvailable callbacks when networks move in and out of the background.
5663 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
5664 // can't request networks.
5665 restrictBackgroundRequestForCaller(nc);
lucaslin783f2212019-10-22 18:27:33 +08005666 ensureValid(nc);
Etan Cohena7434272017-04-03 12:17:51 -07005667
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09005668 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005669 NetworkRequest.Type.LISTEN);
5670 NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09005671 if (VDBG) log("listenForNetwork for " + nri);
Robert Greenwalt9258c642014-03-26 16:47:06 -07005672
5673 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
5674 return networkRequest;
5675 }
5676
5677 @Override
5678 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005679 PendingIntent operation, @NonNull String callingPackageName) {
Daulet Zhanguzinea1a7ca2020-01-03 09:46:50 +00005680 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Roshan Piuse38acab2020-01-16 12:17:17 -08005681 final int callingUid = Binder.getCallingUid();
Paul Jensen694f2b82015-06-17 14:15:39 -04005682 if (!hasWifiNetworkListenPermission(networkCapabilities)) {
5683 enforceAccessPermission();
5684 }
lucaslin783f2212019-10-22 18:27:33 +08005685 ensureValid(networkCapabilities);
Chalard Jeanb03a6222018-04-11 21:09:10 +09005686 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Piuse38acab2020-01-16 12:17:17 -08005687 Binder.getCallingPid(), callingUid, callingPackageName);
Chalard Jeandda156a2018-01-10 21:19:32 +09005688 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
Roshan Piuse38acab2020-01-16 12:17:17 -08005689 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Chalard Jeandda156a2018-01-10 21:19:32 +09005690
5691 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
Lorenzo Colittib35d40d2016-07-01 13:19:21 +09005692 NetworkRequest.Type.LISTEN);
5693 NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
Lorenzo Colitti39d2bb52016-04-08 23:09:09 +09005694 if (VDBG) log("pendingListenForNetwork for " + nri);
Paul Jensen694f2b82015-06-17 14:15:39 -04005695
5696 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
Robert Greenwalt9258c642014-03-26 16:47:06 -07005697 }
5698
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005699 /** Returns the next Network provider ID. */
5700 public final int nextNetworkProviderId() {
5701 return mNextNetworkProviderId.getAndIncrement();
5702 }
5703
Erik Klineacdd6392016-07-07 16:50:58 +09005704 @Override
Robert Greenwalt9258c642014-03-26 16:47:06 -07005705 public void releaseNetworkRequest(NetworkRequest networkRequest) {
Lorenzo Colitti1ec11eb2016-07-05 01:22:13 +09005706 ensureNetworkRequestHasType(networkRequest);
Erik Klineacdd6392016-07-07 16:50:58 +09005707 mHandler.sendMessage(mHandler.obtainMessage(
5708 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
Robert Greenwalt9258c642014-03-26 16:47:06 -07005709 }
5710
5711 @Override
Chalard Jean05ab6812018-05-02 21:14:54 +09005712 public int registerNetworkFactory(Messenger messenger, String name) {
paulhu59148b72019-08-12 16:25:11 +08005713 enforceNetworkFactoryPermission();
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005714 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger, new AsyncChannel(),
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005715 nextNetworkProviderId(), null /* deathRecipient */);
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005716 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
5717 return npi.providerId;
Robert Greenwalte049c232014-04-11 15:53:27 -07005718 }
5719
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005720 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
5721 if (mNetworkProviderInfos.containsKey(npi.messenger)) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005722 // Avoid creating duplicates. even if an app makes a direct AIDL call.
5723 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
5724 // as that will throw if a duplicate provider is registered.
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005725 Slog.e(TAG, "Attempt to register existing NetworkProviderInfo "
5726 + mNetworkProviderInfos.get(npi.messenger).name);
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005727 return;
5728 }
5729
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005730 if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
5731 mNetworkProviderInfos.put(npi.messenger, npi);
5732 npi.connect(mContext, mTrackerHandler);
5733 if (!npi.isLegacyNetworkFactory()) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005734 // Legacy NetworkFactories get their requests when their AsyncChannel connects.
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005735 sendAllRequestsToProvider(npi);
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005736 }
5737 }
5738
5739 @Override
5740 public int registerNetworkProvider(Messenger messenger, String name) {
Aaron Huang7dcb8182020-04-17 05:11:01 +00005741 enforceNetworkFactoryOrSettingsPermission();
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005742 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005743 null /* asyncChannel */, nextNetworkProviderId(),
5744 () -> unregisterNetworkProvider(messenger));
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005745 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
5746 return npi.providerId;
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005747 }
5748
5749 @Override
5750 public void unregisterNetworkProvider(Messenger messenger) {
Aaron Huang7dcb8182020-04-17 05:11:01 +00005751 enforceNetworkFactoryOrSettingsPermission();
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005752 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
Robert Greenwalta67be032014-05-16 15:49:14 -07005753 }
5754
5755 @Override
5756 public void unregisterNetworkFactory(Messenger messenger) {
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005757 unregisterNetworkProvider(messenger);
Robert Greenwalta67be032014-05-16 15:49:14 -07005758 }
5759
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005760 private void handleUnregisterNetworkProvider(Messenger messenger) {
5761 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
5762 if (npi == null) {
5763 loge("Failed to find Messenger in unregisterNetworkProvider");
Robert Greenwalta67be032014-05-16 15:49:14 -07005764 return;
Robert Greenwalt9258c642014-03-26 16:47:06 -07005765 }
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005766 if (DBG) log("unregisterNetworkProvider for " + npi.name);
Robert Greenwalte049c232014-04-11 15:53:27 -07005767 }
5768
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005769 @Override
5770 public void declareNetworkRequestUnfulfillable(NetworkRequest request) {
Aaron Huang7dcb8182020-04-17 05:11:01 +00005771 if (request.hasTransport(TRANSPORT_TEST)) {
5772 enforceNetworkFactoryOrTestNetworksPermission();
5773 } else {
5774 enforceNetworkFactoryPermission();
5775 }
Lorenzo Colittiae5cb712020-01-08 00:04:09 +09005776 mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true));
5777 }
5778
Paul Jensen31a94f42015-02-13 14:18:39 -05005779 // NOTE: Accessed on multiple threads, must be synchronized on itself.
5780 @GuardedBy("mNetworkForNetId")
Chalard Jean4133a122018-06-04 13:33:12 +09005781 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
Paul Jensen31a94f42015-02-13 14:18:39 -05005782 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09005783 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so
Paul Jensen31a94f42015-02-13 14:18:39 -05005784 // there may not be a strict 1:1 correlation between the two.
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09005785 private final NetIdManager mNetIdManager;
Robert Greenwalt9258c642014-03-26 16:47:06 -07005786
Robert Greenwalt7b816022014-04-18 15:25:25 -07005787 // NetworkAgentInfo keyed off its connecting messenger
5788 // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
Paul Jensen31a94f42015-02-13 14:18:39 -05005789 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
Chalard Jean4133a122018-06-04 13:33:12 +09005790 private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = new HashMap<>();
Robert Greenwalt7b816022014-04-18 15:25:25 -07005791
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09005792 @GuardedBy("mBlockedAppUids")
Chalard Jean4133a122018-06-04 13:33:12 +09005793 private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
Lorenzo Colittic1a6ce72016-01-22 04:04:57 +09005794
Paul Jensen2c311d62014-11-17 12:34:51 -05005795 // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
Chalard Jean11293a92019-11-05 14:40:23 +09005796 @NonNull
Robert Greenwalt7b816022014-04-18 15:25:25 -07005797 private final NetworkRequest mDefaultRequest;
Chalard Jean11293a92019-11-05 14:40:23 +09005798 // The NetworkAgentInfo currently satisfying the default request, if any.
5799 @Nullable
5800 private volatile NetworkAgentInfo mDefaultNetworkNai = null;
Chalard Jean6b65ec72018-05-18 22:02:56 +09005801
Erik Klineda4bfa82015-04-30 12:58:40 +09005802 // Request used to optionally keep mobile data active even when higher
5803 // priority networks like Wi-Fi are active.
5804 private final NetworkRequest mDefaultMobileDataRequest;
5805
Leif Hendrik Wildenfd306632018-05-02 12:05:24 -07005806 // Request used to optionally keep wifi data active even when higher
5807 // priority networks like ethernet are active.
5808 private final NetworkRequest mDefaultWifiRequest;
5809
Lorenzo Colitti403aa262014-11-28 11:21:30 +09005810 private NetworkAgentInfo getDefaultNetwork() {
Chalard Jean11293a92019-11-05 14:40:23 +09005811 return mDefaultNetworkNai;
Lorenzo Colitti403aa262014-11-28 11:21:30 +09005812 }
5813
Varun Anand4fa80e82019-02-06 10:13:38 -08005814 @Nullable
5815 private Network getNetwork(@Nullable NetworkAgentInfo nai) {
5816 return nai != null ? nai.network : null;
5817 }
5818
5819 private void ensureRunningOnConnectivityServiceThread() {
5820 if (mHandler.getLooper().getThread() != Thread.currentThread()) {
5821 throw new IllegalStateException(
5822 "Not running on ConnectivityService thread: "
5823 + Thread.currentThread().getName());
5824 }
5825 }
5826
Chalard Jean612522b2019-04-10 23:07:55 +09005827 @VisibleForTesting
5828 protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +09005829 return nai == getDefaultNetwork();
Robert Greenwaltbf4eed72014-08-06 21:32:18 -07005830 }
5831
Lorenzo Colitti5526f9c2016-08-22 16:46:40 +09005832 private boolean isDefaultRequest(NetworkRequestInfo nri) {
5833 return nri.request.requestId == mDefaultRequest.requestId;
5834 }
5835
Chalard Jeana11593c2020-02-21 19:37:21 +09005836 // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
5837 // changes that would conflict throughout the automerger graph. Having this method temporarily
5838 // helps with the process of going through with all these dependent changes across the entire
5839 // tree.
5840 /**
5841 * Register a new agent. {@see #registerNetworkAgent} below.
5842 */
5843 public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
5844 LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
5845 int currentScore, NetworkAgentConfig networkAgentConfig) {
5846 return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities,
5847 currentScore, networkAgentConfig, NetworkProvider.ID_NONE);
5848 }
5849
Chalard Jean05ab6812018-05-02 21:14:54 +09005850 /**
5851 * Register a new agent with ConnectivityService to handle a network.
5852 *
5853 * @param messenger a messenger for ConnectivityService to contact the agent asynchronously.
5854 * @param networkInfo the initial info associated with this network. It can be updated later :
5855 * see {@link #updateNetworkInfo}.
5856 * @param linkProperties the initial link properties of this network. They can be updated
5857 * later : see {@link #updateLinkProperties}.
5858 * @param networkCapabilities the initial capabilites of this network. They can be updated
Chalard Jean67576ac2019-12-12 13:56:13 +09005859 * later : see {@link #updateCapabilities}.
Chalard Jean05ab6812018-05-02 21:14:54 +09005860 * @param currentScore the initial score of the network. See
5861 * {@link NetworkAgentInfo#getCurrentScore}.
Lorenzo Colittid9696562020-01-12 22:28:37 +09005862 * @param networkAgentConfig metadata about the network. This is never updated.
Lorenzo Colitti6654b082020-01-10 00:40:28 +09005863 * @param providerId the ID of the provider owning this NetworkAgent.
Chalard Jeana0e2aa122019-12-13 19:47:12 +09005864 * @return the network created for this agent.
Chalard Jean05ab6812018-05-02 21:14:54 +09005865 */
Chalard Jeana0e2aa122019-12-13 19:47:12 +09005866 public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
Chalard Jean05ab6812018-05-02 21:14:54 +09005867 LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
Chalard Jeana11593c2020-02-21 19:37:21 +09005868 int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
Chalard Jean09c48e42020-03-25 10:33:55 +00005869 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
5870 enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
5871 // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
5872 // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
5873 // sees capabilities that may be malicious, which might prevent mistakes in the future.
5874 networkCapabilities = new NetworkCapabilities(networkCapabilities);
Cody Kesting0d8d6ac2020-05-12 18:47:10 +00005875 networkCapabilities.restrictCapabilitesForTestNetwork(Binder.getCallingUid());
Chalard Jean09c48e42020-03-25 10:33:55 +00005876 } else {
5877 enforceNetworkFactoryPermission();
5878 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07005879
Rubin Xu1bb5c082017-09-05 18:40:49 +01005880 LinkProperties lp = new LinkProperties(linkProperties);
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00005881
Paul Jensen2c311d62014-11-17 12:34:51 -05005882 // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
5883 // satisfies mDefaultRequest.
Chalard Jean804b8fb2018-01-30 22:41:41 +09005884 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
Paul Jensencf4c2c62015-07-01 14:16:32 -04005885 final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09005886 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
Automerger Merge Worker3d40f5782020-03-08 06:07:47 +00005887 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
Cody Kesting0d8d6ac2020-05-12 18:47:10 +00005888 this, mNetd, mDnsResolver, mNMS, providerId, Binder.getCallingUid());
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00005889
5890 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
Chalard Jean7ec1ff62019-11-22 22:39:56 +09005891 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00005892 processLinkPropertiesFromAgent(nai, nai.linkProperties);
5893
Chalard Jeand771aa02018-04-26 16:16:10 +09005894 final String extraInfo = networkInfo.getExtraInfo();
5895 final String name = TextUtils.isEmpty(extraInfo)
Chalard Jeane5e38502020-03-18 15:58:50 +09005896 ? nai.networkCapabilities.getSsid() : extraInfo;
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07005897 if (DBG) log("registerNetworkAgent " + nai);
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09005898 final long token = Binder.clearCallingIdentity();
5899 try {
Remi NGUYEN VAN95dc87e2019-06-13 16:12:02 +09005900 mDeps.getNetworkStack().makeNetworkMonitor(
Remi NGUYEN VAN904a38b2019-03-15 02:25:09 +09005901 nai.network, name, new NetworkMonitorCallbacks(nai));
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09005902 } finally {
5903 Binder.restoreCallingIdentity(token);
5904 }
5905 // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
5906 // If the network disconnects or sends any other event before that, messages are deferred by
5907 // NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the
5908 // registration.
Chalard Jeana0e2aa122019-12-13 19:47:12 +09005909 return nai.network;
Robert Greenwalt7b816022014-04-18 15:25:25 -07005910 }
5911
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09005912 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
5913 nai.onNetworkMonitorCreated(networkMonitor);
Robert Greenwalt7b816022014-04-18 15:25:25 -07005914 if (VDBG) log("Got NetworkAgent Messenger");
Erik Klinee5dac902018-03-04 21:01:01 +09005915 mNetworkAgentInfos.put(nai.messenger, nai);
Paul Jensen31a94f42015-02-13 14:18:39 -05005916 synchronized (mNetworkForNetId) {
Erik Klinee5dac902018-03-04 21:01:01 +09005917 mNetworkForNetId.put(nai.network.netId, nai);
Paul Jensen31a94f42015-02-13 14:18:39 -05005918 }
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09005919
5920 try {
5921 networkMonitor.start();
5922 } catch (RemoteException e) {
Chiachang Wang79bc7e22019-04-24 21:44:05 +08005923 e.rethrowAsRuntimeException();
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09005924 }
Erik Klinee5dac902018-03-04 21:01:01 +09005925 nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger);
5926 NetworkInfo networkInfo = nai.networkInfo;
Erik Klinee5dac902018-03-04 21:01:01 +09005927 updateNetworkInfo(nai, networkInfo);
5928 updateUids(nai, null, nai.networkCapabilities);
Robert Greenwalt7b816022014-04-18 15:25:25 -07005929 }
5930
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00005931 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
5932 lp.ensureDirectlyConnectedRoutes();
Lorenzo Colitti1cb345e2020-04-20 11:37:18 +00005933 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00005934 }
5935
lucaslin25a4ec32018-11-28 12:51:55 +08005936 private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
Chalard Jeanafdecd52019-09-26 18:03:47 +09005937 @NonNull LinkProperties oldLp) {
Robert Greenwalt7b816022014-04-18 15:25:25 -07005938 int netId = networkAgent.network.netId;
5939
Lorenzo Colitti06dcc322020-04-02 15:24:59 +00005940 // The NetworkAgent does not know whether clatd is running on its network or not, or whether
5941 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure
5942 // the LinkProperties for the network are accurate.
Lorenzo Colittidf595632019-01-08 14:43:37 +09005943 networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
Lorenzo Colitti1df5fa52014-09-20 13:47:47 +09005944
Chalard Jeanbbaa33e2019-11-19 19:03:53 +09005945 updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities,
5946 networkAgent.networkInfo.getType());
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00005947
5948 // update filtering rules, need to happen after the interface update so netd knows about the
5949 // new interface (the interface name -> index map becomes initialized)
5950 updateVpnFiltering(newLp, oldLp, networkAgent);
5951
Robert Greenwalt7b816022014-04-18 15:25:25 -07005952 updateMtu(newLp, oldLp);
5953 // TODO - figure out what to do for clat
5954// for (LinkProperties lp : newLp.getStackedLinks()) {
5955// updateMtu(lp, null);
5956// }
lucaslin041a1af2018-11-28 19:27:52 +08005957 if (isDefaultNetwork(networkAgent)) {
5958 updateTcpBufferSizes(newLp.getTcpBufferSizes());
5959 }
Lorenzo Colitti829dfa72014-11-28 20:07:46 +09005960
Erik Kline94887872016-04-05 13:30:49 +09005961 updateRoutes(newLp, oldLp, netId);
5962 updateDnses(newLp, oldLp, netId);
dalyk7301aa42018-03-05 12:42:22 -05005963 // Make sure LinkProperties represents the latest private DNS status.
5964 // This does not need to be done before updateDnses because the
5965 // LinkProperties are not the source of the private DNS configuration.
5966 // updateDnses will fetch the private DNS configuration from DnsManager.
5967 mDnsManager.updatePrivateDnsStatus(netId, newLp);
Lorenzo Colitti829dfa72014-11-28 20:07:46 +09005968
Paul Jensene0bef712014-12-10 15:12:18 -05005969 if (isDefaultNetwork(networkAgent)) {
5970 handleApplyDefaultProxy(newLp.getHttpProxy());
5971 } else {
Chalard Jean4133a122018-06-04 13:33:12 +09005972 updateProxy(newLp, oldLp);
Paul Jensene0bef712014-12-10 15:12:18 -05005973 }
Valentin Iftimec86ebba2019-09-24 13:32:13 +02005974
5975 updateWakeOnLan(newLp);
5976
Remi NGUYEN VAN91aa5bc2019-12-12 12:57:11 +09005977 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo,
5978 // it is not contained in LinkProperties sent from NetworkAgents so needs to be merged here.
5979 newLp.setCaptivePortalData(networkAgent.captivePortalData);
5980
Robert Greenwalta848c1c2014-09-30 16:50:07 -07005981 // TODO - move this check to cover the whole function
5982 if (!Objects.equals(newLp, oldLp)) {
Chalard Jeanc4f53ba2018-05-23 09:07:51 +09005983 synchronized (networkAgent) {
5984 networkAgent.linkProperties = newLp;
5985 }
Lorenzo Colittid593e292019-02-19 13:21:56 +09005986 // Start or stop DNS64 detection and 464xlat according to network state.
5987 networkAgent.clatd.update();
Jeff Davidson0b93c5d2016-01-20 11:35:38 -08005988 notifyIfacesChangedForNetworkStats();
Remi NGUYEN VAN5ab87402020-05-12 08:53:53 +00005989 networkAgent.networkMonitor().notifyLinkPropertiesChanged(
5990 new LinkProperties(newLp, true /* parcelSensitiveFields */));
lucaslin25a4ec32018-11-28 12:51:55 +08005991 if (networkAgent.everConnected) {
5992 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
5993 }
Robert Greenwalta848c1c2014-09-30 16:50:07 -07005994 }
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09005995
5996 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
Paul Jensen3b759822014-05-13 11:44:01 -04005997 }
5998
Joel Scherpelz668370b2017-06-08 15:35:21 +09005999 private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
Chalard Jean4d660112018-06-04 16:52:49 +09006000 // Marks are only available on WiFi interfaces. Checking for
Joel Scherpelzb369bf52017-05-22 13:47:41 +09006001 // marks on unsupported interfaces is harmless.
6002 if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
6003 return;
6004 }
Joel Scherpelzb369bf52017-05-22 13:47:41 +09006005
Joel Scherpelz668370b2017-06-08 15:35:21 +09006006 int mark = mContext.getResources().getInteger(
6007 com.android.internal.R.integer.config_networkWakeupPacketMark);
6008 int mask = mContext.getResources().getInteger(
6009 com.android.internal.R.integer.config_networkWakeupPacketMask);
6010
6011 // Mask/mark of zero will not detect anything interesting.
6012 // Don't install rules unless both values are nonzero.
6013 if (mark == 0 || mask == 0) {
Joel Scherpelzb369bf52017-05-22 13:47:41 +09006014 return;
6015 }
Joel Scherpelz668370b2017-06-08 15:35:21 +09006016
6017 final String prefix = "iface:" + iface;
6018 try {
6019 if (add) {
Luke Huang674660f2018-09-27 19:33:11 +08006020 mNetd.wakeupAddInterface(iface, prefix, mark, mask);
Joel Scherpelz668370b2017-06-08 15:35:21 +09006021 } else {
Luke Huang674660f2018-09-27 19:33:11 +08006022 mNetd.wakeupDelInterface(iface, prefix, mark, mask);
Joel Scherpelz668370b2017-06-08 15:35:21 +09006023 }
6024 } catch (Exception e) {
6025 loge("Exception modifying wakeup packet monitoring: " + e);
6026 }
6027
Joel Scherpelzb369bf52017-05-22 13:47:41 +09006028 }
6029
Chalard Jeanbbaa33e2019-11-19 19:03:53 +09006030 private void updateInterfaces(final @Nullable LinkProperties newLp,
6031 final @Nullable LinkProperties oldLp, final int netId,
6032 final @Nullable NetworkCapabilities caps, final int legacyType) {
6033 final CompareResult<String> interfaceDiff = new CompareResult<>(
Rubin Xu2fc72f72017-08-22 16:35:52 +01006034 oldLp != null ? oldLp.getAllInterfaceNames() : null,
6035 newLp != null ? newLp.getAllInterfaceNames() : null);
Chalard Jeanbbaa33e2019-11-19 19:03:53 +09006036 if (!interfaceDiff.added.isEmpty()) {
6037 final IBatteryStats bs = mDeps.getBatteryStatsService();
6038 for (final String iface : interfaceDiff.added) {
6039 try {
6040 if (DBG) log("Adding iface " + iface + " to network " + netId);
6041 mNMS.addInterfaceToNetwork(iface, netId);
6042 wakeupModifyInterface(iface, caps, true);
6043 bs.noteNetworkInterfaceType(iface, legacyType);
6044 } catch (Exception e) {
6045 loge("Exception adding interface: " + e);
6046 }
Paul Jensen992f2522014-04-28 10:33:11 -04006047 }
6048 }
Chalard Jeanbbaa33e2019-11-19 19:03:53 +09006049 for (final String iface : interfaceDiff.removed) {
Paul Jensen992f2522014-04-28 10:33:11 -04006050 try {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006051 if (DBG) log("Removing iface " + iface + " from network " + netId);
Joel Scherpelz668370b2017-06-08 15:35:21 +09006052 wakeupModifyInterface(iface, caps, false);
Luke Huang4e25ec62018-09-27 16:58:23 +08006053 mNMS.removeInterfaceFromNetwork(iface, netId);
Paul Jensen992f2522014-04-28 10:33:11 -04006054 } catch (Exception e) {
6055 loge("Exception removing interface: " + e);
6056 }
6057 }
6058 }
6059
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006060 // TODO: move to frameworks/libs/net.
6061 private RouteInfoParcel convertRouteInfo(RouteInfo route) {
6062 final String nextHop;
6063
6064 switch (route.getType()) {
6065 case RouteInfo.RTN_UNICAST:
6066 if (route.hasGateway()) {
6067 nextHop = route.getGateway().getHostAddress();
6068 } else {
6069 nextHop = INetd.NEXTHOP_NONE;
6070 }
6071 break;
6072 case RouteInfo.RTN_UNREACHABLE:
6073 nextHop = INetd.NEXTHOP_UNREACHABLE;
6074 break;
6075 case RouteInfo.RTN_THROW:
6076 nextHop = INetd.NEXTHOP_THROW;
6077 break;
6078 default:
6079 nextHop = INetd.NEXTHOP_NONE;
6080 break;
6081 }
6082
6083 final RouteInfoParcel rip = new RouteInfoParcel();
6084 rip.ifName = route.getInterface();
6085 rip.destination = route.getDestination().toString();
6086 rip.nextHop = nextHop;
6087 rip.mtu = route.getMtu();
6088
6089 return rip;
6090 }
6091
Paul Jensen5fb2c6ff2014-08-06 15:51:33 -04006092 /**
6093 * Have netd update routes from oldLp to newLp.
6094 * @return true if routes changed between oldLp and newLp
6095 */
6096 private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006097 // compare the route diff to determine which routes have been updated
Treehugger Robot5dfba4b2020-03-24 06:53:37 +00006098 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
6099 new CompareOrUpdateResult<>(
6100 oldLp != null ? oldLp.getAllRoutes() : null,
6101 newLp != null ? newLp.getAllRoutes() : null,
6102 (r) -> r.getRouteKey());
Robert Greenwalt7b816022014-04-18 15:25:25 -07006103
6104 // add routes before removing old in case it helps with continuous connectivity
6105
Chalard Jean4d660112018-06-04 16:52:49 +09006106 // do this twice, adding non-next-hop routes first, then routes they are dependent on
Robert Greenwalt7b816022014-04-18 15:25:25 -07006107 for (RouteInfo route : routeDiff.added) {
6108 if (route.hasGateway()) continue;
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09006109 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
Robert Greenwalt7b816022014-04-18 15:25:25 -07006110 try {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006111 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalt7b816022014-04-18 15:25:25 -07006112 } catch (Exception e) {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006113 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006114 loge("Exception in networkAddRouteParcel for non-gateway: " + e);
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006115 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006116 }
6117 }
6118 for (RouteInfo route : routeDiff.added) {
Chalard Jeanafdecd52019-09-26 18:03:47 +09006119 if (!route.hasGateway()) continue;
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09006120 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
Robert Greenwalt7b816022014-04-18 15:25:25 -07006121 try {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006122 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalt7b816022014-04-18 15:25:25 -07006123 } catch (Exception e) {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006124 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006125 loge("Exception in networkAddRouteParcel for gateway: " + e);
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006126 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006127 }
6128 }
6129
6130 for (RouteInfo route : routeDiff.removed) {
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09006131 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
Robert Greenwalt7b816022014-04-18 15:25:25 -07006132 try {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006133 mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalt7b816022014-04-18 15:25:25 -07006134 } catch (Exception e) {
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006135 loge("Exception in networkRemoveRouteParcel: " + e);
Robert Greenwalt7b816022014-04-18 15:25:25 -07006136 }
6137 }
Lorenzo Colittid86407b2020-03-18 07:52:25 +00006138
6139 for (RouteInfo route : routeDiff.updated) {
6140 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
6141 try {
6142 mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route));
6143 } catch (Exception e) {
6144 loge("Exception in networkUpdateRouteParcel: " + e);
6145 }
6146 }
6147 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
6148 || !routeDiff.updated.isEmpty();
Robert Greenwalt7b816022014-04-18 15:25:25 -07006149 }
Erik Kline41368502015-06-17 13:19:54 +09006150
Erik Kline94887872016-04-05 13:30:49 +09006151 private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
6152 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
6153 return; // no updating necessary
Robert Greenwalt7b816022014-04-18 15:25:25 -07006154 }
Erik Kline94887872016-04-05 13:30:49 +09006155
Erik Kline1742fe12017-12-13 19:40:49 +09006156 final NetworkAgentInfo defaultNai = getDefaultNetwork();
6157 final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId);
6158
Erik Klinea24d4592018-01-11 21:07:29 +09006159 if (DBG) {
6160 final Collection<InetAddress> dnses = newLp.getDnsServers();
6161 log("Setting DNS servers for network " + netId + " to " + dnses);
6162 }
Erik Kline94887872016-04-05 13:30:49 +09006163 try {
chenbruce5d955622020-02-20 14:28:31 +08006164 mDnsManager.noteDnsServersForNetwork(netId, newLp);
6165 // TODO: netd should listen on [::1]:53 and proxy queries to the current
6166 // default network, and we should just set net.dns1 to ::1, not least
6167 // because applications attempting to use net.dns resolvers will bypass
6168 // the privacy protections of things like DNS-over-TLS.
6169 if (isDefaultNetwork) mDnsManager.setDefaultDnsSystemProperties(newLp.getDnsServers());
6170 mDnsManager.flushVmDnsCache();
Erik Kline94887872016-04-05 13:30:49 +09006171 } catch (Exception e) {
Pierre Imaibd8759b2016-04-28 17:00:04 +09006172 loge("Exception in setDnsConfigurationForNetwork: " + e);
Erik Kline94887872016-04-05 13:30:49 +09006173 }
Erik Kline4edba012017-04-07 15:29:29 +09006174 }
6175
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006176 private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp,
6177 NetworkAgentInfo nai) {
6178 final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null;
6179 final String newIface = newLp != null ? newLp.getInterfaceName() : null;
6180 final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp);
6181 final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp);
6182
6183 if (!wasFiltering && !needsFiltering) {
6184 // Nothing to do.
6185 return;
6186 }
6187
6188 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
6189 // Nothing changed.
6190 return;
6191 }
6192
6193 final Set<UidRange> ranges = nai.networkCapabilities.getUids();
Qingxi Li7cf06622020-01-17 17:54:27 -08006194 final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006195 // TODO: this create a window of opportunity for apps to receive traffic between the time
6196 // when the old rules are removed and the time when new rules are added. To fix this,
6197 // make eBPF support two whitelisted interfaces so here new rules can be added before the
6198 // old rules are being removed.
6199 if (wasFiltering) {
6200 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
6201 }
6202 if (needsFiltering) {
6203 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
6204 }
6205 }
6206
Valentin Iftimec86ebba2019-09-24 13:32:13 +02006207 private void updateWakeOnLan(@NonNull LinkProperties lp) {
6208 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
6209 }
6210
Luke Huang8a462ec2018-08-24 20:33:16 +08006211 private int getNetworkPermission(NetworkCapabilities nc) {
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09006212 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
Luke Huang8a462ec2018-08-24 20:33:16 +08006213 return INetd.PERMISSION_SYSTEM;
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09006214 }
6215 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
Luke Huang8a462ec2018-08-24 20:33:16 +08006216 return INetd.PERMISSION_NETWORK;
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09006217 }
Luke Huang8a462ec2018-08-24 20:33:16 +08006218 return INetd.PERMISSION_NONE;
Lorenzo Colittifbe9b1a2016-07-28 17:14:11 +09006219 }
6220
Chalard Jean1f05eed2019-12-02 18:39:29 +09006221 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
6222 @NonNull final NetworkCapabilities newNc) {
6223 final int oldPermission = getNetworkPermission(nai.networkCapabilities);
6224 final int newPermission = getNetworkPermission(newNc);
6225 if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
6226 try {
6227 mNMS.setNetworkPermission(nai.network.netId, newPermission);
6228 } catch (RemoteException e) {
6229 loge("Exception in setNetworkPermission: " + e);
6230 }
6231 }
6232 }
6233
Paul Jensen3d194ea2015-06-16 14:27:36 -04006234 /**
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006235 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
6236 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
6237 * and foreground status).
Paul Jensen3d194ea2015-06-16 14:27:36 -04006238 */
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006239 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
Hugo Benichi86fc53a2017-08-16 13:19:04 +09006240 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
Lorenzo Colitti6f192a52018-05-30 16:44:47 +09006241 // Don't complain for VPNs since they're not driven by requests and there is no risk of
6242 // causing a connect/teardown loop.
Lorenzo Colitti6654b082020-01-10 00:40:28 +09006243 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to
Lorenzo Colitti6f192a52018-05-30 16:44:47 +09006244 // avoid connect/teardown loops.
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006245 if (nai.everConnected &&
Lorenzo Colitti6f192a52018-05-30 16:44:47 +09006246 !nai.isVPN() &&
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006247 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
6248 // TODO: consider not complaining when a network agent degrades its capabilities if this
Hugo Benichi86fc53a2017-08-16 13:19:04 +09006249 // does not cause any request (that is not a listen) currently matching that agent to
6250 // stop being matched by the updated agent.
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006251 String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
Hugo Benichi683ea482017-07-25 11:40:56 +09006252 if (!TextUtils.isEmpty(diff)) {
Hugo Benichi86fc53a2017-08-16 13:19:04 +09006253 Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
Hugo Benichi683ea482017-07-25 11:40:56 +09006254 }
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006255 }
6256
Paul Jensen3d194ea2015-06-16 14:27:36 -04006257 // Don't modify caller's NetworkCapabilities.
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006258 NetworkCapabilities newNc = new NetworkCapabilities(nc);
Paul Jensene0988542015-06-25 15:30:08 -04006259 if (nai.lastValidated) {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006260 newNc.addCapability(NET_CAPABILITY_VALIDATED);
Paul Jensen3d194ea2015-06-16 14:27:36 -04006261 } else {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006262 newNc.removeCapability(NET_CAPABILITY_VALIDATED);
Paul Jensen3d194ea2015-06-16 14:27:36 -04006263 }
Paul Jensene0988542015-06-25 15:30:08 -04006264 if (nai.lastCaptivePortalDetected) {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006265 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensen3d194ea2015-06-16 14:27:36 -04006266 } else {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006267 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensen3d194ea2015-06-16 14:27:36 -04006268 }
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006269 if (nai.isBackgroundNetwork()) {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006270 newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006271 } else {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006272 newNc.addCapability(NET_CAPABILITY_FOREGROUND);
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006273 }
lucasline252a742019-03-12 13:08:03 +08006274 if (nai.partialConnectivity) {
6275 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
6276 } else {
6277 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
6278 }
lucaslin783f2212019-10-22 18:27:33 +08006279 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006280
Chalard Jean466b6652020-01-15 00:49:43 +09006281 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
Chalard Jean52638ac42020-01-14 22:46:36 +09006282 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
6283 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
Chalard Jean466b6652020-01-15 00:49:43 +09006284 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
Chalard Jean52638ac42020-01-14 22:46:36 +09006285 }
6286
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006287 return newNc;
6288 }
6289
6290 /**
6291 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
6292 *
6293 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
6294 * capabilities we manage and store in {@code nai}, such as validated status and captive
6295 * portal status)
6296 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
6297 * potentially triggers rematches.
6298 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
6299 * change.)
6300 *
6301 * @param oldScore score of the network before any of the changes that prompted us
6302 * to call this function.
6303 * @param nai the network having its capabilities updated.
6304 * @param nc the new network capabilities.
6305 */
Chalard Jean1f05eed2019-12-02 18:39:29 +09006306 private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai,
6307 @NonNull final NetworkCapabilities nc) {
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006308 NetworkCapabilities newNc = mixInCapabilities(nai, nc);
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006309 if (Objects.equals(nai.networkCapabilities, newNc)) return;
Chalard Jean1f05eed2019-12-02 18:39:29 +09006310 updateNetworkPermissions(nai, newNc);
Chalard Jean7ec1ff62019-11-22 22:39:56 +09006311 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006312
Chalard Jeanf213ca12018-01-16 18:43:05 +09006313 updateUids(nai, prevNc, newNc);
6314
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006315 if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006316 // If the requestable capabilities haven't changed, and the score hasn't changed, then
6317 // the change we're processing can't affect any requests, it can only affect the listens
6318 // on this network. We might have been called by rematchNetworkAndRequests when a
6319 // network changed foreground state.
Chalard Jeana6f315a2019-12-09 11:50:38 +09006320 processListenRequests(nai);
Chalard Jean52638ac42020-01-14 22:46:36 +09006321 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
6322 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
Chalard Jean466b6652020-01-15 00:49:43 +09006323 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
6324 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
6325 if (prevSuspended != suspended || prevRoaming != roaming) {
Chalard Jean52638ac42020-01-14 22:46:36 +09006326 // TODO (b/73132094) : remove this call once the few users of onSuspended and
6327 // onResumed have been removed.
6328 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED
6329 : ConnectivityManager.CALLBACK_RESUMED);
6330 // updateNetworkInfo will mix in the suspended info from the capabilities and
6331 // take appropriate action for the network having possibly changed state.
6332 updateNetworkInfo(nai, nai.networkInfo);
6333 }
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006334 } else {
6335 // If the requestable capabilities have changed or the score changed, we can't have been
6336 // called by rematchNetworkAndRequests, so it's safe to start a rematch.
Chalard Jean1a4548c2019-11-07 18:54:49 +09006337 rematchAllNetworksAndRequests();
Paul Jensene0988542015-06-25 15:30:08 -04006338 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07006339 }
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006340
Chalard Jean52638ac42020-01-14 22:46:36 +09006341 // TODO : static analysis indicates that prevNc can't be null here (getAndSetNetworkCaps
6342 // never returns null), so mark the relevant members and functions in nai as @NonNull and
6343 // remove this test
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006344 if (prevNc != null) {
junyulai05986c62018-08-07 19:50:45 +08006345 final boolean oldMetered = prevNc.isMetered();
6346 final boolean newMetered = newNc.isMetered();
6347 final boolean meteredChanged = oldMetered != newMetered;
6348
6349 if (meteredChanged) {
6350 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
6351 mRestrictBackground);
6352 }
6353
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006354 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006355 newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
junyulai05986c62018-08-07 19:50:45 +08006356
6357 // Report changes that are interesting for network statistics tracking.
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006358 if (meteredChanged || roamingChanged) {
6359 notifyIfacesChangedForNetworkStats();
6360 }
6361 }
6362
Lorenzo Colittiaa7f7e42018-01-16 00:52:07 +09006363 if (!newNc.hasTransport(TRANSPORT_VPN)) {
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006364 // Tell VPNs about updated capabilities, since they may need to
6365 // bubble those changes through.
Chalard Jean6b65ec72018-05-18 22:02:56 +09006366 updateAllVpnsCapabilities();
Jeff Sharkey72f9c422017-10-27 17:22:59 -06006367 }
chenbruce5d955622020-02-20 14:28:31 +08006368
6369 if (!newNc.equalsTransportTypes(prevNc)) {
6370 mDnsManager.updateTransportsForNetwork(nai.network.netId, newNc.getTransportTypes());
6371 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006372 }
6373
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006374 /**
6375 * Returns whether VPN isolation (ingress interface filtering) should be applied on the given
6376 * network.
6377 *
6378 * Ingress interface filtering enforces that all apps under the given network can only receive
6379 * packets from the network's interface (and loopback). This is important for VPNs because
6380 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
6381 * non-VPN interfaces.
6382 *
6383 * As a result, this method should return true iff
6384 * 1. the network is an app VPN (not legacy VPN)
6385 * 2. the VPN does not allow bypass
6386 * 3. the VPN is fully-routed
6387 * 4. the VPN interface is non-null
6388 *
Chalard Jeanafdecd52019-09-26 18:03:47 +09006389 * @see INetd#firewallAddUidInterfaceRules
6390 * @see INetd#firewallRemoveUidInterfaceRules
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006391 */
6392 private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
6393 LinkProperties lp) {
6394 if (nc == null || lp == null) return false;
6395 return nai.isVPN()
Lorenzo Colittid9696562020-01-12 22:28:37 +09006396 && !nai.networkAgentConfig.allowBypass
Qingxi Li7cf06622020-01-17 17:54:27 -08006397 && nc.getOwnerUid() != Process.SYSTEM_UID
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006398 && lp.getInterfaceName() != null
Lorenzo Colitti5ccee0c2020-04-02 04:50:41 +00006399 && (lp.hasIPv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute())
6400 && (lp.hasIPv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute());
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006401 }
6402
Chalard Jeanf213ca12018-01-16 18:43:05 +09006403 private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
6404 NetworkCapabilities newNc) {
6405 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
6406 Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
6407 if (null == prevRanges) prevRanges = new ArraySet<>();
6408 if (null == newRanges) newRanges = new ArraySet<>();
6409 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
6410
6411 prevRanges.removeAll(newRanges);
6412 newRanges.removeAll(prevRangesCopy);
6413
6414 try {
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006415 // When updating the VPN uid routing rules, add the new range first then remove the old
6416 // range. If old range were removed first, there would be a window between the old
6417 // range being removed and the new range being added, during which UIDs contained
6418 // in both ranges are not subject to any VPN routing rules. Adding new range before
6419 // removing old range works because, unlike the filtering rules below, it's possible to
6420 // add duplicate UID routing rules.
Chalard Jeanf213ca12018-01-16 18:43:05 +09006421 if (!newRanges.isEmpty()) {
6422 final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
6423 newRanges.toArray(addedRangesArray);
Luke Huang4e25ec62018-09-27 16:58:23 +08006424 mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray);
Chalard Jeanf213ca12018-01-16 18:43:05 +09006425 }
6426 if (!prevRanges.isEmpty()) {
6427 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
6428 prevRanges.toArray(removedRangesArray);
Luke Huang4e25ec62018-09-27 16:58:23 +08006429 mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray);
Chalard Jeanf213ca12018-01-16 18:43:05 +09006430 }
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006431 final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties);
6432 final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties);
6433 final String iface = nai.linkProperties.getInterfaceName();
6434 // For VPN uid interface filtering, old ranges need to be removed before new ranges can
Chalard Jean081ff7a2020-06-11 13:03:37 +00006435 // be added, due to the range being expanded and stored as individual UIDs. For example
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006436 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
6437 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
6438 // were added first and then newRanges got removed later, there would be only one uid
6439 // 10013 left. A consequence of removing old ranges before adding new ranges is that
6440 // there is now a window of opportunity when the UIDs are not subject to any filtering.
6441 // Note that this is in contrast with the (more robust) update of VPN routing rules
6442 // above, where the addition of new ranges happens before the removal of old ranges.
6443 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
6444 // to be removed will never overlap with the new range to be added.
6445 if (wasFiltering && !prevRanges.isEmpty()) {
Qingxi Li7cf06622020-01-17 17:54:27 -08006446 mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, prevNc.getOwnerUid());
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006447 }
6448 if (shouldFilter && !newRanges.isEmpty()) {
Qingxi Li7cf06622020-01-17 17:54:27 -08006449 mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, newNc.getOwnerUid());
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006450 }
Chalard Jeanf213ca12018-01-16 18:43:05 +09006451 } catch (Exception e) {
6452 // Never crash!
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +00006453 loge("Exception in updateUids: ", e);
Chalard Jeanf213ca12018-01-16 18:43:05 +09006454 }
6455 }
6456
Hugo Benichief502882017-09-01 01:23:32 +00006457 public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
Lorenzo Colitti94229b32019-02-20 21:34:01 +09006458 ensureRunningOnConnectivityServiceThread();
6459
Erik Kline736353a2018-03-21 07:18:33 -07006460 if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) {
Hugo Benichief502882017-09-01 01:23:32 +00006461 // Ignore updates for disconnected networks
6462 return;
6463 }
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09006464 if (VDBG || DDBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006465 log("Update of LinkProperties for " + nai.toShortString()
6466 + "; created=" + nai.created
6467 + "; everConnected=" + nai.everConnected);
Hugo Benichief502882017-09-01 01:23:32 +00006468 }
Lorenzo Colittic82a3e42020-04-16 16:49:56 +00006469 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
6470 // modify its oldLp parameter.
lucaslin25a4ec32018-11-28 12:51:55 +08006471 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
Hugo Benichief502882017-09-01 01:23:32 +00006472 }
6473
Paul Jensenc8b9a742014-09-30 15:37:41 -04006474 private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
Lorenzo Colitti767708d2016-07-01 01:37:11 +09006475 for (int i = 0; i < nai.numNetworkRequests(); i++) {
6476 NetworkRequest nr = nai.requestAt(i);
Paul Jensenc8b9a742014-09-30 15:37:41 -04006477 // Don't send listening requests to factories. b/17393458
Lorenzo Colittif4a45f42016-07-18 18:17:08 +09006478 if (nr.isListen()) continue;
Chalard Jean05ab6812018-05-02 21:14:54 +09006479 sendUpdatedScoreToFactories(nr, nai);
Paul Jensenc8b9a742014-09-30 15:37:41 -04006480 }
6481 }
6482
Chalard Jean5b26b622019-12-03 20:37:01 +09006483 private void sendUpdatedScoreToFactories(@NonNull NetworkRequest networkRequest,
6484 @Nullable NetworkAgentInfo nai) {
Chalard Jeance454802019-12-03 21:35:40 +09006485 final int score;
6486 final int serial;
Chalard Jean05ab6812018-05-02 21:14:54 +09006487 if (nai != null) {
6488 score = nai.getCurrentScore();
6489 serial = nai.factorySerialNumber;
Chalard Jeance454802019-12-03 21:35:40 +09006490 } else {
6491 score = 0;
6492 serial = 0;
Chalard Jean05ab6812018-05-02 21:14:54 +09006493 }
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09006494 if (VDBG || DDBG){
6495 log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
6496 }
Lorenzo Colitti6654b082020-01-10 00:40:28 +09006497 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
6498 npi.requestNetwork(networkRequest, score, serial);
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09006499 }
6500 }
6501
6502 /** Sends all current NetworkRequests to the specified factory. */
Lorenzo Colitti6654b082020-01-10 00:40:28 +09006503 private void sendAllRequestsToProvider(NetworkProviderInfo npi) {
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09006504 ensureRunningOnConnectivityServiceThread();
6505 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6506 if (nri.request.isListen()) continue;
6507 NetworkAgentInfo nai = nri.mSatisfier;
6508 final int score;
6509 final int serial;
6510 if (nai != null) {
6511 score = nai.getCurrentScore();
6512 serial = nai.factorySerialNumber;
6513 } else {
6514 score = 0;
Lorenzo Colitti6654b082020-01-10 00:40:28 +09006515 serial = NetworkProvider.ID_NONE;
Lorenzo Colitti43c36b52020-01-07 19:36:24 +09006516 }
Lorenzo Colitti6654b082020-01-10 00:40:28 +09006517 npi.requestNetwork(nri.request, score, serial);
Robert Greenwalt7b816022014-04-18 15:25:25 -07006518 }
6519 }
6520
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08006521 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
6522 int notificationType) {
Jeremy Joslin79294842014-12-03 17:15:28 -08006523 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08006524 Intent intent = new Intent();
Jeremy Joslina68e7d72014-11-26 14:24:15 -08006525 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
6526 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request);
Jeremy Joslin79294842014-12-03 17:15:28 -08006527 nri.mPendingIntentSent = true;
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08006528 sendIntent(nri.mPendingIntent, intent);
6529 }
6530 // else not handled
6531 }
6532
6533 private void sendIntent(PendingIntent pendingIntent, Intent intent) {
6534 mPendingIntentWakeLock.acquire();
6535 try {
6536 if (DBG) log("Sending " + pendingIntent);
6537 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
6538 } catch (PendingIntent.CanceledException e) {
6539 if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
6540 mPendingIntentWakeLock.release();
6541 releasePendingNetworkRequest(pendingIntent);
6542 }
6543 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
6544 }
6545
6546 @Override
6547 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
6548 String resultData, Bundle resultExtras) {
6549 if (DBG) log("Finished sending " + pendingIntent);
6550 mPendingIntentWakeLock.release();
Jeremy Joslin79294842014-12-03 17:15:28 -08006551 // Release with a delay so the receiving client has an opportunity to put in its
6552 // own request.
6553 releasePendingNetworkRequestWithDelay(pendingIntent);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08006554 }
6555
Chalard Jeanf19db372018-01-26 19:24:40 +09006556 private void callCallbackForRequest(NetworkRequestInfo nri,
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006557 NetworkAgentInfo networkAgent, int notificationType, int arg1) {
Hugo Benichidba33db2017-03-23 22:40:44 +09006558 if (nri.messenger == null) {
Cody Kesting63e4e002019-12-18 10:57:50 -08006559 // Default request has no msgr. Also prevents callbacks from being invoked for
6560 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
6561 // are Type.LISTEN, but should not have NetworkCallbacks invoked.
6562 return;
Hugo Benichidba33db2017-03-23 22:40:44 +09006563 }
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006564 Bundle bundle = new Bundle();
Hugo Benichidba33db2017-03-23 22:40:44 +09006565 // TODO: check if defensive copies of data is needed.
6566 putParcelable(bundle, new NetworkRequest(nri.request));
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006567 Message msg = Message.obtain();
Hugo Benichidba33db2017-03-23 22:40:44 +09006568 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
6569 putParcelable(bundle, networkAgent.network);
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006570 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07006571 switch (notificationType) {
Chalard Jean804b8fb2018-01-30 22:41:41 +09006572 case ConnectivityManager.CALLBACK_AVAILABLE: {
Qingxi Li9c5d8b92020-01-08 12:51:49 -08006573 final NetworkCapabilities nc =
6574 networkCapabilitiesRestrictedForCallerPermissions(
6575 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
6576 putParcelable(
6577 bundle,
6578 maybeSanitizeLocationInfoForCaller(
6579 nc, nri.mUid, nri.request.getRequestorPackageName()));
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09006580 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
6581 networkAgent.linkProperties, nri.mPid, nri.mUid));
junyulai05986c62018-08-07 19:50:45 +08006582 // For this notification, arg1 contains the blocked status.
6583 msg.arg1 = arg1;
Chalard Jean804b8fb2018-01-30 22:41:41 +09006584 break;
6585 }
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006586 case ConnectivityManager.CALLBACK_LOSING: {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006587 msg.arg1 = arg1;
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006588 break;
6589 }
6590 case ConnectivityManager.CALLBACK_CAP_CHANGED: {
Chalard Jeanf19db372018-01-26 19:24:40 +09006591 // networkAgent can't be null as it has been accessed a few lines above.
Qingxi Li9c5d8b92020-01-08 12:51:49 -08006592 final NetworkCapabilities netCap =
6593 networkCapabilitiesRestrictedForCallerPermissions(
6594 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
6595 putParcelable(
6596 bundle,
6597 maybeSanitizeLocationInfoForCaller(
6598 netCap, nri.mUid, nri.request.getRequestorPackageName()));
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006599 break;
6600 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07006601 case ConnectivityManager.CALLBACK_IP_CHANGED: {
Remi NGUYEN VANead1ef42019-12-17 16:45:42 +09006602 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
6603 networkAgent.linkProperties, nri.mPid, nri.mUid));
Robert Greenwalt9258c642014-03-26 16:47:06 -07006604 break;
6605 }
junyulai05986c62018-08-07 19:50:45 +08006606 case ConnectivityManager.CALLBACK_BLK_CHANGED: {
junyulaie6b36512018-10-24 22:38:06 +08006607 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1 != 0);
junyulai05986c62018-08-07 19:50:45 +08006608 msg.arg1 = arg1;
6609 break;
6610 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07006611 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07006612 msg.what = notificationType;
Robert Greenwalta848c1c2014-09-30 16:50:07 -07006613 msg.setData(bundle);
Robert Greenwalt9258c642014-03-26 16:47:06 -07006614 try {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006615 if (VDBG) {
Hugo Benichia0385682017-03-22 17:07:57 +09006616 String notification = ConnectivityManager.getCallbackName(notificationType);
6617 log("sending notification " + notification + " for " + nri.request);
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006618 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07006619 nri.messenger.send(msg);
6620 } catch (RemoteException e) {
6621 // may occur naturally in the race of binder death.
6622 loge("RemoteException caught trying to send a callback msg for " + nri.request);
6623 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006624 }
6625
Hugo Benichidba33db2017-03-23 22:40:44 +09006626 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
6627 bundle.putParcelable(t.getClass().getSimpleName(), t);
6628 }
6629
Paul Jensenc8b9a742014-09-30 15:37:41 -04006630 private void teardownUnneededNetwork(NetworkAgentInfo nai) {
Lorenzo Colitti767708d2016-07-01 01:37:11 +09006631 if (nai.numRequestNetworkRequests() != 0) {
6632 for (int i = 0; i < nai.numNetworkRequests(); i++) {
6633 NetworkRequest nr = nai.requestAt(i);
6634 // Ignore listening requests.
Lorenzo Colittif4a45f42016-07-18 18:17:08 +09006635 if (nr.isListen()) continue;
Lorenzo Colitti767708d2016-07-01 01:37:11 +09006636 loge("Dead network still had at least " + nr);
6637 break;
6638 }
Paul Jensenc8b9a742014-09-30 15:37:41 -04006639 }
6640 nai.asyncChannel.disconnect();
6641 }
6642
Robert Greenwalt7b816022014-04-18 15:25:25 -07006643 private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
6644 if (oldNetwork == null) {
6645 loge("Unknown NetworkAgentInfo in handleLingerComplete");
6646 return;
6647 }
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006648 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString());
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006649
6650 // If we get here it means that the last linger timeout for this network expired. So there
6651 // must be no other active linger timers, and we must stop lingering.
6652 oldNetwork.clearLingerState();
6653
Lorenzo Colitti3d4a1062016-09-09 18:48:56 +09006654 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006655 // Tear the network down.
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006656 teardownUnneededNetwork(oldNetwork);
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09006657 } else {
6658 // Put the network in the background.
Lorenzo Colittib8167f62016-09-15 22:47:08 +09006659 updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork,
6660 oldNetwork.networkCapabilities);
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006661 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006662 }
6663
Chalard Jean6d006102019-12-03 20:45:30 +09006664 private void makeDefault(@Nullable final NetworkAgentInfo newNetwork) {
Robert Greenwaltfc0c6892014-08-27 14:34:02 -07006665 if (DBG) log("Switching to new default network: " + newNetwork);
Chiachang Wanga6093042018-09-28 22:42:48 +08006666
Chalard Jean6d006102019-12-03 20:45:30 +09006667 mDefaultNetworkNai = newNetwork;
6668
Paul Jensen27b02b72014-07-14 12:03:33 -04006669 try {
Chalard Jean6d006102019-12-03 20:45:30 +09006670 if (null != newNetwork) {
6671 mNMS.setDefaultNetId(newNetwork.network.netId);
6672 } else {
6673 mNMS.clearDefaultNetId();
6674 }
Paul Jensen27b02b72014-07-14 12:03:33 -04006675 } catch (Exception e) {
6676 loge("Exception setting default network :" + e);
6677 }
Lorenzo Colittic78da292018-01-19 00:50:48 +09006678
Lorenzo Colitti0cb79032014-10-15 16:06:07 +09006679 notifyLockdownVpn(newNetwork);
Chalard Jean6d006102019-12-03 20:45:30 +09006680 handleApplyDefaultProxy(null != newNetwork
6681 ? newNetwork.linkProperties.getHttpProxy() : null);
6682 updateTcpBufferSizes(null != newNetwork
6683 ? newNetwork.linkProperties.getTcpBufferSizes() : null);
6684 mDnsManager.setDefaultDnsSystemProperties(null != newNetwork
6685 ? newNetwork.linkProperties.getDnsServers() : Collections.EMPTY_LIST);
Lorenzo Colittic78da292018-01-19 00:50:48 +09006686 notifyIfacesChangedForNetworkStats();
Varun Anand4fa80e82019-02-06 10:13:38 -08006687 // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks.
6688 updateAllVpnsCapabilities();
Paul Jensen27b02b72014-07-14 12:03:33 -04006689 }
6690
Chalard Jeana6f315a2019-12-09 11:50:38 +09006691 private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
Lorenzo Colitti72bbf482016-07-20 02:39:22 +09006692 // For consistency with previous behaviour, send onLost callbacks before onAvailable.
Chalard Jean18921152019-11-22 22:33:33 +09006693 processNewlyLostListenRequests(nai);
Chalard Jeana6f315a2019-12-09 11:50:38 +09006694 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
Chalard Jean18921152019-11-22 22:33:33 +09006695 processNewlySatisfiedListenRequests(nai);
6696 }
6697
6698 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
Lorenzo Colitti72bbf482016-07-20 02:39:22 +09006699 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6700 NetworkRequest nr = nri.request;
6701 if (!nr.isListen()) continue;
6702 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
6703 nai.removeRequest(nri.request.requestId);
6704 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
6705 }
6706 }
Chalard Jean18921152019-11-22 22:33:33 +09006707 }
Lorenzo Colitti72bbf482016-07-20 02:39:22 +09006708
Chalard Jean18921152019-11-22 22:33:33 +09006709 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
Lorenzo Colitti72bbf482016-07-20 02:39:22 +09006710 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6711 NetworkRequest nr = nri.request;
6712 if (!nr.isListen()) continue;
6713 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
6714 nai.addRequest(nr);
Erik Klinec75d4fa2017-02-15 19:59:17 +09006715 notifyNetworkAvailable(nai, nri);
Lorenzo Colitti72bbf482016-07-20 02:39:22 +09006716 }
6717 }
6718 }
6719
Chalard Jeanf0e63782019-12-02 15:34:05 +09006720 // An accumulator class to gather the list of changes that result from a rematch.
Chalard Jeanf0e63782019-12-02 15:34:05 +09006721 private static class NetworkReassignment {
Chalard Jeanf96e7872019-12-02 18:59:27 +09006722 static class RequestReassignment {
6723 @NonNull public final NetworkRequestInfo mRequest;
6724 @Nullable public final NetworkAgentInfo mOldNetwork;
6725 @Nullable public final NetworkAgentInfo mNewNetwork;
6726 RequestReassignment(@NonNull final NetworkRequestInfo request,
6727 @Nullable final NetworkAgentInfo oldNetwork,
6728 @Nullable final NetworkAgentInfo newNetwork) {
6729 mRequest = request;
6730 mOldNetwork = oldNetwork;
6731 mNewNetwork = newNetwork;
6732 }
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006733
6734 public String toString() {
6735 return mRequest.request.requestId + " : "
6736 + (null != mOldNetwork ? mOldNetwork.network.netId : "null")
6737 + " → " + (null != mNewNetwork ? mNewNetwork.network.netId : "null");
6738 }
Chalard Jeanf96e7872019-12-02 18:59:27 +09006739 }
6740
Chalard Jeancdd4c452019-12-10 21:25:24 +09006741 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>();
Chalard Jean1f05eed2019-12-02 18:39:29 +09006742
Chalard Jeanf96e7872019-12-02 18:59:27 +09006743 @NonNull Iterable<RequestReassignment> getRequestReassignments() {
Chalard Jeancdd4c452019-12-10 21:25:24 +09006744 return mReassignments;
Chalard Jeanf96e7872019-12-02 18:59:27 +09006745 }
6746
6747 void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
Chalard Jeancdd4c452019-12-10 21:25:24 +09006748 if (!Build.IS_USER) {
6749 // The code is never supposed to add two reassignments of the same request. Make
6750 // sure this stays true, but without imposing this expensive check on all
6751 // reassignments on all user devices.
6752 for (final RequestReassignment existing : mReassignments) {
6753 if (existing.mRequest.equals(reassignment.mRequest)) {
6754 throw new IllegalStateException("Trying to reassign ["
6755 + reassignment + "] but already have ["
6756 + existing + "]");
6757 }
6758 }
Chalard Jean25be0372019-12-03 22:16:26 +09006759 }
Chalard Jeancdd4c452019-12-10 21:25:24 +09006760 mReassignments.add(reassignment);
Chalard Jeanf0e63782019-12-02 15:34:05 +09006761 }
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006762
6763 // Will return null if this reassignment does not change the network assigned to
Chalard Jean6d006102019-12-03 20:45:30 +09006764 // the passed request.
6765 @Nullable
6766 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) {
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006767 for (final RequestReassignment event : getRequestReassignments()) {
Chalard Jean6d006102019-12-03 20:45:30 +09006768 if (nri == event.mRequest) return event;
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006769 }
6770 return null;
6771 }
Chalard Jeanf0e63782019-12-02 15:34:05 +09006772
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006773 public String toString() {
6774 final StringJoiner sj = new StringJoiner(", " /* delimiter */,
6775 "NetReassign [" /* prefix */, "]" /* suffix */);
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006776 if (mReassignments.isEmpty()) return sj.add("no changes").toString();
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006777 for (final RequestReassignment rr : getRequestReassignments()) {
6778 sj.add(rr.toString());
Chalard Jean1a4548c2019-11-07 18:54:49 +09006779 }
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006780 return sj.toString();
Chalard Jean1a4548c2019-11-07 18:54:49 +09006781 }
Chalard Jeanb4429fe2019-12-04 18:49:18 +09006782
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006783 public String debugString() {
6784 final StringBuilder sb = new StringBuilder();
6785 sb.append("NetworkReassignment :");
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006786 if (mReassignments.isEmpty()) return sb.append(" no changes").toString();
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006787 for (final RequestReassignment rr : getRequestReassignments()) {
6788 sb.append("\n ").append(rr);
6789 }
6790 return sb.append("\n").toString();
Paul Jensencf4c2c62015-07-01 14:16:32 -04006791 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006792 }
6793
Chalard Jeana15fd132019-12-04 13:32:31 +09006794 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
6795 @Nullable final NetworkAgentInfo previousSatisfier,
6796 @Nullable final NetworkAgentInfo newSatisfier,
6797 final long now) {
6798 if (newSatisfier != null) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006799 if (VDBG) log("rematch for " + newSatisfier.toShortString());
Chalard Jeana15fd132019-12-04 13:32:31 +09006800 if (previousSatisfier != null) {
6801 if (VDBG || DDBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006802 log(" accepting network in place of " + previousSatisfier.toShortString());
Chalard Jeana15fd132019-12-04 13:32:31 +09006803 }
6804 previousSatisfier.removeRequest(nri.request.requestId);
6805 previousSatisfier.lingerRequest(nri.request, now, mLingerDelayMs);
6806 } else {
6807 if (VDBG || DDBG) log(" accepting network in place of null");
6808 }
6809 newSatisfier.unlingerRequest(nri.request);
6810 if (!newSatisfier.addRequest(nri.request)) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006811 Slog.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
6812 + nri.request);
Chalard Jeana15fd132019-12-04 13:32:31 +09006813 }
6814 } else {
6815 if (DBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006816 log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
Chalard Jeana15fd132019-12-04 13:32:31 +09006817 + " request " + nri.request.requestId);
6818 }
6819 previousSatisfier.removeRequest(nri.request.requestId);
6820 }
6821 nri.mSatisfier = newSatisfier;
6822 }
6823
Chalard Jean14c2d1d2019-12-10 18:56:30 +09006824 @NonNull
6825 private NetworkReassignment computeNetworkReassignment() {
6826 ensureRunningOnConnectivityServiceThread();
Chalard Jean47d46482019-12-10 21:08:07 +09006827 final NetworkReassignment changes = new NetworkReassignment();
6828
6829 // Gather the list of all relevant agents and sort them by score.
6830 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
6831 for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
6832 if (!nai.everConnected) continue;
6833 nais.add(nai);
Chalard Jean47d46482019-12-10 21:08:07 +09006834 }
Chalard Jean47d46482019-12-10 21:08:07 +09006835
6836 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
6837 if (nri.request.isListen()) continue;
Chalard Jean7a5e51f2019-12-10 22:16:53 +09006838 final NetworkAgentInfo bestNetwork = mNetworkRanker.getBestNetwork(nri.request, nais);
6839 if (bestNetwork != nri.mSatisfier) {
6840 // bestNetwork may be null if no network can satisfy this request.
Chalard Jean47d46482019-12-10 21:08:07 +09006841 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
6842 nri, nri.mSatisfier, bestNetwork));
6843 }
Chalard Jean14c2d1d2019-12-10 18:56:30 +09006844 }
6845 return changes;
6846 }
6847
Paul Jensen1c7ba022015-06-16 14:27:36 -04006848 /**
6849 * Attempt to rematch all Networks with NetworkRequests. This may result in Networks
6850 * being disconnected.
Paul Jensen1c7ba022015-06-16 14:27:36 -04006851 */
Chalard Jean1a4548c2019-11-07 18:54:49 +09006852 private void rematchAllNetworksAndRequests() {
Chalard Jean47d46482019-12-10 21:08:07 +09006853 // TODO: This may be slow, and should be optimized.
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09006854 final long now = SystemClock.elapsedRealtime();
Chalard Jean14c2d1d2019-12-10 18:56:30 +09006855 final NetworkReassignment changes = computeNetworkReassignment();
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006856 if (VDBG || DDBG) {
6857 log(changes.debugString());
6858 } else if (DBG) {
6859 log(changes.toString()); // Shorter form, only one line of log
6860 }
Chalard Jean26693d42019-12-10 22:01:31 +09006861 applyNetworkReassignment(changes, now);
Chalard Jean8bab4832019-12-10 19:01:29 +09006862 }
Chalard Jean18ee53f2019-11-19 19:16:48 +09006863
Chalard Jean8bab4832019-12-10 19:01:29 +09006864 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
Chalard Jean26693d42019-12-10 22:01:31 +09006865 final long now) {
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006866 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos.values();
6867
6868 // Since most of the time there are only 0 or 1 background networks, it would probably
6869 // be more efficient to just use an ArrayList here. TODO : measure performance
6870 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>();
Chalard Jeana3984a12019-11-19 20:01:10 +09006871 for (final NetworkAgentInfo nai : nais) {
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006872 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai);
Chalard Jeanc89c4892019-11-07 19:05:18 +09006873 }
Chalard Jean24b7fe02019-11-07 23:16:12 +09006874
Chalard Jean8bab4832019-12-10 19:01:29 +09006875 // First, update the lists of satisfied requests in the network agents. This is necessary
6876 // because some code later depends on this state to be correct, most prominently computing
6877 // the linger status.
Chalard Jean5f8010b2019-12-04 19:55:32 +09006878 for (final NetworkReassignment.RequestReassignment event :
6879 changes.getRequestReassignments()) {
Chalard Jean5f8010b2019-12-04 19:55:32 +09006880 updateSatisfiersForRematchRequest(event.mRequest, event.mOldNetwork,
6881 event.mNewNetwork, now);
Chalard Jeanc89c4892019-11-07 19:05:18 +09006882 }
Chalard Jean24b7fe02019-11-07 23:16:12 +09006883
Chalard Jean26693d42019-12-10 22:01:31 +09006884 final NetworkAgentInfo oldDefaultNetwork = getDefaultNetwork();
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006885 final NetworkRequestInfo defaultRequestInfo = mNetworkRequests.get(mDefaultRequest);
Chalard Jean6d006102019-12-03 20:45:30 +09006886 final NetworkReassignment.RequestReassignment reassignment =
6887 changes.getReassignment(defaultRequestInfo);
6888 final NetworkAgentInfo newDefaultNetwork =
6889 null != reassignment ? reassignment.mNewNetwork : oldDefaultNetwork;
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006890
6891 if (oldDefaultNetwork != newDefaultNetwork) {
Chalard Jean59954c82019-12-03 16:06:00 +09006892 if (oldDefaultNetwork != null) {
6893 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
6894 }
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006895 updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
Chalard Jean6d006102019-12-03 20:45:30 +09006896 // Notify system services of the new default.
Chalard Jean9f0e8dd2019-12-03 14:43:57 +09006897 makeDefault(newDefaultNetwork);
6898 // Log 0 -> X and Y -> X default network transitions, where X is the new default.
6899 mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
6900 now, newDefaultNetwork, oldDefaultNetwork);
6901 // Have a new default network, release the transition wakelock in
6902 scheduleReleaseNetworkTransitionWakelock();
6903 }
Chalard Jean18ee53f2019-11-19 19:16:48 +09006904
Chalard Jeanf96e7872019-12-02 18:59:27 +09006905 // Notify requested networks are available after the default net is switched, but
6906 // before LegacyTypeTracker sends legacy broadcasts
6907 for (final NetworkReassignment.RequestReassignment event :
6908 changes.getRequestReassignments()) {
Chalard Jeance454802019-12-03 21:35:40 +09006909 // Tell NetworkProviders about the new score, so they can stop
6910 // trying to connect if they know they cannot match it.
6911 // TODO - this could get expensive if there are a lot of outstanding requests for this
6912 // network. Think of a way to reduce this. Push netid->request mapping to each factory?
6913 sendUpdatedScoreToFactories(event.mRequest.request, event.mNewNetwork);
6914
Chalard Jeanf96e7872019-12-02 18:59:27 +09006915 if (null != event.mNewNetwork) {
6916 notifyNetworkAvailable(event.mNewNetwork, event.mRequest);
Chalard Jeanf2cbe682019-12-03 15:55:14 +09006917 } else {
Chalard Jeanf2cbe682019-12-03 15:55:14 +09006918 callCallbackForRequest(event.mRequest, event.mOldNetwork,
6919 ConnectivityManager.CALLBACK_LOST, 0);
Chalard Jeanf96e7872019-12-02 18:59:27 +09006920 }
6921 }
6922
Chalard Jeana8013252019-12-04 20:01:46 +09006923 // Update the linger state before processing listen callbacks, because the background
6924 // computation depends on whether the network is lingering. Don't send the LOSING callbacks
6925 // just yet though, because they have to be sent after the listens are processed to keep
6926 // backward compatibility.
Chalard Jeanb4429fe2019-12-04 18:49:18 +09006927 final ArrayList<NetworkAgentInfo> lingeredNetworks = new ArrayList<>();
Chalard Jeana3984a12019-11-19 20:01:10 +09006928 for (final NetworkAgentInfo nai : nais) {
6929 // Rematching may have altered the linger state of some networks, so update all linger
6930 // timers. updateLingerState reads the state from the network agent and does nothing
6931 // if the state has not changed : the source of truth is controlled with
6932 // NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which have been
6933 // called while rematching the individual networks above.
Chalard Jeanb4429fe2019-12-04 18:49:18 +09006934 if (updateLingerState(nai, now)) {
6935 lingeredNetworks.add(nai);
6936 }
6937 }
6938
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006939 for (final NetworkAgentInfo nai : nais) {
6940 if (!nai.everConnected) continue;
6941 final boolean oldBackground = oldBgNetworks.contains(nai);
Chalard Jeana8013252019-12-04 20:01:46 +09006942 // Process listen requests and update capabilities if the background state has
6943 // changed for this network. For consistency with previous behavior, send onLost
6944 // callbacks before onAvailable.
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006945 processNewlyLostListenRequests(nai);
6946 if (oldBackground != nai.isBackgroundNetwork()) {
6947 applyBackgroundChangeForRematch(nai);
Chalard Jeana8013252019-12-04 20:01:46 +09006948 }
Chalard Jeanfbb758f2019-12-11 14:12:30 +09006949 processNewlySatisfiedListenRequests(nai);
Chalard Jeana8013252019-12-04 20:01:46 +09006950 }
6951
Chalard Jeanb4429fe2019-12-04 18:49:18 +09006952 for (final NetworkAgentInfo nai : lingeredNetworks) {
6953 notifyNetworkLosing(nai, now);
Chalard Jean24b7fe02019-11-07 23:16:12 +09006954 }
6955
Chalard Jean0147c902019-11-19 19:23:38 +09006956 updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais);
6957
Chalard Jean24b7fe02019-11-07 23:16:12 +09006958 // Tear down all unneeded networks.
Chalard Jeanc89c4892019-11-07 19:05:18 +09006959 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
6960 if (unneeded(nai, UnneededFor.TEARDOWN)) {
6961 if (nai.getLingerExpiry() > 0) {
6962 // This network has active linger timers and no requests, but is not
6963 // lingering. Linger it.
6964 //
6965 // One way (the only way?) this can happen if this network is unvalidated
6966 // and became unneeded due to another network improving its score to the
6967 // point where this network will no longer be able to satisfy any requests
6968 // even if it validates.
Chalard Jeanb4429fe2019-12-04 18:49:18 +09006969 if (updateLingerState(nai, now)) {
6970 notifyNetworkLosing(nai, now);
6971 }
Chalard Jeanc89c4892019-11-07 19:05:18 +09006972 } else {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09006973 if (DBG) log("Reaping " + nai.toShortString());
Chalard Jeanc89c4892019-11-07 19:05:18 +09006974 teardownUnneededNetwork(nai);
6975 }
6976 }
Paul Jensen2161a8e2014-09-11 11:00:39 -04006977 }
6978 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07006979
Chalard Jean1f05eed2019-12-02 18:39:29 +09006980 /**
6981 * Apply a change in background state resulting from rematching networks with requests.
6982 *
6983 * During rematch, a network may change background states by starting to satisfy or stopping
6984 * to satisfy a foreground request. Listens don't count for this. When a network changes
6985 * background states, its capabilities need to be updated and callbacks fired for the
6986 * capability change.
6987 *
6988 * @param nai The network that changed background states
6989 */
6990 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
6991 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
6992 if (Objects.equals(nai.networkCapabilities, newNc)) return;
6993 updateNetworkPermissions(nai, newNc);
6994 nai.getAndSetNetworkCapabilities(newNc);
6995 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
6996 }
6997
Chalard Jean0147c902019-11-19 19:23:38 +09006998 private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
6999 @Nullable final NetworkAgentInfo oldDefaultNetwork,
7000 @Nullable final NetworkAgentInfo newDefaultNetwork,
Chalard Jean14c2d1d2019-12-10 18:56:30 +09007001 @NonNull final Collection<NetworkAgentInfo> nais) {
Chalard Jean18ee53f2019-11-19 19:16:48 +09007002 if (oldDefaultNetwork != newDefaultNetwork) {
7003 // Maintain the illusion : since the legacy API only understands one network at a time,
7004 // if the default network changed, apps should see a disconnected broadcast for the
7005 // old default network before they see a connected broadcast for the new one.
7006 if (oldDefaultNetwork != null) {
7007 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
7008 oldDefaultNetwork, true);
7009 }
7010 if (newDefaultNetwork != null) {
7011 // The new default network can be newly null if and only if the old default
7012 // network doesn't satisfy the default request any more because it lost a
7013 // capability.
7014 mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
7015 mLegacyTypeTracker.add(newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
Chalard Jean0147c902019-11-19 19:23:38 +09007016 // If the legacy VPN is connected, notifyLockdownVpn may end up sending a broadcast
7017 // to reflect the NetworkInfo of this new network. This broadcast has to be sent
7018 // after the disconnect broadcasts above, but before the broadcasts sent by the
7019 // legacy type tracker below.
7020 // TODO : refactor this, it's too complex
Chalard Jean18ee53f2019-11-19 19:16:48 +09007021 notifyLockdownVpn(newDefaultNetwork);
7022 }
7023 }
7024
Robert Greenwalt7b816022014-04-18 15:25:25 -07007025 // Now that all the callbacks have been sent, send the legacy network broadcasts
7026 // as needed. This is necessary so that legacy requests correctly bind dns
7027 // requests to this network. The legacy users are listening for this broadcast
7028 // and will generally do a dns request so they can ensureRouteToHost and if
7029 // they do that before the callbacks happen they'll use the default network.
7030 //
7031 // TODO: Is there still a race here? The legacy broadcast will be sent after sending
7032 // callbacks, but if apps can receive the broadcast before the callback, they still might
7033 // have an inconsistent view of networking.
7034 //
7035 // This *does* introduce a race where if the user uses the new api
7036 // (notification callbacks) and then uses the old api (getNetworkInfo(type))
7037 // they may get old info. Reverse this after the old startUsing api is removed.
7038 // This is on top of the multiple intent sequencing referenced in the todo above.
7039 for (NetworkAgentInfo nai : nais) {
Chalard Jeanfbb758f2019-12-11 14:12:30 +09007040 if (nai.everConnected) {
7041 addNetworkToLegacyTypeTracker(nai);
7042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007043 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07007044 }
7045
Chalard Jean38925832019-11-07 23:07:32 +09007046 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
7047 for (int i = 0; i < nai.numNetworkRequests(); i++) {
7048 NetworkRequest nr = nai.requestAt(i);
7049 if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
7050 // legacy type tracker filters out repeat adds
7051 mLegacyTypeTracker.add(nr.legacyType, nai);
7052 }
7053 }
7054
7055 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
7056 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
7057 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
7058 // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
7059 if (nai.isVPN()) {
7060 mLegacyTypeTracker.add(TYPE_VPN, nai);
7061 }
7062 }
7063
Lorenzo Colitti7b42f392014-12-17 11:26:49 +09007064 private void updateInetCondition(NetworkAgentInfo nai) {
Paul Jensenad50a1f2014-09-05 12:06:44 -04007065 // Don't bother updating until we've graduated to validated at least once.
Lorenzo Colittid3b8a3e2014-12-17 11:14:42 +09007066 if (!nai.everValidated) return;
Paul Jensenad50a1f2014-09-05 12:06:44 -04007067 // For now only update icons for default connection.
7068 // TODO: Update WiFi and cellular icons separately. b/17237507
7069 if (!isDefaultNetwork(nai)) return;
7070
Lorenzo Colitti7b42f392014-12-17 11:26:49 +09007071 int newInetCondition = nai.lastValidated ? 100 : 0;
Paul Jensenad50a1f2014-09-05 12:06:44 -04007072 // Don't repeat publish.
7073 if (newInetCondition == mDefaultInetConditionPublished) return;
7074
7075 mDefaultInetConditionPublished = newInetCondition;
7076 sendInetConditionBroadcast(nai.networkInfo);
7077 }
7078
Lorenzo Colitti0cb79032014-10-15 16:06:07 +09007079 private void notifyLockdownVpn(NetworkAgentInfo nai) {
Hugo Benichi69744342017-11-27 10:57:16 +09007080 synchronized (mVpns) {
7081 if (mLockdownTracker != null) {
7082 if (nai != null && nai.isVPN()) {
7083 mLockdownTracker.onVpnStateChanged(nai.networkInfo);
7084 } else {
7085 mLockdownTracker.onNetworkInfoChanged();
7086 }
Lorenzo Colitti0cb79032014-10-15 16:06:07 +09007087 }
7088 }
7089 }
7090
Chalard Jean52638ac42020-01-14 22:46:36 +09007091 @NonNull
7092 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
7093 final NetworkInfo newInfo = new NetworkInfo(info);
Chalard Jean466b6652020-01-15 00:49:43 +09007094 // The suspended and roaming bits are managed in NetworkCapabilities.
Chalard Jean52638ac42020-01-14 22:46:36 +09007095 final boolean suspended =
7096 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
7097 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
7098 // Only override the state with SUSPENDED if the network is currently in CONNECTED
7099 // state. This is because the network could have been suspended before connecting,
7100 // or it could be disconnecting while being suspended, and in both these cases
7101 // the state should not be overridden. Note that the only detailed state that
7102 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to
7103 // worry about multiple different substates of CONNECTED.
7104 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
7105 info.getExtraInfo());
Chiachang Wanga5d8fe82020-02-12 17:01:59 +08007106 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
7107 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
7108 // network agent is created, then goes to suspended, then goes out of suspended without
7109 // ever setting connected. Check if network agent is ever connected to update the state.
7110 newInfo.setDetailedState(nai.everConnected
7111 ? NetworkInfo.DetailedState.CONNECTED
7112 : NetworkInfo.DetailedState.CONNECTING,
7113 info.getReason(),
7114 info.getExtraInfo());
Chalard Jean52638ac42020-01-14 22:46:36 +09007115 }
Chalard Jean466b6652020-01-15 00:49:43 +09007116 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
Chalard Jean52638ac42020-01-14 22:46:36 +09007117 return newInfo;
7118 }
7119
7120 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {
7121 final NetworkInfo newInfo = mixInInfo(networkAgent, info);
7122
Erik Klinec75d4fa2017-02-15 19:59:17 +09007123 final NetworkInfo.State state = newInfo.getState();
Robert Greenwalt73b6cbae2014-06-23 11:40:00 -07007124 NetworkInfo oldInfo = null;
7125 synchronized (networkAgent) {
7126 oldInfo = networkAgent.networkInfo;
7127 networkAgent.networkInfo = newInfo;
7128 }
Lorenzo Colitti0cb79032014-10-15 16:06:07 +09007129 notifyLockdownVpn(networkAgent);
Robert Greenwalt7b816022014-04-18 15:25:25 -07007130
Robert Greenwalt7b816022014-04-18 15:25:25 -07007131 if (DBG) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09007132 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
7133 + oldInfo.getState() + " to " + state);
Robert Greenwalt7b816022014-04-18 15:25:25 -07007134 }
Robert Greenwalt12e67352014-05-13 21:41:06 -07007135
Robin Lee585e2482016-05-01 23:00:00 +01007136 if (!networkAgent.created
7137 && (state == NetworkInfo.State.CONNECTED
7138 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09007139
7140 // A network that has just connected has zero requests and is thus a foreground network.
7141 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
7142
Luke Huanga24d5d82019-04-09 18:41:49 +08007143 if (!createNativeNetwork(networkAgent)) return;
Chalard Jeanfe5e23f2020-05-08 01:33:13 +00007144 if (networkAgent.isVPN()) {
7145 // Initialize the VPN capabilities to their starting values according to the
7146 // underlying networks. This will avoid a spurious callback to
7147 // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
7148 // the VPN would switch from its default, blank capabilities to those
7149 // that reflect the capabilities of its underlying networks.
7150 updateAllVpnsCapabilities();
7151 }
Paul Jenseneec75412014-08-04 12:21:19 -04007152 networkAgent.created = true;
Robin Lee585e2482016-05-01 23:00:00 +01007153 }
7154
7155 if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
7156 networkAgent.everConnected = true;
7157
Lorenzo Colitti2df4c7d2018-02-27 22:47:01 +09007158 if (networkAgent.linkProperties == null) {
Chalard Jeanbf1170c2019-12-10 21:07:02 +09007159 Slog.wtf(TAG, networkAgent.toShortString() + " connected with null LinkProperties");
Lorenzo Colitti2df4c7d2018-02-27 22:47:01 +09007160 }
7161
lucaslin8175ac992019-04-03 17:09:28 +08007162 // NetworkCapabilities need to be set before sending the private DNS config to
7163 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
Chalard Jean7ec1ff62019-11-22 22:39:56 +09007164 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
7165
Erik Kline736353a2018-03-21 07:18:33 -07007166 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
lucaslin25a4ec32018-11-28 12:51:55 +08007167 updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
7168 null);
Lorenzo Colittibdc45492015-04-09 14:35:26 +09007169
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09007170 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
7171 // command must be sent after updating LinkProperties to maximize chances of
7172 // NetworkMonitor seeing the correct LinkProperties when starting.
7173 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
Lorenzo Colittid9696562020-01-12 22:28:37 +09007174 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) {
Lorenzo Colittiac955b32019-05-31 15:41:29 +09007175 networkAgent.networkMonitor().setAcceptPartialConnectivity();
Remi NGUYEN VANe67b0c32018-12-27 16:43:56 +09007176 }
Lorenzo Colittiac955b32019-05-31 15:41:29 +09007177 networkAgent.networkMonitor().notifyNetworkConnected(
Remi NGUYEN VAN5ab87402020-05-12 08:53:53 +00007178 new LinkProperties(networkAgent.linkProperties,
7179 true /* parcelSensitiveFields */),
7180 networkAgent.networkCapabilities);
Lorenzo Colittie03c3c72015-04-03 16:38:52 +09007181 scheduleUnvalidatedPrompt(networkAgent);
Lorenzo Colittibdc45492015-04-09 14:35:26 +09007182
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09007183 // Whether a particular NetworkRequest listen should cause signal strength thresholds to
7184 // be communicated to a particular NetworkAgent depends only on the network's immutable,
7185 // capabilities, so it only needs to be done once on initial connect, not every time the
7186 // network's capabilities change. Note that we do this before rematching the network,
7187 // so we could decide to tear it down immediately afterwards. That's fine though - on
7188 // disconnection NetworkAgents should stop any signal strength monitoring they have been
7189 // doing.
Lorenzo Colitti6bc0a2b2015-09-15 15:56:01 +09007190 updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09007191
Varun Anand4fa80e82019-02-06 10:13:38 -08007192 if (networkAgent.isVPN()) {
7193 updateAllVpnsCapabilities();
7194 }
7195
Paul Jensen2161a8e2014-09-11 11:00:39 -04007196 // Consider network even though it is not yet validated.
Chalard Jean1a4548c2019-11-07 18:54:49 +09007197 rematchAllNetworksAndRequests();
Lorenzo Colittibdc45492015-04-09 14:35:26 +09007198
7199 // This has to happen after matching the requests, because callbacks are just requests.
7200 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
Robert Greenwalt8d482522015-06-24 13:23:42 -07007201 } else if (state == NetworkInfo.State.DISCONNECTED) {
Robert Greenwalt7b816022014-04-18 15:25:25 -07007202 networkAgent.asyncChannel.disconnect();
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04007203 if (networkAgent.isVPN()) {
Chalard Jeanf213ca12018-01-16 18:43:05 +09007204 updateUids(networkAgent, networkAgent.networkCapabilities, null);
Paul Jensen6bc2c2c2014-05-07 15:27:40 -04007205 }
Chalard Jean392971c2018-05-11 20:19:20 +09007206 disconnectAndDestroyNetwork(networkAgent);
Irina Dumitrescu044a4362018-12-05 16:19:47 +00007207 if (networkAgent.isVPN()) {
7208 // As the active or bound network changes for apps, broadcast the default proxy, as
7209 // apps may need to update their proxy data. This is called after disconnecting from
7210 // VPN to make sure we do not broadcast the old proxy data.
7211 // TODO(b/122649188): send the broadcast only to VPN users.
7212 mProxyTracker.sendProxyBroadcast();
7213 }
Yintang Gu1505d0a2019-06-18 14:24:32 +08007214 } else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED ||
7215 state == NetworkInfo.State.SUSPENDED)) {
Robert Greenwalt8d482522015-06-24 13:23:42 -07007216 mLegacyTypeTracker.update(networkAgent);
Robert Greenwalt7b816022014-04-18 15:25:25 -07007217 }
7218 }
7219
Automerger Merge Worker3d40f5782020-03-08 06:07:47 +00007220 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final int score) {
7221 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
7222 nai.setScore(score);
Chalard Jean1a4548c2019-11-07 18:54:49 +09007223 rematchAllNetworksAndRequests();
Paul Jensenc8b9a742014-09-30 15:37:41 -04007224 sendUpdatedScoreToFactories(nai);
Robert Greenwalt55691b82014-05-27 13:20:24 -07007225 }
7226
Erik Klinec75d4fa2017-02-15 19:59:17 +09007227 // Notify only this one new request of the current state. Transfer all the
7228 // current state by calling NetworkCapabilities and LinkProperties callbacks
7229 // so that callers can be guaranteed to have as close to atomicity in state
7230 // transfer as can be supported by this current API.
7231 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
Etan Cohen681fcda2016-10-27 15:05:50 -07007232 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
Erik Klinec75d4fa2017-02-15 19:59:17 +09007233 if (nri.mPendingIntent != null) {
7234 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
7235 // Attempt no subsequent state pushes where intents are involved.
7236 return;
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08007237 }
Erik Klinec75d4fa2017-02-15 19:59:17 +09007238
junyulai05986c62018-08-07 19:50:45 +08007239 final boolean metered = nai.networkCapabilities.isMetered();
7240 final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
7241 metered, mRestrictBackground);
7242 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
7243 }
7244
Chalard Jeanb4429fe2019-12-04 18:49:18 +09007245 // Notify the requests on this NAI that the network is now lingered.
7246 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
7247 final int lingerTime = (int) (nai.getLingerExpiry() - now);
7248 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
7249 }
7250
junyulai05986c62018-08-07 19:50:45 +08007251 /**
7252 * Notify of the blocked state apps with a registered callback matching a given NAI.
7253 *
7254 * Unlike other callbacks, blocked status is different between each individual uid. So for
7255 * any given nai, all requests need to be considered according to the uid who filed it.
7256 *
7257 * @param nai The target NetworkAgentInfo.
7258 * @param oldMetered True if the previous network capabilities is metered.
7259 * @param newRestrictBackground True if data saver is enabled.
7260 */
7261 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
7262 boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
7263
7264 for (int i = 0; i < nai.numNetworkRequests(); i++) {
7265 NetworkRequest nr = nai.requestAt(i);
7266 NetworkRequestInfo nri = mNetworkRequests.get(nr);
7267 final int uidRules = mUidRules.get(nri.mUid);
7268 final boolean oldBlocked, newBlocked;
7269 // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
7270 // between these two calls.
7271 synchronized (mVpns) {
7272 oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
7273 oldRestrictBackground);
7274 newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
7275 newRestrictBackground);
7276 }
7277 if (oldBlocked != newBlocked) {
7278 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
7279 encodeBool(newBlocked));
7280 }
7281 }
7282 }
7283
7284 /**
7285 * Notify apps with a given UID of the new blocked state according to new uid rules.
7286 * @param uid The uid for which the rules changed.
7287 * @param newRules The new rules to apply.
7288 */
7289 private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
7290 for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
7291 final boolean metered = nai.networkCapabilities.isMetered();
7292 final boolean oldBlocked, newBlocked;
7293 // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
7294 // rules changed event. And this function actually loop through all connected nai and
7295 // its requests. It seems that mVpns lock will be grabbed frequently in this case.
7296 // Reduce the number of locking or optimize the use of lock are likely needed in future.
7297 synchronized (mVpns) {
7298 oldBlocked = isUidNetworkingWithVpnBlocked(
7299 uid, mUidRules.get(uid), metered, mRestrictBackground);
7300 newBlocked = isUidNetworkingWithVpnBlocked(
7301 uid, newRules, metered, mRestrictBackground);
7302 }
7303 if (oldBlocked == newBlocked) {
junyulai26b76642019-04-08 16:58:22 +08007304 continue;
junyulai05986c62018-08-07 19:50:45 +08007305 }
7306 final int arg = encodeBool(newBlocked);
7307 for (int i = 0; i < nai.numNetworkRequests(); i++) {
7308 NetworkRequest nr = nai.requestAt(i);
7309 NetworkRequestInfo nri = mNetworkRequests.get(nr);
7310 if (nri != null && nri.mUid == uid) {
7311 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
7312 }
7313 }
7314 }
Robert Greenwalt9258c642014-03-26 16:47:06 -07007315 }
7316
Chalard Jean612522b2019-04-10 23:07:55 +09007317 @VisibleForTesting
7318 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
Lorenzo Colittia793a672014-07-31 23:20:17 +09007319 // The NetworkInfo we actually send out has no bearing on the real
7320 // state of affairs. For example, if the default connection is mobile,
7321 // and a request for HIPRI has just gone away, we need to pretend that
7322 // HIPRI has just disconnected. So we need to set the type to HIPRI and
7323 // the state to DISCONNECTED, even though the network is of type MOBILE
7324 // and is still connected.
7325 NetworkInfo info = new NetworkInfo(nai.networkInfo);
7326 info.setType(type);
Robert Greenwalt8d482522015-06-24 13:23:42 -07007327 if (state != DetailedState.DISCONNECTED) {
7328 info.setDetailedState(state, null, info.getExtraInfo());
Erik Kline8f29dcf2014-12-08 16:25:20 +09007329 sendConnectedBroadcast(info);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07007330 } else {
Robert Greenwalt8d482522015-06-24 13:23:42 -07007331 info.setDetailedState(state, info.getReason(), info.getExtraInfo());
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07007332 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
7333 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
7334 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
7335 if (info.isFailover()) {
7336 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
7337 nai.networkInfo.setFailover(false);
7338 }
7339 if (info.getReason() != null) {
7340 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
7341 }
7342 if (info.getExtraInfo() != null) {
7343 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
7344 }
7345 NetworkAgentInfo newDefaultAgent = null;
Lorenzo Colitti767708d2016-07-01 01:37:11 +09007346 if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
Paul Jensen85cf78e2015-06-25 13:25:07 -04007347 newDefaultAgent = getDefaultNetwork();
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07007348 if (newDefaultAgent != null) {
7349 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
7350 newDefaultAgent.networkInfo);
7351 } else {
7352 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
7353 }
7354 }
7355 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
7356 mDefaultInetConditionPublished);
Erik Kline8f29dcf2014-12-08 16:25:20 +09007357 sendStickyBroadcast(intent);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07007358 if (newDefaultAgent != null) {
Erik Kline8f29dcf2014-12-08 16:25:20 +09007359 sendConnectedBroadcast(newDefaultAgent.networkInfo);
Robert Greenwalt32aa65a2014-06-02 15:32:02 -07007360 }
7361 }
7362 }
7363
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09007364 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
hiroaki.yokoyamaeeeaab92018-10-16 12:50:33 +09007365 if (VDBG || DDBG) {
Hugo Benichia0385682017-03-22 17:07:57 +09007366 String notification = ConnectivityManager.getCallbackName(notifyType);
Chalard Jeanbf1170c2019-12-10 21:07:02 +09007367 log("notifyType " + notification + " for " + networkAgent.toShortString());
Hugo Benichia0385682017-03-22 17:07:57 +09007368 }
Lorenzo Colitti767708d2016-07-01 01:37:11 +09007369 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
7370 NetworkRequest nr = networkAgent.requestAt(i);
Robert Greenwalt9258c642014-03-26 16:47:06 -07007371 NetworkRequestInfo nri = mNetworkRequests.get(nr);
7372 if (VDBG) log(" sending notification for " + nr);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08007373 if (nri.mPendingIntent == null) {
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09007374 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
Jeremy Joslin46e3ac82014-11-05 10:32:09 -08007375 } else {
7376 sendPendingIntentForRequest(nri, networkAgent, notifyType);
7377 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07007378 }
Robert Greenwalt7b816022014-04-18 15:25:25 -07007379 }
Robert Greenwalt12e67352014-05-13 21:41:06 -07007380
Lorenzo Colittib57578ca2016-07-01 01:53:25 +09007381 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
7382 notifyNetworkCallbacks(networkAgent, notifyType, 0);
7383 }
7384
Jeff Sharkey69736342014-12-08 14:50:12 -08007385 /**
Lorenzo Colittic78da292018-01-19 00:50:48 +09007386 * Returns the list of all interfaces that could be used by network traffic that does not
7387 * explicitly specify a network. This includes the default network, but also all VPNs that are
7388 * currently connected.
7389 *
7390 * Must be called on the handler thread.
7391 */
7392 private Network[] getDefaultNetworks() {
Varun Anandd33cbc62019-02-07 14:13:13 -08007393 ensureRunningOnConnectivityServiceThread();
Lorenzo Colittic78da292018-01-19 00:50:48 +09007394 ArrayList<Network> defaultNetworks = new ArrayList<>();
7395 NetworkAgentInfo defaultNetwork = getDefaultNetwork();
7396 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
7397 if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) {
7398 defaultNetworks.add(nai.network);
7399 }
7400 }
7401 return defaultNetworks.toArray(new Network[0]);
7402 }
7403
7404 /**
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09007405 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
7406 * active iface's tracked properties has changed.
Jeff Sharkey69736342014-12-08 14:50:12 -08007407 */
Jeff Davidson0b93c5d2016-01-20 11:35:38 -08007408 private void notifyIfacesChangedForNetworkStats() {
Varun Anandd33cbc62019-02-07 14:13:13 -08007409 ensureRunningOnConnectivityServiceThread();
7410 String activeIface = null;
7411 LinkProperties activeLinkProperties = getActiveLinkProperties();
7412 if (activeLinkProperties != null) {
7413 activeIface = activeLinkProperties.getInterfaceName();
7414 }
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00007415
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09007416 final VpnInfo[] vpnInfos = getAllVpnInfo();
Jeff Sharkey69736342014-12-08 14:50:12 -08007417 try {
Varun Anandd33cbc62019-02-07 14:13:13 -08007418 mStatsService.forceUpdateIfaces(
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09007419 getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos);
Jeff Sharkey69736342014-12-08 14:50:12 -08007420 } catch (Exception ignored) {
7421 }
7422 }
7423
Sreeram Ramachandranf4e0c0c2014-07-27 14:18:26 -07007424 @Override
7425 public boolean addVpnAddress(String address, int prefixLength) {
Sreeram Ramachandranf4e0c0c2014-07-27 14:18:26 -07007426 int user = UserHandle.getUserId(Binder.getCallingUid());
7427 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09007428 throwIfLockdownEnabled();
Sreeram Ramachandranf4e0c0c2014-07-27 14:18:26 -07007429 return mVpns.get(user).addAddress(address, prefixLength);
7430 }
7431 }
7432
7433 @Override
7434 public boolean removeVpnAddress(String address, int prefixLength) {
Sreeram Ramachandranf4e0c0c2014-07-27 14:18:26 -07007435 int user = UserHandle.getUserId(Binder.getCallingUid());
7436 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09007437 throwIfLockdownEnabled();
Sreeram Ramachandranf4e0c0c2014-07-27 14:18:26 -07007438 return mVpns.get(user).removeAddress(address, prefixLength);
7439 }
7440 }
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08007441
7442 @Override
7443 public boolean setUnderlyingNetworksForVpn(Network[] networks) {
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08007444 int user = UserHandle.getUserId(Binder.getCallingUid());
Hugo Benichi69744342017-11-27 10:57:16 +09007445 final boolean success;
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08007446 synchronized (mVpns) {
Hugo Benichi69744342017-11-27 10:57:16 +09007447 throwIfLockdownEnabled();
Wenchao Tongf5ea3402015-03-04 13:26:38 -08007448 success = mVpns.get(user).setUnderlyingNetworks(networks);
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08007449 }
Wenchao Tongf5ea3402015-03-04 13:26:38 -08007450 if (success) {
Varun Anand4fa80e82019-02-06 10:13:38 -08007451 mHandler.post(() -> {
7452 // Update VPN's capabilities based on updated underlying network set.
7453 updateAllVpnsCapabilities();
7454 notifyIfacesChangedForNetworkStats();
7455 });
Wenchao Tongf5ea3402015-03-04 13:26:38 -08007456 }
7457 return success;
Sreeram Ramachandranc2c0bea2014-11-11 16:09:21 -08007458 }
Stuart Scottf1fb3972015-04-02 18:00:02 -07007459
7460 @Override
Udam Sainib7c24872016-01-04 12:16:14 -08007461 public String getCaptivePortalServerUrl() {
paulhu59148b72019-08-12 16:25:11 +08007462 enforceNetworkStackOrSettingsPermission();
Niklas Lindgrenafc5f9b2018-12-07 11:08:04 +01007463 String settingUrl = mContext.getResources().getString(
7464 R.string.config_networkCaptivePortalServerUrl);
7465
7466 if (!TextUtils.isEmpty(settingUrl)) {
7467 return settingUrl;
7468 }
7469
7470 settingUrl = Settings.Global.getString(mContext.getContentResolver(),
7471 Settings.Global.CAPTIVE_PORTAL_HTTP_URL);
7472 if (!TextUtils.isEmpty(settingUrl)) {
7473 return settingUrl;
7474 }
7475
7476 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
Udam Sainib7c24872016-01-04 12:16:14 -08007477 }
7478
7479 @Override
junyulai7c469172019-01-16 20:23:34 +08007480 public void startNattKeepalive(Network network, int intervalSeconds,
7481 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09007482 enforceKeepalivePermission();
7483 mKeepaliveTracker.startNattKeepalive(
junyulai0c666972019-03-04 22:45:36 +08007484 getNetworkAgentInfoForNetwork(network), null /* fd */,
junyulai7c469172019-01-16 20:23:34 +08007485 intervalSeconds, cb,
junyulai06835112019-01-03 18:50:15 +08007486 srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09007487 }
7488
7489 @Override
junyulai215b8772019-01-15 11:32:44 +08007490 public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId,
junyulai7c469172019-01-16 20:23:34 +08007491 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
junyulai215b8772019-01-15 11:32:44 +08007492 String dstAddr) {
junyulai215b8772019-01-15 11:32:44 +08007493 mKeepaliveTracker.startNattKeepalive(
7494 getNetworkAgentInfoForNetwork(network), fd, resourceId,
junyulai7c469172019-01-16 20:23:34 +08007495 intervalSeconds, cb,
junyulai215b8772019-01-15 11:32:44 +08007496 srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
7497 }
7498
7499 @Override
junyulai352dc2f2019-01-08 20:04:33 +08007500 public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds,
junyulai7c469172019-01-16 20:23:34 +08007501 ISocketKeepaliveCallback cb) {
junyulai352dc2f2019-01-08 20:04:33 +08007502 enforceKeepalivePermission();
7503 mKeepaliveTracker.startTcpKeepalive(
junyulai7c469172019-01-16 20:23:34 +08007504 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
junyulai352dc2f2019-01-08 20:04:33 +08007505 }
7506
7507 @Override
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09007508 public void stopKeepalive(Network network, int slot) {
7509 mHandler.sendMessage(mHandler.obtainMessage(
junyulai06835112019-01-03 18:50:15 +08007510 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network));
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +09007511 }
7512
7513 @Override
Stuart Scottf1fb3972015-04-02 18:00:02 -07007514 public void factoryReset() {
paulhu59148b72019-08-12 16:25:11 +08007515 enforceSettingsPermission();
Stuart Scotte3e314d2015-04-20 14:07:45 -07007516
7517 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
7518 return;
7519 }
7520
Robin Lee3b3dd942015-05-12 18:14:58 +01007521 final int userId = UserHandle.getCallingUserId();
7522
Heemin Seog29ddbd52019-06-12 09:21:44 -07007523 Binder.withCleanCallingIdentity(() -> {
7524 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
7525 ipMemoryStore.factoryReset();
7526 });
Xiao Mad91ec092019-04-10 19:01:52 +09007527
Stuart Scottf1fb3972015-04-02 18:00:02 -07007528 // Turn airplane mode off
7529 setAirplaneMode(false);
7530
Stuart Scotte3e314d2015-04-20 14:07:45 -07007531 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
Victor Changb04a5ea2016-05-30 20:36:30 +01007532 // Remove always-on package
7533 synchronized (mVpns) {
7534 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId);
7535 if (alwaysOnPackage != null) {
Pavel Grafova462bcb2019-01-25 08:50:06 +00007536 setAlwaysOnVpnPackage(userId, null, false, null);
Benedict Wong418017e2019-11-06 00:20:15 -08007537 setVpnPackageAuthorization(alwaysOnPackage, userId, VpnManager.TYPE_VPN_NONE);
Victor Changb04a5ea2016-05-30 20:36:30 +01007538 }
Victor Changb04a5ea2016-05-30 20:36:30 +01007539
Hugo Benichi69744342017-11-27 10:57:16 +09007540 // Turn Always-on VPN off
7541 if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
7542 final long ident = Binder.clearCallingIdentity();
7543 try {
7544 mKeyStore.delete(Credentials.LOCKDOWN_VPN);
7545 mLockdownEnabled = false;
7546 setLockdownTracker(null);
7547 } finally {
7548 Binder.restoreCallingIdentity(ident);
7549 }
Koichi, Sugimotoda1a7ac2016-01-27 18:48:58 +09007550 }
Koichi, Sugimotoda1a7ac2016-01-27 18:48:58 +09007551
Hugo Benichi69744342017-11-27 10:57:16 +09007552 // Turn VPN off
7553 VpnConfig vpnConfig = getVpnConfig(userId);
7554 if (vpnConfig != null) {
7555 if (vpnConfig.legacy) {
7556 prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
7557 } else {
7558 // Prevent this app (packagename = vpnConfig.user) from initiating
7559 // VPN connections in the future without user intervention.
Benedict Wong418017e2019-11-06 00:20:15 -08007560 setVpnPackageAuthorization(
7561 vpnConfig.user, userId, VpnManager.TYPE_VPN_NONE);
Stuart Scottf1fb3972015-04-02 18:00:02 -07007562
Hugo Benichi69744342017-11-27 10:57:16 +09007563 prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
7564 }
Stuart Scotte3e314d2015-04-20 14:07:45 -07007565 }
Stuart Scottf1fb3972015-04-02 18:00:02 -07007566 }
7567 }
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09007568
Xiao Maed25f9c2019-06-12 16:31:14 +09007569 // restore private DNS settings to default mode (opportunistic)
7570 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
7571 Settings.Global.putString(mContext.getContentResolver(),
7572 Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
7573 }
7574
Lorenzo Colitti9be58c52016-09-15 14:02:29 +09007575 Settings.Global.putString(mContext.getContentResolver(),
7576 Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
Stuart Scottf1fb3972015-04-02 18:00:02 -07007577 }
Paul Jensencf4c2c62015-07-01 14:16:32 -04007578
Ricky Wai44dcbde2018-01-23 04:09:45 +00007579 @Override
7580 public byte[] getNetworkWatchlistConfigHash() {
7581 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
7582 if (nwm == null) {
7583 loge("Unable to get NetworkWatchlistManager");
7584 return null;
7585 }
7586 // Redirect it to network watchlist service to access watchlist file and calculate hash.
7587 return nwm.getWatchlistConfigHash();
7588 }
7589
Hugo Benichicfddd682016-05-31 16:28:06 +09007590 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
Hugo Benichiedf5c242017-11-11 08:06:43 +09007591 int[] transports = nai.networkCapabilities.getTransportTypes();
7592 mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype));
Erik Kline48f12f22016-04-14 17:30:59 +09007593 }
Hugo Benichiab7d2e62017-04-21 15:07:12 +09007594
7595 private static boolean toBool(int encodedBoolean) {
7596 return encodedBoolean != 0; // Only 0 means false.
7597 }
7598
7599 private static int encodeBool(boolean b) {
7600 return b ? 1 : 0;
7601 }
mswest46386886f2018-03-12 10:34:34 -07007602
7603 @Override
Chalard Jeanafdecd52019-09-26 18:03:47 +09007604 public void onShellCommand(@NonNull FileDescriptor in, @NonNull FileDescriptor out,
7605 FileDescriptor err, @NonNull String[] args, ShellCallback callback,
7606 @NonNull ResultReceiver resultReceiver) {
mswest46386886f2018-03-12 10:34:34 -07007607 (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
7608 }
7609
7610 private class ShellCmd extends ShellCommand {
7611
7612 @Override
7613 public int onCommand(String cmd) {
7614 if (cmd == null) {
7615 return handleDefaultCommands(cmd);
7616 }
7617 final PrintWriter pw = getOutPrintWriter();
7618 try {
7619 switch (cmd) {
7620 case "airplane-mode":
7621 final String action = getNextArg();
7622 if ("enable".equals(action)) {
7623 setAirplaneMode(true);
7624 return 0;
7625 } else if ("disable".equals(action)) {
7626 setAirplaneMode(false);
7627 return 0;
7628 } else if (action == null) {
7629 final ContentResolver cr = mContext.getContentResolver();
7630 final int enabled = Settings.Global.getInt(cr,
7631 Settings.Global.AIRPLANE_MODE_ON);
7632 pw.println(enabled == 0 ? "disabled" : "enabled");
7633 return 0;
7634 } else {
7635 onHelp();
7636 return -1;
7637 }
7638 default:
7639 return handleDefaultCommands(cmd);
7640 }
7641 } catch (Exception e) {
7642 pw.println(e);
7643 }
7644 return -1;
7645 }
7646
7647 @Override
7648 public void onHelp() {
7649 PrintWriter pw = getOutPrintWriter();
7650 pw.println("Connectivity service commands:");
7651 pw.println(" help");
7652 pw.println(" Print this help text.");
7653 pw.println(" airplane-mode [enable|disable]");
7654 pw.println(" Turn airplane mode on or off.");
7655 pw.println(" airplane-mode");
7656 pw.println(" Get airplane mode.");
7657 }
7658 }
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07007659
Pavel Grafovcb3b8952018-12-14 13:51:07 +00007660 @GuardedBy("mVpns")
7661 private Vpn getVpnIfOwner() {
Cody Kestinga75e26b2020-01-05 14:06:39 -08007662 return getVpnIfOwner(Binder.getCallingUid());
7663 }
7664
7665 @GuardedBy("mVpns")
7666 private Vpn getVpnIfOwner(int uid) {
Pavel Grafovcb3b8952018-12-14 13:51:07 +00007667 final int user = UserHandle.getUserId(uid);
7668
7669 final Vpn vpn = mVpns.get(user);
7670 if (vpn == null) {
7671 return null;
7672 } else {
7673 final VpnInfo info = vpn.getVpnInfo();
7674 return (info == null || info.ownerUid != uid) ? null : vpn;
7675 }
7676 }
7677
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07007678 /**
7679 * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission
7680 * for testing.
7681 */
7682 private Vpn enforceActiveVpnOrNetworkStackPermission() {
7683 if (checkNetworkStackPermission()) {
7684 return null;
7685 }
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07007686 synchronized (mVpns) {
Pavel Grafovcb3b8952018-12-14 13:51:07 +00007687 Vpn vpn = getVpnIfOwner();
7688 if (vpn != null) {
7689 return vpn;
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07007690 }
7691 }
7692 throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK "
7693 + "permission");
7694 }
7695
7696 /**
7697 * @param connectionInfo the connection to resolve.
7698 * @return {@code uid} if the connection is found and the app has permission to observe it
7699 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
7700 * connection is not found.
7701 */
7702 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
7703 final Vpn vpn = enforceActiveVpnOrNetworkStackPermission();
Benedict Wong5d50ce82020-01-20 22:14:59 -08007704
7705 // Only VpnService based VPNs should be able to get this information.
7706 if (vpn != null && vpn.getActiveAppVpnType() != VpnManager.TYPE_VPN_SERVICE) {
7707 throw new SecurityException(
7708 "getConnectionOwnerUid() not allowed for non-VpnService VPNs");
7709 }
7710
Jeff Vander Stoep0ac2c092018-07-23 10:57:53 -07007711 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
7712 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
7713 }
7714
7715 final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol,
7716 connectionInfo.local, connectionInfo.remote);
7717
7718 /* Filter out Uids not associated with the VPN. */
7719 if (vpn != null && !vpn.appliesToUid(uid)) {
7720 return INVALID_UID;
7721 }
7722
7723 return uid;
7724 }
Pavel Grafovcb3b8952018-12-14 13:51:07 +00007725
7726 @Override
7727 public boolean isCallerCurrentAlwaysOnVpnApp() {
7728 synchronized (mVpns) {
7729 Vpn vpn = getVpnIfOwner();
7730 return vpn != null && vpn.getAlwaysOn();
7731 }
7732 }
7733
7734 @Override
7735 public boolean isCallerCurrentAlwaysOnVpnLockdownApp() {
7736 synchronized (mVpns) {
7737 Vpn vpn = getVpnIfOwner();
7738 return vpn != null && vpn.getLockdown();
7739 }
7740 }
Benedict Wonga341fbc2018-11-09 14:45:34 -08007741
7742 /**
7743 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
7744 *
7745 * <p>The TestNetworkService must be run in the system server due to TUN creation.
7746 */
7747 @Override
7748 public IBinder startOrGetTestNetworkService() {
7749 synchronized (mTNSLock) {
7750 TestNetworkService.enforceTestNetworkPermissions(mContext);
7751
7752 if (mTNS == null) {
7753 mTNS = new TestNetworkService(mContext, mNMS);
7754 }
7755
7756 return mTNS;
7757 }
7758 }
Cody Kesting5aadb8b2019-12-17 12:55:28 -08007759
Cody Kesting63e4e002019-12-18 10:57:50 -08007760 /**
7761 * Handler used for managing all Connectivity Diagnostics related functions.
7762 *
7763 * @see android.net.ConnectivityDiagnosticsManager
7764 *
7765 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file
7766 */
7767 @VisibleForTesting
7768 class ConnectivityDiagnosticsHandler extends Handler {
Cody Kesting1e5ab9b2020-01-07 11:18:54 -08007769 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
7770
Cody Kesting63e4e002019-12-18 10:57:50 -08007771 /**
7772 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
7773 * android.net.ConnectivityDiagnosticsManager}.
7774 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and
7775 * NetworkRequestInfo to be registered
7776 */
7777 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1;
7778
7779 /**
7780 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link
7781 * android.net.ConnectivityDiagnosticsManager}.
7782 * obj = the IConnectivityDiagnosticsCallback to be unregistered
7783 * arg1 = the uid of the caller
7784 */
7785 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2;
7786
Cody Kestinga75e26b2020-01-05 14:06:39 -08007787 /**
7788 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
7789 * after processing {@link #EVENT_NETWORK_TESTED} events.
7790 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
7791 * NetworkMonitor.
7792 * data = PersistableBundle of extras passed from NetworkMonitor.
7793 *
7794 * <p>See {@link ConnectivityService#EVENT_NETWORK_TESTED}.
7795 */
7796 private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED;
7797
Cody Kesting4f49f142020-01-06 16:55:35 -08007798 /**
7799 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
7800 * been detected on the network.
7801 * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
7802 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
7803 * arg2 = NetID.
7804 * data = PersistableBundle of extras passed from NetworkMonitor.
7805 */
7806 private static final int EVENT_DATA_STALL_SUSPECTED = 4;
7807
Cody Kesting1e5ab9b2020-01-07 11:18:54 -08007808 /**
7809 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
7810 * the platform. This event will invoke {@link
7811 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
7812 * callbacks.
7813 * obj = Network that was reported on
7814 * arg1 = boolint for the quality reported
7815 */
7816 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
7817
Cody Kesting63e4e002019-12-18 10:57:50 -08007818 private ConnectivityDiagnosticsHandler(Looper looper) {
7819 super(looper);
7820 }
7821
7822 @Override
7823 public void handleMessage(Message msg) {
7824 switch (msg.what) {
7825 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
7826 handleRegisterConnectivityDiagnosticsCallback(
7827 (ConnectivityDiagnosticsCallbackInfo) msg.obj);
7828 break;
7829 }
7830 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
7831 handleUnregisterConnectivityDiagnosticsCallback(
7832 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
7833 break;
7834 }
Cody Kestinga75e26b2020-01-05 14:06:39 -08007835 case EVENT_NETWORK_TESTED: {
7836 final ConnectivityReportEvent reportEvent =
7837 (ConnectivityReportEvent) msg.obj;
7838
7839 // This is safe because {@link
7840 // NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} receives a
7841 // PersistableBundle and converts it to the Bundle in the incoming Message. If
7842 // {@link NetworkMonitorCallbacks#notifyNetworkTested} is called, msg.data will
7843 // not be set. This is also safe, as msg.getData() will return an empty Bundle.
7844 final PersistableBundle extras = new PersistableBundle(msg.getData());
7845 handleNetworkTestedWithExtras(reportEvent, extras);
7846 break;
7847 }
Cody Kesting4f49f142020-01-06 16:55:35 -08007848 case EVENT_DATA_STALL_SUSPECTED: {
7849 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
7850 if (nai == null) break;
7851
7852 // This is safe because NetworkMonitorCallbacks#notifyDataStallSuspected
7853 // receives a PersistableBundle and converts it to the Bundle in the incoming
7854 // Message.
7855 final PersistableBundle extras = new PersistableBundle(msg.getData());
7856 handleDataStallSuspected(nai, (long) msg.obj, msg.arg1, extras);
7857 break;
7858 }
Cody Kesting1e5ab9b2020-01-07 11:18:54 -08007859 case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
7860 handleNetworkConnectivityReported((NetworkAgentInfo) msg.obj, toBool(msg.arg1));
7861 break;
7862 }
7863 default: {
7864 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
7865 }
Cody Kesting63e4e002019-12-18 10:57:50 -08007866 }
7867 }
7868 }
7869
7870 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */
7871 @VisibleForTesting
7872 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient {
7873 @NonNull private final IConnectivityDiagnosticsCallback mCb;
7874 @NonNull private final NetworkRequestInfo mRequestInfo;
Cody Kestinga75e26b2020-01-05 14:06:39 -08007875 @NonNull private final String mCallingPackageName;
Cody Kesting63e4e002019-12-18 10:57:50 -08007876
7877 @VisibleForTesting
7878 ConnectivityDiagnosticsCallbackInfo(
Cody Kestinga75e26b2020-01-05 14:06:39 -08007879 @NonNull IConnectivityDiagnosticsCallback cb,
7880 @NonNull NetworkRequestInfo nri,
7881 @NonNull String callingPackageName) {
Cody Kesting63e4e002019-12-18 10:57:50 -08007882 mCb = cb;
7883 mRequestInfo = nri;
Cody Kestinga75e26b2020-01-05 14:06:39 -08007884 mCallingPackageName = callingPackageName;
Cody Kesting63e4e002019-12-18 10:57:50 -08007885 }
7886
7887 @Override
7888 public void binderDied() {
7889 log("ConnectivityDiagnosticsCallback IBinder died.");
7890 unregisterConnectivityDiagnosticsCallback(mCb);
7891 }
7892 }
7893
Cody Kestinga75e26b2020-01-05 14:06:39 -08007894 /**
7895 * Class used for sending information from {@link
7896 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it.
7897 */
7898 private static class NetworkTestedResults {
7899 private final int mNetId;
7900 private final int mTestResult;
7901 private final long mTimestampMillis;
7902 @Nullable private final String mRedirectUrl;
7903
7904 private NetworkTestedResults(
7905 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) {
7906 mNetId = netId;
7907 mTestResult = testResult;
7908 mTimestampMillis = timestampMillis;
7909 mRedirectUrl = redirectUrl;
7910 }
7911 }
7912
7913 /**
7914 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link
7915 * ConnectivityDiagnosticsHandler}.
7916 */
7917 private static class ConnectivityReportEvent {
7918 private final long mTimestampMillis;
7919 @NonNull private final NetworkAgentInfo mNai;
7920
7921 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai) {
7922 mTimestampMillis = timestampMillis;
7923 mNai = nai;
7924 }
7925 }
7926
Cody Kesting63e4e002019-12-18 10:57:50 -08007927 private void handleRegisterConnectivityDiagnosticsCallback(
7928 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) {
7929 ensureRunningOnConnectivityServiceThread();
7930
7931 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
Cody Kesting4600fa52020-03-05 10:46:02 -08007932 final IBinder iCb = cb.asBinder();
Cody Kesting63e4e002019-12-18 10:57:50 -08007933 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
7934
7935 // This means that the client registered the same callback multiple times. Do
7936 // not override the previous entry, and exit silently.
Cody Kesting4600fa52020-03-05 10:46:02 -08007937 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
Cody Kesting63e4e002019-12-18 10:57:50 -08007938 if (VDBG) log("Diagnostics callback is already registered");
7939
7940 // Decrement the reference count for this NetworkRequestInfo. The reference count is
7941 // incremented when the NetworkRequestInfo is created as part of
7942 // enforceRequestCountLimit().
7943 decrementNetworkRequestPerUidCount(nri);
7944 return;
7945 }
7946
Cody Kesting4600fa52020-03-05 10:46:02 -08007947 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
Cody Kesting63e4e002019-12-18 10:57:50 -08007948
7949 try {
Cody Kesting4600fa52020-03-05 10:46:02 -08007950 iCb.linkToDeath(cbInfo, 0);
Cody Kesting63e4e002019-12-18 10:57:50 -08007951 } catch (RemoteException e) {
7952 cbInfo.binderDied();
Cody Kesting560eb262020-02-12 14:50:58 -08007953 return;
7954 }
7955
7956 // Once registered, provide ConnectivityReports for matching Networks
7957 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>();
7958 synchronized (mNetworkForNetId) {
7959 for (int i = 0; i < mNetworkForNetId.size(); i++) {
7960 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
7961 if (nai.satisfies(nri.request)) {
7962 matchingNetworks.add(nai);
7963 }
7964 }
7965 }
7966 for (final NetworkAgentInfo nai : matchingNetworks) {
7967 final ConnectivityReport report = nai.getConnectivityReport();
7968 if (report == null) {
7969 continue;
7970 }
7971 if (!checkConnectivityDiagnosticsPermissions(
7972 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
7973 continue;
7974 }
7975
7976 try {
7977 cb.onConnectivityReportAvailable(report);
7978 } catch (RemoteException e) {
7979 // Exception while sending the ConnectivityReport. Move on to the next network.
7980 }
Cody Kesting63e4e002019-12-18 10:57:50 -08007981 }
7982 }
7983
7984 private void handleUnregisterConnectivityDiagnosticsCallback(
7985 @NonNull IConnectivityDiagnosticsCallback cb, int uid) {
7986 ensureRunningOnConnectivityServiceThread();
Cody Kesting4600fa52020-03-05 10:46:02 -08007987 final IBinder iCb = cb.asBinder();
Cody Kesting63e4e002019-12-18 10:57:50 -08007988
Cody Kesting98201372020-03-30 12:43:49 -07007989 final ConnectivityDiagnosticsCallbackInfo cbInfo =
7990 mConnectivityDiagnosticsCallbacks.remove(iCb);
7991 if (cbInfo == null) {
Cody Kesting63e4e002019-12-18 10:57:50 -08007992 if (VDBG) log("Removing diagnostics callback that is not currently registered");
7993 return;
7994 }
7995
Cody Kesting98201372020-03-30 12:43:49 -07007996 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
Cody Kesting63e4e002019-12-18 10:57:50 -08007997
7998 if (uid != nri.mUid) {
7999 if (VDBG) loge("Different uid than registrant attempting to unregister cb");
8000 return;
8001 }
8002
Cody Kesting13564ee2020-03-04 13:35:20 -08008003 // Decrement the reference count for this NetworkRequestInfo. The reference count is
8004 // incremented when the NetworkRequestInfo is created as part of
8005 // enforceRequestCountLimit().
8006 decrementNetworkRequestPerUidCount(nri);
8007
Cody Kesting4600fa52020-03-05 10:46:02 -08008008 iCb.unlinkToDeath(cbInfo, 0);
Cody Kesting63e4e002019-12-18 10:57:50 -08008009 }
8010
Cody Kestinga75e26b2020-01-05 14:06:39 -08008011 private void handleNetworkTestedWithExtras(
8012 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) {
8013 final NetworkAgentInfo nai = reportEvent.mNai;
Cody Kestinga3b71c42020-02-11 10:03:26 -08008014 final NetworkCapabilities networkCapabilities =
Cody Kestinge277c772020-03-05 22:13:31 -08008015 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
Cody Kestinga75e26b2020-01-05 14:06:39 -08008016 final ConnectivityReport report =
8017 new ConnectivityReport(
8018 reportEvent.mNai.network,
8019 reportEvent.mTimestampMillis,
8020 nai.linkProperties,
Cody Kestinga3b71c42020-02-11 10:03:26 -08008021 networkCapabilities,
Cody Kestinga75e26b2020-01-05 14:06:39 -08008022 extras);
Cody Kesting560eb262020-02-12 14:50:58 -08008023 nai.setConnectivityReport(report);
Cody Kestinga75e26b2020-01-05 14:06:39 -08008024 final List<IConnectivityDiagnosticsCallback> results =
8025 getMatchingPermissionedCallbacks(nai);
8026 for (final IConnectivityDiagnosticsCallback cb : results) {
8027 try {
Cody Kesting9347e332020-03-05 15:19:48 -08008028 cb.onConnectivityReportAvailable(report);
Cody Kestinga75e26b2020-01-05 14:06:39 -08008029 } catch (RemoteException ex) {
8030 loge("Error invoking onConnectivityReport", ex);
8031 }
8032 }
8033 }
8034
Cody Kesting4f49f142020-01-06 16:55:35 -08008035 private void handleDataStallSuspected(
8036 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
8037 @NonNull PersistableBundle extras) {
Cody Kestinga3b71c42020-02-11 10:03:26 -08008038 final NetworkCapabilities networkCapabilities =
Cody Kestinge277c772020-03-05 22:13:31 -08008039 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
Cody Kesting4f49f142020-01-06 16:55:35 -08008040 final DataStallReport report =
Cody Kesting7064b5c2020-02-04 21:52:09 -08008041 new DataStallReport(
8042 nai.network,
8043 timestampMillis,
8044 detectionMethod,
8045 nai.linkProperties,
Cody Kestinga3b71c42020-02-11 10:03:26 -08008046 networkCapabilities,
Cody Kesting7064b5c2020-02-04 21:52:09 -08008047 extras);
Cody Kesting4f49f142020-01-06 16:55:35 -08008048 final List<IConnectivityDiagnosticsCallback> results =
8049 getMatchingPermissionedCallbacks(nai);
8050 for (final IConnectivityDiagnosticsCallback cb : results) {
8051 try {
8052 cb.onDataStallSuspected(report);
8053 } catch (RemoteException ex) {
8054 loge("Error invoking onDataStallSuspected", ex);
8055 }
8056 }
8057 }
8058
Cody Kesting1e5ab9b2020-01-07 11:18:54 -08008059 private void handleNetworkConnectivityReported(
8060 @NonNull NetworkAgentInfo nai, boolean connectivity) {
8061 final List<IConnectivityDiagnosticsCallback> results =
8062 getMatchingPermissionedCallbacks(nai);
8063 for (final IConnectivityDiagnosticsCallback cb : results) {
8064 try {
8065 cb.onNetworkConnectivityReported(nai.network, connectivity);
8066 } catch (RemoteException ex) {
8067 loge("Error invoking onNetworkConnectivityReported", ex);
8068 }
8069 }
8070 }
8071
Cody Kestinge277c772020-03-05 22:13:31 -08008072 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) {
8073 final NetworkCapabilities sanitized = new NetworkCapabilities(nc);
8074 sanitized.setUids(null);
8075 sanitized.setAdministratorUids(new int[0]);
8076 sanitized.setOwnerUid(Process.INVALID_UID);
8077 return sanitized;
Cody Kestinga3b71c42020-02-11 10:03:26 -08008078 }
8079
Cody Kestinga75e26b2020-01-05 14:06:39 -08008080 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
8081 @NonNull NetworkAgentInfo nai) {
8082 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
Cody Kesting4600fa52020-03-05 10:46:02 -08008083 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
Cody Kestinga75e26b2020-01-05 14:06:39 -08008084 mConnectivityDiagnosticsCallbacks.entrySet()) {
8085 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
8086 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
8087 if (nai.satisfies(nri.request)) {
8088 if (checkConnectivityDiagnosticsPermissions(
8089 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
Cody Kesting4600fa52020-03-05 10:46:02 -08008090 results.add(entry.getValue().mCb);
Cody Kestinga75e26b2020-01-05 14:06:39 -08008091 }
8092 }
8093 }
8094 return results;
8095 }
8096
8097 @VisibleForTesting
8098 boolean checkConnectivityDiagnosticsPermissions(
8099 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
8100 if (checkNetworkStackPermission(callbackPid, callbackUid)) {
8101 return true;
8102 }
8103
Automerger Merge Workera5333b92020-03-16 15:48:50 +00008104 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
8105 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
8106 // call in a try-catch.
8107 try {
8108 if (!mLocationPermissionChecker.checkLocationPermission(
8109 callbackPackageName, null /* featureId */, callbackUid, null /* message */)) {
8110 return false;
8111 }
8112 } catch (SecurityException e) {
Cody Kestinga75e26b2020-01-05 14:06:39 -08008113 return false;
8114 }
8115
Cody Kesting3096b662020-03-18 21:11:29 +00008116 final Network[] underlyingNetworks;
Cody Kestinga75e26b2020-01-05 14:06:39 -08008117 synchronized (mVpns) {
Cody Kesting3096b662020-03-18 21:11:29 +00008118 final Vpn vpn = getVpnIfOwner(callbackUid);
8119 underlyingNetworks = (vpn == null) ? null : vpn.getUnderlyingNetworks();
8120 }
8121 if (underlyingNetworks != null) {
8122 if (Arrays.asList(underlyingNetworks).contains(nai.network)) return true;
Cody Kestinga75e26b2020-01-05 14:06:39 -08008123 }
8124
8125 // Administrator UIDs also contains the Owner UID
Cody Kestingf7ac9962020-03-16 18:15:28 -07008126 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
Cody Kesting919385b2020-03-18 15:22:12 -07008127 return ArrayUtils.contains(administratorUids, callbackUid);
Cody Kestinga75e26b2020-01-05 14:06:39 -08008128 }
8129
Cody Kesting5aadb8b2019-12-17 12:55:28 -08008130 @Override
8131 public void registerConnectivityDiagnosticsCallback(
Cody Kestinga75e26b2020-01-05 14:06:39 -08008132 @NonNull IConnectivityDiagnosticsCallback callback,
8133 @NonNull NetworkRequest request,
8134 @NonNull String callingPackageName) {
Cody Kesting63e4e002019-12-18 10:57:50 -08008135 if (request.legacyType != TYPE_NONE) {
8136 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
8137 + " Please use NetworkCapabilities instead.");
8138 }
Roshan Piuse38acab2020-01-16 12:17:17 -08008139 final int callingUid = Binder.getCallingUid();
8140 mAppOpsManager.checkPackage(callingUid, callingPackageName);
Cody Kesting63e4e002019-12-18 10:57:50 -08008141
8142 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
8143 // and administrator uids to be safe.
8144 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
Roshan Piuse38acab2020-01-16 12:17:17 -08008145 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Cody Kesting63e4e002019-12-18 10:57:50 -08008146
8147 final NetworkRequest requestWithId =
8148 new NetworkRequest(
8149 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN);
8150
8151 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit.
8152 //
8153 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
8154 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
8155 // callback's binder death.
8156 final NetworkRequestInfo nri = new NetworkRequestInfo(requestWithId);
8157 final ConnectivityDiagnosticsCallbackInfo cbInfo =
Cody Kestinga75e26b2020-01-05 14:06:39 -08008158 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
Cody Kesting63e4e002019-12-18 10:57:50 -08008159
8160 mConnectivityDiagnosticsHandler.sendMessage(
8161 mConnectivityDiagnosticsHandler.obtainMessage(
8162 ConnectivityDiagnosticsHandler
8163 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
8164 cbInfo));
Cody Kesting5aadb8b2019-12-17 12:55:28 -08008165 }
8166
8167 @Override
8168 public void unregisterConnectivityDiagnosticsCallback(
8169 @NonNull IConnectivityDiagnosticsCallback callback) {
Cody Kesting63e4e002019-12-18 10:57:50 -08008170 mConnectivityDiagnosticsHandler.sendMessage(
8171 mConnectivityDiagnosticsHandler.obtainMessage(
8172 ConnectivityDiagnosticsHandler
8173 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
8174 Binder.getCallingUid(),
8175 0,
8176 callback));
Cody Kesting5aadb8b2019-12-17 12:55:28 -08008177 }
Automerger Merge Worker42f81352020-05-12 18:48:04 +00008178
8179 @Override
8180 public void simulateDataStall(int detectionMethod, long timestampMillis,
8181 @NonNull Network network, @NonNull PersistableBundle extras) {
8182 enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
8183 android.Manifest.permission.NETWORK_STACK);
8184 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
8185 if (!nc.hasTransport(TRANSPORT_TEST)) {
8186 throw new SecurityException("Data Stall simluation is only possible for test networks");
8187 }
8188
8189 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
8190 if (nai == null || nai.creatorUid != Binder.getCallingUid()) {
8191 throw new SecurityException("Data Stall simulation is only possible for network "
8192 + "creators");
8193 }
8194
Cody Kesting637887b2020-05-27 18:22:56 +00008195 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
8196 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
8197 // Data Stall information as a DataStallReportParcelable and passing to
8198 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
8199 // still passed to ConnectivityDiagnostics (with new detection methods masked).
Cody Kesting56c22b72020-05-22 00:28:02 +00008200 final DataStallReportParcelable p = new DataStallReportParcelable();
8201 p.timestampMillis = timestampMillis;
8202 p.detectionMethod = detectionMethod;
8203
8204 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
8205 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
8206 }
8207 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
8208 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
8209 p.tcpMetricsCollectionPeriodMillis = extras.getInt(
8210 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
8211 }
8212
8213 notifyDataStallSuspected(p, network.netId);
Automerger Merge Worker42f81352020-05-12 18:48:04 +00008214 }
Nathan Haroldfd45e5f2018-07-30 13:38:01 -07008215}