blob: f6153b1384a0af9bc54a465a11c28d7636eba389 [file] [log] [blame]
The Android Open Source Project28527d22009-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;
Remi NGUYEN VAN028cb1b2021-05-12 14:15:24 +000018
Haoyu Baib5da5752012-06-20 14:29:57 -070019import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090020import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
21import static android.content.pm.PackageManager.FEATURE_WATCH;
22import static android.content.pm.PackageManager.FEATURE_WIFI;
23import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
Chalard Jean9a396cc2018-02-21 18:43:54 +090024import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +090025import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
26import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
27import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
28import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
29import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
30import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
31import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
32import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
Lorenzo Colitti79c6f222021-03-18 00:54:57 +090033import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
34import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
Sudheer Shanka98215562021-03-23 08:12:28 +000035import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
Jeff Sharkey971cd162011-08-29 16:02:57 -070036import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
markchien3c04e662022-03-22 16:29:56 +080037import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
38import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
39import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090040import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
Lorenzo Colitti23e9afc2017-08-24 22:35:10 +090041import static android.net.ConnectivityManager.TYPE_ETHERNET;
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090042import static android.net.ConnectivityManager.TYPE_MOBILE;
43import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
44import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
45import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY;
46import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
47import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
48import static android.net.ConnectivityManager.TYPE_MOBILE_IA;
49import static android.net.ConnectivityManager.TYPE_MOBILE_IMS;
50import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
51import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
Robert Greenwaltbe46b752014-05-13 21:41:06 -070052import static android.net.ConnectivityManager.TYPE_NONE;
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090053import static android.net.ConnectivityManager.TYPE_PROXY;
Sreeram Ramachandrane8cb66e2014-10-30 14:55:29 -070054import static android.net.ConnectivityManager.TYPE_VPN;
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090055import static android.net.ConnectivityManager.TYPE_WIFI;
56import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
Jeff Sharkey6b9021d2012-07-26 18:32:30 -070057import static android.net.ConnectivityManager.getNetworkTypeName;
Jeff Sharkey921ebf22011-05-19 17:12:49 -070058import static android.net.ConnectivityManager.isNetworkTypeValid;
lucaslinb1ff1b22021-04-23 21:03:39 +080059import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
lucasline117e2e2019-10-22 18:27:33 +080060import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
Chiachang Wangeff18972019-05-23 16:29:30 +080061import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
Cody Kestingf1120be2020-08-03 18:01:40 -070062import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_SKIPPED;
Chiachang Wangeff18972019-05-23 16:29:30 +080063import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
Paul Jensen53f08952015-06-16 14:27:36 -040064import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
Chalard Jeanb5a139f2021-02-25 21:46:34 +090065import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
Lorenzo Colitti0f042202016-07-18 18:40:42 +090066import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
Lorenzo Colittie14a6222015-05-14 17:07:20 +090067import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
Lorenzo Colitticda101b2020-11-24 21:45:25 +090068import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
Lorenzo Colittie14a6222015-05-14 17:07:20 +090069import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
70import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
Jeff Sharkey07e19362017-10-27 17:22:59 -060071import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
Chalard Jeana23bc9e2018-01-30 22:41:41 +090072import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
junyulai719814c2021-01-13 18:13:11 +080073import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +090074import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
James Mattis45d81842021-01-10 14:24:24 -080075import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
76import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
lucaslin2240ef62019-03-12 13:08:03 +080077import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
Lorenzo Colittie14a6222015-05-14 17:07:20 +090078import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080079import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
80import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
Roshan Pius98f59ec2021-02-23 08:47:39 -080081import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
82import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
83import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
Chalard Jeand61375d2020-01-14 22:46:36 +090084import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Chalard Jean5b639762020-03-09 21:25:37 +090085import static android.net.NetworkCapabilities.TRANSPORT_TEST;
Jeff Sharkey07e19362017-10-27 17:22:59 -060086import static android.net.NetworkCapabilities.TRANSPORT_VPN;
Cody Kesting7474f672021-05-11 14:22:40 -070087import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
junyulai1b1c8742021-03-12 20:05:08 +080088import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
Chalard Jean0702f982021-09-16 21:50:07 +090089import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY;
James Mattisfa270db2021-05-31 17:11:10 -070090import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
91import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070092import static android.os.Process.INVALID_UID;
Ken Chen5e65a852020-12-24 12:59:10 +080093import static android.os.Process.VPN_UID;
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +090094import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
Patrick Rohr2857ac42022-01-21 14:58:16 +010095import static android.system.OsConstants.ETH_P_ALL;
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070096import static android.system.OsConstants.IPPROTO_TCP;
97import static android.system.OsConstants.IPPROTO_UDP;
Jeff Sharkey07e19362017-10-27 17:22:59 -060098
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +090099import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
Xiao Ma60142372022-07-16 17:30:20 +0900100import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
Junyu Lai4c6fe232023-04-11 11:33:46 +0800101import static com.android.net.module.util.PermissionUtils.checkAnyPermissionOf;
paulhu3ffffe72021-09-16 10:15:22 +0800102import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
103import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission;
104import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr;
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +0900105
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800106import static java.util.Map.Entry;
107
Chalard Jean5b639762020-03-09 21:25:37 +0900108import android.Manifest;
Lorenzo Colittibad9d912019-04-12 10:48:06 +0000109import android.annotation.NonNull;
Wenchao Tonge164e002015-03-04 13:26:38 -0800110import android.annotation.Nullable;
Michael Groover73f69482023-01-27 11:01:25 -0600111import android.annotation.SuppressLint;
Chiachang Wang3bc52762021-11-25 14:17:57 +0800112import android.annotation.TargetApi;
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800113import android.app.AppOpsManager;
Dianne Hackborn66dd0332015-12-09 17:22:26 -0800114import android.app.BroadcastOptions;
Wink Saville32506bc2013-06-29 21:10:57 -0700115import android.app.PendingIntent;
Sooraj Sasindranbb65aa82022-04-20 21:16:02 -0700116import android.app.admin.DevicePolicyManager;
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900117import android.app.compat.CompatChanges;
junyulaie7c7d2a2021-01-26 15:29:15 +0800118import android.app.usage.NetworkStatsManager;
Jeff Sharkeyebcc7972012-08-25 00:05:46 -0700119import android.content.BroadcastReceiver;
paulhu7746e4e2020-06-09 19:07:03 +0800120import android.content.ComponentName;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.Intent;
Jeff Sharkeyebcc7972012-08-25 00:05:46 -0700124import android.content.IntentFilter;
markchien9eb93992020-03-27 18:12:39 +0800125import android.content.pm.PackageManager;
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900126import android.content.res.XmlResourceParser;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700127import android.database.ContentObserver;
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +0900128import android.net.CaptivePortal;
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +0900129import android.net.CaptivePortalData;
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -0700130import android.net.ConnectionInfo;
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800131import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
Cody Kestingb12ad4c2020-01-06 16:55:35 -0800132import android.net.ConnectivityDiagnosticsManager.DataStallReport;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800133import android.net.ConnectivityManager;
Lorenzo Colitti79c6f222021-03-18 00:54:57 +0900134import android.net.ConnectivityManager.BlockedReason;
Roshan Pius951c0032020-12-22 15:10:42 -0800135import android.net.ConnectivityManager.NetworkCallback;
Remi NGUYEN VANe2139a02021-03-18 14:23:12 +0900136import android.net.ConnectivityManager.RestrictBackgroundStatus;
Remi NGUYEN VAN73f96a22021-02-19 12:53:54 +0900137import android.net.ConnectivityResources;
paulhu90a7a512021-03-17 17:19:09 +0800138import android.net.ConnectivitySettingsManager;
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +0900139import android.net.DataStallReportParcelable;
paulhua10d8212020-11-10 15:32:56 +0800140import android.net.DnsResolverServiceManager;
Tyler Wear72388212021-09-09 14:49:02 -0700141import android.net.DscpPolicy;
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +0900142import android.net.ICaptivePortal;
Cody Kestingd199a9d2019-12-17 12:55:28 -0800143import android.net.IConnectivityDiagnosticsCallback;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800144import android.net.IConnectivityManager;
Luke Huang81413192019-03-16 00:31:46 +0800145import android.net.IDnsResolver;
Luke Huang46289a22018-09-27 19:33:11 +0800146import android.net.INetd;
Chiachang Wang6a7d31e2021-02-04 17:29:59 +0800147import android.net.INetworkActivityListener;
Remi NGUYEN VAN73f96a22021-02-19 12:53:54 +0900148import android.net.INetworkAgent;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900149import android.net.INetworkMonitor;
150import android.net.INetworkMonitorCallbacks;
Chalard Jeancdd68bc2021-01-05 08:40:09 +0900151import android.net.INetworkOfferCallback;
Chalard Jeanfa45a682021-02-25 17:23:40 +0900152import android.net.IOnCompleteListener;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700153import android.net.IQosCallback;
junyulai070f9ff2019-01-16 20:23:34 +0800154import android.net.ISocketKeepaliveCallback;
Lorenzo Colittif7e17392019-01-08 10:04:25 +0900155import android.net.InetAddresses;
Xiao Ma555e4082019-04-10 19:01:52 +0900156import android.net.IpMemoryStore;
Lorenzo Colittif7e17392019-01-08 10:04:25 +0900157import android.net.IpPrefix;
Jaikumar Ganesh0db51a02010-12-21 22:31:44 -0800158import android.net.LinkProperties;
Charles He9369e612017-05-15 17:07:18 +0100159import android.net.MatchAllNetworkSpecifier;
Ken Chen6df7a902021-04-09 15:08:42 +0800160import android.net.NativeNetworkConfig;
161import android.net.NativeNetworkType;
junyulaid05a1922019-01-15 11:32:44 +0800162import android.net.NattSocketKeepalive;
Robert Greenwalt42a0e1e2014-03-19 17:56:12 -0700163import android.net.Network;
Robert Greenwalte20f7a22014-04-18 15:25:25 -0700164import android.net.NetworkAgent;
Lorenzo Colittiab2fed72020-01-12 22:28:37 +0900165import android.net.NetworkAgentConfig;
Robert Greenwalt7e45d112014-04-11 15:53:27 -0700166import android.net.NetworkCapabilities;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800167import android.net.NetworkInfo;
Jeff Sharkey921ebf22011-05-19 17:12:49 -0700168import android.net.NetworkInfo.DetailedState;
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +0900169import android.net.NetworkMonitorManager;
Jeff Sharkey0f2738e2018-01-18 22:01:59 +0900170import android.net.NetworkPolicyManager;
Sudheer Shanka9967d462021-03-18 19:09:25 +0000171import android.net.NetworkPolicyManager.NetworkPolicyCallback;
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +0900172import android.net.NetworkProvider;
Robert Greenwalt7e45d112014-04-11 15:53:27 -0700173import android.net.NetworkRequest;
Chalard Jean28018572020-12-21 18:36:52 +0900174import android.net.NetworkScore;
Etan Cohen1b6d4182017-04-03 17:42:34 -0700175import android.net.NetworkSpecifier;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900176import android.net.NetworkStack;
Jeff Sharkey21062e72011-05-28 20:56:34 -0700177import android.net.NetworkState;
junyulaide41fc22021-01-22 22:46:01 +0800178import android.net.NetworkStateSnapshot;
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +0900179import android.net.NetworkTestResultParcelable;
Robert Greenwalt7fe44cb2010-08-27 09:24:29 -0700180import android.net.NetworkUtils;
Ricky Wai7097cc92018-01-23 04:09:45 +0000181import android.net.NetworkWatchlistManager;
James Mattis47db0582021-01-01 14:13:35 -0800182import android.net.OemNetworkPreferences;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900183import android.net.PrivateDnsConfigParcel;
Sooraj Sasindrane7aee272021-11-24 20:26:55 -0800184import android.net.ProfileNetworkPreference;
Jason Monk4d5e20f2014-04-25 15:00:09 -0400185import android.net.ProxyInfo;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700186import android.net.QosCallbackException;
187import android.net.QosFilter;
188import android.net.QosSocketFilter;
189import android.net.QosSocketInfo;
Robert Greenwalt5a901292011-04-28 14:28:50 -0700190import android.net.RouteInfo;
Tyler Weare4314862019-12-05 14:55:30 -0800191import android.net.RouteInfoParcel;
junyulai011b1f12019-01-03 18:50:15 +0800192import android.net.SocketKeepalive;
markchien5e866652019-09-30 14:40:57 +0800193import android.net.TetheringManager;
Lorenzo Colittia5a903d2021-02-04 00:18:27 +0900194import android.net.TransportInfo;
Paul Jensen8b5fc622014-05-07 15:27:40 -0400195import android.net.UidRange;
Chiachang Wang28afaff2020-12-10 22:24:47 +0800196import android.net.UidRangeParcel;
junyulai2050bed2021-01-23 09:46:34 +0800197import android.net.UnderlyingNetworkInfo;
Jason Monka5bf2842013-07-03 17:04:33 -0400198import android.net.Uri;
Benedict Wonga7319912019-11-06 00:20:15 -0800199import android.net.VpnManager;
Lorenzo Colittia5a903d2021-02-04 00:18:27 +0900200import android.net.VpnTransportInfo;
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900201import android.net.connectivity.ConnectivityCompatChanges;
Hugo Benichibe0c7652016-05-31 16:28:06 +0900202import android.net.metrics.IpConnectivityLog;
Hugo Benichi134a18c2016-04-21 15:02:38 +0900203import android.net.metrics.NetworkEvent;
paulhu0e79d952021-06-09 16:11:35 +0800204import android.net.netd.aidl.NativeUidRangeConfig;
Remi NGUYEN VAN8ae54f72021-03-06 00:26:43 +0900205import android.net.networkstack.ModuleNetworkStackClient;
206import android.net.networkstack.NetworkStackClientBase;
Chalard Jeand4900722022-02-06 12:25:38 +0900207import android.net.networkstack.aidl.NetworkMonitorParameters;
paulhu7c0a2e62021-01-08 00:51:49 +0800208import android.net.resolv.aidl.DnsHealthEventParcel;
209import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
210import android.net.resolv.aidl.Nat64PrefixEventParcel;
211import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900212import android.net.shared.PrivateDnsConfig;
he_won.hwang881307a2022-03-15 21:23:52 +0900213import android.net.wifi.WifiInfo;
lucaslinb961efc2021-01-21 02:03:17 +0800214import android.os.BatteryStatsManager;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800215import android.os.Binder;
Dianne Hackborn66dd0332015-12-09 17:22:26 -0800216import android.os.Build;
Robert Greenwalte525a0a2014-09-30 16:50:07 -0700217import android.os.Bundle;
Paul Hu3c8c8102022-08-25 07:06:16 +0000218import android.os.ConditionVariable;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800219import android.os.Handler;
Wink Saville775aad62010-09-02 19:23:52 -0700220import android.os.HandlerThread;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700221import android.os.IBinder;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800222import android.os.Looper;
223import android.os.Message;
Robert Greenwalt15a41532012-08-21 19:27:00 -0700224import android.os.Messenger;
Chia-chi Yeh9a4ad7d2011-05-23 17:26:46 -0700225import android.os.ParcelFileDescriptor;
Hugo Benichif8a0f9f2017-03-23 22:40:44 +0900226import android.os.Parcelable;
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800227import android.os.PersistableBundle;
Robert Greenwalt93dc1042010-06-15 12:19:37 -0700228import android.os.PowerManager;
Jeff Sharkey69fc5f82012-09-06 17:54:29 -0700229import android.os.Process;
lucaslin1193a5d2021-01-21 02:04:15 +0800230import android.os.RemoteCallbackList;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700231import android.os.RemoteException;
Hugo Benichia590ab82017-05-11 13:16:17 +0900232import android.os.ServiceSpecificException;
Lorenzo Colitti79869ea2016-07-01 01:53:25 +0900233import android.os.SystemClock;
Anil Admale1a28862019-04-05 10:06:37 -0700234import android.os.SystemProperties;
Dianne Hackborn22986892012-08-29 18:32:08 -0700235import android.os.UserHandle;
Julia Reynoldsc8e3a712014-06-24 10:56:55 -0400236import android.os.UserManager;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800237import android.provider.Settings;
Lorenzo Colitti9b8b90b2021-03-10 16:39:18 +0900238import android.sysprop.NetworkProperties;
Tyler Wear72388212021-09-09 14:49:02 -0700239import android.system.ErrnoException;
Wink Saville32506bc2013-06-29 21:10:57 -0700240import android.telephony.TelephonyManager;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700241import android.text.TextUtils;
lucaslin1193a5d2021-01-21 02:04:15 +0800242import android.util.ArrayMap;
Chalard Jeanb2a49912018-01-16 18:43:05 +0900243import android.util.ArraySet;
Serik Beketayev47c4d4d2021-02-06 09:19:47 +0000244import android.util.LocalLog;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -0600245import android.util.Log;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900246import android.util.Pair;
Chad Brubakerb7652cd2013-06-14 11:16:51 -0700247import android.util.SparseArray;
Jeff Sharkey921ebf22011-05-19 17:12:49 -0700248import android.util.SparseIntArray;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800249
Sudheer Shanka2453a3a2022-11-29 15:15:50 -0800250import androidx.annotation.RequiresApi;
251
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +0900252import com.android.connectivity.resources.R;
Jason Monka5bf2842013-07-03 17:04:33 -0400253import com.android.internal.annotations.GuardedBy;
Paul Jensenbd2f32f2015-06-10 11:22:17 -0400254import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -0700255import com.android.internal.util.IndentingPrintWriter;
Lorenzo Colittib54bea92016-04-05 17:52:16 +0900256import com.android.internal.util.MessageUtils;
Chiachang Wang62740142020-11-02 16:51:24 +0800257import com.android.modules.utils.BasicShellCommandHandler;
Chalard Jean524f0b12021-10-25 21:11:56 +0900258import com.android.modules.utils.build.SdkLevel;
lucaslin66f44212021-02-23 01:12:55 +0800259import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
chiachangwang18a6e8c2022-12-01 00:22:34 +0000260import com.android.net.module.util.BinderUtils;
Chalard Jean1d420b32022-10-12 16:39:37 +0900261import com.android.net.module.util.BitUtils;
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +0900262import com.android.net.module.util.CollectionUtils;
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +0900263import com.android.net.module.util.DeviceConfigUtils;
Patrick Rohr9f371f02022-03-04 15:14:27 +0100264import com.android.net.module.util.InterfaceParams;
Chalard Jean79162542020-08-19 16:07:22 +0900265import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
266import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
Remi NGUYEN VAN79b241b2021-03-04 17:46:46 +0900267import com.android.net.module.util.LocationPermissionChecker;
Junyu Lai00d92df2022-07-05 11:01:52 +0800268import com.android.net.module.util.PerUidCounter;
paulhudf23d662021-01-25 18:53:17 +0800269import com.android.net.module.util.PermissionUtils;
Patrick Rohr2857ac42022-01-21 14:58:16 +0100270import com.android.net.module.util.TcUtils;
Xiao Ma09c07272021-07-01 14:00:34 +0000271import com.android.net.module.util.netlink.InetDiagMessage;
Sudheer Shanka2453a3a2022-11-29 15:15:50 -0800272import com.android.networkstack.apishim.BroadcastOptionsShimImpl;
273import com.android.networkstack.apishim.ConstantsShim;
274import com.android.networkstack.apishim.common.BroadcastOptionsShim;
275import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900276import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities;
Chalard Jean7284daa2019-05-30 14:58:29 +0900277import com.android.server.connectivity.AutodestructReference;
chiachangwang3d60bac2023-01-17 14:38:08 +0000278import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker;
Chalard Jean23f1bfd2023-01-24 17:11:27 +0900279import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
Sooraj Sasindrane9cd2082022-01-13 15:46:52 -0800280import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
Hungming Cheneb15a2d2022-01-16 15:15:57 +0800281import com.android.server.connectivity.ClatCoordinator;
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +0900282import com.android.server.connectivity.ConnectivityFlags;
Erik Kline32120082017-12-13 19:40:49 +0900283import com.android.server.connectivity.DnsManager;
dalyk1720e542018-03-05 12:42:22 -0500284import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
Tyler Wear72388212021-09-09 14:49:02 -0700285import com.android.server.connectivity.DscpPolicyTracker;
Chalard Jeancdd68bc2021-01-05 08:40:09 +0900286import com.android.server.connectivity.FullScore;
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900287import com.android.server.connectivity.InvalidTagException;
chiachangwang9ef4ffe2023-01-18 01:19:27 +0000288import com.android.server.connectivity.KeepaliveTracker;
Charles He9369e612017-05-15 17:07:18 +0100289import com.android.server.connectivity.LingerMonitor;
Christopher Wileyfcc0d9f2016-10-11 13:26:03 -0700290import com.android.server.connectivity.MockableSystemProperties;
Chalard Jean43aae652022-09-14 21:33:06 +0900291import com.android.server.connectivity.MultinetworkPolicyTracker;
Robert Greenwalte20f7a22014-04-18 15:25:25 -0700292import com.android.server.connectivity.NetworkAgentInfo;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -0600293import com.android.server.connectivity.NetworkDiagnostics;
Lorenzo Colitti74c205f2016-08-22 16:30:00 +0900294import com.android.server.connectivity.NetworkNotificationManager;
295import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
Chalard Jeancdd68bc2021-01-05 08:40:09 +0900296import com.android.server.connectivity.NetworkOffer;
Chalard Jean0606fc82022-12-14 20:34:43 +0900297import com.android.server.connectivity.NetworkPreferenceList;
Chalard Jean96a4f4b2019-12-10 22:16:53 +0900298import com.android.server.connectivity.NetworkRanker;
Sreeram Ramachandranae6c5072014-09-24 09:16:19 -0700299import com.android.server.connectivity.PermissionMonitor;
Chalard Jean0606fc82022-12-14 20:34:43 +0900300import com.android.server.connectivity.ProfileNetworkPreferenceInfo;
Chalard Jean5d70ba42018-06-07 16:44:04 +0900301import com.android.server.connectivity.ProxyTracker;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700302import com.android.server.connectivity.QosCallbackTracker;
Sooraj Sasindran499117f2021-11-29 12:40:09 -0800303import com.android.server.connectivity.UidRangeUtils;
lucaslin3ba7cc22022-12-19 02:35:33 +0000304import com.android.server.connectivity.VpnNetworkPreferenceInfo;
Igor Chernyshev9dac6602022-12-13 19:28:32 -0800305import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -0600306
Josh Gao461a1222020-06-16 15:58:11 -0700307import libcore.io.IoUtils;
308
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900309import org.xmlpull.v1.XmlPullParserException;
310
The Android Open Source Project28527d22009-03-03 19:31:44 -0800311import java.io.FileDescriptor;
Patrick Rohr2857ac42022-01-21 14:58:16 +0100312import java.io.IOException;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800313import java.io.PrintWriter;
Chalard Jean524f0b12021-10-25 21:11:56 +0900314import java.io.Writer;
Wink Savilledc5d1ba2011-07-14 12:23:28 -0700315import java.net.Inet4Address;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700316import java.net.InetAddress;
Lorenzo Colitti3be9df12021-02-04 01:47:38 +0900317import java.net.InetSocketAddress;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700318import java.net.UnknownHostException;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700319import java.util.ArrayList;
Jeff Sharkeya47d7a12011-06-16 15:07:48 -0700320import java.util.Arrays;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700321import java.util.Collection;
James Mattis60b84b22020-11-03 15:54:33 -0800322import java.util.Collections;
Hugo Benichia480ba52018-09-03 08:19:02 +0900323import java.util.Comparator;
junyulaif2c67e42018-08-07 19:50:45 +0800324import java.util.ConcurrentModificationException;
Vinit Deshapnde30ad2542013-08-21 13:09:01 -0700325import java.util.HashMap;
Jeff Sharkeya47d7a12011-06-16 15:07:48 -0700326import java.util.HashSet;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700327import java.util.List;
Vinit Deshapnde30ad2542013-08-21 13:09:01 -0700328import java.util.Map;
Chalard Jean524f0b12021-10-25 21:11:56 +0900329import java.util.NoSuchElementException;
Robert Greenwalte525a0a2014-09-30 16:50:07 -0700330import java.util.Objects;
Chalard Jeanb2a49912018-01-16 18:43:05 +0900331import java.util.Set;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -0600332import java.util.SortedSet;
Chalard Jean49707572019-12-10 21:07:02 +0900333import java.util.StringJoiner;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -0600334import java.util.TreeSet;
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +0900335import java.util.concurrent.atomic.AtomicInteger;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800336
337/**
338 * @hide
339 */
Jeremy Joslin60d379b2014-11-05 10:32:09 -0800340public class ConnectivityService extends IConnectivityManager.Stub
341 implements PendingIntent.OnFinished {
Lorenzo Colitti79869ea2016-07-01 01:53:25 +0900342 private static final String TAG = ConnectivityService.class.getSimpleName();
The Android Open Source Project28527d22009-03-03 19:31:44 -0800343
Chalard Jeand6c33dc2018-06-04 13:33:12 +0900344 private static final String DIAG_ARG = "--diag";
Erik Klined364a242017-05-12 16:52:48 +0900345 public static final String SHORT_ARG = "--short";
Hugo Benichi5df91ce2018-09-03 08:32:56 +0900346 private static final String NETWORK_ARG = "networks";
347 private static final String REQUEST_ARG = "requests";
Ken Chene6d511f2022-01-25 11:10:42 +0800348 private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller";
Erik Klined364a242017-05-12 16:52:48 +0900349
Lorenzo Colittiebf757d2016-04-08 23:09:09 +0900350 private static final boolean DBG = true;
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +0900351 private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
352 private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
The Android Open Source Project28527d22009-03-03 19:31:44 -0800353
Lorenzo Colittiac136a02016-01-22 04:04:57 +0900354 private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
Jeff Sharkey921ebf22011-05-19 17:12:49 -0700355
Niklas Lindgrenfd6f92e2018-12-07 11:08:04 +0100356 /**
357 * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
358 * by OEMs for configuration purposes, as this value is overridden by
paulhu56e09df2021-03-17 20:30:33 +0800359 * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL.
Niklas Lindgrenfd6f92e2018-12-07 11:08:04 +0100360 * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
361 * (preferably via runtime resource overlays).
362 */
363 private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
364 "http://connectivitycheck.gstatic.com/generate_204";
365
Jeff Sharkey366e0b72012-08-04 15:24:58 -0700366 // TODO: create better separation between radio types and network types
367
Robert Greenwalt2034b912009-08-12 16:08:25 -0700368 // how long to wait before switching back to a radio's default network
369 private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
370 // system property that can override the above value
371 private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
372 "android.telephony.apn-restore";
373
Lorenzo Colitti6947c062015-04-03 16:38:52 +0900374 // How long to wait before putting up a "This network doesn't have an Internet connection,
375 // connect anyway?" dialog after the user selects a network that doesn't validate.
376 private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
377
Chalard Jean5fb43c72022-09-08 19:03:14 +0900378 // How long to wait before considering that a network is bad in the absence of any form
379 // of connectivity (valid, partial, captive portal). If none has been detected after this
380 // delay, the stack considers this network bad, which may affect how it's handled in ranking
381 // according to config_networkAvoidBadWifi.
Chalard Jeane63c42f2022-09-16 19:31:45 +0900382 // Timeout in case the "actively prefer bad wifi" feature is on
383 private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000;
384 // Timeout in case the "actively prefer bad wifi" feature is off
385 private static final int DONT_ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 8 * 1000;
Chalard Jean5fb43c72022-09-08 19:03:14 +0900386
junyulai0ac374f2020-12-14 18:41:52 +0800387 // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing.
Lorenzo Colitti79869ea2016-07-01 01:53:25 +0900388 private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
389 private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
junyulai0ac374f2020-12-14 18:41:52 +0800390 private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700391
Sudheer Shanka2453a3a2022-11-29 15:15:50 -0800392 // Delimiter used when creating the broadcast delivery group for sending
393 // CONNECTIVITY_ACTION broadcast.
394 private static final char DELIVERY_GROUP_KEY_DELIMITER = ';';
395
he_won.hwang881307a2022-03-15 21:23:52 +0900396 // The maximum value for the blocking validation result, in milliseconds.
Lorenzo Colitti580d0d52022-10-13 19:56:58 +0900397 public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000;
he_won.hwang881307a2022-03-15 21:23:52 +0900398
Daniel Brightf9e945b2020-06-15 16:10:01 -0700399 // The maximum number of network request allowed per uid before an exception is thrown.
Chalard Jean9473c982021-07-29 20:03:04 +0900400 @VisibleForTesting
401 static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700402
Lorenzo Colitti6dba5882021-03-30 19:29:00 +0900403 // The maximum number of network request allowed for system UIDs before an exception is thrown.
James Mattis20a4a8b2021-03-28 17:41:09 -0700404 @VisibleForTesting
405 static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250;
Lorenzo Colitti6dba5882021-03-30 19:29:00 +0900406
Lorenzo Colitti79869ea2016-07-01 01:53:25 +0900407 @VisibleForTesting
408 protected int mLingerDelayMs; // Can't be final, or test subclass constructors can't change it.
junyulai0ac374f2020-12-14 18:41:52 +0800409 @VisibleForTesting
410 protected int mNascentDelayMs;
Chalard Jean0702f982021-09-16 21:50:07 +0900411 // True if the cell radio of the device is capable of time-sharing.
412 @VisibleForTesting
413 protected boolean mCellularRadioTimesharingCapable = true;
Lorenzo Colitti79869ea2016-07-01 01:53:25 +0900414
Jeremy Joslin1d3acf92014-12-03 17:15:28 -0800415 // How long to delay to removal of a pending intent based request.
paulhu56e09df2021-03-17 20:30:33 +0800416 // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
Jeremy Joslin1d3acf92014-12-03 17:15:28 -0800417 private final int mReleasePendingIntentDelayMs;
418
Chalard Jean46bfbf02022-02-02 00:56:25 +0900419 private final MockableSystemProperties mSystemProperties;
Lorenzo Colitticd447b22017-03-21 18:54:11 +0900420
Motomu Utsumif360aa62023-01-30 17:52:20 +0900421 private final PermissionMonitor mPermissionMonitor;
Sreeram Ramachandranae6c5072014-09-24 09:16:19 -0700422
Chalard Jean9473c982021-07-29 20:03:04 +0900423 @VisibleForTesting
Junyu Lai00d92df2022-07-05 11:01:52 +0800424 final RequestInfoPerUidCounter mNetworkRequestCounter;
James Mattis20a4a8b2021-03-28 17:41:09 -0700425 @VisibleForTesting
Junyu Lai00d92df2022-07-05 11:01:52 +0800426 final RequestInfoPerUidCounter mSystemNetworkRequestCounter;
Daniel Brightf9e945b2020-06-15 16:10:01 -0700427
Lorenzo Colittibcd692f2021-01-15 01:29:01 +0900428 private volatile boolean mLockdownEnabled;
Jeff Sharkeyebcc7972012-08-25 00:05:46 -0700429
junyulaif2c67e42018-08-07 19:50:45 +0800430 /**
Sudheer Shanka9967d462021-03-18 19:09:25 +0000431 * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
432 * internal handler thread, they don't need a lock.
junyulaif2c67e42018-08-07 19:50:45 +0800433 */
Chalard Jean46bfbf02022-02-02 00:56:25 +0900434 private final SparseIntArray mUidBlockedReasons = new SparseIntArray();
junyulaif2c67e42018-08-07 19:50:45 +0800435
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +0900436 private final Context mContext;
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +0900437 private final ConnectivityResources mResources;
Paul Hu96f1cbb2021-01-26 02:53:06 +0000438 // The Context is created for UserHandle.ALL.
439 private final Context mUserAllContext;
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +0900440 private final Dependencies mDeps;
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +0900441 private final ConnectivityFlags mFlags;
Robert Greenwalt986c7412010-09-08 15:24:47 -0700442 // 0 is full bad, 100 is full good
Robert Greenwalt986c7412010-09-08 15:24:47 -0700443 private int mDefaultInetConditionPublished = 0;
The Android Open Source Project28527d22009-03-03 19:31:44 -0800444
Chenbo Feng15416292018-11-08 17:36:21 -0800445 @VisibleForTesting
Luke Huang81413192019-03-16 00:31:46 +0800446 protected IDnsResolver mDnsResolver;
447 @VisibleForTesting
Chenbo Feng15416292018-11-08 17:36:21 -0800448 protected INetd mNetd;
Tyler Wear72388212021-09-09 14:49:02 -0700449 private DscpPolicyTracker mDscpPolicyTracker = null;
Chalard Jean46bfbf02022-02-02 00:56:25 +0900450 private final NetworkStatsManager mStatsManager;
451 private final NetworkPolicyManager mPolicyManager;
Wayne Ma2fde98c2022-01-17 18:04:05 +0800452 private final BpfNetMaps mBpfNetMaps;
Robert Greenwalt355205c2011-05-10 15:05:02 -0700453
Benedict Wong493e04b2018-11-09 14:45:34 -0800454 /**
455 * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
456 * instances.
457 */
458 @GuardedBy("mTNSLock")
459 private TestNetworkService mTNS;
Igor Chernyshev9dac6602022-12-13 19:28:32 -0800460 private final CompanionDeviceManagerProxyService mCdmps;
Benedict Wong493e04b2018-11-09 14:45:34 -0800461
462 private final Object mTNSLock = new Object();
463
Robert Greenwaltdebf0e02014-08-06 12:00:25 -0700464 private String mCurrentTcpBufferSizes;
465
Lorenzo Colittib54bea92016-04-05 17:52:16 +0900466 private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
lifraf3a3492021-03-10 13:58:14 +0800467 new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
Lorenzo Colittib54bea92016-04-05 17:52:16 +0900468
Paul Jensen5c4e5fc2014-11-25 12:33:08 -0500469 private enum ReapUnvalidatedNetworks {
Paul Jensend2a43f92015-06-25 13:25:07 -0400470 // Tear down networks that have no chance (e.g. even if validated) of becoming
471 // the highest scoring network satisfying a NetworkRequest. This should be passed when
Paul Jensen5c4e5fc2014-11-25 12:33:08 -0500472 // all networks have been rematched against all NetworkRequests.
473 REAP,
Paul Jensend2a43f92015-06-25 13:25:07 -0400474 // Don't reap networks. This should be passed when some networks have not yet been
475 // rematched against all NetworkRequests.
Paul Jensen5c4e5fc2014-11-25 12:33:08 -0500476 DONT_REAP
Chalard Jeand6c33dc2018-06-04 13:33:12 +0900477 }
Paul Jensen5c4e5fc2014-11-25 12:33:08 -0500478
Lorenzo Colitti2666be82016-09-09 18:48:56 +0900479 private enum UnneededFor {
480 LINGER, // Determine whether this network is unneeded and should be lingered.
481 TEARDOWN, // Determine whether this network is unneeded and should be torn down.
482 }
483
Robert Greenwalt6a2db8a2010-09-23 10:05:56 -0700484 /**
paulhuaa0743d2021-05-26 21:56:03 +0800485 * For per-app preferences, requests contain an int to signify which request
paulhu48291862021-07-14 14:53:57 +0800486 * should have priority. The order is passed to netd which will use it together
487 * with UID ranges to generate the corresponding IP rule. This serves to
488 * direct device-originated data traffic of the specific UIDs to the correct
paulhuaa0743d2021-05-26 21:56:03 +0800489 * default network for each app.
paulhu48291862021-07-14 14:53:57 +0800490 * Order ints passed to netd must be in the 0~999 range. Larger values code for
chiachangwang9473c592022-07-15 02:25:52 +0000491 * a lower priority, see {@link NativeUidRangeConfig}.
paulhue9913722021-05-26 15:19:20 +0800492 *
paulhu48291862021-07-14 14:53:57 +0800493 * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID.
494 * The default request uses PREFERENCE_ORDER_DEFAULT.
paulhue9913722021-05-26 15:19:20 +0800495 */
paulhu48291862021-07-14 14:53:57 +0800496 // Used when sending to netd to code for "no order".
497 static final int PREFERENCE_ORDER_NONE = 0;
498 // Order for requests that don't code for a per-app preference. As it is
499 // out of the valid range, the corresponding order should be
500 // PREFERENCE_ORDER_NONE when sending to netd.
paulhue9913722021-05-26 15:19:20 +0800501 @VisibleForTesting
paulhu48291862021-07-14 14:53:57 +0800502 static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE;
paulhuaa0743d2021-05-26 21:56:03 +0800503 // As a security feature, VPNs have the top priority.
paulhu48291862021-07-14 14:53:57 +0800504 static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN.
505 // Order of per-app OEM preference. See {@link #setOemNetworkPreference}.
paulhue9913722021-05-26 15:19:20 +0800506 @VisibleForTesting
paulhu48291862021-07-14 14:53:57 +0800507 static final int PREFERENCE_ORDER_OEM = 10;
508 // Order of per-profile preference, such as used by enterprise networks.
paulhue9913722021-05-26 15:19:20 +0800509 // See {@link #setProfileNetworkPreference}.
510 @VisibleForTesting
paulhu48291862021-07-14 14:53:57 +0800511 static final int PREFERENCE_ORDER_PROFILE = 20;
512 // Order of user setting to prefer mobile data even when networks with
paulhuaa0743d2021-05-26 21:56:03 +0800513 // better scores are connected.
514 // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids}
paulhue9913722021-05-26 15:19:20 +0800515 @VisibleForTesting
paulhu48291862021-07-14 14:53:57 +0800516 static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30;
Chalard Jeane6c95272022-01-25 21:04:21 +0900517 // Preference order that signifies the network shouldn't be set as a default network for
518 // the UIDs, only give them access to it. TODO : replace this with a boolean
519 // in NativeUidRangeConfig
520 @VisibleForTesting
521 static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999;
522 // Bound for the lowest valid preference order.
523 static final int PREFERENCE_ORDER_LOWEST = 999;
paulhue9913722021-05-26 15:19:20 +0800524
525 /**
Robert Greenwaltccb36f92010-09-24 14:32:21 -0700526 * used internally to clear a wakelock when transitioning
Robert Greenwalt520d6dc2014-06-25 16:45:57 -0700527 * from one net to another. Clear happens when we get a new
528 * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
529 * after a timeout if no network is found (typically 1 min).
Robert Greenwaltccb36f92010-09-24 14:32:21 -0700530 */
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -0700531 private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
Robert Greenwaltccb36f92010-09-24 14:32:21 -0700532
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700533 /**
534 * used internally to reload global proxy settings
535 */
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -0700536 private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700537
Robert Greenwalt34848c02011-03-25 13:09:25 -0700538 /**
Jason Monka69f1b02013-10-10 14:02:51 -0400539 * PAC manager has received new port.
540 */
541 private static final int EVENT_PROXY_HAS_CHANGED = 16;
542
Robert Greenwalt7e45d112014-04-11 15:53:27 -0700543 /**
Lorenzo Colittia86fae72020-01-10 00:40:28 +0900544 * used internally when registering NetworkProviders
545 * obj = NetworkProviderInfo
Robert Greenwalt7e45d112014-04-11 15:53:27 -0700546 */
Lorenzo Colittia86fae72020-01-10 00:40:28 +0900547 private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17;
Robert Greenwalt7e45d112014-04-11 15:53:27 -0700548
Robert Greenwalte20f7a22014-04-18 15:25:25 -0700549 /**
550 * used internally when registering NetworkAgents
551 * obj = Messenger
552 */
553 private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
554
Robert Greenwaltf99b8392014-03-26 16:47:06 -0700555 /**
556 * used to add a network request
557 * includes a NetworkRequestInfo
558 */
559 private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
560
561 /**
562 * indicates a timeout period is over - check if we had a network yet or not
Erik Kline0c04b742016-07-07 16:50:58 +0900563 * and if not, call the timeout callback (but leave the request live until they
Robert Greenwaltf99b8392014-03-26 16:47:06 -0700564 * cancel it.
565 * includes a NetworkRequestInfo
566 */
567 private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
568
569 /**
570 * used to add a network listener - no request
571 * includes a NetworkRequestInfo
572 */
573 private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
574
575 /**
576 * used to remove a network request, either a listener or a real request
Paul Jensen961cb0d2014-05-16 14:31:12 -0400577 * arg1 = UID of caller
578 * obj = NetworkRequest
Robert Greenwaltf99b8392014-03-26 16:47:06 -0700579 */
580 private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
581
Robert Greenwalt46dcbab2014-05-16 15:49:14 -0700582 /**
Lorenzo Colittia86fae72020-01-10 00:40:28 +0900583 * used internally when registering NetworkProviders
Robert Greenwalt46dcbab2014-05-16 15:49:14 -0700584 * obj = Messenger
585 */
Lorenzo Colittia86fae72020-01-10 00:40:28 +0900586 private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23;
Robert Greenwalt46dcbab2014-05-16 15:49:14 -0700587
Robert Greenwalt520d6dc2014-06-25 16:45:57 -0700588 /**
589 * used internally to expire a wakelock when transitioning
590 * from one net to another. Expire happens when we fail to find
591 * a new network (typically after 1 minute) -
592 * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
593 * a replacement network.
594 */
595 private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
596
Robert Greenwaltdc2d5612014-08-13 13:43:32 -0700597 /**
Jeremy Joslin60d379b2014-11-05 10:32:09 -0800598 * used to add a network request with a pending intent
Paul Jensenc8873fc2015-06-17 14:15:39 -0400599 * obj = NetworkRequestInfo
Jeremy Joslin60d379b2014-11-05 10:32:09 -0800600 */
601 private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
602
603 /**
604 * used to remove a pending intent and its associated network request.
605 * arg1 = UID of caller
606 * obj = PendingIntent
607 */
608 private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
609
Lorenzo Colitti6947c062015-04-03 16:38:52 +0900610 /**
611 * used to specify whether a network should be used even if unvalidated.
612 * arg1 = whether to accept the network if it's unvalidated (1 or 0)
613 * arg2 = whether to remember this choice in the future (1 or 0)
614 * obj = network
615 */
616 private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
617
618 /**
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -0700619 * used internally to (re)configure always-on networks.
Erik Kline05f2b402015-04-30 12:58:40 +0900620 */
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -0700621 private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
Erik Kline05f2b402015-04-30 12:58:40 +0900622
Paul Jensenc8873fc2015-06-17 14:15:39 -0400623 /**
624 * used to add a network listener with a pending intent
625 * obj = NetworkRequestInfo
626 */
627 private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
628
Hugo Benichid6b510a2017-04-06 17:22:18 +0900629 /**
630 * used to specify whether a network should not be penalized when it becomes unvalidated.
631 */
632 private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
633
634 /**
Cody Kestingf1120be2020-08-03 18:01:40 -0700635 * used to handle reported network connectivity. May trigger revalidation of a network.
Hugo Benichid6b510a2017-04-06 17:22:18 +0900636 */
Cody Kestingf1120be2020-08-03 18:01:40 -0700637 private static final int EVENT_REPORT_NETWORK_CONNECTIVITY = 36;
Hugo Benichid6b510a2017-04-06 17:22:18 +0900638
Erik Kline31b4a9e2018-01-11 21:07:29 +0900639 // Handle changes in Private DNS settings.
640 private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
641
dalyk1720e542018-03-05 12:42:22 -0500642 // Handle private DNS validation status updates.
643 private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
644
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900645 /**
646 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
647 * been tested.
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800648 * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor.
649 * data = PersistableBundle of extras passed from NetworkMonitor. If {@link
650 * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null.
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900651 */
Chalard Jeanfbab6d42019-09-26 18:03:47 +0900652 private static final int EVENT_NETWORK_TESTED = 41;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900653
654 /**
655 * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
656 * config was resolved.
657 * obj = PrivateDnsConfig
658 * arg2 = netid
659 */
Chalard Jeanfbab6d42019-09-26 18:03:47 +0900660 private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900661
662 /**
663 * Request ConnectivityService display provisioning notification.
664 * arg1 = Whether to make the notification visible.
665 * arg2 = NetID.
666 * obj = Intent to be launched when notification selected by user, null if !arg1.
667 */
Chalard Jeanfbab6d42019-09-26 18:03:47 +0900668 private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900669
670 /**
lucaslin2240ef62019-03-12 13:08:03 +0800671 * Used to specify whether a network should be used even if connectivity is partial.
672 * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
673 * false)
674 * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
675 * obj = network
676 */
lucaslin444d43a2020-02-20 16:56:59 +0800677 private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
lucaslin2240ef62019-03-12 13:08:03 +0800678
679 /**
lucasline117e2e2019-10-22 18:27:33 +0800680 * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
681 * Both of the arguments are bitmasks, and the value of bits come from
682 * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +0900683 * arg1 = unused
684 * arg2 = netId
685 * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes.
lucasline117e2e2019-10-22 18:27:33 +0800686 */
lucaslin444d43a2020-02-20 16:56:59 +0800687 public static final int EVENT_PROBE_STATUS_CHANGED = 45;
lucasline117e2e2019-10-22 18:27:33 +0800688
689 /**
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +0900690 * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
691 * arg1 = unused
692 * arg2 = netId
693 * obj = captive portal data
694 */
lucaslin444d43a2020-02-20 16:56:59 +0800695 private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +0900696
697 /**
Lorenzo Colitti3f54f102020-12-12 00:51:11 +0900698 * Used by setRequireVpnForUids.
699 * arg1 = whether the specified UID ranges are required to use a VPN.
700 * obj = Array of UidRange objects.
701 */
702 private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;
703
704 /**
Chalard Jeanb5a139f2021-02-25 21:46:34 +0900705 * Used internally when setting the default networks for OemNetworkPreferences.
706 * obj = Pair<OemNetworkPreferences, listener>
James Mattis45d81842021-01-10 14:24:24 -0800707 */
708 private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
709
710 /**
lucaslin1193a5d2021-01-21 02:04:15 +0800711 * Used to indicate the system default network becomes active.
712 */
713 private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
714
715 /**
Chalard Jeanb5a139f2021-02-25 21:46:34 +0900716 * Used internally when setting a network preference for a user profile.
717 * obj = Pair<ProfileNetworkPreference, Listener>
718 */
719 private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
720
721 /**
Sudheer Shanka9967d462021-03-18 19:09:25 +0000722 * Event to specify that reasons for why an uid is blocked changed.
723 * arg1 = uid
724 * arg2 = blockedReasons
725 */
726 private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
727
728 /**
Chalard Jeancdd68bc2021-01-05 08:40:09 +0900729 * Event to register a new network offer
730 * obj = NetworkOffer
731 */
732 private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
733
734 /**
735 * Event to unregister an existing network offer
736 * obj = INetworkOfferCallback
737 */
738 private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
739
740 /**
paulhu51f77dc2021-06-07 02:34:20 +0000741 * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed.
742 */
743 private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54;
744
745 /**
Chiachang Wang6eac9fb2021-06-17 22:11:30 +0800746 * Event to set temporary allow bad wifi within a limited time to override
747 * {@code config_networkAvoidBadWifi}.
748 */
749 private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55;
750
751 /**
Patrick Rohr2857ac42022-01-21 14:58:16 +0100752 * Used internally when INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting changes.
753 */
754 private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56;
755
756 /**
Chalard Jean5fb43c72022-09-08 19:03:14 +0900757 * The initial evaluation period is over for this network.
758 *
759 * If no form of connectivity has been found on this network (valid, partial, captive portal)
760 * then the stack will now consider it to have been determined bad.
761 */
762 private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57;
763
764 /**
Hansen Kurli55396972022-10-28 03:31:17 +0000765 * Used internally when the user does not want the network from captive portal app.
766 * obj = Network
767 */
768 private static final int EVENT_USER_DOES_NOT_WANT = 58;
769
770 /**
lucaslin3ba7cc22022-12-19 02:35:33 +0000771 * Event to set VPN as preferred network for specific apps.
772 * obj = VpnNetworkPreferenceInfo
773 */
774 private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59;
775
776 /**
chiachangwange0192a72023-02-06 13:25:01 +0000777 * Event to use low TCP polling timer used in automatic on/off keepalive temporarily.
778 */
779 private static final int EVENT_SET_LOW_TCP_POLLING_UNTIL = 60;
780
781 /**
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900782 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
783 * should be shown.
784 */
Chalard Jeanfbab6d42019-09-26 18:03:47 +0900785 private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900786
787 /**
788 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
789 * should be hidden.
790 */
Chalard Jeanfbab6d42019-09-26 18:03:47 +0900791 private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +0900792
Chiachang Wang6eac9fb2021-06-17 22:11:30 +0800793 /**
794 * The maximum alive time to allow bad wifi configuration for testing.
795 */
796 private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L;
797
Patrick Rohr2857ac42022-01-21 14:58:16 +0100798 /**
chiachangwange0192a72023-02-06 13:25:01 +0000799 * The maximum alive time to decrease TCP polling timer in automatic on/off keepalive for
800 * testing.
801 */
802 private static final long MAX_TEST_LOW_TCP_POLLING_UNTIL_MS = 5 * 60 * 1000L;
803
804 /**
Patrick Rohr2857ac42022-01-21 14:58:16 +0100805 * The priority of the tc police rate limiter -- smaller value is higher priority.
806 * This value needs to be coordinated with PRIO_CLAT, PRIO_TETHER4, and PRIO_TETHER6.
807 */
808 private static final short TC_PRIO_POLICE = 1;
809
810 /**
811 * The BPF program attached to the tc-police hook to account for to-be-dropped traffic.
812 */
813 private static final String TC_POLICE_BPF_PROG_PATH =
Maciej Żenczykowski6d116d02022-05-16 13:59:12 -0700814 "/sys/fs/bpf/netd_shared/prog_netd_schedact_ingress_account";
Patrick Rohr2857ac42022-01-21 14:58:16 +0100815
Hugo Benichi47011212017-03-30 10:46:05 +0900816 private static String eventName(int what) {
817 return sMagicDecoderRing.get(what, Integer.toString(what));
818 }
819
paulhua10d8212020-11-10 15:32:56 +0800820 private static IDnsResolver getDnsResolver(Context context) {
Lorenzo Colitti34a294f2021-04-15 18:03:54 +0900821 final DnsResolverServiceManager dsm = context.getSystemService(
822 DnsResolverServiceManager.class);
823 return IDnsResolver.Stub.asInterface(dsm.getService());
Luke Huang81413192019-03-16 00:31:46 +0800824 }
825
Cody Kesting73708bf2019-12-18 10:57:50 -0800826 /** Handler thread used for all of the handlers below. */
Lorenzo Colitti0891bc42015-08-07 20:17:27 +0900827 @VisibleForTesting
828 protected final HandlerThread mHandlerThread;
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -0700829 /** Handler used for internal events. */
Robert Greenwalte20f7a22014-04-18 15:25:25 -0700830 final private InternalHandler mHandler;
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -0700831 /** Handler used for incoming {@link NetworkStateTracker} events. */
Robert Greenwalte20f7a22014-04-18 15:25:25 -0700832 final private NetworkStateTrackerHandler mTrackerHandler;
Cody Kesting73708bf2019-12-18 10:57:50 -0800833 /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */
834 @VisibleForTesting
835 final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
836
Erik Kline32120082017-12-13 19:40:49 +0900837 private final DnsManager mDnsManager;
Chalard Jean020b93a2022-09-01 13:20:14 +0900838 @VisibleForTesting
839 final NetworkRanker mNetworkRanker;
Robert Greenwalt2034b912009-08-12 16:08:25 -0700840
Mike Lockwoodfde2b762009-08-14 14:18:49 -0400841 private boolean mSystemReady;
Dianne Hackborna417ff82009-12-08 19:45:14 -0800842 private Intent mInitialBroadcast;
Mike Lockwoodfde2b762009-08-14 14:18:49 -0400843
Chalard Jean46bfbf02022-02-02 00:56:25 +0900844 private final PowerManager.WakeLock mNetTransitionWakeLock;
Jeremy Joslin60d379b2014-11-05 10:32:09 -0800845 private final PowerManager.WakeLock mPendingIntentWakeLock;
Robert Greenwalt93dc1042010-06-15 12:19:37 -0700846
Chalard Jean5d70ba42018-06-07 16:44:04 +0900847 // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
848 // the world when it changes.
Irina Dumitrescude132bb2018-12-05 16:19:47 +0000849 @VisibleForTesting
850 protected final ProxyTracker mProxyTracker;
Jason Monka5bf2842013-07-03 17:04:33 -0400851
Erik Kline05f2b402015-04-30 12:58:40 +0900852 final private SettingsObserver mSettingsObserver;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700853
Chalard Jean46bfbf02022-02-02 00:56:25 +0900854 private final UserManager mUserManager;
Julia Reynoldsc8e3a712014-06-24 10:56:55 -0400855
Robert Greenwalt6cac0742011-06-21 17:26:14 -0700856 // the set of network types that can only be enabled by system/sig apps
Chalard Jean46bfbf02022-02-02 00:56:25 +0900857 private final List<Integer> mProtectedNetworks;
Robert Greenwalt6cac0742011-06-21 17:26:14 -0700858
Valentin Iftime9fa35092019-09-24 13:32:13 +0200859 private Set<String> mWolSupportedInterfaces;
860
Roshan Pius08c94fb2020-01-16 12:17:17 -0800861 private final TelephonyManager mTelephonyManager;
Sooraj Sasindrane9cd2082022-01-13 15:46:52 -0800862 private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator;
Cody Kesting83bb5fa2020-01-05 14:06:39 -0800863 private final AppOpsManager mAppOpsManager;
864
865 private final LocationPermissionChecker mLocationPermissionChecker;
John Spurlock1f5cec72013-06-24 14:20:23 -0400866
chiachangwang3d60bac2023-01-17 14:38:08 +0000867 private final AutomaticOnOffKeepaliveTracker mKeepaliveTracker;
Chalard Jean46bfbf02022-02-02 00:56:25 +0900868 private final QosCallbackTracker mQosCallbackTracker;
869 private final NetworkNotificationManager mNotifier;
870 private final LingerMonitor mLingerMonitor;
Lorenzo Colitti0b798a82015-06-15 14:29:22 +0900871
Robert Greenwalt0eb55c12014-05-18 16:22:10 -0700872 // sequence number of NetworkRequests
junyulai70afb0c2020-12-14 18:51:02 +0800873 private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID;
Robert Greenwalt0eb55c12014-05-18 16:22:10 -0700874
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +0900875 // Sequence number for NetworkProvider IDs.
876 private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
877 NetworkProvider.FIRST_PROVIDER_ID);
878
Erik Klineedf878b2015-07-09 18:24:03 +0900879 // NetworkRequest activity String log entries.
880 private static final int MAX_NETWORK_REQUEST_LOGS = 20;
881 private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
882
Hugo Benichid159fdd2016-07-11 11:05:12 +0900883 // NetworkInfo blocked and unblocked String log entries
Hugo Benichi47011212017-03-30 10:46:05 +0900884 private static final int MAX_NETWORK_INFO_LOGS = 40;
Hugo Benichid159fdd2016-07-11 11:05:12 +0900885 private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
886
Hugo Benichi47011212017-03-30 10:46:05 +0900887 private static final int MAX_WAKELOCK_LOGS = 20;
888 private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
Hugo Benichi88f49ac2017-09-05 13:25:07 +0900889 private int mTotalWakelockAcquisitions = 0;
890 private int mTotalWakelockReleases = 0;
891 private long mTotalWakelockDurationMs = 0;
892 private long mMaxWakelockDurationMs = 0;
893 private long mLastWakeLockAcquireTimestamp = 0;
Hugo Benichi47011212017-03-30 10:46:05 +0900894
Hugo Benichi208c0102016-07-28 17:53:06 +0900895 private final IpConnectivityLog mMetricsLog;
Hugo Benichibe0c7652016-05-31 16:28:06 +0900896
Nathan Haroldb89cbfb2018-07-30 13:38:01 -0700897 @GuardedBy("mBandwidthRequests")
Chalard Jean46bfbf02022-02-02 00:56:25 +0900898 private final SparseArray<Integer> mBandwidthRequests = new SparseArray<>(10);
Nathan Haroldb89cbfb2018-07-30 13:38:01 -0700899
Erik Kline95ecfee2016-10-02 18:02:14 +0900900 @VisibleForTesting
Lorenzo Colittiee6c69e2017-01-24 09:41:36 +0900901 final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
Erik Kline95ecfee2016-10-02 18:02:14 +0900902
Lorenzo Colitti389a8142018-01-24 17:35:07 +0900903 @VisibleForTesting
Cody Kesting31f1ff62020-03-05 10:46:02 -0800904 final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
905 new HashMap<>();
Cody Kesting73708bf2019-12-18 10:57:50 -0800906
Patrick Rohr2857ac42022-01-21 14:58:16 +0100907 // Rate limit applicable to all internet capable networks (-1 = disabled). This value is
908 // configured via {@link
909 // ConnectivitySettingsManager#INGRESS_RATE_LIMIT_BYTES_PER_SECOND}
910 // Only the handler thread is allowed to access this field.
911 private long mIngressRateLimit = -1;
912
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900913 // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This
914 // value can be accessed from both handler thread and any random binder thread. Therefore,
Yuyang Huang2d13d432023-03-13 12:27:40 +0900915 // accessing this value requires holding a lock. The cache is the same across all the users.
Yuyang Huang96e8bfe2023-01-27 17:05:07 +0900916 @GuardedBy("mSelfCertifiedCapabilityCache")
917 private final Map<String, ApplicationSelfCertifiedNetworkCapabilities>
918 mSelfCertifiedCapabilityCache = new HashMap<>();
919
Robert Greenwalt802c1102014-06-02 15:32:02 -0700920 /**
921 * Implements support for the legacy "one network per network type" model.
922 *
923 * We used to have a static array of NetworkStateTrackers, one for each
924 * network type, but that doesn't work any more now that we can have,
925 * for example, more that one wifi network. This class stores all the
926 * NetworkAgentInfo objects that support a given type, but the legacy
927 * API will only see the first one.
928 *
929 * It serves two main purposes:
930 *
931 * 1. Provide information about "the network for a given type" (since this
932 * API only supports one).
933 * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
934 * the first network for a given type changes, or if the default network
935 * changes.
936 */
Chalard Jean3a3f5f22019-04-10 23:07:55 +0900937 @VisibleForTesting
938 static class LegacyTypeTracker {
Lorenzo Colitticfb36572014-07-31 23:20:17 +0900939
Lorenzo Colittiebf757d2016-04-08 23:09:09 +0900940 private static final boolean DBG = true;
Lorenzo Colitticfb36572014-07-31 23:20:17 +0900941 private static final boolean VDBG = false;
Lorenzo Colitticfb36572014-07-31 23:20:17 +0900942
Robert Greenwalt802c1102014-06-02 15:32:02 -0700943 /**
944 * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
945 * Each list holds references to all NetworkAgentInfos that are used to
946 * satisfy requests for that network type.
947 *
948 * This array is built out at startup such that an unsupported network
949 * doesn't get an ArrayList instance, making this a tristate:
950 * unsupported, supported but not active and active.
951 *
952 * The actual lists are populated when we scan the network types that
953 * are supported on this device.
Hugo Benichi389633f2016-06-21 09:48:07 +0900954 *
955 * Threading model:
956 * - addSupportedType() is only called in the constructor
957 * - add(), update(), remove() are only called from the ConnectivityService handler thread.
958 * They are therefore not thread-safe with respect to each other.
959 * - getNetworkForType() can be called at any time on binder threads. It is synchronized
960 * on mTypeLists to be thread-safe with respect to a concurrent remove call.
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +0900961 * - getRestoreTimerForType(type) is also synchronized on mTypeLists.
Hugo Benichi389633f2016-06-21 09:48:07 +0900962 * - dump is thread-safe with respect to concurrent add and remove calls.
Robert Greenwalt802c1102014-06-02 15:32:02 -0700963 */
Chalard Jean46bfbf02022-02-02 00:56:25 +0900964 private final ArrayList<NetworkAgentInfo>[] mTypeLists;
Chalard Jean3a3f5f22019-04-10 23:07:55 +0900965 @NonNull
966 private final ConnectivityService mService;
Robert Greenwalt802c1102014-06-02 15:32:02 -0700967
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +0900968 // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without
969 // an entry have no timer (equivalent to -1). Lazily loaded.
970 @NonNull
971 private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>();
972
Chalard Jean3a3f5f22019-04-10 23:07:55 +0900973 LegacyTypeTracker(@NonNull ConnectivityService service) {
974 mService = service;
975 mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
Robert Greenwalt802c1102014-06-02 15:32:02 -0700976 }
977
Chiachang Wang3bc52762021-11-25 14:17:57 +0800978 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is
979 // addressed.
980 @TargetApi(Build.VERSION_CODES.S)
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +0900981 public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) {
982 final PackageManager pm = ctx.getPackageManager();
983 if (pm.hasSystemFeature(FEATURE_WIFI)) {
984 addSupportedType(TYPE_WIFI);
985 }
986 if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) {
987 addSupportedType(TYPE_WIFI_P2P);
988 }
989 if (tm.isDataCapable()) {
990 // Telephony does not have granular support for these types: they are either all
991 // supported, or none is supported
992 addSupportedType(TYPE_MOBILE);
993 addSupportedType(TYPE_MOBILE_MMS);
994 addSupportedType(TYPE_MOBILE_SUPL);
995 addSupportedType(TYPE_MOBILE_DUN);
996 addSupportedType(TYPE_MOBILE_HIPRI);
997 addSupportedType(TYPE_MOBILE_FOTA);
998 addSupportedType(TYPE_MOBILE_IMS);
999 addSupportedType(TYPE_MOBILE_CBS);
1000 addSupportedType(TYPE_MOBILE_IA);
1001 addSupportedType(TYPE_MOBILE_EMERGENCY);
1002 }
1003 if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) {
1004 addSupportedType(TYPE_BLUETOOTH);
1005 }
1006 if (pm.hasSystemFeature(FEATURE_WATCH)) {
1007 // TYPE_PROXY is only used on Wear
1008 addSupportedType(TYPE_PROXY);
1009 }
1010 // Ethernet is often not specified in the configs, although many devices can use it via
1011 // USB host adapters. Add it as long as the ethernet service is here.
Xiao Ma0a171c02022-01-23 16:14:51 +00001012 if (deviceSupportsEthernet(ctx)) {
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09001013 addSupportedType(TYPE_ETHERNET);
1014 }
1015
1016 // Always add TYPE_VPN as a supported type
1017 addSupportedType(TYPE_VPN);
1018 }
1019
1020 private void addSupportedType(int type) {
Robert Greenwalt802c1102014-06-02 15:32:02 -07001021 if (mTypeLists[type] != null) {
1022 throw new IllegalStateException(
1023 "legacy list for type " + type + "already initialized");
1024 }
Chalard Jeand6c33dc2018-06-04 13:33:12 +09001025 mTypeLists[type] = new ArrayList<>();
Robert Greenwalt802c1102014-06-02 15:32:02 -07001026 }
1027
Robert Greenwalt802c1102014-06-02 15:32:02 -07001028 public boolean isTypeSupported(int type) {
1029 return isNetworkTypeValid(type) && mTypeLists[type] != null;
1030 }
1031
1032 public NetworkAgentInfo getNetworkForType(int type) {
Hugo Benichi389633f2016-06-21 09:48:07 +09001033 synchronized (mTypeLists) {
1034 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
1035 return mTypeLists[type].get(0);
1036 }
Robert Greenwalt802c1102014-06-02 15:32:02 -07001037 }
Hugo Benichi389633f2016-06-21 09:48:07 +09001038 return null;
Robert Greenwalt802c1102014-06-02 15:32:02 -07001039 }
1040
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09001041 public int getRestoreTimerForType(int type) {
1042 synchronized (mTypeLists) {
1043 if (mRestoreTimers == null) {
1044 mRestoreTimers = loadRestoreTimers();
1045 }
1046 return mRestoreTimers.getOrDefault(type, -1);
1047 }
1048 }
1049
1050 private ArrayMap<Integer, Integer> loadRestoreTimers() {
1051 final String[] configs = mService.mResources.get().getStringArray(
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09001052 R.array.config_legacy_networktype_restore_timers);
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09001053 final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length);
1054 for (final String config : configs) {
1055 final String[] splits = TextUtils.split(config, ",");
1056 if (splits.length != 2) {
1057 logwtf("Invalid restore timer token count: " + config);
1058 continue;
1059 }
1060 try {
1061 ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
1062 } catch (NumberFormatException e) {
1063 logwtf("Invalid restore timer number format: " + config, e);
1064 }
1065 }
1066 return ret;
1067 }
1068
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07001069 private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
Chalard Jean5b409c72021-02-04 13:12:59 +09001070 boolean isDefaultNetwork) {
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001071 if (DBG) {
Chalard Jean49707572019-12-10 21:07:02 +09001072 log("Sending " + state
1073 + " broadcast for type " + type + " " + nai.toShortString()
Chalard Jean5b409c72021-02-04 13:12:59 +09001074 + " isDefaultNetwork=" + isDefaultNetwork);
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001075 }
1076 }
1077
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09001078 // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying
1079 // network type, to preserve previous behaviour.
1080 private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) {
1081 if (vpnNai != mService.getLegacyLockdownNai()) return;
1082
1083 if (vpnNai.declaredUnderlyingNetworks == null
1084 || vpnNai.declaredUnderlyingNetworks.length != 1) {
1085 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: "
1086 + Arrays.toString(vpnNai.declaredUnderlyingNetworks));
1087 return;
1088 }
Lorenzo Colitti1f4db552021-02-12 10:14:01 +09001089 final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork(
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09001090 vpnNai.declaredUnderlyingNetworks[0]);
1091 if (underlyingNai == null) return;
1092
1093 final int type = underlyingNai.networkInfo.getType();
1094 final DetailedState state = DetailedState.CONNECTED;
1095 maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */);
1096 mService.sendLegacyNetworkBroadcast(underlyingNai, state, type);
1097 }
1098
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001099 /** Adds the given network to the specified legacy type list. */
Robert Greenwalt802c1102014-06-02 15:32:02 -07001100 public void add(int type, NetworkAgentInfo nai) {
1101 if (!isTypeSupported(type)) {
1102 return; // Invalid network type.
1103 }
1104 if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
1105
1106 ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1107 if (list.contains(nai)) {
Robert Greenwalt802c1102014-06-02 15:32:02 -07001108 return;
1109 }
Hugo Benichi389633f2016-06-21 09:48:07 +09001110 synchronized (mTypeLists) {
1111 list.add(nai);
1112 }
Lorenzo Colitti4b584062014-09-28 16:08:06 +09001113
Chalard Jean5b409c72021-02-04 13:12:59 +09001114 // Send a broadcast if this is the first network of its type or if it's the default.
1115 final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09001116
1117 // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts
1118 // to preserve previous behaviour.
1119 final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED);
Chalard Jean5b409c72021-02-04 13:12:59 +09001120 if ((list.size() == 1) || isDefaultNetwork) {
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09001121 maybeLogBroadcast(nai, state, type, isDefaultNetwork);
1122 mService.sendLegacyNetworkBroadcast(nai, state, type);
1123 }
1124
1125 if (type == TYPE_VPN && state == DetailedState.CONNECTED) {
1126 maybeSendLegacyLockdownBroadcast(nai);
Robert Greenwalt802c1102014-06-02 15:32:02 -07001127 }
Robert Greenwalt802c1102014-06-02 15:32:02 -07001128 }
1129
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001130 /** Removes the given network from the specified legacy type list. */
Lorenzo Colitti49767722015-05-01 00:30:10 +09001131 public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001132 ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1133 if (list == null || list.isEmpty()) {
1134 return;
1135 }
Lorenzo Colitti49767722015-05-01 00:30:10 +09001136 final boolean wasFirstNetwork = list.get(0).equals(nai);
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001137
Hugo Benichi389633f2016-06-21 09:48:07 +09001138 synchronized (mTypeLists) {
1139 if (!list.remove(nai)) {
1140 return;
1141 }
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001142 }
1143
Lorenzo Colitti49767722015-05-01 00:30:10 +09001144 if (wasFirstNetwork || wasDefault) {
Chalard Jean37a2b462019-04-11 14:09:07 +09001145 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
1146 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001147 }
1148
1149 if (!list.isEmpty() && wasFirstNetwork) {
1150 if (DBG) log("Other network available for type " + type +
1151 ", sending connected broadcast");
Lorenzo Colitti49767722015-05-01 00:30:10 +09001152 final NetworkAgentInfo replacement = list.get(0);
Chalard Jean37a2b462019-04-11 14:09:07 +09001153 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
Chalard Jean5b409c72021-02-04 13:12:59 +09001154 mService.isDefaultNetwork(replacement));
Chalard Jean37a2b462019-04-11 14:09:07 +09001155 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
Lorenzo Colitticfb36572014-07-31 23:20:17 +09001156 }
1157 }
1158
1159 /** Removes the given network from all legacy type lists. */
Lorenzo Colitti49767722015-05-01 00:30:10 +09001160 public void remove(NetworkAgentInfo nai, boolean wasDefault) {
1161 if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
Robert Greenwalt802c1102014-06-02 15:32:02 -07001162 for (int type = 0; type < mTypeLists.length; type++) {
Lorenzo Colitti49767722015-05-01 00:30:10 +09001163 remove(type, nai, wasDefault);
Robert Greenwalt802c1102014-06-02 15:32:02 -07001164 }
1165 }
Robert Greenwalt94e22142014-07-30 16:31:24 -07001166
Chalard Jean46bfbf02022-02-02 00:56:25 +09001167 // send out another legacy broadcast - currently only used for suspend/unsuspend toggle
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07001168 public void update(NetworkAgentInfo nai) {
Chalard Jean5b409c72021-02-04 13:12:59 +09001169 final boolean isDefault = mService.isDefaultNetwork(nai);
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07001170 final DetailedState state = nai.networkInfo.getDetailedState();
1171 for (int type = 0; type < mTypeLists.length; type++) {
1172 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
Robert Greenwalt3df86c62015-07-10 16:00:36 -07001173 final boolean contains = (list != null && list.contains(nai));
Hugo Benichi389633f2016-06-21 09:48:07 +09001174 final boolean isFirst = contains && (nai == list.get(0));
Chalard Jean5b409c72021-02-04 13:12:59 +09001175 if (isFirst || contains && isDefault) {
1176 maybeLogBroadcast(nai, state, type, isDefault);
Chalard Jean3a3f5f22019-04-10 23:07:55 +09001177 mService.sendLegacyNetworkBroadcast(nai, state, type);
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07001178 }
1179 }
1180 }
1181
Robert Greenwalt94e22142014-07-30 16:31:24 -07001182 public void dump(IndentingPrintWriter pw) {
Lorenzo Colitti3b1ad962015-06-03 11:18:24 +09001183 pw.println("mLegacyTypeTracker:");
1184 pw.increaseIndent();
1185 pw.print("Supported types:");
Robert Greenwalt94e22142014-07-30 16:31:24 -07001186 for (int type = 0; type < mTypeLists.length; type++) {
Lorenzo Colitti3b1ad962015-06-03 11:18:24 +09001187 if (mTypeLists[type] != null) pw.print(" " + type);
Robert Greenwalt94e22142014-07-30 16:31:24 -07001188 }
Lorenzo Colitti3b1ad962015-06-03 11:18:24 +09001189 pw.println();
1190 pw.println("Current state:");
1191 pw.increaseIndent();
Hugo Benichi389633f2016-06-21 09:48:07 +09001192 synchronized (mTypeLists) {
1193 for (int type = 0; type < mTypeLists.length; type++) {
1194 if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
1195 for (NetworkAgentInfo nai : mTypeLists[type]) {
Chalard Jean49707572019-12-10 21:07:02 +09001196 pw.println(type + " " + nai.toShortString());
Hugo Benichi389633f2016-06-21 09:48:07 +09001197 }
Lorenzo Colitti3b1ad962015-06-03 11:18:24 +09001198 }
1199 }
1200 pw.decreaseIndent();
1201 pw.decreaseIndent();
1202 pw.println();
Robert Greenwalt94e22142014-07-30 16:31:24 -07001203 }
Robert Greenwalt802c1102014-06-02 15:32:02 -07001204 }
Chalard Jean3a3f5f22019-04-10 23:07:55 +09001205 private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
Robert Greenwalt802c1102014-06-02 15:32:02 -07001206
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001207 final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
Vishnu Nair0701e422017-10-26 10:08:50 -07001208 /**
1209 * Helper class which parses out priority arguments and dumps sections according to their
1210 * priority. If priority arguments are omitted, function calls the legacy dump command.
1211 */
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001212 private class LocalPriorityDump {
1213 private static final String PRIORITY_ARG = "--dump-priority";
1214 private static final String PRIORITY_ARG_HIGH = "HIGH";
1215 private static final String PRIORITY_ARG_NORMAL = "NORMAL";
1216
1217 LocalPriorityDump() {}
1218
1219 private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
1220 doDump(fd, pw, new String[] {DIAG_ARG});
1221 doDump(fd, pw, new String[] {SHORT_ARG});
Vishnu Nair0701e422017-10-26 10:08:50 -07001222 }
1223
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001224 private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
1225 doDump(fd, pw, args);
Vishnu Nair0701e422017-10-26 10:08:50 -07001226 }
1227
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001228 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1229 if (args == null) {
1230 dumpNormal(fd, pw, args);
1231 return;
1232 }
1233
1234 String priority = null;
1235 for (int argIndex = 0; argIndex < args.length; argIndex++) {
1236 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
1237 argIndex++;
1238 priority = args[argIndex];
1239 }
1240 }
1241
1242 if (PRIORITY_ARG_HIGH.equals(priority)) {
1243 dumpHigh(fd, pw);
1244 } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
1245 dumpNormal(fd, pw, args);
1246 } else {
1247 // ConnectivityService publishes binder service using publishBinderService() with
1248 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
Chiachang Wang05fbb452021-05-17 16:57:15 +08001249 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the
1250 // legacy output for dumpsys connectivity.
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001251 // TODO: Integrate into signal dump.
1252 dumpNormal(fd, pw, args);
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001253 }
Vishnu Nair0701e422017-10-26 10:08:50 -07001254 }
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08001255 }
Vishnu Nair0701e422017-10-26 10:08:50 -07001256
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001257 /**
1258 * Dependencies of ConnectivityService, for injection in tests.
1259 */
1260 @VisibleForTesting
1261 public static class Dependencies {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09001262 public int getCallingUid() {
1263 return Binder.getCallingUid();
1264 }
1265
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001266 /**
1267 * Get system properties to use in ConnectivityService.
1268 */
1269 public MockableSystemProperties getSystemProperties() {
1270 return new MockableSystemProperties();
1271 }
1272
1273 /**
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09001274 * Get the {@link ConnectivityResources} to use in ConnectivityService.
1275 */
1276 public ConnectivityResources getResources(@NonNull Context ctx) {
1277 return new ConnectivityResources(ctx);
1278 }
1279
1280 /**
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001281 * Create a HandlerThread to use in ConnectivityService.
1282 */
1283 public HandlerThread makeHandlerThread() {
1284 return new HandlerThread("ConnectivityServiceThread");
1285 }
1286
1287 /**
Remi NGUYEN VAN8ae54f72021-03-06 00:26:43 +09001288 * Get a reference to the ModuleNetworkStackClient.
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001289 */
Remi NGUYEN VAN8ae54f72021-03-06 00:26:43 +09001290 public NetworkStackClientBase getNetworkStack() {
1291 return ModuleNetworkStackClient.getInstance(null);
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001292 }
1293
1294 /**
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001295 * @see ProxyTracker
1296 */
1297 public ProxyTracker makeProxyTracker(@NonNull Context context,
1298 @NonNull Handler connServiceHandler) {
1299 return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED);
1300 }
1301
1302 /**
1303 * @see NetIdManager
1304 */
1305 public NetIdManager makeNetIdManager() {
1306 return new NetIdManager();
1307 }
1308
1309 /**
1310 * @see NetworkUtils#queryUserAccess(int, int)
1311 */
Lorenzo Colitti22c677e2021-03-23 21:01:07 +09001312 public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
1313 return cs.queryUserAccess(uid, network);
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001314 }
1315
1316 /**
Lorenzo Colitti3be9df12021-02-04 01:47:38 +09001317 * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets
1318 * requires CAP_NET_ADMIN, which the unit tests do not have.
1319 */
1320 public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
1321 InetSocketAddress remote) {
1322 return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote);
1323 }
1324
1325 /**
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001326 * @see MultinetworkPolicyTracker
1327 */
1328 public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
1329 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) {
1330 return new MultinetworkPolicyTracker(c, h, r);
1331 }
1332
Aaron Huang330a4c02020-10-27 03:36:19 +08001333 /**
chiachangwang7c17c282023-02-02 05:58:59 +00001334 * @see AutomaticOnOffKeepaliveTracker
1335 */
1336 public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker(
1337 @NonNull Context c, @NonNull Handler h) {
1338 return new AutomaticOnOffKeepaliveTracker(c, h);
1339 }
1340
1341 /**
Aaron Huang330a4c02020-10-27 03:36:19 +08001342 * @see BatteryStatsManager
1343 */
1344 public void reportNetworkInterfaceForTransports(Context context, String iface,
1345 int[] transportTypes) {
Lorenzo Colitti9b8b90b2021-03-10 16:39:18 +09001346 final BatteryStatsManager batteryStats =
Aaron Huang330a4c02020-10-27 03:36:19 +08001347 context.getSystemService(BatteryStatsManager.class);
1348 batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
1349 }
Lorenzo Colitti9b8b90b2021-03-10 16:39:18 +09001350
1351 public boolean getCellular464XlatEnabled() {
1352 return NetworkProperties.isCellular464XlatEnabled().orElse(true);
1353 }
Remi NGUYEN VAN18a979f2021-06-04 18:51:25 +09001354
1355 /**
1356 * @see PendingIntent#intentFilterEquals
1357 */
1358 public boolean intentFilterEquals(PendingIntent a, PendingIntent b) {
1359 return a.intentFilterEquals(b);
1360 }
1361
1362 /**
1363 * @see LocationPermissionChecker
1364 */
1365 public LocationPermissionChecker makeLocationPermissionChecker(Context context) {
1366 return new LocationPermissionChecker(context);
1367 }
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +09001368
1369 /**
Chalard Jeanac9ace02022-01-26 16:54:05 +09001370 * @see CarrierPrivilegeAuthenticator
Chalard Jean46bfbf02022-02-02 00:56:25 +09001371 *
1372 * This method returns null in versions before T, where carrier privilege
1373 * authentication is not supported.
Chalard Jeanac9ace02022-01-26 16:54:05 +09001374 */
Chalard Jean46bfbf02022-02-02 00:56:25 +09001375 @Nullable
Chalard Jeanac9ace02022-01-26 16:54:05 +09001376 public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
1377 @NonNull final Context context, @NonNull final TelephonyManager tm) {
1378 if (SdkLevel.isAtLeastT()) {
1379 return new CarrierPrivilegeAuthenticator(context, tm);
1380 } else {
1381 return null;
1382 }
1383 }
1384
1385 /**
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +09001386 * @see DeviceConfigUtils#isFeatureEnabled
1387 */
1388 public boolean isFeatureEnabled(Context context, String name, boolean defaultEnabled) {
1389 return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name,
1390 TETHERING_MODULE_NAME, defaultEnabled);
1391 }
Wayne Ma2fde98c2022-01-17 18:04:05 +08001392
1393 /**
1394 * Get the BpfNetMaps implementation to use in ConnectivityService.
Chalard Jean46bfbf02022-02-02 00:56:25 +09001395 * @param netd a netd binder
Wayne Ma2fde98c2022-01-17 18:04:05 +08001396 * @return BpfNetMaps implementation.
1397 */
Motomu Utsumif688eeb2022-07-22 03:47:35 +00001398 public BpfNetMaps getBpfNetMaps(Context context, INetd netd) {
1399 return new BpfNetMaps(context, netd);
Wayne Ma2fde98c2022-01-17 18:04:05 +08001400 }
Patrick Rohr2857ac42022-01-21 14:58:16 +01001401
1402 /**
Hungming Cheneb15a2d2022-01-16 15:15:57 +08001403 * @see ClatCoordinator
1404 */
1405 public ClatCoordinator getClatCoordinator(INetd netd) {
1406 return new ClatCoordinator(
1407 new ClatCoordinator.Dependencies() {
1408 @NonNull
1409 public INetd getNetd() {
1410 return netd;
1411 }
1412 });
1413 }
1414
1415 /**
Patrick Rohr2857ac42022-01-21 14:58:16 +01001416 * Wraps {@link TcUtils#tcFilterAddDevIngressPolice}
1417 */
1418 public void enableIngressRateLimit(String iface, long rateInBytesPerSecond) {
1419 final InterfaceParams params = InterfaceParams.getByName(iface);
1420 if (params == null) {
1421 // the interface might have disappeared.
1422 logw("Failed to get interface params for interface " + iface);
1423 return;
1424 }
1425 try {
1426 // converting rateInBytesPerSecond from long to int is safe here because the
1427 // setting's range is limited to INT_MAX.
1428 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice.
Patrick Rohr64592df2022-02-10 15:19:31 +01001429 Log.i(TAG,
1430 "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s");
Patrick Rohr2857ac42022-01-21 14:58:16 +01001431 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL,
1432 (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH);
1433 } catch (IOException e) {
1434 loge("TcUtils.tcFilterAddDevIngressPolice(ifaceIndex=" + params.index
1435 + ", PRIO_POLICE, ETH_P_ALL, rateInBytesPerSecond="
1436 + rateInBytesPerSecond + ", bpfProgPath=" + TC_POLICE_BPF_PROG_PATH
1437 + ") failure: ", e);
1438 }
1439 }
1440
1441 /**
1442 * Wraps {@link TcUtils#tcFilterDelDev}
1443 */
1444 public void disableIngressRateLimit(String iface) {
1445 final InterfaceParams params = InterfaceParams.getByName(iface);
1446 if (params == null) {
1447 // the interface might have disappeared.
1448 logw("Failed to get interface params for interface " + iface);
1449 return;
1450 }
1451 try {
Patrick Rohr64592df2022-02-10 15:19:31 +01001452 Log.i(TAG,
1453 "disableIngressRateLimit on " + iface);
Patrick Rohr2857ac42022-01-21 14:58:16 +01001454 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL);
1455 } catch (IOException e) {
1456 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index
1457 + ", ingress=true, PRIO_POLICE, ETH_P_ALL) failure: ", e);
1458 }
1459 }
Sudheer Shanka2453a3a2022-11-29 15:15:50 -08001460
1461 /**
1462 * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)}
1463 */
1464 // TODO: when available in all active branches:
1465 // @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
1466 @RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
1467 public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) {
1468 return BroadcastOptionsShimImpl.newInstance(options);
1469 }
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09001470
1471 /**
1472 * Wrapper method for
1473 * {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}.
1474 *
1475 * @param changeId The ID of the compatibility change in question.
1476 * @param packageName The package name of the app in question.
1477 * @param user The user that the operation is done for.
1478 * @return {@code true} if the change is enabled for the specified package.
1479 */
1480 public boolean isChangeEnabled(long changeId, @NonNull final String packageName,
1481 @NonNull final UserHandle user) {
1482 return CompatChanges.isChangeEnabled(changeId, packageName, user);
1483 }
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001484 }
1485
junyulaie7c7d2a2021-01-26 15:29:15 +08001486 public ConnectivityService(Context context) {
1487 this(context, getDnsResolver(context), new IpConnectivityLog(),
Remi NGUYEN VAN8ae54f72021-03-06 00:26:43 +09001488 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
1489 new Dependencies());
Hugo Benichi208c0102016-07-28 17:53:06 +09001490 }
1491
1492 @VisibleForTesting
junyulaie7c7d2a2021-01-26 15:29:15 +08001493 protected ConnectivityService(Context context, IDnsResolver dnsresolver,
1494 IpConnectivityLog logger, INetd netd, Dependencies deps) {
Wink Savillee70c6f52010-12-03 12:01:38 -08001495 if (DBG) log("ConnectivityService starting up");
Robert Greenwaltd48f8ee2010-01-14 17:47:58 -08001496
Daulet Zhanguzinee674252020-03-26 12:30:39 +00001497 mDeps = Objects.requireNonNull(deps, "missing Dependencies");
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +09001498 mFlags = new ConnectivityFlags();
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001499 mSystemProperties = mDeps.getSystemProperties();
1500 mNetIdManager = mDeps.makeNetIdManager();
Daulet Zhanguzinee674252020-03-26 12:30:39 +00001501 mContext = Objects.requireNonNull(context, "missing Context");
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09001502 mResources = deps.getResources(mContext);
Junyu Lai00d92df2022-07-05 11:01:52 +08001503 // The legacy PerUidCounter is buggy and throwing exception at count == limit.
1504 // Pass limit - 1 to maintain backward compatibility.
1505 // TODO: Remove the workaround.
1506 mNetworkRequestCounter =
1507 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_UID - 1);
1508 mSystemNetworkRequestCounter =
1509 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1);
Lorenzo Colitticd447b22017-03-21 18:54:11 +09001510
Hugo Benichi208c0102016-07-28 17:53:06 +09001511 mMetricsLog = logger;
James Mattis45d81842021-01-10 14:24:24 -08001512 final NetworkRequest defaultInternetRequest = createDefaultRequest();
1513 mDefaultRequest = new NetworkRequestInfo(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09001514 Process.myUid(), defaultInternetRequest, null,
Chalard Jeana3578a52021-10-25 19:24:48 +09001515 null /* binder */, NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
James Mattis45d81842021-01-10 14:24:24 -08001516 null /* attributionTags */);
Chalard Jean5b409c72021-02-04 13:12:59 +09001517 mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
1518 mDefaultNetworkRequests.add(mDefaultRequest);
1519 mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
Erik Kline05f2b402015-04-30 12:58:40 +09001520
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +09001521 mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
Lorenzo Colitti2666be82016-09-09 18:48:56 +09001522 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
Robert Greenwalt7e45d112014-04-11 15:53:27 -07001523
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001524 // The default WiFi request is a background request so that apps using WiFi are
1525 // migrated to a better network (typically ethernet) when one comes up, instead
1526 // of staying on WiFi forever.
1527 mDefaultWifiRequest = createDefaultInternetRequestForTransport(
1528 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
1529
Tomasz Wasilczyk54605b82020-12-14 13:42:51 -08001530 mDefaultVehicleRequest = createAlwaysOnRequestForCapability(
1531 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL,
1532 NetworkRequest.Type.BACKGROUND_REQUEST);
1533
Chalard Jean0702f982021-09-16 21:50:07 +09001534 mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
1535 // TODO: Consider making the timer customizable.
1536 mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
1537 mCellularRadioTimesharingCapable =
1538 mResources.get().getBoolean(R.bool.config_cellular_radio_timesharing_capable);
1539
Paul Hu51f816b2022-08-11 14:43:47 +00001540 mNetd = netd;
1541 mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd);
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001542 mHandlerThread = mDeps.makeHandlerThread();
Paul Hu51f816b2022-08-11 14:43:47 +00001543 mPermissionMonitor =
1544 new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mHandlerThread);
Lorenzo Colitti0891bc42015-08-07 20:17:27 +09001545 mHandlerThread.start();
1546 mHandler = new InternalHandler(mHandlerThread.getLooper());
1547 mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
Cody Kesting73708bf2019-12-18 10:57:50 -08001548 mConnectivityDiagnosticsHandler =
1549 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
Wink Saville775aad62010-09-02 19:23:52 -07001550
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08001551 mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +08001552 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08001553
junyulaie7c7d2a2021-01-26 15:29:15 +08001554 mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
paulhu9a9f71b2020-12-29 18:15:13 +08001555 mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
Daulet Zhanguzinee674252020-03-26 12:30:39 +00001556 mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001557 mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
Hugo Benichi39621362017-02-11 17:04:43 +09001558
Wink Saville32506bc2013-06-29 21:10:57 -07001559 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08001560 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
Remi NGUYEN VAN18a979f2021-06-04 18:51:25 +09001561 mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
Chalard Jeanac9ace02022-01-26 16:54:05 +09001562 mCarrierPrivilegeAuthenticator =
1563 mDeps.makeCarrierPrivilegeAuthenticator(mContext, mTelephonyManager);
Robert Greenwalt93dc1042010-06-15 12:19:37 -07001564
Sudheer Shanka9967d462021-03-18 19:09:25 +00001565 // To ensure uid state is synchronized with Network Policy, register for
junyulaif2c67e42018-08-07 19:50:45 +08001566 // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
1567 // reading existing policy from disk.
Sudheer Shanka9967d462021-03-18 19:09:25 +00001568 mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001569
1570 final PowerManager powerManager = (PowerManager) context.getSystemService(
1571 Context.POWER_SERVICE);
Robert Greenwalt93dc1042010-06-15 12:19:37 -07001572 mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08001573 mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
Robert Greenwalt93dc1042010-06-15 12:19:37 -07001574
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09001575 mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager);
1576 mProtectedNetworks = new ArrayList<>();
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09001577 int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks);
Robert Greenwalt6cac0742011-06-21 17:26:14 -07001578 for (int p : protectedNetworks) {
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09001579 if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) {
Robert Greenwalt6cac0742011-06-21 17:26:14 -07001580 mProtectedNetworks.add(p);
1581 } else {
1582 if (DBG) loge("Ignoring protectedNetwork " + p);
1583 }
1584 }
1585
soma, kawata29444ae2019-05-23 09:30:40 +09001586 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1587
James Mattis02220e22021-03-13 19:27:21 -08001588 mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
Lorenzo Colitticd675292021-02-04 17:32:07 +09001589 // Listen for user add/removes to inform PermissionMonitor.
Varun Ananddf569952019-02-06 10:13:38 -08001590 // Should run on mHandler to avoid any races.
James Mattis02220e22021-03-13 19:27:21 -08001591 final IntentFilter userIntentFilter = new IntentFilter();
1592 userIntentFilter.addAction(Intent.ACTION_USER_ADDED);
1593 userIntentFilter.addAction(Intent.ACTION_USER_REMOVED);
1594 mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter,
1595 null /* broadcastPermission */, mHandler);
paulhuedd411a2020-10-13 15:56:13 +08001596
James Mattis02220e22021-03-13 19:27:21 -08001597 // Listen to package add/removes for netd
1598 final IntentFilter packageIntentFilter = new IntentFilter();
1599 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1600 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1601 packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
1602 packageIntentFilter.addDataScheme("package");
1603 mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter,
Lorenzo Colitticd675292021-02-04 17:32:07 +09001604 null /* broadcastPermission */, mHandler);
junyulaid91e7052020-08-28 13:44:33 +08001605
lucaslind5c2d072021-02-20 18:59:47 +08001606 mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
Chia-chi Yehf3204aa2011-05-23 15:08:29 -07001607
Chalard Jean46bfbf02022-02-02 00:56:25 +09001608 final NetdCallback netdCallback = new NetdCallback();
lucaslin66f44212021-02-23 01:12:55 +08001609 try {
Chalard Jean46bfbf02022-02-02 00:56:25 +09001610 mNetd.registerUnsolicitedEventListener(netdCallback);
lucaslin66f44212021-02-23 01:12:55 +08001611 } catch (RemoteException | ServiceSpecificException e) {
1612 loge("Error registering event listener :" + e);
1613 }
1614
Erik Kline05f2b402015-04-30 12:58:40 +09001615 mSettingsObserver = new SettingsObserver(mContext, mHandler);
1616 registerSettingsCallbacks();
Robert Greenwalt6f7c6092010-12-02 11:31:00 -08001617
chiachangwang7c17c282023-02-02 05:58:59 +00001618 mKeepaliveTracker = mDeps.makeAutomaticOnOffKeepaliveTracker(mContext, mHandler);
paulhu539aa9a2020-10-14 09:51:54 +08001619 mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
Daniel Brightf9e945b2020-06-15 16:10:01 -07001620 mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter);
Lorenzo Colitti9bf6fef2016-08-29 14:03:11 +09001621
1622 final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +08001623 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
Lorenzo Colitti9bf6fef2016-08-29 14:03:11 +09001624 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
1625 final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +08001626 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
Lorenzo Colitti9bf6fef2016-08-29 14:03:11 +09001627 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
1628 mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
Lorenzo Colitti21924542016-09-16 23:43:38 +09001629
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09001630 mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
Chalard Jeanf3ff3622021-03-19 13:49:56 +09001631 mContext, mHandler, () -> updateAvoidBadWifi());
Chalard Jean020b93a2022-09-01 13:20:14 +09001632 mNetworkRanker =
1633 new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi()));
1634
Lorenzo Colittiee6c69e2017-01-24 09:41:36 +09001635 mMultinetworkPolicyTracker.start();
Erik Kline32120082017-12-13 19:40:49 +09001636
Chiachang Wangc1215d32020-10-20 15:38:58 +08001637 mDnsManager = new DnsManager(mContext, mDnsResolver);
Erik Kline31b4a9e2018-01-11 21:07:29 +09001638 registerPrivateDnsSettingsCallbacks();
James Mattisd31bdfa2020-12-23 16:37:26 -08001639
Chalard Jean28018572020-12-21 18:36:52 +09001640 // This NAI is a sentinel used to offer no service to apps that are on a multi-layer
1641 // request that doesn't allow fallback to the default network. It should never be visible
1642 // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal
1643 // arguments like the handler or the DnsResolver.
1644 // TODO : remove this ; it is probably better handled with a sentinel request.
lucaslind5c2d072021-02-20 18:59:47 +08001645 mNoServiceNetwork = new NetworkAgentInfo(null,
Ken Chen75c6d332021-05-14 14:30:43 +08001646 new Network(INetd.UNREACHABLE_NET_ID),
James Mattisd31bdfa2020-12-23 16:37:26 -08001647 new NetworkInfo(TYPE_NONE, 0, "", ""),
Chalard Jean28018572020-12-21 18:36:52 +09001648 new LinkProperties(), new NetworkCapabilities(),
1649 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
Chalard Jean550b5212021-03-05 23:07:53 +09001650 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID,
1651 mLingerDelayMs, mQosCallbackTracker, mDeps);
Tyler Wear72388212021-09-09 14:49:02 -07001652
1653 try {
Lorenzo Colittidebd9ea2022-01-27 23:02:59 +09001654 // DscpPolicyTracker cannot run on S because on S the tethering module can only load
1655 // BPF programs/maps into /sys/fs/tethering/bpf, which the system server cannot access.
1656 // Even if it could, running on S would at least require mocking out the BPF map,
1657 // otherwise the unit tests will fail on pre-T devices where the seccomp filter blocks
1658 // the bpf syscall. http://aosp/1907693
1659 if (SdkLevel.isAtLeastT()) {
1660 mDscpPolicyTracker = new DscpPolicyTracker();
1661 }
Tyler Wear72388212021-09-09 14:49:02 -07001662 } catch (ErrnoException e) {
1663 loge("Unable to create DscpPolicyTracker");
1664 }
Patrick Rohr2857ac42022-01-21 14:58:16 +01001665
1666 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(
1667 mContext);
Igor Chernyshev9dac6602022-12-13 19:28:32 -08001668
1669 if (SdkLevel.isAtLeastT()) {
1670 mCdmps = new CompanionDeviceManagerProxyService(context);
1671 } else {
1672 mCdmps = null;
1673 }
The Android Open Source Project28527d22009-03-03 19:31:44 -08001674 }
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07001675
Xiao Ma0a171c02022-01-23 16:14:51 +00001676 /**
1677 * Check whether or not the device supports Ethernet transport.
1678 */
1679 public static boolean deviceSupportsEthernet(final Context context) {
1680 final PackageManager pm = context.getPackageManager();
1681 return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET)
1682 || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST);
1683 }
1684
Chalard Jean46adcf32018-04-18 20:18:38 +09001685 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
Sooraj Sasindran499117f2021-11-29 12:40:09 -08001686 return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton(
1687 new UidRange(uid, uid)));
Chalard Jeanb5a139f2021-02-25 21:46:34 +09001688 }
1689
Sooraj Sasindran499117f2021-11-29 12:40:09 -08001690 private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet(
1691 @NonNull final Set<UidRange> uidRangeSet) {
Chalard Jean46adcf32018-04-18 20:18:38 +09001692 final NetworkCapabilities netCap = new NetworkCapabilities();
1693 netCap.addCapability(NET_CAPABILITY_INTERNET);
junyulai719814c2021-01-13 18:13:11 +08001694 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
Chalard Jean46adcf32018-04-18 20:18:38 +09001695 netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
Sooraj Sasindran499117f2021-11-29 12:40:09 -08001696 netCap.setUids(UidRange.toIntRanges(uidRangeSet));
Chalard Jean46adcf32018-04-18 20:18:38 +09001697 return netCap;
1698 }
1699
James Mattis45d81842021-01-10 14:24:24 -08001700 private NetworkRequest createDefaultRequest() {
1701 return createDefaultInternetRequestForTransport(
1702 TYPE_NONE, NetworkRequest.Type.REQUEST);
1703 }
1704
lucaslin3ba7cc22022-12-19 02:35:33 +00001705 private NetworkRequest createVpnRequest() {
1706 final NetworkCapabilities netCap = new NetworkCapabilities.Builder()
1707 .withoutDefaultCapabilities()
1708 .addTransportType(TRANSPORT_VPN)
1709 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
1710 .addCapability(NET_CAPABILITY_NOT_RESTRICTED)
1711 .build();
1712 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
1713 return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap);
1714 }
1715
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +09001716 private NetworkRequest createDefaultInternetRequestForTransport(
Lorenzo Colitti2666be82016-09-09 18:48:56 +09001717 int transportType, NetworkRequest.Type type) {
Erik Klinea34b5842018-06-14 17:36:40 +09001718 final NetworkCapabilities netCap = new NetworkCapabilities();
Lorenzo Colittie14a6222015-05-14 17:07:20 +09001719 netCap.addCapability(NET_CAPABILITY_INTERNET);
junyulai719814c2021-01-13 18:13:11 +08001720 netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
Roshan Pius08c94fb2020-01-16 12:17:17 -08001721 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
James Mattis45d81842021-01-10 14:24:24 -08001722 if (transportType > TYPE_NONE) {
Erik Kline05f2b402015-04-30 12:58:40 +09001723 netCap.addTransportType(transportType);
1724 }
James Mattis45d81842021-01-10 14:24:24 -08001725 return createNetworkRequest(type, netCap);
1726 }
1727
1728 private NetworkRequest createNetworkRequest(
1729 NetworkRequest.Type type, NetworkCapabilities netCap) {
Lorenzo Colitti2666be82016-09-09 18:48:56 +09001730 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
Erik Kline05f2b402015-04-30 12:58:40 +09001731 }
1732
Tomasz Wasilczyk54605b82020-12-14 13:42:51 -08001733 private NetworkRequest createAlwaysOnRequestForCapability(int capability,
1734 NetworkRequest.Type type) {
1735 final NetworkCapabilities netCap = new NetworkCapabilities();
1736 netCap.clearAll();
1737 netCap.addCapability(capability);
1738 netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
1739 return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
1740 }
1741
Lorenzo Colitti9fc66e02016-06-05 21:00:23 +09001742 // Used only for testing.
1743 // TODO: Delete this and either:
Erik Kline9a62f012018-03-21 07:18:33 -07001744 // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
Lorenzo Colitti9fc66e02016-06-05 21:00:23 +09001745 // changing ContentResolver to make registerContentObserver non-final).
1746 // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
1747 // by subclassing SettingsObserver.
1748 @VisibleForTesting
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001749 void updateAlwaysOnNetworks() {
1750 mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
Lorenzo Colitti9fc66e02016-06-05 21:00:23 +09001751 }
1752
Erik Kline9a62f012018-03-21 07:18:33 -07001753 // See FakeSettingsProvider comment above.
1754 @VisibleForTesting
1755 void updatePrivateDnsSettings() {
1756 mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1757 }
1758
paulhu51f77dc2021-06-07 02:34:20 +00001759 @VisibleForTesting
1760 void updateMobileDataPreferredUids() {
1761 mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
1762 }
1763
Patrick Rohr2857ac42022-01-21 14:58:16 +01001764 @VisibleForTesting
1765 void updateIngressRateLimit() {
1766 mHandler.sendEmptyMessage(EVENT_INGRESS_RATE_LIMIT_CHANGED);
1767 }
1768
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001769 private void handleAlwaysOnNetworkRequest(
1770 NetworkRequest networkRequest, String settingName, boolean defaultValue) {
Hugo Benichif4210292017-04-21 15:07:12 +09001771 final boolean enable = toBool(Settings.Global.getInt(
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001772 mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
Tomasz Wasilczyk54605b82020-12-14 13:42:51 -08001773 handleAlwaysOnNetworkRequest(networkRequest, enable);
1774 }
1775
1776 private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) {
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001777 final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
Erik Kline05f2b402015-04-30 12:58:40 +09001778 if (enable == isEnabled) {
1779 return; // Nothing to do.
1780 }
1781
1782 if (enable) {
1783 handleRegisterNetworkRequest(new NetworkRequestInfo(
Chalard Jeana3578a52021-10-25 19:24:48 +09001784 Process.myUid(), networkRequest, null /* messenger */, null /* binder */,
Roshan Pius951c0032020-12-22 15:10:42 -08001785 NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
James Mattis45d81842021-01-10 14:24:24 -08001786 null /* attributionTags */));
Erik Kline05f2b402015-04-30 12:58:40 +09001787 } else {
Etan Cohenfbfdd842019-01-08 12:09:18 -08001788 handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
1789 /* callOnUnavailable */ false);
Erik Kline05f2b402015-04-30 12:58:40 +09001790 }
1791 }
1792
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001793 private void handleConfigureAlwaysOnNetworks() {
paulhu56e09df2021-03-17 20:30:33 +08001794 handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest,
1795 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */);
1796 handleAlwaysOnNetworkRequest(mDefaultWifiRequest,
1797 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */);
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09001798 final boolean vehicleAlwaysRequested = mResources.get().getBoolean(
1799 R.bool.config_vehicleInternalNetworkAlwaysRequested);
Remi NGUYEN VAN14233472021-05-19 12:05:13 +09001800 handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested);
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001801 }
1802
paulhu51f77dc2021-06-07 02:34:20 +00001803 // Note that registering observer for setting do not get initial callback when registering,
paulhu01f52e72021-05-26 12:22:38 +08001804 // callers must fetch the initial value of the setting themselves if needed.
Erik Kline05f2b402015-04-30 12:58:40 +09001805 private void registerSettingsCallbacks() {
1806 // Watch for global HTTP proxy changes.
1807 mSettingsObserver.observe(
1808 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
1809 EVENT_APPLY_GLOBAL_HTTP_PROXY);
1810
Chalard Jean46bfbf02022-02-02 00:56:25 +09001811 // Watch for whether to keep mobile data always on.
Erik Kline05f2b402015-04-30 12:58:40 +09001812 mSettingsObserver.observe(
paulhu56e09df2021-03-17 20:30:33 +08001813 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON),
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001814 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1815
Chalard Jean46bfbf02022-02-02 00:56:25 +09001816 // Watch for whether to keep wifi always on.
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001817 mSettingsObserver.observe(
paulhu56e09df2021-03-17 20:30:33 +08001818 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED),
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07001819 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
paulhu51f77dc2021-06-07 02:34:20 +00001820
1821 // Watch for mobile data preferred uids changes.
1822 mSettingsObserver.observe(
1823 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS),
1824 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
Patrick Rohr2857ac42022-01-21 14:58:16 +01001825
1826 // Watch for ingress rate limit changes.
1827 mSettingsObserver.observe(
Patrick Rohrcdac7492022-02-10 15:13:29 +01001828 Settings.Global.getUriFor(
Patrick Rohr2857ac42022-01-21 14:58:16 +01001829 ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND),
1830 EVENT_INGRESS_RATE_LIMIT_CHANGED);
Erik Kline05f2b402015-04-30 12:58:40 +09001831 }
1832
Erik Kline31b4a9e2018-01-11 21:07:29 +09001833 private void registerPrivateDnsSettingsCallbacks() {
Erik Kline9a62f012018-03-21 07:18:33 -07001834 for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
1835 mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
Erik Kline31b4a9e2018-01-11 21:07:29 +09001836 }
1837 }
1838
Robert Greenwalt0eb55c12014-05-18 16:22:10 -07001839 private synchronized int nextNetworkRequestId() {
junyulai70afb0c2020-12-14 18:51:02 +08001840 // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if
1841 // doing that.
Robert Greenwalt0eb55c12014-05-18 16:22:10 -07001842 return mNextNetworkRequestId++;
1843 }
1844
junyulai74f9a8b2018-06-13 15:00:37 +08001845 @VisibleForTesting
Chalard Jean46bfbf02022-02-02 00:56:25 +09001846 @Nullable
junyulai74f9a8b2018-06-13 15:00:37 +08001847 protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08001848 if (network == null) {
1849 return null;
1850 }
Serik Beketayevec8ad212020-12-07 22:43:07 -08001851 return getNetworkAgentInfoForNetId(network.getNetId());
Erik Kline9a62f012018-03-21 07:18:33 -07001852 }
1853
1854 private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08001855 synchronized (mNetworkForNetId) {
Erik Kline9a62f012018-03-21 07:18:33 -07001856 return mNetworkForNetId.get(netId);
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08001857 }
Jeff Sharkey40d1fb82016-04-22 09:50:16 -06001858 }
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08001859
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001860 // TODO: determine what to do when more than one VPN applies to |uid|.
Chalard Jean46bfbf02022-02-02 00:56:25 +09001861 @Nullable
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001862 private NetworkAgentInfo getVpnForUid(int uid) {
1863 synchronized (mNetworkForNetId) {
1864 for (int i = 0; i < mNetworkForNetId.size(); i++) {
1865 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
Chalard Jean254bd162022-08-25 13:04:51 +09001866 if (nai.isVPN() && nai.everConnected()
1867 && nai.networkCapabilities.appliesToUid(uid)) {
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001868 return nai;
Lorenzo Colitti489eb042015-02-05 13:57:17 +09001869 }
1870 }
1871 }
1872 return null;
1873 }
1874
Chalard Jean46bfbf02022-02-02 00:56:25 +09001875 @Nullable
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001876 private Network[] getVpnUnderlyingNetworks(int uid) {
Lorenzo Colitticd675292021-02-04 17:32:07 +09001877 if (mLockdownEnabled) return null;
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001878 final NetworkAgentInfo nai = getVpnForUid(uid);
1879 if (nai != null) return nai.declaredUnderlyingNetworks;
1880 return null;
1881 }
1882
Lorenzo Colittia7574052021-01-19 01:33:05 +09001883 private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) {
James Mattis2516da32021-01-31 17:06:19 -08001884 NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
Sreeram Ramachandrand2b4fe22014-11-11 16:09:21 -08001885
Lorenzo Colitti489eb042015-02-05 13:57:17 +09001886 final Network[] networks = getVpnUnderlyingNetworks(uid);
1887 if (networks != null) {
1888 // getUnderlyingNetworks() returns:
1889 // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
1890 // empty array => the VPN explicitly said "no default network".
1891 // non-empty array => the VPN specified one or more default networks; we use the
1892 // first one.
1893 if (networks.length > 0) {
1894 nai = getNetworkAgentInfoForNetwork(networks[0]);
1895 } else {
1896 nai = null;
Sreeram Ramachandrand2b4fe22014-11-11 16:09:21 -08001897 }
1898 }
Lorenzo Colittia7574052021-01-19 01:33:05 +09001899 return nai;
Paul Jensen83f5d572014-08-29 09:54:01 -04001900 }
1901
1902 /**
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001903 * Check if UID should be blocked from using the specified network.
Paul Jensen83f5d572014-08-29 09:54:01 -04001904 */
paulhu7aeba372020-12-30 00:42:19 +08001905 private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc,
1906 final int uid, final boolean ignoreBlocked) {
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06001907 // Networks aren't blocked when ignoring blocked status
Hugo Benichi39621362017-02-11 17:04:43 +09001908 if (ignoreBlocked) {
1909 return false;
1910 }
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09001911 if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true;
paulhu7aeba372020-12-30 00:42:19 +08001912 final long ident = Binder.clearCallingIdentity();
1913 try {
1914 final boolean metered = nc == null ? true : nc.isMetered();
1915 return mPolicyManager.isUidNetworkingBlocked(uid, metered);
1916 } finally {
1917 Binder.restoreCallingIdentity(ident);
1918 }
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001919 }
1920
Lorenzo Colittiac136a02016-01-22 04:04:57 +09001921 private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
Hugo Benichid159fdd2016-07-11 11:05:12 +09001922 if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
1923 return;
1924 }
Hugo Benichi47011212017-03-30 10:46:05 +09001925 final boolean blocked;
Lorenzo Colittiac136a02016-01-22 04:04:57 +09001926 synchronized (mBlockedAppUids) {
1927 if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
Hugo Benichi47011212017-03-30 10:46:05 +09001928 blocked = true;
Lorenzo Colittiac136a02016-01-22 04:04:57 +09001929 } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
Hugo Benichi47011212017-03-30 10:46:05 +09001930 blocked = false;
1931 } else {
1932 return;
Lorenzo Colittiac136a02016-01-22 04:04:57 +09001933 }
1934 }
Hugo Benichi47011212017-03-30 10:46:05 +09001935 String action = blocked ? "BLOCKED" : "UNBLOCKED";
1936 log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
1937 mNetworkInfoBlockingLogs.log(action + " " + uid);
Lorenzo Colittiac136a02016-01-22 04:04:57 +09001938 }
1939
Lorenzo Colitti42fe2232021-03-25 23:17:36 +09001940 private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
junyulaif2c67e42018-08-07 19:50:45 +08001941 if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
1942 return;
1943 }
Lorenzo Colitti42fe2232021-03-25 23:17:36 +09001944 final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
James Mattisa076c532020-12-02 14:12:41 -08001945 final int requestId = nri.getActiveRequest() != null
1946 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
junyulai31a6c322020-05-29 14:44:42 +08001947 mNetworkInfoBlockingLogs.log(String.format(
Lorenzo Colitti42fe2232021-03-25 23:17:36 +09001948 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
Sudheer Shankaf0ffc772021-04-21 07:23:54 +00001949 Integer.toHexString(blocked)));
junyulaif2c67e42018-08-07 19:50:45 +08001950 }
1951
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001952 /**
Lorenzo Colittia7574052021-01-19 01:33:05 +09001953 * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For
Jeff Sharkey40d1fb82016-04-22 09:50:16 -06001954 * example, this may mark the network as {@link DetailedState#BLOCKED} based
paulhu7aeba372020-12-30 00:42:19 +08001955 * on {@link #isNetworkWithCapabilitiesBlocked}.
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001956 */
Lorenzo Colittia7574052021-01-19 01:33:05 +09001957 @NonNull
1958 private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type,
1959 @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) {
Lorenzo Colitti3da6f1b2021-03-03 14:39:04 +09001960 final NetworkInfo filtered = new NetworkInfo(networkInfo);
1961 // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network
1962 // but only exists if an app asks about them or requests them. Ensure the requesting app
1963 // gets the type it asks for.
Lorenzo Colittia7574052021-01-19 01:33:05 +09001964 filtered.setType(type);
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09001965 if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
1966 filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
1967 null /* extraInfo */);
1968 }
1969 filterForLegacyLockdown(filtered);
Lorenzo Colittia7574052021-01-19 01:33:05 +09001970 return filtered;
1971 }
1972
1973 private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid,
1974 boolean ignoreBlocked) {
1975 return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(),
1976 nai.networkCapabilities, uid, ignoreBlocked);
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001977 }
1978
1979 /**
The Android Open Source Project28527d22009-03-03 19:31:44 -08001980 * Return NetworkInfo for the active (i.e., connected) network interface.
1981 * It is assumed that at most one network is active at a time. If more
1982 * than one is active, it is indeterminate which will be returned.
Robert Greenwalt0659da32009-07-16 17:21:39 -07001983 * @return the info for the active network, or {@code null} if none is
1984 * active
The Android Open Source Project28527d22009-03-03 19:31:44 -08001985 */
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001986 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09001987 @Nullable
The Android Open Source Project28527d22009-03-03 19:31:44 -08001988 public NetworkInfo getActiveNetworkInfo() {
Jeff Sharkey921ebf22011-05-19 17:12:49 -07001989 enforceAccessPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09001990 final int uid = mDeps.getCallingUid();
Lorenzo Colittia7574052021-01-19 01:33:05 +09001991 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
1992 if (nai == null) return null;
1993 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
1994 maybeLogBlockedNetworkInfo(networkInfo, uid);
1995 return networkInfo;
The Android Open Source Project28527d22009-03-03 19:31:44 -08001996 }
1997
Paul Jensen1f567382015-02-13 14:18:39 -05001998 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09001999 @Nullable
Paul Jensen1f567382015-02-13 14:18:39 -05002000 public Network getActiveNetwork() {
2001 enforceAccessPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002002 return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false);
Robin Lee5b52bef2016-03-24 12:07:00 +00002003 }
2004
2005 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002006 @Nullable
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002007 public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
paulhu3ffffe72021-09-16 10:15:22 +08002008 enforceNetworkStackPermission(mContext);
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002009 return getActiveNetworkForUidInternal(uid, ignoreBlocked);
Robin Lee5b52bef2016-03-24 12:07:00 +00002010 }
2011
Chalard Jean46bfbf02022-02-02 00:56:25 +09002012 @Nullable
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002013 private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09002014 final NetworkAgentInfo vpnNai = getVpnForUid(uid);
2015 if (vpnNai != null) {
2016 final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid);
2017 if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) {
2018 return vpnNai.network;
Chalard Jean46adcf32018-04-18 20:18:38 +09002019 }
Paul Jensen1f567382015-02-13 14:18:39 -05002020 }
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09002021
James Mattis2516da32021-01-31 17:06:19 -08002022 NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09002023 if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
2024 ignoreBlocked)) {
2025 return null;
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002026 }
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09002027 return nai.network;
Paul Jensen1f567382015-02-13 14:18:39 -05002028 }
2029
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002030 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002031 @Nullable
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002032 public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
paulhu3ffffe72021-09-16 10:15:22 +08002033 enforceNetworkStackPermission(mContext);
Lorenzo Colittia7574052021-01-19 01:33:05 +09002034 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2035 if (nai == null) return null;
2036 return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002037 }
2038
Lorenzo Colittia45cfb32021-03-02 23:28:49 +09002039 /** Returns a NetworkInfo object for a network that doesn't exist. */
2040 private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) {
2041 final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */,
2042 getNetworkTypeName(networkType), "" /* subtypeName */);
2043 info.setIsAvailable(true);
2044 // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when
2045 // background data is restricted.
2046 final NetworkCapabilities nc = new NetworkCapabilities(); // Metered.
2047 final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
2048 ? DetailedState.BLOCKED
2049 : DetailedState.DISCONNECTED;
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09002050 info.setDetailedState(state, null /* reason */, null /* extraInfo */);
2051 filterForLegacyLockdown(info);
Lorenzo Colittia45cfb32021-03-02 23:28:49 +09002052 return info;
2053 }
2054
Lorenzo Colittia7574052021-01-19 01:33:05 +09002055 private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) {
Lorenzo Colitti63aaccb2021-01-15 23:35:16 +09002056 if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
2057 return null;
2058 }
2059 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
Lorenzo Colittia45cfb32021-03-02 23:28:49 +09002060 if (nai == null) {
2061 return makeFakeNetworkInfo(networkType, uid);
Lorenzo Colitti63aaccb2021-01-15 23:35:16 +09002062 }
Lorenzo Colittia7574052021-01-19 01:33:05 +09002063 return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid,
2064 false);
Lorenzo Colitti63aaccb2021-01-15 23:35:16 +09002065 }
2066
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002067 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002068 @Nullable
The Android Open Source Project28527d22009-03-03 19:31:44 -08002069 public NetworkInfo getNetworkInfo(int networkType) {
2070 enforceAccessPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002071 final int uid = mDeps.getCallingUid();
Lorenzo Colitti489eb042015-02-05 13:57:17 +09002072 if (getVpnUnderlyingNetworks(uid) != null) {
2073 // A VPN is active, so we may need to return one of its underlying networks. This
2074 // information is not available in LegacyTypeTracker, so we have to get it from
Lorenzo Colittia7574052021-01-19 01:33:05 +09002075 // getNetworkAgentInfoForUid.
2076 final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2077 if (nai == null) return null;
2078 final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
2079 if (networkInfo.getType() == networkType) {
2080 return networkInfo;
Lorenzo Colitti489eb042015-02-05 13:57:17 +09002081 }
2082 }
Lorenzo Colittia7574052021-01-19 01:33:05 +09002083 return getFilteredNetworkInfoForType(networkType, uid);
The Android Open Source Project28527d22009-03-03 19:31:44 -08002084 }
2085
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002086 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002087 @Nullable
Jeff Sharkey7dbf83d2016-04-28 15:33:18 -06002088 public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002089 enforceAccessPermission();
Jeff Sharkey40d1fb82016-04-22 09:50:16 -06002090 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Lorenzo Colittia7574052021-01-19 01:33:05 +09002091 if (nai == null) return null;
2092 return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002093 }
2094
2095 @Override
The Android Open Source Project28527d22009-03-03 19:31:44 -08002096 public NetworkInfo[] getAllNetworkInfo() {
2097 enforceAccessPermission();
Serik Beketayev05130302021-01-15 16:47:25 -08002098 final ArrayList<NetworkInfo> result = new ArrayList<>();
Paul Jensen42aba3e2014-09-19 11:14:12 -04002099 for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
2100 networkType++) {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002101 NetworkInfo info = getNetworkInfo(networkType);
2102 if (info != null) {
2103 result.add(info);
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002104 }
The Android Open Source Project28527d22009-03-03 19:31:44 -08002105 }
Jeff Sharkey21062e72011-05-28 20:56:34 -07002106 return result.toArray(new NetworkInfo[result.size()]);
The Android Open Source Project28527d22009-03-03 19:31:44 -08002107 }
2108
Robert Greenwalt0114f6e2011-08-31 11:46:42 -07002109 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002110 @Nullable
Lorenzo Colitti860a7aa2014-08-22 17:10:50 -07002111 public Network getNetworkForType(int networkType) {
2112 enforceAccessPermission();
Lorenzo Colitti63aaccb2021-01-15 23:35:16 +09002113 if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
2114 return null;
2115 }
2116 final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2117 if (nai == null) {
2118 return null;
2119 }
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002120 final int uid = mDeps.getCallingUid();
Lorenzo Colittia7574052021-01-19 01:33:05 +09002121 if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
2122 return null;
Lorenzo Colitti860a7aa2014-08-22 17:10:50 -07002123 }
Lorenzo Colittia7574052021-01-19 01:33:05 +09002124 return nai.network;
Lorenzo Colitti860a7aa2014-08-22 17:10:50 -07002125 }
2126
2127 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09002128 @NonNull
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002129 public Network[] getAllNetworks() {
2130 enforceAccessPermission();
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002131 synchronized (mNetworkForNetId) {
Paul Jensenc7a1d232015-04-06 11:54:53 -04002132 final Network[] result = new Network[mNetworkForNetId.size()];
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002133 for (int i = 0; i < mNetworkForNetId.size(); i++) {
Paul Jensenc7a1d232015-04-06 11:54:53 -04002134 result[i] = mNetworkForNetId.valueAt(i).network;
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002135 }
Paul Jensenc7a1d232015-04-06 11:54:53 -04002136 return result;
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002137 }
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002138 }
2139
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09002140 @Override
Qingxi Lib2748102020-01-08 12:51:49 -08002141 public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
Roshan Piusaa24fde2020-12-17 14:53:09 -08002142 int userId, String callingPackageName, @Nullable String callingAttributionTag) {
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09002143 // The basic principle is: if an app's traffic could possibly go over a
2144 // network, without the app doing anything multinetwork-specific,
2145 // (hence, by "default"), then include that network's capabilities in
2146 // the array.
2147 //
2148 // In the normal case, app traffic only goes over the system's default
2149 // network connection, so that's the only network returned.
2150 //
2151 // With a VPN in force, some app traffic may go into the VPN, and thus
2152 // over whatever underlying networks the VPN specifies, while other app
2153 // traffic may go over the system default network (e.g.: a split-tunnel
2154 // VPN, or an app disallowed by the VPN), so the set of networks
2155 // returned includes the VPN's underlying networks and the system
2156 // default.
2157 enforceAccessPermission();
2158
Chalard Jeand6c33dc2018-06-04 13:33:12 +09002159 HashMap<Network, NetworkCapabilities> result = new HashMap<>();
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09002160
James Mattis2516da32021-01-31 17:06:19 -08002161 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
2162 if (!nri.isBeingSatisfied()) {
2163 continue;
2164 }
2165 final NetworkAgentInfo nai = nri.getSatisfier();
2166 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
2167 if (null != nc
2168 && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
2169 && !result.containsKey(nai.network)) {
2170 result.put(
2171 nai.network,
2172 createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Roshan Pius951c0032020-12-22 15:10:42 -08002173 nc, false /* includeLocationSensitiveInfo */,
Roshan Pius98f59ec2021-02-23 08:47:39 -08002174 getCallingPid(), mDeps.getCallingUid(), callingPackageName,
2175 callingAttributionTag));
James Mattis2516da32021-01-31 17:06:19 -08002176 }
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09002177 }
2178
Lorenzo Colittidfab3032020-12-15 00:49:41 +09002179 // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +09002180 final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
James Mattis2516da32021-01-31 17:06:19 -08002181 if (null != networks) {
2182 for (final Network network : networks) {
2183 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
2184 if (null != nc) {
Roshan Pius9ed14622020-12-28 09:01:49 -08002185 result.put(
2186 network,
2187 createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Roshan Pius951c0032020-12-22 15:10:42 -08002188 nc,
2189 false /* includeLocationSensitiveInfo */,
Roshan Pius98f59ec2021-02-23 08:47:39 -08002190 getCallingPid(), mDeps.getCallingUid(), callingPackageName,
Roshan Piusaa24fde2020-12-17 14:53:09 -08002191 callingAttributionTag));
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09002192 }
2193 }
2194 }
2195
2196 NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
2197 out = result.values().toArray(out);
2198 return out;
2199 }
2200
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002201 @Override
Robert Greenwalt0114f6e2011-08-31 11:46:42 -07002202 public boolean isNetworkSupported(int networkType) {
2203 enforceAccessPermission();
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002204 return mLegacyTypeTracker.isTypeSupported(networkType);
Robert Greenwalt0114f6e2011-08-31 11:46:42 -07002205 }
2206
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002207 /**
2208 * Return LinkProperties for the active (i.e., connected) default
James Mattis2516da32021-01-31 17:06:19 -08002209 * network interface for the calling uid.
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002210 * @return the ip properties for the active network, or {@code null} if
2211 * none is active
2212 */
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002213 @Override
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002214 public LinkProperties getActiveLinkProperties() {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002215 enforceAccessPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002216 final int uid = mDeps.getCallingUid();
Lorenzo Colittia7574052021-01-19 01:33:05 +09002217 NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2218 if (nai == null) return null;
2219 return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties,
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002220 Binder.getCallingPid(), uid);
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002221 }
2222
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002223 @Override
Robert Greenwaltf99b8392014-03-26 16:47:06 -07002224 public LinkProperties getLinkPropertiesForType(int networkType) {
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002225 enforceAccessPermission();
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08002226 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002227 final LinkProperties lp = getLinkProperties(nai);
2228 if (lp == null) return null;
2229 return linkPropertiesRestrictedForCallerPermissions(
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002230 lp, Binder.getCallingPid(), mDeps.getCallingUid());
Robert Greenwalt9f0ee4f2010-09-14 09:18:02 -07002231 }
2232
Robert Greenwaltbe46b752014-05-13 21:41:06 -07002233 // TODO - this should be ALL networks
Jeff Sharkey21062e72011-05-28 20:56:34 -07002234 @Override
Robert Greenwaltf99b8392014-03-26 16:47:06 -07002235 public LinkProperties getLinkProperties(Network network) {
2236 enforceAccessPermission();
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002237 final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network));
2238 if (lp == null) return null;
2239 return linkPropertiesRestrictedForCallerPermissions(
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002240 lp, Binder.getCallingPid(), mDeps.getCallingUid());
Hugo Benichie9d321b2017-04-06 16:01:44 +09002241 }
2242
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002243 @Nullable
2244 private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) {
Hugo Benichie9d321b2017-04-06 16:01:44 +09002245 if (nai == null) {
2246 return null;
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002247 }
Hugo Benichie9d321b2017-04-06 16:01:44 +09002248 synchronized (nai) {
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002249 return nai.linkProperties;
Hugo Benichie9d321b2017-04-06 16:01:44 +09002250 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07002251 }
2252
lucaslinc582d502022-01-27 09:07:00 +08002253 @Override
2254 @Nullable
lucaslind2b06132022-03-02 10:56:57 +08002255 public LinkProperties getRedactedLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid,
lucaslinc582d502022-01-27 09:07:00 +08002256 @NonNull String packageName, @Nullable String callingAttributionTag) {
2257 Objects.requireNonNull(packageName);
2258 Objects.requireNonNull(lp);
2259 enforceNetworkStackOrSettingsPermission();
2260 if (!checkAccessPermission(-1 /* pid */, uid)) {
2261 return null;
2262 }
2263 return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid);
2264 }
2265
Qingxi Lib2748102020-01-08 12:51:49 -08002266 private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
2267 return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
2268 }
2269
Lorenzo Colittie97685a2015-05-14 17:28:27 +09002270 private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002271 if (nai == null) return null;
2272 synchronized (nai) {
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002273 return networkCapabilitiesRestrictedForCallerPermissions(
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002274 nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid());
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002275 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07002276 }
2277
2278 @Override
Roshan Piusaa24fde2020-12-17 14:53:09 -08002279 public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName,
2280 @Nullable String callingAttributionTag) {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002281 mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName);
Lorenzo Colittie97685a2015-05-14 17:28:27 +09002282 enforceAccessPermission();
Roshan Pius9ed14622020-12-28 09:01:49 -08002283 return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Qingxi Lib2748102020-01-08 12:51:49 -08002284 getNetworkCapabilitiesInternal(network),
Roshan Pius951c0032020-12-22 15:10:42 -08002285 false /* includeLocationSensitiveInfo */,
Roshan Pius98f59ec2021-02-23 08:47:39 -08002286 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
Lorenzo Colittie97685a2015-05-14 17:28:27 +09002287 }
2288
lucaslinc582d502022-01-27 09:07:00 +08002289 @Override
lucaslind2b06132022-03-02 10:56:57 +08002290 public NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(
2291 @NonNull NetworkCapabilities nc, int uid, @NonNull String packageName,
2292 @Nullable String callingAttributionTag) {
lucaslinc582d502022-01-27 09:07:00 +08002293 Objects.requireNonNull(nc);
2294 Objects.requireNonNull(packageName);
2295 enforceNetworkStackOrSettingsPermission();
2296 if (!checkAccessPermission(-1 /* pid */, uid)) {
2297 return null;
2298 }
2299 return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2300 networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid),
2301 true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName,
2302 callingAttributionTag);
2303 }
2304
lucaslin69e1aa92022-03-22 18:15:09 +08002305 private void redactUnderlyingNetworksForCapabilities(NetworkCapabilities nc, int pid, int uid) {
2306 if (nc.getUnderlyingNetworks() != null
2307 && !checkNetworkFactoryOrSettingsPermission(pid, uid)) {
2308 nc.setUnderlyingNetworks(null);
2309 }
2310 }
2311
Qingxi Libb8da982020-01-17 17:54:27 -08002312 @VisibleForTesting
2313 NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
Chalard Jean9a396cc2018-02-21 18:43:54 +09002314 NetworkCapabilities nc, int callerPid, int callerUid) {
lucaslinc582d502022-01-27 09:07:00 +08002315 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
2316 // this would be expensive (one more permission check every time any NC callback is
2317 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
2318 // it happens for some reason (e.g. the package is uninstalled while CS is trying to
2319 // send the callback) it would crash the system server with NPE.
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09002320 final NetworkCapabilities newNc = new NetworkCapabilities(nc);
Chalard Jean46adcf32018-04-18 20:18:38 +09002321 if (!checkSettingsPermission(callerPid, callerUid)) {
2322 newNc.setUids(null);
2323 newNc.setSSID(null);
2324 }
Etan Cohen107ae952018-12-30 17:59:59 -08002325 if (newNc.getNetworkSpecifier() != null) {
2326 newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
2327 }
Junyu Lai4c6fe232023-04-11 11:33:46 +08002328 if (!checkAnyPermissionOf(mContext, callerPid, callerUid,
2329 android.Manifest.permission.NETWORK_STACK,
Benedict Wonga5604ea2021-07-09 00:13:45 -07002330 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) {
2331 newNc.setAdministratorUids(new int[0]);
2332 }
Junyu Lai4c6fe232023-04-11 11:33:46 +08002333 if (!checkAnyPermissionOf(mContext,
Benedict Wong53de25f2021-03-24 14:01:51 -07002334 callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
Chalard Jeande665262022-02-25 16:12:12 +09002335 newNc.setAllowedUids(new ArraySet<>());
junyulai2217bec2021-04-14 23:33:31 +08002336 newNc.setSubscriptionIds(Collections.emptySet());
Benedict Wong53de25f2021-03-24 14:01:51 -07002337 }
lucaslin69e1aa92022-03-22 18:15:09 +08002338 redactUnderlyingNetworksForCapabilities(newNc, callerPid, callerUid);
Qingxi Libb8da982020-01-17 17:54:27 -08002339
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09002340 return newNc;
Chalard Jean2550e062018-01-26 19:24:40 +09002341 }
2342
Roshan Pius98f59ec2021-02-23 08:47:39 -08002343 /**
2344 * Wrapper used to cache the permission check results performed for the corresponding
lucaslinc582d502022-01-27 09:07:00 +08002345 * app. This avoids performing multiple permission checks for different fields in
Roshan Pius98f59ec2021-02-23 08:47:39 -08002346 * NetworkCapabilities.
2347 * Note: This wrapper does not support any sort of invalidation and thus must not be
2348 * persistent or long-lived. It may only be used for the time necessary to
2349 * compute the redactions required by one particular NetworkCallback or
2350 * synchronous call.
2351 */
2352 private class RedactionPermissionChecker {
2353 private final int mCallingPid;
2354 private final int mCallingUid;
2355 @NonNull private final String mCallingPackageName;
2356 @Nullable private final String mCallingAttributionTag;
2357
2358 private Boolean mHasLocationPermission = null;
2359 private Boolean mHasLocalMacAddressPermission = null;
2360 private Boolean mHasSettingsPermission = null;
2361
2362 RedactionPermissionChecker(int callingPid, int callingUid,
2363 @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
2364 mCallingPid = callingPid;
2365 mCallingUid = callingUid;
2366 mCallingPackageName = callingPackageName;
2367 mCallingAttributionTag = callingAttributionTag;
Roshan Pius9ed14622020-12-28 09:01:49 -08002368 }
Roshan Pius98f59ec2021-02-23 08:47:39 -08002369
2370 private boolean hasLocationPermissionInternal() {
2371 final long token = Binder.clearCallingIdentity();
2372 try {
2373 return mLocationPermissionChecker.checkLocationPermission(
2374 mCallingPackageName, mCallingAttributionTag, mCallingUid,
2375 null /* message */);
2376 } finally {
2377 Binder.restoreCallingIdentity(token);
2378 }
2379 }
2380
2381 /**
2382 * Returns whether the app holds location permission or not (might return cached result
2383 * if the permission was already checked before).
2384 */
2385 public boolean hasLocationPermission() {
2386 if (mHasLocationPermission == null) {
2387 // If there is no cached result, perform the check now.
2388 mHasLocationPermission = hasLocationPermissionInternal();
2389 }
2390 return mHasLocationPermission;
2391 }
2392
2393 /**
2394 * Returns whether the app holds local mac address permission or not (might return cached
2395 * result if the permission was already checked before).
2396 */
2397 public boolean hasLocalMacAddressPermission() {
2398 if (mHasLocalMacAddressPermission == null) {
2399 // If there is no cached result, perform the check now.
2400 mHasLocalMacAddressPermission =
2401 checkLocalMacAddressPermission(mCallingPid, mCallingUid);
2402 }
2403 return mHasLocalMacAddressPermission;
2404 }
2405
2406 /**
2407 * Returns whether the app holds settings permission or not (might return cached
2408 * result if the permission was already checked before).
2409 */
2410 public boolean hasSettingsPermission() {
2411 if (mHasSettingsPermission == null) {
2412 // If there is no cached result, perform the check now.
2413 mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
2414 }
2415 return mHasSettingsPermission;
2416 }
2417 }
2418
2419 private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
2420 @NetworkCapabilities.NetCapability long redaction) {
2421 return (redactions & redaction) != 0;
2422 }
2423
2424 /**
2425 * Use the provided |applicableRedactions| to check the receiving app's
2426 * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
2427 * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
2428 * before being sent to the corresponding app.
2429 */
2430 private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
2431 @NetworkCapabilities.RedactionType long applicableRedactions,
2432 @NonNull RedactionPermissionChecker redactionPermissionChecker,
2433 boolean includeLocationSensitiveInfo) {
2434 long redactions = applicableRedactions;
2435 if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
2436 if (includeLocationSensitiveInfo
2437 && redactionPermissionChecker.hasLocationPermission()) {
2438 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
2439 }
2440 }
2441 if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
2442 if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
2443 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
2444 }
2445 }
2446 if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
2447 if (redactionPermissionChecker.hasSettingsPermission()) {
2448 redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
2449 }
2450 }
2451 return redactions;
Roshan Pius9ed14622020-12-28 09:01:49 -08002452 }
2453
Qingxi Lib2748102020-01-08 12:51:49 -08002454 @VisibleForTesting
2455 @Nullable
Roshan Pius9ed14622020-12-28 09:01:49 -08002456 NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Roshan Pius951c0032020-12-22 15:10:42 -08002457 @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
Roshan Pius98f59ec2021-02-23 08:47:39 -08002458 int callingPid, int callingUid, @NonNull String callingPkgName,
2459 @Nullable String callingAttributionTag) {
Qingxi Lib2748102020-01-08 12:51:49 -08002460 if (nc == null) {
2461 return null;
2462 }
Roshan Pius9ed14622020-12-28 09:01:49 -08002463 // Avoid doing location permission check if the transport info has no location sensitive
2464 // data.
Roshan Pius98f59ec2021-02-23 08:47:39 -08002465 final RedactionPermissionChecker redactionPermissionChecker =
2466 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
2467 callingAttributionTag);
2468 final long redactions = retrieveRequiredRedactions(
2469 nc.getApplicableRedactions(), redactionPermissionChecker,
2470 includeLocationSensitiveInfo);
2471 final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
Roshan Pius9ed14622020-12-28 09:01:49 -08002472 // Reset owner uid if not destined for the owner app.
lucaslinc582d502022-01-27 09:07:00 +08002473 // TODO : calling UID is redacted because apps should generally not know what UID is
2474 // bringing up the VPN, but this should not apply to some very privileged apps like settings
Roshan Pius98f59ec2021-02-23 08:47:39 -08002475 if (callingUid != nc.getOwnerUid()) {
Qingxi Lib2748102020-01-08 12:51:49 -08002476 newNc.setOwnerUid(INVALID_UID);
2477 return newNc;
2478 }
Benedict Wongbf004e92020-06-08 11:55:38 -07002479 // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
2480 if (nc.hasTransport(TRANSPORT_VPN)) {
2481 // Owner UIDs already checked above. No need to re-check.
2482 return newNc;
2483 }
Roshan Pius98f59ec2021-02-23 08:47:39 -08002484 // If the calling does not want location sensitive data & target SDK >= S, then mask info.
2485 // Else include the owner UID iff the calling has location permission to provide backwards
Roshan Pius951c0032020-12-22 15:10:42 -08002486 // compatibility for older apps.
2487 if (!includeLocationSensitiveInfo
2488 && isTargetSdkAtleast(
Roshan Pius98f59ec2021-02-23 08:47:39 -08002489 Build.VERSION_CODES.S, callingUid, callingPkgName)) {
Roshan Pius951c0032020-12-22 15:10:42 -08002490 newNc.setOwnerUid(INVALID_UID);
2491 return newNc;
2492 }
Roshan Pius9ed14622020-12-28 09:01:49 -08002493 // Reset owner uid if the app has no location permission.
Roshan Pius98f59ec2021-02-23 08:47:39 -08002494 if (!redactionPermissionChecker.hasLocationPermission()) {
Roshan Pius9ed14622020-12-28 09:01:49 -08002495 newNc.setOwnerUid(INVALID_UID);
2496 }
Qingxi Lib2748102020-01-08 12:51:49 -08002497 return newNc;
Qingxi Libb8da982020-01-17 17:54:27 -08002498 }
2499
lucaslinc582d502022-01-27 09:07:00 +08002500 @NonNull
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002501 private LinkProperties linkPropertiesRestrictedForCallerPermissions(
2502 LinkProperties lp, int callerPid, int callerUid) {
2503 if (lp == null) return new LinkProperties();
lucaslinc582d502022-01-27 09:07:00 +08002504 // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
2505 // this would be expensive (one more permission check every time any LP callback is
2506 // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
2507 // it happens for some reason (e.g. the package is uninstalled while CS is trying to
2508 // send the callback) it would crash the system server with NPE.
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002509
2510 // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
2511 final boolean needsSanitization =
2512 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null);
2513 if (!needsSanitization) {
2514 return new LinkProperties(lp);
2515 }
2516
2517 if (checkSettingsPermission(callerPid, callerUid)) {
Remi NGUYEN VAN8dd694d2020-03-16 14:48:37 +09002518 return new LinkProperties(lp, true /* parcelSensitiveFields */);
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09002519 }
2520
2521 final LinkProperties newLp = new LinkProperties(lp);
2522 // Sensitive fields would not be parceled anyway, but sanitize for consistency before the
2523 // object gets parceled.
2524 newLp.setCaptivePortalApiUrl(null);
2525 newLp.setCaptivePortalData(null);
2526 return newLp;
2527 }
2528
Roshan Pius08c94fb2020-01-16 12:17:17 -08002529 private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
2530 int callerUid, String callerPackageName) {
Lorenzo Colitti86714b12021-05-17 20:31:21 +09002531 // There is no need to track the effective UID of the request here. If the caller
2532 // lacks the settings permission, the effective UID is the same as the calling ID.
Chalard Jean9a396cc2018-02-21 18:43:54 +09002533 if (!checkSettingsPermission()) {
Lorenzo Colitti86714b12021-05-17 20:31:21 +09002534 // Unprivileged apps can only pass in null or their own UID.
2535 if (nc.getUids() == null) {
2536 // If the caller passes in null, the callback will also match networks that do not
2537 // apply to its UID, similarly to what it would see if it called getAllNetworks.
2538 // In this case, redact everything in the request immediately. This ensures that the
2539 // app is not able to get any redacted information by filing an unredacted request
2540 // and observing whether the request matches something.
2541 if (nc.getNetworkSpecifier() != null) {
2542 nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact());
2543 }
2544 } else {
2545 nc.setSingleUid(callerUid);
2546 }
Chalard Jean9a396cc2018-02-21 18:43:54 +09002547 }
Roshan Pius08c94fb2020-01-16 12:17:17 -08002548 nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
Cody Kesting5ab1f552020-03-16 18:15:28 -07002549 nc.setAdministratorUids(new int[0]);
Qingxi Libb8da982020-01-17 17:54:27 -08002550
2551 // Clear owner UID; this can never come from an app.
2552 nc.setOwnerUid(INVALID_UID);
Chalard Jean9a396cc2018-02-21 18:43:54 +09002553 }
2554
Chalard Jean38354d12018-03-20 19:13:57 +09002555 private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002556 if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) {
Chalard Jean38354d12018-03-20 19:13:57 +09002557 nc.addCapability(NET_CAPABILITY_FOREGROUND);
2558 }
2559 }
2560
Remi NGUYEN VANe2139a02021-03-18 14:23:12 +09002561 @Override
2562 public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() {
2563 enforceAccessPermission();
2564 final int callerUid = Binder.getCallingUid();
2565 final long token = Binder.clearCallingIdentity();
2566 try {
2567 return mPolicyManager.getRestrictBackgroundStatus(callerUid);
2568 } finally {
2569 Binder.restoreCallingIdentity(token);
2570 }
2571 }
2572
junyulaiebd15162021-03-03 12:09:05 +08002573 // TODO: Consider delete this function or turn it into a no-op method.
Lorenzo Colittie97685a2015-05-14 17:28:27 +09002574 @Override
Jeff Sharkey21062e72011-05-28 20:56:34 -07002575 public NetworkState[] getAllNetworkState() {
paulhu8e96a752019-08-12 16:25:11 +08002576 // This contains IMSI details, so make sure the caller is privileged.
paulhu3ffffe72021-09-16 10:15:22 +08002577 enforceNetworkStackPermission(mContext);
Jeff Sharkeyfffa9832014-12-02 18:30:14 -08002578
Serik Beketayev05130302021-01-15 16:47:25 -08002579 final ArrayList<NetworkState> result = new ArrayList<>();
Aaron Huangee78b1f2021-04-17 13:46:25 +08002580 for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
junyulaiebd15162021-03-03 12:09:05 +08002581 // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
2582 // NetworkAgentInfo.
Aaron Huangb8f56642021-04-20 17:19:46 +08002583 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork());
junyulaid49aab92020-12-29 19:17:01 +08002584 if (nai != null && nai.networkInfo.isConnected()) {
junyulaiebd15162021-03-03 12:09:05 +08002585 result.add(new NetworkState(new NetworkInfo(nai.networkInfo),
Aaron Huangb8f56642021-04-20 17:19:46 +08002586 snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(),
2587 snapshot.getNetwork(), snapshot.getSubscriberId()));
Jeff Sharkey21062e72011-05-28 20:56:34 -07002588 }
2589 }
Chalard Jean46bfbf02022-02-02 00:56:25 +09002590 return result.toArray(new NetworkState[0]);
Jeff Sharkey21062e72011-05-28 20:56:34 -07002591 }
2592
Jeff Sharkey66fa9682011-08-02 17:22:34 -07002593 @Override
junyulaiebd15162021-03-03 12:09:05 +08002594 @NonNull
Aaron Huangee78b1f2021-04-17 13:46:25 +08002595 public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
junyulaiebd15162021-03-03 12:09:05 +08002596 // This contains IMSI details, so make sure the caller is privileged.
junyulaieaaacb02021-05-14 18:04:29 +08002597 enforceNetworkStackOrSettingsPermission();
junyulaiebd15162021-03-03 12:09:05 +08002598
2599 final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
2600 for (Network network : getAllNetworks()) {
2601 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Chalard Jean254bd162022-08-25 13:04:51 +09002602 if (nai != null && nai.everConnected()) {
junyulaiebd15162021-03-03 12:09:05 +08002603 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
2604 // NetworkCapabilities, which may contain UIDs of apps to which the
2605 // network applies. Should the UIDs be cleared so as not to leak or
2606 // interfere ?
2607 result.add(nai.getNetworkStateSnapshot());
2608 }
2609 }
2610 return result;
2611 }
2612
2613 @Override
Jeff Sharkeyd00b1302012-04-12 18:34:54 -07002614 public boolean isActiveNetworkMetered() {
2615 enforceAccessPermission();
Jeff Sharkeyd00b1302012-04-12 18:34:54 -07002616
Qingxi Lib2748102020-01-08 12:51:49 -08002617 final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork());
Jeff Sharkeyadebffc2017-07-12 10:50:42 -06002618 if (caps != null) {
2619 return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
2620 } else {
2621 // Always return the most conservative value
2622 return true;
2623 }
Jeff Sharkeyedf85d42012-04-30 15:47:05 -07002624 }
2625
Robert Greenwaltaffc3a12009-09-27 17:27:04 -07002626 /**
Lorenzo Colitti23862912018-09-28 11:31:55 +09002627 * Ensures that the system cannot call a particular method.
2628 */
2629 private boolean disallowedBecauseSystemCaller() {
2630 // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
Anil Admale1a28862019-04-05 10:06:37 -07002631 // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
2632 // for devices launched with Q and above. However, existing devices upgrading to Q and
2633 // above must continued to be supported for few more releases.
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002634 if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt(
Anil Admale1a28862019-04-05 10:06:37 -07002635 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
Lorenzo Colitti23862912018-09-28 11:31:55 +09002636 log("This method exists only for app backwards compatibility"
2637 + " and must not be called by system services.");
2638 return true;
2639 }
2640 return false;
2641 }
2642
paulhub2c28682021-08-18 18:35:54 +08002643 private int getAppUid(final String app, final UserHandle user) {
2644 final PackageManager pm =
2645 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
2646 final long token = Binder.clearCallingIdentity();
2647 try {
2648 return pm.getPackageUid(app, 0 /* flags */);
2649 } catch (PackageManager.NameNotFoundException e) {
2650 return -1;
2651 } finally {
2652 Binder.restoreCallingIdentity(token);
2653 }
2654 }
2655
2656 private void verifyCallingUidAndPackage(String packageName, int callingUid) {
2657 final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
2658 if (getAppUid(packageName, user) != callingUid) {
2659 throw new SecurityException(packageName + " does not belong to uid " + callingUid);
2660 }
2661 }
2662
Lorenzo Colitti23862912018-09-28 11:31:55 +09002663 /**
The Android Open Source Project28527d22009-03-03 19:31:44 -08002664 * Ensure that a network route exists to deliver traffic to the specified
2665 * host via the specified network interface.
Robert Greenwalt0659da32009-07-16 17:21:39 -07002666 * @param networkType the type of the network over which traffic to the
2667 * specified host is to be routed
2668 * @param hostAddress the IP address of the host to which the route is
2669 * desired
The Android Open Source Project28527d22009-03-03 19:31:44 -08002670 * @return {@code true} on success, {@code false} on failure
2671 */
Lorenzo Colittid6459092016-07-04 12:55:44 +09002672 @Override
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07002673 public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
2674 String callingPackageName, String callingAttributionTag) {
Lorenzo Colitti23862912018-09-28 11:31:55 +09002675 if (disallowedBecauseSystemCaller()) {
2676 return false;
2677 }
paulhub2c28682021-08-18 18:35:54 +08002678 verifyCallingUidAndPackage(callingPackageName, mDeps.getCallingUid());
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07002679 enforceChangePermission(callingPackageName, callingAttributionTag);
Robert Greenwalt6cac0742011-06-21 17:26:14 -07002680 if (mProtectedNetworks.contains(networkType)) {
Paul Hu8fc2a552022-05-04 18:44:42 +08002681 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
Robert Greenwalt6cac0742011-06-21 17:26:14 -07002682 }
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002683
Chad Brubaker7965e0a2014-02-14 13:24:29 -08002684 InetAddress addr;
2685 try {
2686 addr = InetAddress.getByAddress(hostAddress);
2687 } catch (UnknownHostException e) {
Chalard Jean46bfbf02022-02-02 00:56:25 +09002688 if (DBG) log("requestRouteToHostAddress got " + e);
Chad Brubaker7965e0a2014-02-14 13:24:29 -08002689 return false;
2690 }
Robert Greenwalt6cac0742011-06-21 17:26:14 -07002691
The Android Open Source Project28527d22009-03-03 19:31:44 -08002692 if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
Robert Greenwalt7fa3bdb2011-12-13 15:26:02 -08002693 if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
The Android Open Source Project28527d22009-03-03 19:31:44 -08002694 return false;
2695 }
Robert Greenwaltae5370c2014-06-03 17:22:11 -07002696
2697 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2698 if (nai == null) {
Chalard Jean46bfbf02022-02-02 00:56:25 +09002699 if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
Robert Greenwaltae5370c2014-06-03 17:22:11 -07002700 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
2701 } else {
2702 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
2703 }
2704 return false;
Ken Mixter0c6544b2013-11-07 22:08:24 -08002705 }
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002706
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002707 DetailedState netState;
2708 synchronized (nai) {
2709 netState = nai.networkInfo.getDetailedState();
2710 }
Robert Greenwaltae5370c2014-06-03 17:22:11 -07002711
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002712 if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
Robert Greenwalt78f28112011-08-02 17:18:41 -07002713 if (VDBG) {
Wink Saville32506bc2013-06-29 21:10:57 -07002714 log("requestRouteToHostAddress on down network "
2715 + "(" + networkType + ") - dropped"
Robert Greenwaltae5370c2014-06-03 17:22:11 -07002716 + " netState=" + netState);
Robert Greenwalt4666ed02009-09-10 15:06:20 -07002717 }
2718 return false;
The Android Open Source Project28527d22009-03-03 19:31:44 -08002719 }
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002720
Lorenzo Colittif61ca942020-12-15 11:02:22 +09002721 final int uid = mDeps.getCallingUid();
Robert Greenwalt7fa3bdb2011-12-13 15:26:02 -08002722 final long token = Binder.clearCallingIdentity();
Robert Greenwalta7dfbd32010-06-15 15:43:39 -07002723 try {
Paul Jensen65743a22014-07-11 08:17:29 -04002724 LinkProperties lp;
2725 int netId;
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002726 synchronized (nai) {
2727 lp = nai.linkProperties;
Serik Beketayevec8ad212020-12-07 22:43:07 -08002728 netId = nai.network.getNetId();
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07002729 }
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002730 boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
Lorenzo Colittia2e1fe82021-04-10 01:01:43 +09002731 if (DBG) {
2732 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok);
2733 }
Wink Saville32506bc2013-06-29 21:10:57 -07002734 return ok;
Robert Greenwalt7fa3bdb2011-12-13 15:26:02 -08002735 } finally {
2736 Binder.restoreCallingIdentity(token);
2737 }
Irfan Sheriff7f132d92010-06-09 15:39:36 -07002738 }
2739
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002740 private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
Lorenzo Colittie43b6c42013-03-15 13:58:38 +09002741 RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
Robert Greenwalt98107422011-07-22 11:55:33 -07002742 if (bestRoute == null) {
Lorenzo Colittie43b6c42013-03-15 13:58:38 +09002743 bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
Robert Greenwalt98107422011-07-22 11:55:33 -07002744 } else {
Lorenzo Colittie43b6c42013-03-15 13:58:38 +09002745 String iface = bestRoute.getInterface();
Robert Greenwalt98107422011-07-22 11:55:33 -07002746 if (bestRoute.getGateway().equals(addr)) {
2747 // if there is no better route, add the implied hostroute for our gateway
Lorenzo Colitti7a43b0f2013-03-08 12:30:44 -08002748 bestRoute = RouteInfo.makeHostRoute(addr, iface);
Robert Greenwalt98107422011-07-22 11:55:33 -07002749 } else {
2750 // if we will connect to this through another route, add a direct route
2751 // to it's gateway
Lorenzo Colitti7a43b0f2013-03-08 12:30:44 -08002752 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
Robert Greenwalt98107422011-07-22 11:55:33 -07002753 }
2754 }
Lorenzo Colitti4e69f082015-09-04 13:12:42 +09002755 if (DBG) log("Adding legacy route " + bestRoute +
2756 " for UID/PID " + uid + "/" + Binder.getCallingPid());
Chiachang Wang6f952792020-11-06 14:48:30 +08002757
2758 final String dst = bestRoute.getDestinationLinkAddress().toString();
2759 final String nextHop = bestRoute.hasGateway()
2760 ? bestRoute.getGateway().getHostAddress() : "";
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002761 try {
Chiachang Wang6f952792020-11-06 14:48:30 +08002762 mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
2763 } catch (RemoteException | ServiceSpecificException e) {
Sreeram Ramachandranc06ec732014-07-19 23:21:46 -07002764 if (DBG) loge("Exception trying to add a route: " + e);
Robert Greenwalt7fa3bdb2011-12-13 15:26:02 -08002765 return false;
2766 }
Robert Greenwalte8d2a4a2011-07-14 14:28:05 -07002767 return true;
The Android Open Source Project28527d22009-03-03 19:31:44 -08002768 }
2769
paulhu7c0a2e62021-01-08 00:51:49 +08002770 class DnsResolverUnsolicitedEventCallback extends
2771 IDnsResolverUnsolicitedEventListener.Stub {
dalyk1720e542018-03-05 12:42:22 -05002772 @Override
paulhu7c0a2e62021-01-08 00:51:49 +08002773 public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) {
dalyk1720e542018-03-05 12:42:22 -05002774 try {
2775 mHandler.sendMessage(mHandler.obtainMessage(
2776 EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
paulhu7c0a2e62021-01-08 00:51:49 +08002777 new PrivateDnsValidationUpdate(event.netId,
2778 InetAddresses.parseNumericAddress(event.ipAddress),
2779 event.hostname, event.validation)));
dalyk1720e542018-03-05 12:42:22 -05002780 } catch (IllegalArgumentException e) {
2781 loge("Error parsing ip address in validation event");
2782 }
2783 }
Chiachang Wang686e7c02018-11-27 18:00:05 +08002784
2785 @Override
paulhu7c0a2e62021-01-08 00:51:49 +08002786 public void onDnsHealthEvent(final DnsHealthEventParcel event) {
2787 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId);
Chiachang Wang686e7c02018-11-27 18:00:05 +08002788 // Netd event only allow registrants from system. Each NetworkMonitor thread is under
2789 // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
2790 // event callback for certain nai. e.g. cellular. Register here to pass to
2791 // NetworkMonitor instead.
Chalard Jean46bfbf02022-02-02 00:56:25 +09002792 // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allows one
Remi NGUYEN VAN6bf8f0f2019-02-04 10:25:11 +09002793 // callback from each caller type. Need to re-factor NetdEventListenerService to allow
2794 // multiple NetworkMonitor registrants.
Chalard Jean5b409c72021-02-04 13:12:59 +09002795 if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
paulhu7c0a2e62021-01-08 00:51:49 +08002796 nai.networkMonitor().notifyDnsResponse(event.healthResult);
Chiachang Wang686e7c02018-11-27 18:00:05 +08002797 }
2798 }
Lorenzo Colittif7e17392019-01-08 10:04:25 +09002799
2800 @Override
paulhu7c0a2e62021-01-08 00:51:49 +08002801 public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) {
2802 mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation,
2803 event.prefixAddress, event.prefixLength));
Lorenzo Colittif7e17392019-01-08 10:04:25 +09002804 }
dalyk1720e542018-03-05 12:42:22 -05002805
Lorenzo Colitti5cefdf22021-01-07 17:16:24 +09002806 @Override
paulhu7c0a2e62021-01-08 00:51:49 +08002807 public int getInterfaceVersion() {
Lorenzo Colitti5cefdf22021-01-07 17:16:24 +09002808 return this.VERSION;
2809 }
2810
2811 @Override
2812 public String getInterfaceHash() {
2813 return this.HASH;
2814 }
paulhu7c0a2e62021-01-08 00:51:49 +08002815 }
Lorenzo Colitti5cefdf22021-01-07 17:16:24 +09002816
2817 @VisibleForTesting
paulhu7c0a2e62021-01-08 00:51:49 +08002818 protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback =
2819 new DnsResolverUnsolicitedEventCallback();
Lorenzo Colitti5cefdf22021-01-07 17:16:24 +09002820
paulhu7c0a2e62021-01-08 00:51:49 +08002821 private void registerDnsResolverUnsolicitedEventListener() {
dalyk1720e542018-03-05 12:42:22 -05002822 try {
paulhu7c0a2e62021-01-08 00:51:49 +08002823 mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback);
dalyk1720e542018-03-05 12:42:22 -05002824 } catch (Exception e) {
paulhu7c0a2e62021-01-08 00:51:49 +08002825 loge("Error registering DnsResolver unsolicited event callback: " + e);
dalyk1720e542018-03-05 12:42:22 -05002826 }
2827 }
2828
Sudheer Shanka9967d462021-03-18 19:09:25 +00002829 private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002830 @Override
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09002831 public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
Sudheer Shanka9967d462021-03-18 19:09:25 +00002832 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
2833 uid, blockedReasons));
Jeff Sharkeyb1b6ccd2012-02-07 12:05:43 -08002834 }
Jeff Sharkey921ebf22011-05-19 17:12:49 -07002835 };
2836
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09002837 private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
Sudheer Shanka9967d462021-03-18 19:09:25 +00002838 maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09002839 setUidBlockedReasons(uid, blockedReasons);
junyulaif2c67e42018-08-07 19:50:45 +08002840 }
2841
Paul Jensen83f5d572014-08-29 09:54:01 -04002842 private void enforceInternetPermission() {
2843 mContext.enforceCallingOrSelfPermission(
2844 android.Manifest.permission.INTERNET,
2845 "ConnectivityService");
2846 }
2847
The Android Open Source Project28527d22009-03-03 19:31:44 -08002848 private void enforceAccessPermission() {
Robert Greenwalt0659da32009-07-16 17:21:39 -07002849 mContext.enforceCallingOrSelfPermission(
2850 android.Manifest.permission.ACCESS_NETWORK_STATE,
2851 "ConnectivityService");
The Android Open Source Project28527d22009-03-03 19:31:44 -08002852 }
2853
lucaslinc582d502022-01-27 09:07:00 +08002854 private boolean checkAccessPermission(int pid, int uid) {
2855 return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid)
2856 == PERMISSION_GRANTED;
2857 }
2858
paulhua6ee2122021-02-22 15:40:43 +08002859 /**
2860 * Performs a strict and comprehensive check of whether a calling package is allowed to
2861 * change the state of network, as the condition differs for pre-M, M+, and
2862 * privileged/preinstalled apps. The caller is expected to have either the
2863 * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
2864 * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
2865 * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
2866 * permission and cannot be revoked. See http://b/23597341
2867 *
2868 * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
2869 * of this app will be updated to the current time.
2870 */
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07002871 private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
paulhua6ee2122021-02-22 15:40:43 +08002872 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
2873 == PackageManager.PERMISSION_GRANTED) {
2874 return;
2875 }
2876
2877 if (callingPkg == null) {
2878 throw new SecurityException("Calling package name is null.");
2879 }
2880
2881 final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
2882 final int uid = mDeps.getCallingUid();
2883 final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
2884 callingPkg, callingAttributionTag, null /* message */);
2885
2886 if (mode == AppOpsManager.MODE_ALLOWED) {
2887 return;
2888 }
2889
2890 if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
2891 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
2892 return;
2893 }
2894
2895 throw new SecurityException(callingPkg + " was not granted either of these permissions:"
2896 + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
2897 + android.Manifest.permission.WRITE_SETTINGS + ".");
The Android Open Source Project28527d22009-03-03 19:31:44 -08002898 }
2899
Charles He9369e612017-05-15 17:07:18 +01002900 private void enforceSettingsPermission() {
paulhu3ffffe72021-09-16 10:15:22 +08002901 enforceAnyPermissionOf(mContext,
Charles He9369e612017-05-15 17:07:18 +01002902 android.Manifest.permission.NETWORK_SETTINGS,
Remi NGUYEN VAN097a5972019-01-31 16:42:12 +09002903 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Charles He9369e612017-05-15 17:07:18 +01002904 }
2905
Quang Luong98858d62023-02-11 00:25:24 +00002906 private void enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission() {
Junyu Laiaa4ad8c2022-10-28 15:42:00 +08002907 enforceAnyPermissionOf(mContext,
2908 android.Manifest.permission.NETWORK_SETTINGS,
Quang Luong98858d62023-02-11 00:25:24 +00002909 android.Manifest.permission.NETWORK_SETUP_WIZARD,
Junyu Laiaa4ad8c2022-10-28 15:42:00 +08002910 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
2911 Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS);
2912 }
2913
paulhu8e96a752019-08-12 16:25:11 +08002914 private void enforceNetworkFactoryPermission() {
Lorenzo Colittid12af7e2022-04-06 09:56:22 +09002915 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
Andrew Cheng2ae5c732022-04-18 17:21:57 -07002916 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
paulhu3ffffe72021-09-16 10:15:22 +08002917 enforceAnyPermissionOf(mContext,
paulhu8e96a752019-08-12 16:25:11 +08002918 android.Manifest.permission.NETWORK_FACTORY,
paulhub6ba8e82020-03-04 09:43:41 +08002919 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
paulhu8e96a752019-08-12 16:25:11 +08002920 }
2921
Aaron Huangebbfd3c2020-04-14 13:43:49 +08002922 private void enforceNetworkFactoryOrSettingsPermission() {
Lorenzo Colittid12af7e2022-04-06 09:56:22 +09002923 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
Andrew Cheng2ae5c732022-04-18 17:21:57 -07002924 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
paulhu3ffffe72021-09-16 10:15:22 +08002925 enforceAnyPermissionOf(mContext,
Aaron Huangebbfd3c2020-04-14 13:43:49 +08002926 android.Manifest.permission.NETWORK_SETTINGS,
2927 android.Manifest.permission.NETWORK_FACTORY,
2928 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2929 }
2930
2931 private void enforceNetworkFactoryOrTestNetworksPermission() {
Lorenzo Colittid12af7e2022-04-06 09:56:22 +09002932 // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
Andrew Cheng2ae5c732022-04-18 17:21:57 -07002933 if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
paulhu3ffffe72021-09-16 10:15:22 +08002934 enforceAnyPermissionOf(mContext,
Aaron Huangebbfd3c2020-04-14 13:43:49 +08002935 android.Manifest.permission.MANAGE_TEST_NETWORKS,
2936 android.Manifest.permission.NETWORK_FACTORY,
2937 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
2938 }
2939
lucaslin69e1aa92022-03-22 18:15:09 +08002940 private boolean checkNetworkFactoryOrSettingsPermission(int pid, int uid) {
2941 return PERMISSION_GRANTED == mContext.checkPermission(
2942 android.Manifest.permission.NETWORK_FACTORY, pid, uid)
2943 || PERMISSION_GRANTED == mContext.checkPermission(
2944 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
2945 || PERMISSION_GRANTED == mContext.checkPermission(
Lorenzo Colittid12af7e2022-04-06 09:56:22 +09002946 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid)
Andrew Cheng2ae5c732022-04-18 17:21:57 -07002947 || UserHandle.getAppId(uid) == Process.BLUETOOTH_UID;
lucaslin69e1aa92022-03-22 18:15:09 +08002948 }
2949
Chalard Jean9a396cc2018-02-21 18:43:54 +09002950 private boolean checkSettingsPermission() {
paulhu3ffffe72021-09-16 10:15:22 +08002951 return PermissionUtils.checkAnyPermissionOf(mContext,
Remi NGUYEN VAN097a5972019-01-31 16:42:12 +09002952 android.Manifest.permission.NETWORK_SETTINGS,
2953 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Chalard Jean9a396cc2018-02-21 18:43:54 +09002954 }
2955
2956 private boolean checkSettingsPermission(int pid, int uid) {
2957 return PERMISSION_GRANTED == mContext.checkPermission(
Remi NGUYEN VAN097a5972019-01-31 16:42:12 +09002958 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
2959 || PERMISSION_GRANTED == mContext.checkPermission(
2960 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
Chalard Jean9a396cc2018-02-21 18:43:54 +09002961 }
2962
paulhu8e96a752019-08-12 16:25:11 +08002963 private void enforceNetworkStackOrSettingsPermission() {
paulhu3ffffe72021-09-16 10:15:22 +08002964 enforceNetworkStackPermissionOr(mContext,
2965 android.Manifest.permission.NETWORK_SETTINGS);
paulhu8e96a752019-08-12 16:25:11 +08002966 }
2967
Lorenzo Colittic7da00d2018-10-09 18:55:11 +09002968 private void enforceNetworkStackSettingsOrSetup() {
paulhu3ffffe72021-09-16 10:15:22 +08002969 enforceNetworkStackPermissionOr(mContext,
Remi NGUYEN VAN097a5972019-01-31 16:42:12 +09002970 android.Manifest.permission.NETWORK_SETTINGS,
paulhu3ffffe72021-09-16 10:15:22 +08002971 android.Manifest.permission.NETWORK_SETUP_WIZARD);
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00002972 }
2973
Edward Savage-Jonesd4723692019-11-26 13:18:08 +01002974 private void enforceAirplaneModePermission() {
paulhu3ffffe72021-09-16 10:15:22 +08002975 enforceNetworkStackPermissionOr(mContext,
Edward Savage-Jonesd4723692019-11-26 13:18:08 +01002976 android.Manifest.permission.NETWORK_AIRPLANE_MODE,
2977 android.Manifest.permission.NETWORK_SETTINGS,
paulhu3ffffe72021-09-16 10:15:22 +08002978 android.Manifest.permission.NETWORK_SETUP_WIZARD);
Edward Savage-Jonesd4723692019-11-26 13:18:08 +01002979 }
2980
James Mattis8378aec2021-01-26 14:05:36 -08002981 private void enforceOemNetworkPreferencesPermission() {
2982 mContext.enforceCallingOrSelfPermission(
2983 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
2984 "ConnectivityService");
2985 }
2986
James Mattisfa270db2021-05-31 17:11:10 -07002987 private void enforceManageTestNetworksPermission() {
2988 mContext.enforceCallingOrSelfPermission(
2989 android.Manifest.permission.MANAGE_TEST_NETWORKS,
2990 "ConnectivityService");
2991 }
2992
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -07002993 private boolean checkNetworkStackPermission() {
paulhu3ffffe72021-09-16 10:15:22 +08002994 return PermissionUtils.checkAnyPermissionOf(mContext,
Remi NGUYEN VAN097a5972019-01-31 16:42:12 +09002995 android.Manifest.permission.NETWORK_STACK,
2996 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -07002997 }
2998
Cody Kesting83bb5fa2020-01-05 14:06:39 -08002999 private boolean checkNetworkStackPermission(int pid, int uid) {
Junyu Lai4c6fe232023-04-11 11:33:46 +08003000 return checkAnyPermissionOf(mContext, pid, uid,
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003001 android.Manifest.permission.NETWORK_STACK,
3002 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3003 }
3004
paulhu1a407652019-03-22 16:35:06 +08003005 private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
Junyu Lai4c6fe232023-04-11 11:33:46 +08003006 return checkAnyPermissionOf(mContext, pid, uid,
paulhu1a407652019-03-22 16:35:06 +08003007 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
Chalard Jean6b59b8f2020-04-13 21:54:58 +09003008 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
3009 android.Manifest.permission.NETWORK_SETTINGS);
paulhu1a407652019-03-22 16:35:06 +08003010 }
3011
Paul Hu8fc2a552022-05-04 18:44:42 +08003012 private boolean checkConnectivityRestrictedNetworksPermission(int callingUid,
3013 boolean checkUidsAllowedList) {
3014 if (PermissionUtils.checkAnyPermissionOf(mContext,
3015 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)) {
3016 return true;
3017 }
3018
3019 // fallback to ConnectivityInternalPermission
3020 // TODO: Remove this fallback check after all apps have declared
3021 // CONNECTIVITY_USE_RESTRICTED_NETWORKS.
3022 if (PermissionUtils.checkAnyPermissionOf(mContext,
3023 android.Manifest.permission.CONNECTIVITY_INTERNAL)) {
3024 return true;
3025 }
3026
3027 // Check whether uid is in allowed on restricted networks list.
3028 if (checkUidsAllowedList
3029 && mPermissionMonitor.isUidAllowedOnRestrictedNetworks(callingUid)) {
3030 return true;
3031 }
3032 return false;
3033 }
3034
3035 private void enforceConnectivityRestrictedNetworksPermission(boolean checkUidsAllowedList) {
3036 final int callingUid = mDeps.getCallingUid();
3037 if (!checkConnectivityRestrictedNetworksPermission(callingUid, checkUidsAllowedList)) {
3038 throw new SecurityException("ConnectivityService: user " + callingUid
3039 + " has no permission to access restricted network.");
3040 }
Hugo Benichibd0cc762016-07-19 15:59:27 +09003041 }
3042
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09003043 private void enforceKeepalivePermission() {
chiachangwang9ef4ffe2023-01-18 01:19:27 +00003044 mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09003045 }
3046
Roshan Pius98f59ec2021-02-23 08:47:39 -08003047 private boolean checkLocalMacAddressPermission(int pid, int uid) {
3048 return PERMISSION_GRANTED == mContext.checkPermission(
3049 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
3050 }
3051
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09003052 private void sendConnectedBroadcast(NetworkInfo info) {
Jeff Sharkey971cd162011-08-29 16:02:57 -07003053 sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
Robert Greenwaltd3401f92010-09-15 17:36:33 -07003054 }
3055
3056 private void sendInetConditionBroadcast(NetworkInfo info) {
3057 sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
3058 }
3059
Wink Saville4f0de1e2011-08-04 15:01:58 -07003060 private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
Robert Greenwaltd3401f92010-09-15 17:36:33 -07003061 Intent intent = new Intent(bcastType);
Irfan Sheriff32bed2c2012-09-20 09:32:41 -07003062 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
Jeff Sharkey47905d12012-08-06 11:41:50 -07003063 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
The Android Open Source Project28527d22009-03-03 19:31:44 -08003064 if (info.isFailover()) {
3065 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
3066 info.setFailover(false);
3067 }
3068 if (info.getReason() != null) {
3069 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
3070 }
3071 if (info.getExtraInfo() != null) {
Robert Greenwalt0659da32009-07-16 17:21:39 -07003072 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
3073 info.getExtraInfo());
The Android Open Source Project28527d22009-03-03 19:31:44 -08003074 }
Robert Greenwalt986c7412010-09-08 15:24:47 -07003075 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
Wink Saville4f0de1e2011-08-04 15:01:58 -07003076 return intent;
3077 }
3078
3079 private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
3080 sendStickyBroadcast(makeGeneralIntent(info, bcastType));
3081 }
3082
Michael Groover73f69482023-01-27 11:01:25 -06003083 // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
3084 @SuppressLint("NewApi")
Chiachang Wang3bc52762021-11-25 14:17:57 +08003085 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
3086 @TargetApi(Build.VERSION_CODES.S)
Mike Lockwoodfde2b762009-08-14 14:18:49 -04003087 private void sendStickyBroadcast(Intent intent) {
Hugo Benichie5220992017-04-26 14:53:28 +09003088 synchronized (this) {
Chalard Jean09335372018-06-08 14:24:49 +09003089 if (!mSystemReady
3090 && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Dianne Hackborna417ff82009-12-08 19:45:14 -08003091 mInitialBroadcast = new Intent(intent);
Mike Lockwoodfde2b762009-08-14 14:18:49 -04003092 }
Dianne Hackborna417ff82009-12-08 19:45:14 -08003093 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Lorenzo Colittiebf757d2016-04-08 23:09:09 +09003094 if (VDBG) {
Jeff Sharkey971cd162011-08-29 16:02:57 -07003095 log("sendStickyBroadcast: action=" + intent.getAction());
Wink Saville4f0de1e2011-08-04 15:01:58 -07003096 }
3097
Dianne Hackborn66dd0332015-12-09 17:22:26 -08003098 Bundle options = null;
Dianne Hackborne588ca12012-09-04 18:48:37 -07003099 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn37e2d0e2014-12-04 17:46:42 -08003100 if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
Robert Greenwalt6803efe2015-09-01 08:23:04 -07003101 final NetworkInfo ni = intent.getParcelableExtra(
3102 ConnectivityManager.EXTRA_NETWORK_INFO);
paulhu27ca4492020-02-03 19:52:43 +08003103 final BroadcastOptions opts = BroadcastOptions.makeBasic();
3104 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
Sudheer Shanka2453a3a2022-11-29 15:15:50 -08003105 applyMostRecentPolicyForConnectivityAction(opts, ni);
paulhu27ca4492020-02-03 19:52:43 +08003106 options = opts.toBundle();
Chad Brubakercaced412018-03-08 10:37:09 -08003107 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Dianne Hackborn37e2d0e2014-12-04 17:46:42 -08003108 }
Dianne Hackborne588ca12012-09-04 18:48:37 -07003109 try {
Paul Hu96f1cbb2021-01-26 02:53:06 +00003110 mUserAllContext.sendStickyBroadcast(intent, options);
Dianne Hackborne588ca12012-09-04 18:48:37 -07003111 } finally {
3112 Binder.restoreCallingIdentity(ident);
3113 }
Mike Lockwoodfde2b762009-08-14 14:18:49 -04003114 }
3115 }
3116
Sudheer Shanka2453a3a2022-11-29 15:15:50 -08003117 private void applyMostRecentPolicyForConnectivityAction(BroadcastOptions options,
3118 NetworkInfo info) {
3119 // Delivery group policy APIs are only available on U+.
3120 if (!SdkLevel.isAtLeastU()) return;
3121
3122 final BroadcastOptionsShim optsShim = mDeps.makeBroadcastOptionsShim(options);
3123 try {
3124 // This allows us to discard older broadcasts still waiting to be delivered
3125 // which have the same namespace and key.
3126 optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT);
3127 optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION,
3128 createDeliveryGroupKeyForConnectivityAction(info));
Jeff Sharkey4ffd34c2023-03-06 14:10:30 -07003129 optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE);
Sudheer Shanka2453a3a2022-11-29 15:15:50 -08003130 } catch (UnsupportedApiLevelException e) {
3131 Log.wtf(TAG, "Using unsupported API" + e);
3132 }
3133 }
3134
3135 @VisibleForTesting
3136 static String createDeliveryGroupKeyForConnectivityAction(NetworkInfo info) {
3137 final StringBuilder sb = new StringBuilder();
3138 sb.append(info.getType()).append(DELIVERY_GROUP_KEY_DELIMITER);
3139 sb.append(info.getSubtype()).append(DELIVERY_GROUP_KEY_DELIMITER);
3140 sb.append(info.getExtraInfo());
3141 return sb.toString();
3142 }
3143
Remi NGUYEN VAN317b2d22019-06-20 18:29:36 +09003144 /**
Aaron Huang96011892020-06-27 07:18:23 +08003145 * Called by SystemServer through ConnectivityManager when the system is ready.
3146 */
3147 @Override
3148 public void systemReady() {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09003149 if (mDeps.getCallingUid() != Process.SYSTEM_UID) {
Aaron Huang96011892020-06-27 07:18:23 +08003150 throw new SecurityException("Calling Uid is not system uid.");
3151 }
3152 systemReadyInternal();
3153 }
3154
3155 /**
3156 * Called when ConnectivityService can initialize remaining components.
Remi NGUYEN VAN317b2d22019-06-20 18:29:36 +09003157 */
3158 @VisibleForTesting
Aaron Huang96011892020-06-27 07:18:23 +08003159 public void systemReadyInternal() {
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +09003160 // Load flags after PackageManager is ready to query module version
3161 mFlags.loadFlags(mDeps, mContext);
3162
Aaron Huang9a57acf2020-12-08 10:03:29 +08003163 // Since mApps in PermissionMonitor needs to be populated first to ensure that
3164 // listening network request which is sent by MultipathPolicyTracker won't be added
3165 // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
3166 // be called after PermissionMonitor#startMonitoring().
3167 // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
3168 // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
3169 // to ensure the tracking will be initialized correctly.
Paul Hu3c8c8102022-08-25 07:06:16 +00003170 final ConditionVariable startMonitoringDone = new ConditionVariable();
3171 mHandler.post(() -> {
3172 mPermissionMonitor.startMonitoring();
3173 startMonitoringDone.open();
3174 });
Chalard Jeane4f9bd92018-06-08 12:47:42 +09003175 mProxyTracker.loadGlobalProxy();
paulhu7c0a2e62021-01-08 00:51:49 +08003176 registerDnsResolverUnsolicitedEventListener();
Wink Saville9a1a7ef2013-08-29 08:55:16 -07003177
Hugo Benichie5220992017-04-26 14:53:28 +09003178 synchronized (this) {
Mike Lockwoodfde2b762009-08-14 14:18:49 -04003179 mSystemReady = true;
Dianne Hackborna417ff82009-12-08 19:45:14 -08003180 if (mInitialBroadcast != null) {
Dianne Hackborn22986892012-08-29 18:32:08 -07003181 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
Dianne Hackborna417ff82009-12-08 19:45:14 -08003182 mInitialBroadcast = null;
Mike Lockwoodfde2b762009-08-14 14:18:49 -04003183 }
3184 }
Jeff Sharkeyebcc7972012-08-25 00:05:46 -07003185
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07003186 // Create network requests for always-on networks.
3187 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
paulhu51f77dc2021-06-07 02:34:20 +00003188
3189 // Update mobile data preference if necessary.
Chalard Jean46bfbf02022-02-02 00:56:25 +09003190 // Note that updating can be skipped here if the list is empty only because no uid
3191 // rules are applied before system ready. Normally, the empty uid list means to clear
3192 // the uids rules on netd.
paulhu51f77dc2021-06-07 02:34:20 +00003193 if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) {
3194 updateMobileDataPreferredUids();
3195 }
Motomu Utsumi166f9662022-09-01 10:35:29 +09003196
3197 // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom
3198 if (SdkLevel.isAtLeastT()) {
3199 mBpfNetMaps.setPullAtomCallback(mContext);
3200 }
Paul Hu3c8c8102022-08-25 07:06:16 +00003201 // Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't
3202 // have permission problem. While CV#block() is unbounded in time and can in principle block
3203 // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which
3204 // could have blocked forever too.
3205 startMonitoringDone.block();
The Android Open Source Project28527d22009-03-03 19:31:44 -08003206 }
3207
The Android Open Source Project28527d22009-03-03 19:31:44 -08003208 /**
Chiachang Wang4068dcb2020-12-15 15:56:00 +08003209 * Start listening for default data network activity state changes.
3210 */
3211 @Override
3212 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
lucaslin1193a5d2021-01-21 02:04:15 +08003213 mNetworkActivityTracker.registerNetworkActivityListener(l);
Chiachang Wang4068dcb2020-12-15 15:56:00 +08003214 }
3215
3216 /**
3217 * Stop listening for default data network activity state changes.
3218 */
3219 @Override
3220 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
lucaslin1193a5d2021-01-21 02:04:15 +08003221 mNetworkActivityTracker.unregisterNetworkActivityListener(l);
Chiachang Wang4068dcb2020-12-15 15:56:00 +08003222 }
3223
3224 /**
3225 * Check whether the default network radio is currently active.
3226 */
3227 @Override
3228 public boolean isDefaultNetworkActive() {
lucaslin1193a5d2021-01-21 02:04:15 +08003229 return mNetworkActivityTracker.isDefaultNetworkActive();
Chiachang Wang4068dcb2020-12-15 15:56:00 +08003230 }
3231
3232 /**
Chalard Jean9dd11612018-06-04 16:52:49 +09003233 * Reads the network specific MTU size from resources.
sy.yun4aa73922013-09-02 05:24:09 +09003234 * and set it on it's iface.
3235 */
Junyu Lai970963e2022-10-25 15:46:47 +08003236 private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003237 final String iface = newLp.getInterfaceName();
3238 final int mtu = newLp.getMtu();
Hansen Kurli04252032022-12-07 11:21:49 +00003239 if (mtu == 0) {
Pierre Imai07c53a32016-02-08 16:01:40 +09003240 // Silently ignore unset MTU value.
3241 return;
3242 }
Hansen Kurli04252032022-12-07 11:21:49 +00003243 if (oldLp != null && newLp.isIdenticalMtu(oldLp)
3244 && TextUtils.equals(oldLp.getInterfaceName(), iface)) {
3245 if (VDBG) log("identical MTU and iface - not setting");
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003246 return;
3247 }
Hansen Kurli04252032022-12-07 11:21:49 +00003248 // Cannot set MTU without interface name
3249 if (TextUtils.isEmpty(iface)) {
3250 if (VDBG) log("Setting MTU size with null iface.");
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003251 return;
3252 }
sy.yun4aa73922013-09-02 05:24:09 +09003253
Hansen Kurli04252032022-12-07 11:21:49 +00003254 if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
3255 loge("Unexpected mtu value: " + mtu + ", " + iface);
w19976e714f1d2014-08-05 15:18:11 -07003256 return;
3257 }
3258
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003259 try {
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09003260 if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
Chiachang Wang6d5c0e72020-10-26 17:13:09 +08003261 mNetd.interfaceSetMtu(iface, mtu);
3262 } catch (RemoteException | ServiceSpecificException e) {
Aaron Huang6616df32020-10-30 22:04:25 +08003263 loge("exception in interfaceSetMtu()" + e);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003264 }
3265 }
Irfan Sheriff7f132d92010-06-09 15:39:36 -07003266
Chenbo Feng15416292018-11-08 17:36:21 -08003267 @VisibleForTesting
3268 protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
Paul Jensenbb910e92015-05-13 14:05:12 -04003269
Junyu Lai970963e2022-10-25 15:46:47 +08003270 private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) {
Robert Greenwaltdebf0e02014-08-06 12:00:25 -07003271 String[] values = null;
3272 if (tcpBufferSizes != null) {
3273 values = tcpBufferSizes.split(",");
3274 }
3275
3276 if (values == null || values.length != 6) {
Robert Greenwalt419e1b42014-08-27 14:34:02 -07003277 if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
Robert Greenwaltdebf0e02014-08-06 12:00:25 -07003278 tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
3279 values = tcpBufferSizes.split(",");
3280 }
3281
3282 if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
3283
3284 try {
Aaron Huang6616df32020-10-30 22:04:25 +08003285 if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes);
Robert Greenwaltdebf0e02014-08-06 12:00:25 -07003286
Chenbo Feng15416292018-11-08 17:36:21 -08003287 String rmemValues = String.join(" ", values[0], values[1], values[2]);
3288 String wmemValues = String.join(" ", values[3], values[4], values[5]);
3289 mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
Robert Greenwaltdebf0e02014-08-06 12:00:25 -07003290 mCurrentTcpBufferSizes = tcpBufferSizes;
Chenbo Feng15416292018-11-08 17:36:21 -08003291 } catch (RemoteException | ServiceSpecificException e) {
Robert Greenwaltdebf0e02014-08-06 12:00:25 -07003292 loge("Can't set TCP buffer sizes:" + e);
Irfan Sheriff7f132d92010-06-09 15:39:36 -07003293 }
3294 }
3295
Robert Greenwalt3dc73e52014-05-15 18:07:26 -07003296 @Override
3297 public int getRestoreDefaultNetworkDelay(int networkType) {
Lorenzo Colitticd447b22017-03-21 18:54:11 +09003298 String restoreDefaultNetworkDelayStr = mSystemProperties.get(
Robert Greenwalt2034b912009-08-12 16:08:25 -07003299 NETWORK_RESTORE_DELAY_PROP_NAME);
3300 if(restoreDefaultNetworkDelayStr != null &&
3301 restoreDefaultNetworkDelayStr.length() != 0) {
3302 try {
Narayan Kamath46f0dd62016-04-15 18:32:45 +01003303 return Integer.parseInt(restoreDefaultNetworkDelayStr);
Robert Greenwalt2034b912009-08-12 16:08:25 -07003304 } catch (NumberFormatException e) {
3305 }
The Android Open Source Project28527d22009-03-03 19:31:44 -08003306 }
Robert Greenwalt20f819c2011-05-03 19:02:44 -07003307 // if the system property isn't set, use the value for the apn type
3308 int ret = RESTORE_DEFAULT_NETWORK_DELAY;
3309
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09003310 if (mLegacyTypeTracker.isTypeSupported(networkType)) {
3311 ret = mLegacyTypeTracker.getRestoreTimerForType(networkType);
Robert Greenwalt20f819c2011-05-03 19:02:44 -07003312 }
3313 return ret;
The Android Open Source Project28527d22009-03-03 19:31:44 -08003314 }
3315
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003316 private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
Chalard Jean46bfbf02022-02-02 00:56:25 +09003317 final List<NetworkDiagnostics> netDiags = new ArrayList<>();
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003318 final long DIAG_TIME_MS = 5000;
Hugo Benichia480ba52018-09-03 08:19:02 +09003319 for (NetworkAgentInfo nai : networksSortedById()) {
Mike Yu6cad4b12019-07-05 11:51:34 +08003320 PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network);
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003321 // Start gathering diagnostic information.
3322 netDiags.add(new NetworkDiagnostics(
3323 nai.network,
3324 new LinkProperties(nai.linkProperties), // Must be a copy.
Mike Yu6cad4b12019-07-05 11:51:34 +08003325 privateDnsCfg,
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003326 DIAG_TIME_MS));
3327 }
3328
3329 for (NetworkDiagnostics netDiag : netDiags) {
3330 pw.println();
3331 netDiag.waitForMeasurements();
3332 netDiag.dump(pw);
3333 }
3334 }
3335
The Android Open Source Project28527d22009-03-03 19:31:44 -08003336 @Override
Chalard Jeanfbab6d42019-09-26 18:03:47 +09003337 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
3338 @Nullable String[] args) {
Chiachang Wanga101f852021-04-19 10:59:24 +08003339 if (!checkDumpPermission(mContext, TAG, writer)) return;
3340
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08003341 mPriorityDumper.dump(fd, writer, args);
Vishnu Nair0701e422017-10-26 10:08:50 -07003342 }
3343
lucaslin99473f62020-12-10 15:10:54 +08003344 private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
3345 if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
3346 != PackageManager.PERMISSION_GRANTED) {
3347 pw.println("Permission Denial: can't dump " + tag + " from from pid="
Lorenzo Colittif61ca942020-12-15 11:02:22 +09003348 + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid()
lucaslin99473f62020-12-10 15:10:54 +08003349 + " due to missing android.permission.DUMP permission");
3350 return false;
3351 } else {
3352 return true;
3353 }
3354 }
3355
Chiachang Wang96e1a0b2021-03-09 14:55:31 +08003356 private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003357 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003358
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09003359 if (CollectionUtils.contains(args, DIAG_ARG)) {
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003360 dumpNetworkDiagnostics(pw);
3361 return;
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09003362 } else if (CollectionUtils.contains(args, NETWORK_ARG)) {
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003363 dumpNetworks(pw);
3364 return;
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09003365 } else if (CollectionUtils.contains(args, REQUEST_ARG)) {
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003366 dumpNetworkRequests(pw);
3367 return;
Ken Chene6d511f2022-01-25 11:10:42 +08003368 } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) {
3369 boolean verbose = !CollectionUtils.contains(args, SHORT_ARG);
3370 dumpTrafficController(pw, fd, verbose);
3371 return;
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003372 }
Erik Kline9647f382015-06-05 17:47:34 +09003373
Junyu Lai0da479b2022-04-20 15:06:29 +08003374 pw.println("NetworkProviders for:");
3375 pw.increaseIndent();
Lorenzo Colittia86fae72020-01-10 00:40:28 +09003376 for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
Junyu Lai0da479b2022-04-20 15:06:29 +08003377 pw.println(npi.providerId + ": " + npi.name);
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07003378 }
Junyu Lai0da479b2022-04-20 15:06:29 +08003379 pw.decreaseIndent();
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07003380 pw.println();
3381
Chalard Jean5b409c72021-02-04 13:12:59 +09003382 final NetworkAgentInfo defaultNai = getDefaultNetwork();
Robert Greenwalta6d85c82014-05-13 15:36:27 -07003383 pw.print("Active default network: ");
Chalard Jean5b409c72021-02-04 13:12:59 +09003384 if (defaultNai == null) {
Robert Greenwalta6d85c82014-05-13 15:36:27 -07003385 pw.println("none");
3386 } else {
Chalard Jean5b409c72021-02-04 13:12:59 +09003387 pw.println(defaultNai.network.getNetId());
The Android Open Source Project28527d22009-03-03 19:31:44 -08003388 }
Dianne Hackborn5ac88162014-02-26 16:20:52 -08003389 pw.println();
3390
James Mattis8b298a02021-06-01 22:34:04 -07003391 pw.println("Current network preferences: ");
James Mattis45d81842021-01-10 14:24:24 -08003392 pw.increaseIndent();
James Mattis8b298a02021-06-01 22:34:04 -07003393 dumpNetworkPreferences(pw);
James Mattis45d81842021-01-10 14:24:24 -08003394 pw.decreaseIndent();
3395 pw.println();
3396
Robert Greenwalta6d85c82014-05-13 15:36:27 -07003397 pw.println("Current Networks:");
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003398 pw.increaseIndent();
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003399 dumpNetworks(pw);
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003400 pw.decreaseIndent();
Robert Greenwalta6d85c82014-05-13 15:36:27 -07003401 pw.println();
Robert Greenwalt3eeb6032009-12-21 18:24:07 -08003402
junyulaif2c67e42018-08-07 19:50:45 +08003403 pw.println("Status for known UIDs:");
3404 pw.increaseIndent();
Sudheer Shanka9967d462021-03-18 19:09:25 +00003405 final int size = mUidBlockedReasons.size();
junyulaif2c67e42018-08-07 19:50:45 +08003406 for (int i = 0; i < size; i++) {
3407 // Don't crash if the array is modified while dumping in bugreports.
3408 try {
Sudheer Shanka9967d462021-03-18 19:09:25 +00003409 final int uid = mUidBlockedReasons.keyAt(i);
3410 final int blockedReasons = mUidBlockedReasons.valueAt(i);
3411 pw.println("UID=" + uid + " blockedReasons="
Sudheer Shankaf0ffc772021-04-21 07:23:54 +00003412 + Integer.toHexString(blockedReasons));
junyulaif2c67e42018-08-07 19:50:45 +08003413 } catch (ArrayIndexOutOfBoundsException e) {
3414 pw.println(" ArrayIndexOutOfBoundsException");
3415 } catch (ConcurrentModificationException e) {
3416 pw.println(" ConcurrentModificationException");
3417 }
3418 }
3419 pw.println();
3420 pw.decreaseIndent();
3421
Robert Greenwalta6d85c82014-05-13 15:36:27 -07003422 pw.println("Network Requests:");
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003423 pw.increaseIndent();
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003424 dumpNetworkRequests(pw);
Jeff Sharkeycf6ffaf2012-09-14 13:47:51 -07003425 pw.decreaseIndent();
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003426 pw.println();
Robert Greenwalt8e87f122010-02-11 18:18:40 -08003427
Junyu Lai0da479b2022-04-20 15:06:29 +08003428 pw.println("Network Offers:");
3429 pw.increaseIndent();
3430 for (final NetworkOfferInfo offerInfo : mNetworkOffers) {
3431 pw.println(offerInfo.offer);
3432 }
3433 pw.decreaseIndent();
3434 pw.println();
3435
Robert Greenwalt94e22142014-07-30 16:31:24 -07003436 mLegacyTypeTracker.dump(pw);
Robert Greenwalt94e22142014-07-30 16:31:24 -07003437
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09003438 pw.println();
markchien5e866652019-09-30 14:40:57 +08003439 mKeepaliveTracker.dump(pw);
Robert Greenwalt0e80be12010-09-20 14:35:25 -07003440
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09003441 pw.println();
Lorenzo Colittia4e88082016-09-20 16:03:27 +09003442 dumpAvoidBadWifiSettings(pw);
Lorenzo Colitti1e01f082016-03-03 17:53:46 +09003443
Lorenzo Colitti389a8142018-01-24 17:35:07 +09003444 pw.println();
Lorenzo Colitti389a8142018-01-24 17:35:07 +09003445
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09003446 if (!CollectionUtils.contains(args, SHORT_ARG)) {
Robert Greenwalt27ff7742015-06-23 15:03:33 -07003447 pw.println();
Erik Klineedf878b2015-07-09 18:24:03 +09003448 pw.println("mNetworkRequestInfoLogs (most recent first):");
3449 pw.increaseIndent();
James Mattiscb1e0362021-04-06 17:07:42 -07003450 mNetworkRequestInfoLogs.reverseDump(pw);
Erik Klineedf878b2015-07-09 18:24:03 +09003451 pw.decreaseIndent();
Hugo Benichid159fdd2016-07-11 11:05:12 +09003452
3453 pw.println();
3454 pw.println("mNetworkInfoBlockingLogs (most recent first):");
3455 pw.increaseIndent();
James Mattiscb1e0362021-04-06 17:07:42 -07003456 mNetworkInfoBlockingLogs.reverseDump(pw);
Hugo Benichid159fdd2016-07-11 11:05:12 +09003457 pw.decreaseIndent();
Hugo Benichi47011212017-03-30 10:46:05 +09003458
3459 pw.println();
3460 pw.println("NetTransition WakeLock activity (most recent first):");
3461 pw.increaseIndent();
Hugo Benichi88f49ac2017-09-05 13:25:07 +09003462 pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
3463 pw.println("total releases: " + mTotalWakelockReleases);
3464 pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
3465 pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
3466 if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
3467 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
3468 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
3469 }
James Mattiscb1e0362021-04-06 17:07:42 -07003470 mWakelockLogs.reverseDump(pw);
Nathan Haroldb89cbfb2018-07-30 13:38:01 -07003471
3472 pw.println();
3473 pw.println("bandwidth update requests (by uid):");
3474 pw.increaseIndent();
3475 synchronized (mBandwidthRequests) {
3476 for (int i = 0; i < mBandwidthRequests.size(); i++) {
3477 pw.println("[" + mBandwidthRequests.keyAt(i)
3478 + "]: " + mBandwidthRequests.valueAt(i));
3479 }
3480 }
3481 pw.decreaseIndent();
James Mattiscb1e0362021-04-06 17:07:42 -07003482 pw.decreaseIndent();
Nathan Haroldb89cbfb2018-07-30 13:38:01 -07003483
James Mattiscb1e0362021-04-06 17:07:42 -07003484 pw.println();
3485 pw.println("mOemNetworkPreferencesLogs (most recent first):");
3486 pw.increaseIndent();
3487 mOemNetworkPreferencesLogs.reverseDump(pw);
Hugo Benichi47011212017-03-30 10:46:05 +09003488 pw.decreaseIndent();
Robert Greenwalt27ff7742015-06-23 15:03:33 -07003489 }
Remi NGUYEN VAN31c44d72019-02-18 11:20:28 +09003490
3491 pw.println();
Lorenzo Colittibad9d912019-04-12 10:48:06 +00003492
3493 pw.println();
3494 pw.println("Permission Monitor:");
3495 pw.increaseIndent();
3496 mPermissionMonitor.dump(pw);
3497 pw.decreaseIndent();
lucaslin012f7a12021-01-21 02:04:35 +08003498
3499 pw.println();
3500 pw.println("Legacy network activity:");
3501 pw.increaseIndent();
3502 mNetworkActivityTracker.dump(pw);
3503 pw.decreaseIndent();
The Android Open Source Project28527d22009-03-03 19:31:44 -08003504 }
3505
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003506 private void dumpNetworks(IndentingPrintWriter pw) {
3507 for (NetworkAgentInfo nai : networksSortedById()) {
3508 pw.println(nai.toString());
3509 pw.increaseIndent();
Hungming Chenc6e00ea2022-05-18 22:36:20 +08003510 pw.println("Nat464Xlat:");
3511 pw.increaseIndent();
3512 nai.dumpNat464Xlat(pw);
3513 pw.decreaseIndent();
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003514 pw.println(String.format(
3515 "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
3516 nai.numForegroundNetworkRequests(),
3517 nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
3518 nai.numBackgroundNetworkRequests(),
3519 nai.numNetworkRequests()));
3520 pw.increaseIndent();
3521 for (int i = 0; i < nai.numNetworkRequests(); i++) {
3522 pw.println(nai.requestAt(i).toString());
3523 }
3524 pw.decreaseIndent();
junyulai2b6f0c22021-02-03 20:15:30 +08003525 pw.println("Inactivity Timers:");
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003526 pw.increaseIndent();
junyulai2b6f0c22021-02-03 20:15:30 +08003527 nai.dumpInactivityTimers(pw);
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003528 pw.decreaseIndent();
3529 pw.decreaseIndent();
3530 }
3531 }
3532
James Mattis8b298a02021-06-01 22:34:04 -07003533 private void dumpNetworkPreferences(IndentingPrintWriter pw) {
3534 if (!mProfileNetworkPreferences.isEmpty()) {
3535 pw.println("Profile preferences:");
3536 pw.increaseIndent();
Chalard Jean0606fc82022-12-14 20:34:43 +09003537 pw.println(mProfileNetworkPreferences);
James Mattis8b298a02021-06-01 22:34:04 -07003538 pw.decreaseIndent();
James Mattis45d81842021-01-10 14:24:24 -08003539 }
James Mattis8b298a02021-06-01 22:34:04 -07003540 if (!mOemNetworkPreferences.isEmpty()) {
3541 pw.println("OEM preferences:");
3542 pw.increaseIndent();
3543 pw.println(mOemNetworkPreferences);
3544 pw.decreaseIndent();
3545 }
3546 if (!mMobileDataPreferredUids.isEmpty()) {
3547 pw.println("Mobile data preferred UIDs:");
3548 pw.increaseIndent();
3549 pw.println(mMobileDataPreferredUids);
3550 pw.decreaseIndent();
3551 }
James Mattis45d81842021-01-10 14:24:24 -08003552
James Mattis8b298a02021-06-01 22:34:04 -07003553 pw.println("Default requests:");
3554 pw.increaseIndent();
3555 dumpPerAppDefaultRequests(pw);
3556 pw.decreaseIndent();
3557 }
3558
3559 private void dumpPerAppDefaultRequests(IndentingPrintWriter pw) {
James Mattis45d81842021-01-10 14:24:24 -08003560 for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) {
3561 if (mDefaultRequest == defaultRequest) {
3562 continue;
3563 }
3564
James Mattis8b298a02021-06-01 22:34:04 -07003565 final NetworkAgentInfo satisfier = defaultRequest.getSatisfier();
3566 final String networkOutput;
3567 if (null == satisfier) {
3568 networkOutput = "null";
3569 } else if (mNoServiceNetwork.equals(satisfier)) {
3570 networkOutput = "no service network";
James Mattis45d81842021-01-10 14:24:24 -08003571 } else {
James Mattis8b298a02021-06-01 22:34:04 -07003572 networkOutput = String.valueOf(satisfier.network.netId);
James Mattis45d81842021-01-10 14:24:24 -08003573 }
James Mattis8b298a02021-06-01 22:34:04 -07003574 final String asUidString = (defaultRequest.mAsUid == defaultRequest.mUid)
3575 ? "" : " asUid: " + defaultRequest.mAsUid;
3576 final String requestInfo = "Request: [uid/pid:" + defaultRequest.mUid + "/"
3577 + defaultRequest.mPid + asUidString + "]";
3578 final String satisfierOutput = "Satisfier: [" + networkOutput + "]"
3579 + " Preference order: " + defaultRequest.mPreferenceOrder
3580 + " Tracked UIDs: " + defaultRequest.getUids();
3581 pw.println(requestInfo + " - " + satisfierOutput);
James Mattis45d81842021-01-10 14:24:24 -08003582 }
3583 }
3584
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003585 private void dumpNetworkRequests(IndentingPrintWriter pw) {
Chiachang Wangeb256742021-07-27 14:00:17 +08003586 NetworkRequestInfo[] infos = null;
3587 while (infos == null) {
3588 try {
3589 infos = requestsSortedById();
3590 } catch (ConcurrentModificationException e) {
3591 // mNetworkRequests should only be accessed from handler thread, except dump().
3592 // As dump() is never called in normal usage, it would be needlessly expensive
3593 // to lock the collection only for its benefit. Instead, retry getting the
3594 // requests if ConcurrentModificationException is thrown during dump().
3595 }
3596 }
3597 for (NetworkRequestInfo nri : infos) {
Hugo Benichi5df91ce2018-09-03 08:32:56 +09003598 pw.println(nri.toString());
3599 }
3600 }
3601
Ken Chene6d511f2022-01-25 11:10:42 +08003602 private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd,
3603 boolean verbose) {
3604 try {
Motomu Utsumi310850f2022-09-02 12:48:20 +09003605 mBpfNetMaps.dump(pw, fd, verbose);
Ken Chene6d511f2022-01-25 11:10:42 +08003606 } catch (ServiceSpecificException e) {
3607 pw.println(e.getMessage());
3608 } catch (IOException e) {
3609 loge("Dump BPF maps failed, " + e);
3610 }
3611 }
3612
Chalard Jean524f0b12021-10-25 21:11:56 +09003613 private void dumpAllRequestInfoLogsToLogcat() {
3614 try (PrintWriter logPw = new PrintWriter(new Writer() {
3615 @Override
3616 public void write(final char[] cbuf, final int off, final int len) {
3617 // This method is called with 0-length and 1-length arrays for empty strings
3618 // or strings containing only the DEL character.
3619 if (len <= 1) return;
3620 Log.e(TAG, new String(cbuf, off, len));
3621 }
3622 @Override public void flush() {}
3623 @Override public void close() {}
3624 })) {
3625 mNetworkRequestInfoLogs.dump(logPw);
3626 }
3627 }
3628
Hugo Benichia480ba52018-09-03 08:19:02 +09003629 /**
3630 * Return an array of all current NetworkAgentInfos sorted by network id.
3631 */
3632 private NetworkAgentInfo[] networksSortedById() {
3633 NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09003634 networks = mNetworkAgentInfos.toArray(networks);
Serik Beketayevec8ad212020-12-07 22:43:07 -08003635 Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId()));
Hugo Benichia480ba52018-09-03 08:19:02 +09003636 return networks;
3637 }
3638
3639 /**
3640 * Return an array of all current NetworkRequest sorted by request id.
3641 */
James Mattis258ea3c2020-11-15 15:04:40 -08003642 @VisibleForTesting
James Mattisa152f882020-11-20 16:08:10 -08003643 NetworkRequestInfo[] requestsSortedById() {
Hugo Benichia480ba52018-09-03 08:19:02 +09003644 NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
James Mattisa076c532020-12-02 14:12:41 -08003645 requests = getNrisFromGlobalRequests().toArray(requests);
James Mattis258ea3c2020-11-15 15:04:40 -08003646 // Sort the array based off the NRI containing the min requestId in its requests.
3647 Arrays.sort(requests,
3648 Comparator.comparingInt(nri -> Collections.min(nri.mRequests,
3649 Comparator.comparingInt(req -> req.requestId)).requestId
3650 )
3651 );
Hugo Benichia480ba52018-09-03 08:19:02 +09003652 return requests;
3653 }
3654
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003655 private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
Sreeram Ramachandran7c987162014-11-12 22:31:52 -08003656 final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
Robert Greenwalta6fd83d2014-08-19 18:58:04 -07003657 if (officialNai != null && officialNai.equals(nai)) return true;
3658 if (officialNai != null || VDBG) {
Hugo Benichi47011212017-03-30 10:46:05 +09003659 loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
Robert Greenwalta6fd83d2014-08-19 18:58:04 -07003660 " - " + nai);
3661 }
3662 return false;
3663 }
3664
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09003665 private boolean isDisconnectRequest(Message msg) {
3666 if (msg.what != NetworkAgent.EVENT_NETWORK_INFO_CHANGED) return false;
3667 final NetworkInfo info = (NetworkInfo) ((Pair) msg.obj).second;
3668 return info.getState() == NetworkInfo.State.DISCONNECTED;
3669 }
3670
Robert Greenwalt2034b912009-08-12 16:08:25 -07003671 // must be stateless - things change under us.
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07003672 private class NetworkStateTrackerHandler extends Handler {
3673 public NetworkStateTrackerHandler(Looper looper) {
Wink Saville775aad62010-09-02 19:23:52 -07003674 super(looper);
3675 }
3676
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003677 private void maybeHandleNetworkAgentMessage(Message msg) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09003678 final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
3679 final NetworkAgentInfo nai = arg.first;
3680 if (!mNetworkAgentInfos.contains(nai)) {
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003681 if (VDBG) {
Hugo Benichi47011212017-03-30 10:46:05 +09003682 log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003683 }
3684 return;
3685 }
3686
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09003687 // If the network has been destroyed, the only thing that it can do is disconnect.
Chalard Jean254bd162022-08-25 13:04:51 +09003688 if (nai.isDestroyed() && !isDisconnectRequest(msg)) {
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09003689 return;
3690 }
3691
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003692 switch (msg.what) {
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003693 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
Chalard Jean39b12d42022-02-27 12:08:49 +09003694 nai.setDeclaredCapabilities((NetworkCapabilities) arg.second);
3695 final NetworkCapabilities sanitized =
3696 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator);
Chalard Jeanda7fe572022-02-01 23:47:23 +09003697 maybeUpdateWifiRoamTimestamp(nai, sanitized);
Chalard Jeanaa5bc622022-02-26 21:34:48 +09003698 updateCapabilities(nai.getScore(), nai, sanitized);
Robert Greenwalt7e45d112014-04-11 15:53:27 -07003699 break;
3700 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003701 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09003702 LinkProperties newLp = (LinkProperties) arg.second;
Lorenzo Colitti18a58462020-04-16 01:52:40 +09003703 processLinkPropertiesFromAgent(nai, newLp);
3704 handleUpdateLinkProperties(nai, newLp);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003705 break;
3706 }
3707 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09003708 NetworkInfo info = (NetworkInfo) arg.second;
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003709 updateNetworkInfo(nai, info);
3710 break;
3711 }
Robert Greenwalt06c734e2014-05-27 13:20:24 -07003712 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
Chalard Jean28018572020-12-21 18:36:52 +09003713 updateNetworkScore(nai, (NetworkScore) arg.second);
Robert Greenwalt06c734e2014-05-27 13:20:24 -07003714 break;
3715 }
Robert Greenwalte06ea4b2014-09-07 16:50:01 -07003716 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
Chalard Jean254bd162022-08-25 13:04:51 +09003717 if (nai.everConnected()) {
Lorenzo Colittib882c542019-06-04 14:37:26 +09003718 loge("ERROR: cannot call explicitlySelected on already-connected network");
Chalard Jeanfbc54672021-01-20 20:47:32 +09003719 // Note that if the NAI had been connected, this would affect the
3720 // score, and therefore would require re-mixing the score and performing
3721 // a rematch.
Paul Jensen0fa1abf2014-09-26 10:10:22 -04003722 }
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003723 nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
3724 nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
lucaslin2240ef62019-03-12 13:08:03 +08003725 // Mark the network as temporarily accepting partial connectivity so that it
3726 // will be validated (and possibly become default) even if it only provides
3727 // partial internet access. Note that if user connects to partial connectivity
3728 // and choose "don't ask again", then wifi disconnected by some reasons(maybe
3729 // out of wifi coverage) and if the same wifi is available again, the device
3730 // will auto connect to this wifi even though the wifi has "no internet".
3731 // TODO: Evaluate using a separate setting in IpMemoryStore.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003732 nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2);
Robert Greenwalte06ea4b2014-09-07 16:50:01 -07003733 break;
3734 }
junyulai011b1f12019-01-03 18:50:15 +08003735 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09003736 mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2);
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09003737 break;
3738 }
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09003739 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
Lorenzo Colitti96dba632020-12-02 00:48:09 +09003740 // TODO: prevent loops, e.g., if a network declares itself as underlying.
Remi NGUYEN VAN28d69fc2020-12-25 12:45:46 +09003741 final List<Network> underlying = (List<Network>) arg.second;
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09003742
3743 if (isLegacyLockdownNai(nai)
3744 && (underlying == null || underlying.size() != 1)) {
3745 Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString()
3746 + " must have exactly one underlying network: " + underlying);
3747 }
3748
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09003749 final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
3750 nai.declaredUnderlyingNetworks = (underlying != null)
3751 ? underlying.toArray(new Network[0]) : null;
3752
3753 if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) {
3754 if (DBG) {
3755 log(nai.toShortString() + " changed underlying networks to "
3756 + Arrays.toString(nai.declaredUnderlyingNetworks));
3757 }
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09003758 updateCapabilitiesForNetwork(nai);
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09003759 notifyIfacesChangedForNetworkStats();
3760 }
Daniel Brightf9e945b2020-06-15 16:10:01 -07003761 break;
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09003762 }
Lorenzo Colittid5385c42021-03-11 01:32:09 +09003763 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
3764 if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
3765 nai.teardownDelayMs = msg.arg1;
3766 } else {
3767 logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
3768 }
Chalard Jean550b5212021-03-05 23:07:53 +09003769 break;
3770 }
3771 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: {
3772 nai.setLingerDuration((int) arg.second);
3773 break;
Lorenzo Colittid5385c42021-03-11 01:32:09 +09003774 }
Tyler Wear72388212021-09-09 14:49:02 -07003775 case NetworkAgent.EVENT_ADD_DSCP_POLICY: {
3776 DscpPolicy policy = (DscpPolicy) arg.second;
3777 if (mDscpPolicyTracker != null) {
3778 mDscpPolicyTracker.addDscpPolicy(nai, policy);
3779 }
3780 break;
3781 }
3782 case NetworkAgent.EVENT_REMOVE_DSCP_POLICY: {
3783 if (mDscpPolicyTracker != null) {
3784 mDscpPolicyTracker.removeDscpPolicy(nai, (int) arg.second);
3785 }
3786 break;
3787 }
3788 case NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES: {
3789 if (mDscpPolicyTracker != null) {
Tyler Wear3ad80892022-02-03 15:14:44 -08003790 mDscpPolicyTracker.removeAllDscpPolicies(nai, true);
Tyler Wear72388212021-09-09 14:49:02 -07003791 }
3792 break;
3793 }
Lorenzo Colittia63e2342022-03-23 23:17:16 +09003794 case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: {
Lorenzo Colitti82350ea2022-09-16 19:53:03 +09003795 if (!nai.isCreated()) {
3796 Log.d(TAG, "unregisterAfterReplacement on uncreated " + nai.toShortString()
3797 + ", tearing down instead");
3798 teardownUnneededNetwork(nai);
3799 break;
3800 }
3801
3802 if (nai.isDestroyed()) {
3803 Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString()
3804 + ", ignoring");
3805 break;
3806 }
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09003807
3808 final int timeoutMs = (int) arg.second;
3809 if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
3810 Log.e(TAG, "Invalid network replacement timer " + timeoutMs
3811 + ", must be between 0 and " + NetworkAgent.MAX_TEARDOWN_DELAY_MS);
3812 }
3813
3814 // Marking a network awaiting replacement is used to ensure that any requests
3815 // satisfied by the network do not switch to another network until a
3816 // replacement is available or the wait for a replacement times out.
3817 // If the network is inactive (i.e., nascent or lingering), then there are no
3818 // such requests, and there is no point keeping it. Just tear it down.
3819 // Note that setLingerDuration(0) cannot be used to do this because the network
3820 // could be nascent.
3821 nai.clearInactivityState();
3822 if (unneeded(nai, UnneededFor.TEARDOWN)) {
3823 Log.d(TAG, nai.toShortString()
3824 + " marked awaiting replacement is unneeded, tearing down instead");
3825 teardownUnneededNetwork(nai);
3826 break;
3827 }
3828
3829 Log.d(TAG, "Marking " + nai.toShortString()
3830 + " destroyed, awaiting replacement within " + timeoutMs + "ms");
3831 destroyNativeNetwork(nai);
3832
3833 // TODO: deduplicate this call with the one in disconnectAndDestroyNetwork.
3834 // This is not trivial because KeepaliveTracker#handleStartKeepalive does not
3835 // consider the fact that the network could already have disconnected or been
3836 // destroyed. Fix the code to send ERROR_INVALID_NETWORK when this happens
3837 // (taking care to ensure no dup'd FD leaks), then remove the code duplication
3838 // and move this code to a sensible location (destroyNativeNetwork perhaps?).
3839 mKeepaliveTracker.handleStopAllKeepalives(nai,
3840 SocketKeepalive.ERROR_INVALID_NETWORK);
3841
3842 nai.updateScoreForNetworkAgentUpdate();
3843 // This rematch is almost certainly not going to result in any changes, because
3844 // the destroyed flag is only just above the "current satisfier wins"
3845 // tie-breaker. But technically anything that affects scoring should rematch.
3846 rematchAllNetworksAndRequests();
3847 mHandler.postDelayed(() -> nai.disconnect(), timeoutMs);
3848 break;
3849 }
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003850 }
3851 }
3852
3853 private boolean maybeHandleNetworkMonitorMessage(Message msg) {
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09003854 final int netId = msg.arg2;
3855 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09003856 // If a network has already been destroyed, all NetworkMonitor updates are ignored.
Chalard Jean254bd162022-08-25 13:04:51 +09003857 if (nai != null && nai.isDestroyed()) return true;
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003858 switch (msg.what) {
3859 default:
3860 return false;
lucasline117e2e2019-10-22 18:27:33 +08003861 case EVENT_PROBE_STATUS_CHANGED: {
lucasline117e2e2019-10-22 18:27:33 +08003862 if (nai == null) {
3863 break;
3864 }
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09003865 final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first;
3866 final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second;
lucasline117e2e2019-10-22 18:27:33 +08003867 final boolean probePrivateDnsCompleted =
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09003868 ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
lucasline117e2e2019-10-22 18:27:33 +08003869 final boolean privateDnsBroken =
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09003870 ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
lucasline117e2e2019-10-22 18:27:33 +08003871 if (probePrivateDnsCompleted) {
3872 if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
3873 nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09003874 updateCapabilitiesForNetwork(nai);
lucasline117e2e2019-10-22 18:27:33 +08003875 }
3876 // Only show the notification when the private DNS is broken and the
3877 // PRIVATE_DNS_BROKEN notification hasn't shown since last valid.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003878 if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) {
lucasline117e2e2019-10-22 18:27:33 +08003879 showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN);
3880 }
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003881 nai.networkAgentConfig.hasShownBroken = privateDnsBroken;
lucasline117e2e2019-10-22 18:27:33 +08003882 } else if (nai.networkCapabilities.isPrivateDnsBroken()) {
3883 // If probePrivateDnsCompleted is false but nai.networkCapabilities says
3884 // private DNS is broken, it means this network is being reevaluated.
3885 // Either probing private DNS is not necessary any more or it hasn't been
3886 // done yet. In either case, the networkCapabilities should be updated to
3887 // reflect the new status.
3888 nai.networkCapabilities.setPrivateDnsBroken(false);
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09003889 updateCapabilitiesForNetwork(nai);
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003890 nai.networkAgentConfig.hasShownBroken = false;
lucasline117e2e2019-10-22 18:27:33 +08003891 }
3892 break;
3893 }
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09003894 case EVENT_NETWORK_TESTED: {
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003895 final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
3896
Erik Kline31b4a9e2018-01-11 21:07:29 +09003897 if (nai == null) break;
3898
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003899 handleNetworkTested(nai, results.mTestResult,
3900 (results.mRedirectUrl == null) ? "" : results.mRedirectUrl);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07003901 break;
3902 }
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09003903 case EVENT_PROVISIONING_NOTIFICATION: {
Hugo Benichif4210292017-04-21 15:07:12 +09003904 final boolean visible = toBool(msg.arg1);
Calvin Ondada1452016-10-11 15:10:46 -07003905 // If captive portal status has changed, update capabilities or disconnect.
Paul Jensen53f08952015-06-16 14:27:36 -04003906 if (!visible) {
lucaslinb1e8e382019-01-24 15:55:30 +08003907 // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
lucaslin2240ef62019-03-12 13:08:03 +08003908 // notifications belong to the same network may be cleared unexpectedly.
lucaslinb1e8e382019-01-24 15:55:30 +08003909 mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
3910 mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
Paul Jensen26dd0022014-07-15 12:07:36 -04003911 } else {
Paul Jensen7844b812014-08-25 22:45:39 -04003912 if (nai == null) {
3913 loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
3914 break;
3915 }
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003916 if (!nai.networkAgentConfig.provisioningNotificationDisabled) {
Lorenzo Colittiddc5fd82016-08-22 16:46:40 +09003917 mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09003918 (PendingIntent) msg.obj,
3919 nai.networkAgentConfig.explicitlySelected);
fionaxu5310c302016-05-23 16:33:16 -07003920 }
Paul Jensen239ce0b2014-05-15 10:33:05 -04003921 }
Paul Jensen239ce0b2014-05-15 10:33:05 -04003922 break;
3923 }
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09003924 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
Erik Kline31b4a9e2018-01-11 21:07:29 +09003925 if (nai == null) break;
3926
Erik Kline9a62f012018-03-21 07:18:33 -07003927 updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
Erik Kline31b4a9e2018-01-11 21:07:29 +09003928 break;
3929 }
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09003930 case EVENT_CAPPORT_DATA_CHANGED: {
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09003931 if (nai == null) break;
Hai Shalome58bdc62021-01-11 18:45:34 -08003932 handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09003933 break;
3934 }
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07003935 }
Lorenzo Colittib54bea92016-04-05 17:52:16 +09003936 return true;
3937 }
3938
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003939 private void handleNetworkTested(
3940 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
Chalard Jean5fb43c72022-09-08 19:03:14 +09003941 final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0;
3942 final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0;
Chalard Jean8a9061f2022-09-22 16:25:10 +09003943 final boolean portal = !TextUtils.isEmpty(redirectUrl);
Chalard Jean5fb43c72022-09-08 19:03:14 +09003944
3945 // If there is any kind of working networking, then the NAI has been evaluated
3946 // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is
3947 // the first time this ever happened.
Chalard Jean8a9061f2022-09-22 16:25:10 +09003948 final boolean someConnectivity = (valid || partial || portal);
Chalard Jean5fb43c72022-09-08 19:03:14 +09003949 final boolean becameEvaluated = someConnectivity && nai.setEvaluated();
Chalard Jeane63c42f2022-09-16 19:31:45 +09003950 // Because of b/245893397, if the score is updated when updateCapabilities is called,
3951 // any callback that receives onAvailable for that rematch receives an extra caps
3952 // callback. To prevent that, update the score in the agent so the updates below won't
3953 // see an update to both caps and score at the same time.
3954 // TODO : fix b/245893397 and remove this.
Chalard Jean5fb43c72022-09-08 19:03:14 +09003955 if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate();
3956
he_won.hwang881307a2022-03-15 21:23:52 +09003957 if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) {
3958 // Assume the validation failure is due to a temporary failure after roaming
3959 // and ignore it. NetworkMonitor will continue to retry validation. If it
3960 // continues to fail after the block timeout expires, the network will be
3961 // marked unvalidated. If it succeeds, then validation state will not change.
3962 return;
3963 }
3964
Chalard Jean254bd162022-08-25 13:04:51 +09003965 final boolean wasValidated = nai.isValidated();
3966 final boolean wasPartial = nai.partialConnectivity();
Chalard Jean8a9061f2022-09-22 16:25:10 +09003967 final boolean wasPortal = nai.captivePortalDetected();
3968 nai.setPartialConnectivity(partial);
3969 nai.setCaptivePortalDetected(portal);
3970 nai.updateScoreForNetworkAgentUpdate();
3971 final boolean partialConnectivityChanged = (wasPartial != partial);
3972 final boolean portalChanged = (wasPortal != portal);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003973
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003974 if (DBG) {
3975 final String logMsg = !TextUtils.isEmpty(redirectUrl)
3976 ? " with redirect to " + redirectUrl
3977 : "";
Chalard Jean49707572019-12-10 21:07:02 +09003978 log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003979 }
Chalard Jean8a9061f2022-09-22 16:25:10 +09003980 if (valid != wasValidated) {
Chalard Jeanaa5bc622022-02-26 21:34:48 +09003981 final FullScore oldScore = nai.getScore();
Chalard Jean254bd162022-08-25 13:04:51 +09003982 nai.setValidated(valid);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003983 updateCapabilities(oldScore, nai, nai.networkCapabilities);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003984 if (valid) {
3985 handleFreshlyValidatedNetwork(nai);
3986 // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
3987 // LOST_INTERNET notifications if network becomes valid.
Serik Beketayevec8ad212020-12-07 22:43:07 -08003988 mNotifier.clearNotification(nai.network.getNetId(),
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003989 NotificationType.NO_INTERNET);
Serik Beketayevec8ad212020-12-07 22:43:07 -08003990 mNotifier.clearNotification(nai.network.getNetId(),
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003991 NotificationType.LOST_INTERNET);
Serik Beketayevec8ad212020-12-07 22:43:07 -08003992 mNotifier.clearNotification(nai.network.getNetId(),
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003993 NotificationType.PARTIAL_CONNECTIVITY);
Serik Beketayevec8ad212020-12-07 22:43:07 -08003994 mNotifier.clearNotification(nai.network.getNetId(),
Cody Kesting83bb5fa2020-01-05 14:06:39 -08003995 NotificationType.PRIVATE_DNS_BROKEN);
3996 // If network becomes valid, the hasShownBroken should be reset for
3997 // that network so that the notification will be fired when the private
3998 // DNS is broken again.
3999 nai.networkAgentConfig.hasShownBroken = false;
4000 }
4001 } else if (partialConnectivityChanged) {
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09004002 updateCapabilitiesForNetwork(nai);
Chalard Jean8a9061f2022-09-22 16:25:10 +09004003 } else if (portalChanged) {
4004 if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
4005 == getCaptivePortalMode()) {
4006 if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
4007 nai.onPreventAutomaticReconnect();
4008 teardownUnneededNetwork(nai);
4009 return;
4010 } else {
4011 updateCapabilitiesForNetwork(nai);
4012 }
Chalard Jean5fb43c72022-09-08 19:03:14 +09004013 } else if (becameEvaluated) {
4014 // If valid or partial connectivity changed, updateCapabilities* has
4015 // done the rematch.
4016 rematchAllNetworksAndRequests();
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004017 }
4018 updateInetCondition(nai);
Chalard Jean5fb43c72022-09-08 19:03:14 +09004019
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004020 // Let the NetworkAgent know the state of its network
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004021 // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004022 nai.onValidationStatusChanged(
4023 valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK,
4024 redirectUrl);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004025
4026 // If NetworkMonitor detects partial connectivity before
Chalard Jean5fb43c72022-09-08 19:03:14 +09004027 // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004028 // immediately. Re-notify partial connectivity silently if no internet
4029 // notification already there.
Chalard Jean254bd162022-08-25 13:04:51 +09004030 if (!wasPartial && nai.partialConnectivity()) {
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004031 // Remove delayed message if there is a pending message.
Chalard Jean5fb43c72022-09-08 19:03:14 +09004032 mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network);
4033 handleInitialEvaluationTimeout(nai.network);
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004034 }
4035
Chalard Jean254bd162022-08-25 13:04:51 +09004036 if (wasValidated && !nai.isValidated()) {
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004037 handleNetworkUnvalidated(nai);
4038 }
4039 }
4040
Calvin Ondada1452016-10-11 15:10:46 -07004041 private int getCaptivePortalMode() {
4042 return Settings.Global.getInt(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +08004043 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE,
4044 ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT);
Calvin Ondada1452016-10-11 15:10:46 -07004045 }
4046
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004047 private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
4048 switch (msg.what) {
4049 default:
4050 return false;
4051 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
4052 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
4053 if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
4054 handleLingerComplete(nai);
4055 }
4056 break;
4057 }
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004058 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: {
4059 handleNetworkAgentRegistered(msg);
4060 break;
4061 }
4062 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: {
4063 handleNetworkAgentDisconnected(msg);
4064 break;
4065 }
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004066 }
4067 return true;
4068 }
4069
Lorenzo Colittib54bea92016-04-05 17:52:16 +09004070 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +09004071 public void handleMessage(@NonNull Message msg) {
lifraf3a3492021-03-10 13:58:14 +08004072 if (!maybeHandleNetworkMonitorMessage(msg)
Remi NGUYEN VAN82b5bb62020-01-14 19:48:18 +09004073 && !maybeHandleNetworkAgentInfoMessage(msg)) {
Lorenzo Colittib54bea92016-04-05 17:52:16 +09004074 maybeHandleNetworkAgentMessage(msg);
4075 }
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07004076 }
4077 }
4078
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004079 private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
Chalard Jean7284daa2019-05-30 14:58:29 +09004080 private final int mNetId;
4081 private final AutodestructReference<NetworkAgentInfo> mNai;
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004082
4083 private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08004084 mNetId = nai.network.getNetId();
Chalard Jeanfbab6d42019-09-26 18:03:47 +09004085 mNai = new AutodestructReference<>(nai);
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004086 }
4087
4088 @Override
4089 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
4090 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
Chalard Jean7284daa2019-05-30 14:58:29 +09004091 new Pair<>(mNai.getAndDestroy(), networkMonitor)));
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004092 }
4093
4094 @Override
4095 public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004096 // Legacy version of notifyNetworkTestedWithExtras.
4097 // Would only be called if the system has a NetworkStack module older than the
4098 // framework, which does not happen in practice.
Aaron Huang6616df32020-10-30 22:04:25 +08004099 Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004100 }
4101
4102 @Override
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004103 public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
Remi NGUYEN VAN455b93d2020-04-24 20:56:39 +09004104 // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
4105 // the same looper so messages will be processed in sequence.
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004106 final Message msg = mTrackerHandler.obtainMessage(
4107 EVENT_NETWORK_TESTED,
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09004108 0, mNetId,
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004109 new NetworkTestedResults(
4110 mNetId, p.result, p.timestampMillis, p.redirectUrl));
Cody Kesting83bb5fa2020-01-05 14:06:39 -08004111 mTrackerHandler.sendMessage(msg);
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004112
4113 // Invoke ConnectivityReport generation for this Network test event.
4114 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId);
4115 if (nai == null) return;
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004116
Cody Kestingf1120be2020-08-03 18:01:40 -07004117 // NetworkMonitor reports the network validation result as a bitmask while
4118 // ConnectivityDiagnostics treats this value as an int. Convert the result to a single
4119 // logical value for ConnectivityDiagnostics.
4120 final int validationResult = networkMonitorValidationResultToConnDiagsValidationResult(
4121 p.result);
4122
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004123 final PersistableBundle extras = new PersistableBundle();
Cody Kestingf1120be2020-08-03 18:01:40 -07004124 extras.putInt(KEY_NETWORK_VALIDATION_RESULT, validationResult);
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004125 extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded);
4126 extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted);
4127
Aaron Huang959d3642021-01-21 15:47:41 +08004128 ConnectivityReportEvent reportEvent =
4129 new ConnectivityReportEvent(p.timestampMillis, nai, extras);
4130 final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
Lorenzo Colitti0261ced2022-02-18 00:23:56 +09004131 ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent);
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004132 mConnectivityDiagnosticsHandler.sendMessage(m);
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004133 }
4134
4135 @Override
4136 public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
4137 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
4138 EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
Chalard Jean7284daa2019-05-30 14:58:29 +09004139 0, mNetId, PrivateDnsConfig.fromParcel(config)));
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004140 }
4141
4142 @Override
lucasline117e2e2019-10-22 18:27:33 +08004143 public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
4144 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
4145 EVENT_PROBE_STATUS_CHANGED,
Lorenzo Colittid1b11dc2022-02-17 14:28:53 +09004146 0, mNetId, new Pair<>(probesCompleted, probesSucceeded)));
lucasline117e2e2019-10-22 18:27:33 +08004147 }
4148
4149 @Override
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09004150 public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
4151 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
4152 EVENT_CAPPORT_DATA_CHANGED,
4153 0, mNetId, data));
4154 }
4155
4156 @Override
Remi NGUYEN VAN794c7f22019-02-07 21:29:57 +09004157 public void showProvisioningNotification(String action, String packageName) {
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004158 final Intent intent = new Intent(action);
Remi NGUYEN VAN794c7f22019-02-07 21:29:57 +09004159 intent.setPackage(packageName);
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004160
4161 final PendingIntent pendingIntent;
4162 // Only the system server can register notifications with package "android"
4163 final long token = Binder.clearCallingIdentity();
4164 try {
paulhu7746e4e2020-06-09 19:07:03 +08004165 pendingIntent = PendingIntent.getBroadcast(
4166 mContext,
4167 0 /* requestCode */,
4168 intent,
4169 PendingIntent.FLAG_IMMUTABLE);
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004170 } finally {
4171 Binder.restoreCallingIdentity(token);
4172 }
4173 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
4174 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
Chalard Jean7284daa2019-05-30 14:58:29 +09004175 mNetId, pendingIntent));
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004176 }
4177
4178 @Override
4179 public void hideProvisioningNotification() {
4180 mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
Chalard Jean7284daa2019-05-30 14:58:29 +09004181 EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004182 }
Remi NGUYEN VAN683df1d2019-04-05 15:15:48 +09004183
4184 @Override
Remi NGUYEN VAN9b647ca2020-04-15 18:39:28 +09004185 public void notifyDataStallSuspected(DataStallReportParcelable p) {
Cody Kestingf5cc4ea2020-05-11 10:06:51 -07004186 ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
Cody Kestingb12ad4c2020-01-06 16:55:35 -08004187 }
4188
4189 @Override
Remi NGUYEN VAN683df1d2019-04-05 15:15:48 +09004190 public int getInterfaceVersion() {
4191 return this.VERSION;
4192 }
Paul Trautrim79a9c8c2020-01-23 14:55:57 +09004193
4194 @Override
4195 public String getInterfaceHash() {
4196 return this.HASH;
4197 }
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004198 }
4199
Cody Kestingf1120be2020-08-03 18:01:40 -07004200 /**
4201 * Converts the given NetworkMonitor-specific validation result bitmask to a
4202 * ConnectivityDiagnostics-specific validation result int.
4203 */
4204 private int networkMonitorValidationResultToConnDiagsValidationResult(int validationResult) {
4205 if ((validationResult & NETWORK_VALIDATION_RESULT_SKIPPED) != 0) {
4206 return ConnectivityReport.NETWORK_VALIDATION_RESULT_SKIPPED;
4207 }
4208 if ((validationResult & NETWORK_VALIDATION_RESULT_VALID) == 0) {
4209 return ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID;
4210 }
4211 return (validationResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0
4212 ? ConnectivityReport.NETWORK_VALIDATION_RESULT_PARTIALLY_VALID
4213 : ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID;
4214 }
4215
Cody Kestingf5cc4ea2020-05-11 10:06:51 -07004216 private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
Cody Kestingb37958e2020-05-15 10:36:01 -07004217 log("Data stall detected with methods: " + p.detectionMethod);
4218
Cody Kestingf5cc4ea2020-05-11 10:06:51 -07004219 final PersistableBundle extras = new PersistableBundle();
Cody Kestingb37958e2020-05-15 10:36:01 -07004220 int detectionMethod = 0;
4221 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
4222 extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
4223 detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
4224 }
4225 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
4226 extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
4227 extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
4228 p.tcpMetricsCollectionPeriodMillis);
4229 detectionMethod |= DETECTION_METHOD_TCP_METRICS;
Cody Kestingf5cc4ea2020-05-11 10:06:51 -07004230 }
4231
Cody Kestingf53a0752020-04-15 12:33:28 -07004232 final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
Cody Kestingf5cc4ea2020-05-11 10:06:51 -07004233 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
Aaron Huang959d3642021-01-21 15:47:41 +08004234 new Pair<>(p.timestampMillis, extras));
Cody Kestingf53a0752020-04-15 12:33:28 -07004235
4236 // NetworkStateTrackerHandler currently doesn't take any actions based on data
4237 // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
4238 // the cost of going through two handlers.
4239 mConnectivityDiagnosticsHandler.sendMessage(msg);
4240 }
4241
Cody Kestingb37958e2020-05-15 10:36:01 -07004242 private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
4243 return (p.detectionMethod & detectionMethod) != 0;
4244 }
4245
Lorenzo Colitti2fca7e32019-03-22 00:28:28 +09004246 private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
4247 return isPrivateDnsValidationRequired(nai.networkCapabilities);
Erik Kline9a62f012018-03-21 07:18:33 -07004248 }
4249
Erik Klinea73af002018-06-26 18:53:43 +09004250 private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
4251 if (nai == null) return;
4252 // If the Private DNS mode is opportunistic, reprogram the DNS servers
4253 // in order to restart a validation pass from within netd.
4254 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
4255 if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08004256 updateDnses(nai.linkProperties, null, nai.network.getNetId());
Erik Klinea73af002018-06-26 18:53:43 +09004257 }
4258 }
4259
Erik Kline31b4a9e2018-01-11 21:07:29 +09004260 private void handlePrivateDnsSettingsChanged() {
4261 final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
4262
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004263 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
Erik Kline9a62f012018-03-21 07:18:33 -07004264 handlePerNetworkPrivateDnsConfig(nai, cfg);
Lorenzo Colitti2fca7e32019-03-22 00:28:28 +09004265 if (networkRequiresPrivateDnsValidation(nai)) {
dalyk1720e542018-03-05 12:42:22 -05004266 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
4267 }
Erik Kline31b4a9e2018-01-11 21:07:29 +09004268 }
4269 }
4270
Erik Kline9a62f012018-03-21 07:18:33 -07004271 private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
4272 // Private DNS only ever applies to networks that might provide
4273 // Internet access and therefore also require validation.
Lorenzo Colitti2fca7e32019-03-22 00:28:28 +09004274 if (!networkRequiresPrivateDnsValidation(nai)) return;
Erik Kline31b4a9e2018-01-11 21:07:29 +09004275
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09004276 // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
Erik Kline9a62f012018-03-21 07:18:33 -07004277 // schedule DNS resolutions. If a DNS resolution is required the
4278 // result will be sent back to us.
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09004279 nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
Erik Kline9a62f012018-03-21 07:18:33 -07004280
4281 // With Private DNS bypass support, we can proceed to update the
4282 // Private DNS config immediately, even if we're in strict mode
4283 // and have not yet resolved the provider name into a set of IPs.
4284 updatePrivateDns(nai, cfg);
4285 }
4286
4287 private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
4288 mDnsManager.updatePrivateDns(nai.network, newCfg);
Serik Beketayevec8ad212020-12-07 22:43:07 -08004289 updateDnses(nai.linkProperties, null, nai.network.getNetId());
Erik Kline31b4a9e2018-01-11 21:07:29 +09004290 }
4291
dalyk1720e542018-03-05 12:42:22 -05004292 private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
4293 NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
4294 if (nai == null) {
4295 return;
4296 }
4297 mDnsManager.updatePrivateDnsValidation(update);
4298 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
4299 }
4300
paulhu7c0a2e62021-01-08 00:51:49 +08004301 private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress,
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004302 int prefixLength) {
4303 NetworkAgentInfo nai = mNetworkForNetId.get(netId);
4304 if (nai == null) return;
4305
paulhu7c0a2e62021-01-08 00:51:49 +08004306 log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d",
4307 netId, operation, prefixAddress, prefixLength));
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004308
4309 IpPrefix prefix = null;
paulhu7c0a2e62021-01-08 00:51:49 +08004310 if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) {
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004311 try {
paulhu7c0a2e62021-01-08 00:51:49 +08004312 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress),
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004313 prefixLength);
4314 } catch (IllegalArgumentException e) {
paulhu7c0a2e62021-01-08 00:51:49 +08004315 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength);
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004316 return;
4317 }
4318 }
4319
Lorenzo Colittid523d142020-04-01 20:16:30 +09004320 nai.clatd.setNat64PrefixFromDns(prefix);
Lorenzo Colittif7e17392019-01-08 10:04:25 +09004321 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
4322 }
4323
Hai Shalome58bdc62021-01-11 18:45:34 -08004324 private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09004325 @Nullable final CaptivePortalData data) {
Hai Shalome58bdc62021-01-11 18:45:34 -08004326 nai.capportApiData = data;
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09004327 // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
4328 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
4329 }
4330
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004331 /**
junyulai2b6f0c22021-02-03 20:15:30 +08004332 * Updates the inactivity state from the network requests inside the NAI.
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004333 * @param nai the agent info to update
4334 * @param now the timestamp of the event causing this update
junyulai2b6f0c22021-02-03 20:15:30 +08004335 * @return whether the network was inactive as a result of this update
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004336 */
junyulai2b6f0c22021-02-03 20:15:30 +08004337 private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) {
4338 // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm.
4339 // 2. If the network was inactive and there are now requests, unset inactive.
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004340 // 3. If this network is unneeded (which implies it is not lingering), and there is at least
junyulai2b6f0c22021-02-03 20:15:30 +08004341 // one lingered request, set inactive.
4342 nai.updateInactivityTimer();
junyulai0ac374f2020-12-14 18:41:52 +08004343 if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) {
junyulai2b6f0c22021-02-03 20:15:30 +08004344 if (DBG) log("Unsetting inactive " + nai.toShortString());
4345 nai.unsetInactive();
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004346 logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
junyulai2b6f0c22021-02-03 20:15:30 +08004347 } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) {
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004348 if (DBG) {
junyulai2b6f0c22021-02-03 20:15:30 +08004349 final int lingerTime = (int) (nai.getInactivityExpiry() - now);
4350 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms");
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004351 }
junyulai2b6f0c22021-02-03 20:15:30 +08004352 nai.setInactive();
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004353 logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004354 return true;
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09004355 }
Chalard Jean8fd82ae2019-12-04 18:49:18 +09004356 return false;
Paul Jensend5f53392014-11-25 15:26:53 -05004357 }
4358
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004359 private void handleNetworkAgentRegistered(Message msg) {
4360 final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
4361 if (!mNetworkAgentInfos.contains(nai)) {
4362 return;
4363 }
4364
4365 if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) {
4366 if (VDBG) log("NetworkAgent registered");
4367 } else {
4368 loge("Error connecting NetworkAgent");
4369 mNetworkAgentInfos.remove(nai);
4370 if (nai != null) {
Chalard Jean5b409c72021-02-04 13:12:59 +09004371 final boolean wasDefault = isDefaultNetwork(nai);
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004372 synchronized (mNetworkForNetId) {
4373 mNetworkForNetId.remove(nai.network.getNetId());
Robert Greenwaltf99b8392014-03-26 16:47:06 -07004374 }
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004375 mNetIdManager.releaseNetId(nai.network.getNetId());
4376 // Just in case.
Chalard Jean5b409c72021-02-04 13:12:59 +09004377 mLegacyTypeTracker.remove(nai, wasDefault);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07004378 }
4379 }
4380 }
Paul Jensend5f53392014-11-25 15:26:53 -05004381
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004382 private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
Chalard Jean254bd162022-08-25 13:04:51 +09004383 return nai.isCreated() && !nai.isDestroyed();
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004384 }
4385
Lorenzo Colitti580d0d52022-10-13 19:56:58 +09004386 @VisibleForTesting
4387 boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
Lorenzo Colittia63e2342022-03-23 23:17:16 +09004388 // T+ devices should use unregisterAfterReplacement.
he_won.hwang881307a2022-03-15 21:23:52 +09004389 if (SdkLevel.isAtLeastT()) return false;
Lorenzo Colitti580d0d52022-10-13 19:56:58 +09004390
4391 // If the network never roamed, return false. The check below is not sufficient if time
4392 // since boot is less than blockTimeOut, though that's extremely unlikely to happen.
4393 if (nai.lastRoamTime == 0) return false;
4394
he_won.hwang881307a2022-03-15 21:23:52 +09004395 final long blockTimeOut = Long.valueOf(mResources.get().getInteger(
4396 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
Lorenzo Colitti580d0d52022-10-13 19:56:58 +09004397 if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS
he_won.hwang881307a2022-03-15 21:23:52 +09004398 && blockTimeOut >= 0) {
Chalard Jean254bd162022-08-25 13:04:51 +09004399 final long currentTimeMs = SystemClock.elapsedRealtime();
4400 long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime;
he_won.hwang881307a2022-03-15 21:23:52 +09004401 if (timeSinceLastRoam <= blockTimeOut) {
4402 log ("blocked because only " + timeSinceLastRoam + "ms after roam");
4403 return true;
4404 }
4405 }
4406 return false;
4407 }
4408
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004409 private void handleNetworkAgentDisconnected(Message msg) {
4410 NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
Tyler Wear614b27b2021-08-19 09:33:26 -07004411 disconnectAndDestroyNetwork(nai);
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004412 }
4413
Chalard Jeand9fffc32018-05-11 20:19:20 +09004414 // Destroys a network, remove references to it from the internal state managed by
4415 // ConnectivityService, free its interfaces and clean up.
4416 // Must be called on the Handler thread.
4417 private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
Chalard Jean2c8b3e32019-11-05 14:40:23 +09004418 ensureRunningOnConnectivityServiceThread();
Tyler Wear614b27b2021-08-19 09:33:26 -07004419
4420 if (!mNetworkAgentInfos.contains(nai)) return;
4421
Chalard Jeand9fffc32018-05-11 20:19:20 +09004422 if (DBG) {
Chalard Jean49707572019-12-10 21:07:02 +09004423 log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
Chalard Jeand9fffc32018-05-11 20:19:20 +09004424 }
lucaslinb25c9a62019-02-12 15:30:13 +08004425 // Clear all notifications of this network.
Serik Beketayevec8ad212020-12-07 22:43:07 -08004426 mNotifier.clearNotification(nai.network.getNetId());
Chalard Jeand9fffc32018-05-11 20:19:20 +09004427 // A network agent has disconnected.
4428 // TODO - if we move the logic to the network agent (have them disconnect
4429 // because they lost all their requests or because their score isn't good)
4430 // then they would disconnect organically, report their new state and then
4431 // disconnect the channel.
4432 if (nai.networkInfo.isConnected()) {
4433 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
4434 null, null);
4435 }
Chalard Jean5b409c72021-02-04 13:12:59 +09004436 final boolean wasDefault = isDefaultNetwork(nai);
4437 if (wasDefault) {
Chalard Jeand9fffc32018-05-11 20:19:20 +09004438 mDefaultInetConditionPublished = 0;
Chalard Jeand9fffc32018-05-11 20:19:20 +09004439 }
4440 notifyIfacesChangedForNetworkStats();
4441 // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
4442 // by other networks that are already connected. Perhaps that can be done by
4443 // sending all CALLBACK_LOST messages (for requests, not listens) at the end
4444 // of rematchAllNetworksAndRequests
4445 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
junyulai011b1f12019-01-03 18:50:15 +08004446 mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
Daniel Brightf9e945b2020-06-15 16:10:01 -07004447
4448 mQosCallbackTracker.handleNetworkReleased(nai.network);
Chalard Jeand9fffc32018-05-11 20:19:20 +09004449 for (String iface : nai.linkProperties.getAllInterfaceNames()) {
4450 // Disable wakeup packet monitoring for each interface.
Suprabh Shukla1e312032023-01-24 03:36:37 -08004451 wakeupModifyInterface(iface, nai, false);
Chalard Jeand9fffc32018-05-11 20:19:20 +09004452 }
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09004453 nai.networkMonitor().notifyNetworkDisconnected();
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09004454 mNetworkAgentInfos.remove(nai);
Lorenzo Colitti84298d82019-02-19 13:21:56 +09004455 nai.clatd.update();
Chalard Jeand9fffc32018-05-11 20:19:20 +09004456 synchronized (mNetworkForNetId) {
4457 // Remove the NetworkAgent, but don't mark the netId as
4458 // available until we've told netd to delete it below.
Serik Beketayevec8ad212020-12-07 22:43:07 -08004459 mNetworkForNetId.remove(nai.network.getNetId());
Chalard Jeand9fffc32018-05-11 20:19:20 +09004460 }
Lorenzo Colitti24c152c2021-01-12 00:34:44 +09004461 propagateUnderlyingNetworkCapabilities(nai.network);
Junyu Lai35665cc2022-12-19 17:37:48 +08004462 // Update allowed network lists in netd. This should be called after removing nai
4463 // from mNetworkAgentInfos.
4464 updateProfileAllowedNetworks();
Chalard Jeand9fffc32018-05-11 20:19:20 +09004465 // Remove all previously satisfied requests.
4466 for (int i = 0; i < nai.numNetworkRequests(); i++) {
James Mattisd31bdfa2020-12-23 16:37:26 -08004467 final NetworkRequest request = nai.requestAt(i);
Chalard Jeandd8adb92019-11-05 15:07:09 +09004468 final NetworkRequestInfo nri = mNetworkRequests.get(request);
James Mattisa076c532020-12-02 14:12:41 -08004469 final NetworkAgentInfo currentNetwork = nri.getSatisfier();
Serik Beketayevec8ad212020-12-07 22:43:07 -08004470 if (currentNetwork != null
4471 && currentNetwork.network.getNetId() == nai.network.getNetId()) {
James Mattisd31bdfa2020-12-23 16:37:26 -08004472 // uid rules for this network will be removed in destroyNativeNetwork(nai).
Chalard Jean0354d8c2021-01-12 10:58:56 +09004473 // TODO : setting the satisfier is in fact the job of the rematch. Teach the
4474 // rematch not to keep disconnected agents instead of setting it here ; this
4475 // will also allow removing updating the offers below.
James Mattisa076c532020-12-02 14:12:41 -08004476 nri.setSatisfier(null, null);
Chalard Jean0354d8c2021-01-12 10:58:56 +09004477 for (final NetworkOfferInfo noi : mNetworkOffers) {
4478 informOffer(nri, noi.offer, mNetworkRanker);
James Mattisd31bdfa2020-12-23 16:37:26 -08004479 }
James Mattise3ef1912020-12-20 11:09:58 -08004480
Chalard Jean5b409c72021-02-04 13:12:59 +09004481 if (mDefaultRequest == nri) {
James Mattise3ef1912020-12-20 11:09:58 -08004482 // TODO : make battery stats aware that since 2013 multiple interfaces may be
Chalard Jean5b409c72021-02-04 13:12:59 +09004483 // active at the same time. For now keep calling this with the default
James Mattise3ef1912020-12-20 11:09:58 -08004484 // network, because while incorrect this is the closest to the old (also
4485 // incorrect) behavior.
4486 mNetworkActivityTracker.updateDataActivityTracking(
4487 null /* newNetwork */, nai);
James Mattise3ef1912020-12-20 11:09:58 -08004488 ensureNetworkTransitionWakelock(nai.toShortString());
4489 }
Chalard Jeand9fffc32018-05-11 20:19:20 +09004490 }
4491 }
junyulai2b6f0c22021-02-03 20:15:30 +08004492 nai.clearInactivityState();
James Mattise3ef1912020-12-20 11:09:58 -08004493 // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
Chalard Jean5b409c72021-02-04 13:12:59 +09004494 // Currently, deleting it breaks tests that check for the default network disconnecting.
James Mattise3ef1912020-12-20 11:09:58 -08004495 // Find out why, fix the rematch code, and delete this.
Chalard Jean5b409c72021-02-04 13:12:59 +09004496 mLegacyTypeTracker.remove(nai, wasDefault);
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09004497 rematchAllNetworksAndRequests();
Chalard Jeand9fffc32018-05-11 20:19:20 +09004498 mLingerMonitor.noteDisconnect(nai);
Lorenzo Colittid5385c42021-03-11 01:32:09 +09004499
4500 // Immediate teardown.
4501 if (nai.teardownDelayMs == 0) {
4502 destroyNetwork(nai);
4503 return;
4504 }
4505
4506 // Delayed teardown.
Chalard Jean254bd162022-08-25 13:04:51 +09004507 if (nai.isCreated()) {
Pavan Kumar Mbe994242021-09-29 17:59:24 +05304508 try {
4509 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
4510 } catch (RemoteException e) {
4511 Log.d(TAG, "Error marking network restricted during teardown: ", e);
4512 }
Lorenzo Colittid5385c42021-03-11 01:32:09 +09004513 }
4514 mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
4515 }
4516
4517 private void destroyNetwork(NetworkAgentInfo nai) {
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004518 if (shouldDestroyNativeNetwork(nai)) {
Chalard Jeand9fffc32018-05-11 20:19:20 +09004519 // Tell netd to clean up the configuration for this network
4520 // (routing rules, DNS, etc).
4521 // This may be slow as it requires a lot of netd shelling out to ip and
4522 // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
Chalard Jean5b409c72021-02-04 13:12:59 +09004523 // after we've rematched networks with requests (which might change the default
4524 // network or service a new request from an app), so network traffic isn't interrupted
4525 // for an unnecessarily long time.
Luke Huangfdd11f82019-04-09 18:41:49 +08004526 destroyNativeNetwork(nai);
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004527 }
Chalard Jean254bd162022-08-25 13:04:51 +09004528 if (!nai.isCreated() && !SdkLevel.isAtLeastT()) {
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004529 // Backwards compatibility: send onNetworkDestroyed even if network was never created.
4530 // This can never run if the code above runs because shouldDestroyNativeNetwork is
4531 // false if the network was never created.
4532 // TODO: delete when S is no longer supported.
4533 nai.onNetworkDestroyed();
Chalard Jeand9fffc32018-05-11 20:19:20 +09004534 }
Serik Beketayevec8ad212020-12-07 22:43:07 -08004535 mNetIdManager.releaseNetId(nai.network.getNetId());
Chalard Jeand9fffc32018-05-11 20:19:20 +09004536 }
4537
Ken Chen6df7a902021-04-09 15:08:42 +08004538 private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) {
Luke Huangfdd11f82019-04-09 18:41:49 +08004539 try {
4540 // This should never fail. Specifying an already in use NetID will cause failure.
Ken Chen6df7a902021-04-09 15:08:42 +08004541 final NativeNetworkConfig config;
4542 if (nai.isVPN()) {
4543 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) {
Ken Chen755a4e72021-05-12 13:38:13 +08004544 Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString());
Ken Chen6df7a902021-04-09 15:08:42 +08004545 return false;
4546 }
4547 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL,
4548 INetd.PERMISSION_NONE,
Chalard Jean46bfbf02022-02-02 00:56:25 +09004549 !nai.networkAgentConfig.allowBypass /* secure */,
Chiachang Wang9164c102022-01-13 10:54:32 +08004550 getVpnType(nai), nai.networkAgentConfig.excludeLocalRouteVpn);
Luke Huangfdd11f82019-04-09 18:41:49 +08004551 } else {
Ken Chen6df7a902021-04-09 15:08:42 +08004552 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL,
Chalard Jean46bfbf02022-02-02 00:56:25 +09004553 getNetworkPermission(nai.networkCapabilities),
4554 false /* secure */,
4555 VpnManager.TYPE_VPN_NONE,
4556 false /* excludeLocalRoutes */);
Luke Huangfdd11f82019-04-09 18:41:49 +08004557 }
Ken Chen6df7a902021-04-09 15:08:42 +08004558 mNetd.networkCreate(config);
4559 mDnsResolver.createNetworkCache(nai.network.getNetId());
4560 mDnsManager.updateTransportsForNetwork(nai.network.getNetId(),
4561 nai.networkCapabilities.getTransportTypes());
Luke Huangfdd11f82019-04-09 18:41:49 +08004562 return true;
4563 } catch (RemoteException | ServiceSpecificException e) {
Ken Chen755a4e72021-05-12 13:38:13 +08004564 loge("Error creating network " + nai.toShortString() + ": " + e.getMessage());
Luke Huangfdd11f82019-04-09 18:41:49 +08004565 return false;
4566 }
4567 }
4568
Ken Chen6df7a902021-04-09 15:08:42 +08004569 private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
Tyler Wear3ad80892022-02-03 15:14:44 -08004570 if (mDscpPolicyTracker != null) {
4571 mDscpPolicyTracker.removeAllDscpPolicies(nai, false);
4572 }
Luke Huangfdd11f82019-04-09 18:41:49 +08004573 try {
Ken Chen6df7a902021-04-09 15:08:42 +08004574 mNetd.networkDestroy(nai.network.getNetId());
Wangkeun Ohe0a9d1b2021-01-20 11:04:46 +09004575 } catch (RemoteException | ServiceSpecificException e) {
4576 loge("Exception destroying network(networkDestroy): " + e);
4577 }
4578 try {
Ken Chen6df7a902021-04-09 15:08:42 +08004579 mDnsResolver.destroyNetworkCache(nai.network.getNetId());
Luke Huangfdd11f82019-04-09 18:41:49 +08004580 } catch (RemoteException | ServiceSpecificException e) {
4581 loge("Exception destroying network: " + e);
4582 }
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004583 // TODO: defer calling this until the network is removed from mNetworkAgentInfos.
4584 // Otherwise, a private DNS configuration update for a destroyed network, or one that never
4585 // gets created, could add data to DnsManager data structures that will never get deleted.
4586 mDnsManager.removeNetwork(nai.network);
4587
4588 // clean up tc police filters on interface.
Chalard Jean254bd162022-08-25 13:04:51 +09004589 if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004590 mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName());
4591 }
4592
Chalard Jean254bd162022-08-25 13:04:51 +09004593 nai.setDestroyed();
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09004594 nai.onNetworkDestroyed();
Luke Huangfdd11f82019-04-09 18:41:49 +08004595 }
4596
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004597 // If this method proves to be too slow then we can maintain a separate
4598 // pendingIntent => NetworkRequestInfo map.
4599 // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
4600 private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004601 for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
4602 PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
4603 if (existingPendingIntent != null &&
Remi NGUYEN VAN18a979f2021-06-04 18:51:25 +09004604 mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) {
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004605 return entry.getValue();
4606 }
4607 }
4608 return null;
4609 }
4610
Chalard Jean524f0b12021-10-25 21:11:56 +09004611 private void checkNrisConsistency(final NetworkRequestInfo nri) {
4612 if (SdkLevel.isAtLeastT()) {
4613 for (final NetworkRequestInfo n : mNetworkRequests.values()) {
4614 if (n.mBinder != null && n.mBinder == nri.mBinder) {
4615 // Temporary help to debug b/194394697 ; TODO : remove this function when the
4616 // bug is fixed.
4617 dumpAllRequestInfoLogsToLogcat();
Chalard Jeanba551d42021-10-28 12:45:12 +09004618 throw new IllegalStateException("This NRI is already registered. New : " + nri
4619 + ", existing : " + n);
Chalard Jean524f0b12021-10-25 21:11:56 +09004620 }
4621 }
4622 }
4623 }
4624
Chalard Jeanac9ace02022-01-26 16:54:05 +09004625 private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid,
4626 @NonNull final NetworkCapabilities caps) {
junyulai96bd9fe2022-03-08 17:36:42 +08004627 if (mCarrierPrivilegeAuthenticator != null) {
Chalard Jeanac9ace02022-01-26 16:54:05 +09004628 return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
4629 callingUid, caps);
Sooraj Sasindrane9cd2082022-01-13 15:46:52 -08004630 }
4631 return false;
4632 }
4633
James Mattisf7027322020-12-13 16:28:14 -08004634 private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004635 final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
James Mattisf7027322020-12-13 16:28:14 -08004636 // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
4637 ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent");
4638 final NetworkRequestInfo existingRequest =
4639 findExistingNetworkRequestInfo(nri.mPendingIntent);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004640 if (existingRequest != null) { // remove the existing request.
James Mattisf7027322020-12-13 16:28:14 -08004641 if (DBG) {
4642 log("Replacing " + existingRequest.mRequests.get(0) + " with "
4643 + nri.mRequests.get(0) + " because their intents matched.");
4644 }
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +09004645 handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
Etan Cohenfbfdd842019-01-08 12:09:18 -08004646 /* callOnUnavailable */ false);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004647 }
Erik Kline05f2b402015-04-30 12:58:40 +09004648 handleRegisterNetworkRequest(nri);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004649 }
4650
James Mattisf7027322020-12-13 16:28:14 -08004651 private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08004652 handleRegisterNetworkRequests(Collections.singleton(nri));
James Mattis45d81842021-01-10 14:24:24 -08004653 }
4654
James Mattis3ce3d3c2021-02-09 18:18:28 -08004655 private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
Chalard Jean2c8b3e32019-11-05 14:40:23 +09004656 ensureRunningOnConnectivityServiceThread();
James Mattis45d81842021-01-10 14:24:24 -08004657 for (final NetworkRequestInfo nri : nris) {
4658 mNetworkRequestInfoLogs.log("REGISTER " + nri);
Chalard Jean524f0b12021-10-25 21:11:56 +09004659 checkNrisConsistency(nri);
James Mattis45d81842021-01-10 14:24:24 -08004660 for (final NetworkRequest req : nri.mRequests) {
4661 mNetworkRequests.put(req, nri);
junyulai1b1c8742021-03-12 20:05:08 +08004662 // TODO: Consider update signal strength for other types.
James Mattis45d81842021-01-10 14:24:24 -08004663 if (req.isListen()) {
4664 for (final NetworkAgentInfo network : mNetworkAgentInfos) {
4665 if (req.networkCapabilities.hasSignalStrength()
4666 && network.satisfiesImmutableCapabilitiesOf(req)) {
4667 updateSignalStrengthThresholds(network, "REGISTER", req);
4668 }
James Mattisf7027322020-12-13 16:28:14 -08004669 }
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09004670 }
4671 }
Sooraj Sasindrane9cd2082022-01-13 15:46:52 -08004672
Chalard Jeanb5becbc2021-03-05 19:18:14 +09004673 // If this NRI has a satisfier already, it is replacing an older request that
4674 // has been removed. Track it.
4675 final NetworkRequest activeRequest = nri.getActiveRequest();
4676 if (null != activeRequest) {
4677 // If there is an active request, then for sure there is a satisfier.
4678 nri.getSatisfier().addRequest(activeRequest);
4679 }
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09004680 }
James Mattisf7027322020-12-13 16:28:14 -08004681
Remi NGUYEN VAN959d2cb2021-08-02 13:04:31 +09004682 if (mFlags.noRematchAllRequestsOnRegister()) {
4683 rematchNetworksAndRequests(nris);
4684 } else {
4685 rematchAllNetworksAndRequests();
4686 }
James Mattis45d81842021-01-10 14:24:24 -08004687
Chalard Jean0354d8c2021-01-12 10:58:56 +09004688 // Requests that have not been matched to a network will not have been sent to the
4689 // providers, because the old satisfier and the new satisfier are the same (null in this
4690 // case). Send these requests to the providers.
4691 for (final NetworkRequestInfo nri : nris) {
4692 for (final NetworkOfferInfo noi : mNetworkOffers) {
4693 informOffer(nri, noi.offer, mNetworkRanker);
James Mattis45d81842021-01-10 14:24:24 -08004694 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07004695 }
4696 }
4697
James Mattisf7027322020-12-13 16:28:14 -08004698 private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
4699 final int callingUid) {
4700 final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004701 if (nri != null) {
James Mattisf7027322020-12-13 16:28:14 -08004702 // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests.
4703 ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent");
4704 handleReleaseNetworkRequest(
4705 nri.mRequests.get(0),
4706 callingUid,
4707 /* callOnUnavailable */ false);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08004708 }
4709 }
4710
Lorenzo Colitti2666be82016-09-09 18:48:56 +09004711 // Determines whether the network is the best (or could become the best, if it validated), for
4712 // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
4713 // on the value of reason:
4714 //
4715 // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
4716 // then it should be torn down.
4717 // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
4718 // then it should be lingered.
4719 private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
Chalard Jean2c8b3e32019-11-05 14:40:23 +09004720 ensureRunningOnConnectivityServiceThread();
Chalard Jean947acd42021-03-08 22:29:27 +09004721
Chalard Jean254bd162022-08-25 13:04:51 +09004722 if (!nai.everConnected() || nai.isVPN() || nai.isInactive()
Chalard Jean947acd42021-03-08 22:29:27 +09004723 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
4724 return false;
4725 }
4726
Lorenzo Colitti2666be82016-09-09 18:48:56 +09004727 final int numRequests;
4728 switch (reason) {
4729 case TEARDOWN:
4730 numRequests = nai.numRequestNetworkRequests();
4731 break;
4732 case LINGER:
4733 numRequests = nai.numForegroundNetworkRequests();
4734 break;
4735 default:
Aaron Huang6616df32020-10-30 22:04:25 +08004736 Log.wtf(TAG, "Invalid reason. Cannot happen.");
Lorenzo Colitti2666be82016-09-09 18:48:56 +09004737 return true;
4738 }
4739
Chalard Jean947acd42021-03-08 22:29:27 +09004740 if (numRequests > 0) return false;
4741
Paul Jensende49eb12015-06-25 15:30:08 -04004742 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
James Mattis3d229892020-11-16 16:46:28 -08004743 if (reason == UnneededFor.LINGER
4744 && !nri.isMultilayerRequest()
4745 && nri.mRequests.get(0).isBackgroundRequest()) {
Lorenzo Colitti2666be82016-09-09 18:48:56 +09004746 // Background requests don't affect lingering.
4747 continue;
4748 }
4749
James Mattis3d229892020-11-16 16:46:28 -08004750 if (isNetworkPotentialSatisfier(nai, nri)) {
Paul Jensende49eb12015-06-25 15:30:08 -04004751 return false;
Paul Jensen9e078d22014-12-09 11:43:45 -05004752 }
4753 }
Paul Jensende49eb12015-06-25 15:30:08 -04004754 return true;
Paul Jensen9e078d22014-12-09 11:43:45 -05004755 }
4756
James Mattis3d229892020-11-16 16:46:28 -08004757 private boolean isNetworkPotentialSatisfier(
4758 @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) {
4759 // listen requests won't keep up a network satisfying it. If this is not a multilayer
James Mattis64b8b0f2020-11-24 17:40:49 -08004760 // request, return immediately. For multilayer requests, check to see if any of the
4761 // multilayer requests may have a potential satisfier.
junyulai1b1c8742021-03-12 20:05:08 +08004762 if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen()
4763 || nri.mRequests.get(0).isListenForBest())) {
James Mattis3d229892020-11-16 16:46:28 -08004764 return false;
4765 }
4766 for (final NetworkRequest req : nri.mRequests) {
James Mattisa076c532020-12-02 14:12:41 -08004767 // This multilayer listen request is satisfied therefore no further requests need to be
4768 // evaluated deeming this network not a potential satisfier.
junyulai1b1c8742021-03-12 20:05:08 +08004769 if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) {
James Mattisa076c532020-12-02 14:12:41 -08004770 return false;
4771 }
James Mattis3d229892020-11-16 16:46:28 -08004772 // As non-multilayer listen requests have already returned, the below would only happen
4773 // for a multilayer request therefore continue to the next request if available.
junyulai1b1c8742021-03-12 20:05:08 +08004774 if (req.isListen() || req.isListenForBest()) {
James Mattis3d229892020-11-16 16:46:28 -08004775 continue;
4776 }
Chalard Jean2a96cf22022-09-06 13:44:10 +09004777 // If this Network is already the best Network for a request, or if
James Mattis3d229892020-11-16 16:46:28 -08004778 // there is hope for it to become one if it validated, then it is needed.
4779 if (candidate.satisfies(req)) {
4780 // As soon as a network is found that satisfies a request, return. Specifically for
4781 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
4782 // is important so as to not evaluate lower priority requests further in
4783 // nri.mRequests.
Chalard Jeanc81d4c32021-04-07 17:06:19 +09004784 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest())
4785 ? nri.getSatisfier() : null;
4786 // Note that this catches two important cases:
4787 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
4788 // is currently satisfying the request. This is desirable when
4789 // cellular ends up validating but WiFi does not.
4790 // 2. Unvalidated WiFi will not be reaped when validated cellular
4791 // is currently satisfying the request. This is desirable when
4792 // WiFi ends up validating and out scoring cellular.
4793 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable());
James Mattis3d229892020-11-16 16:46:28 -08004794 }
4795 }
4796
4797 return false;
4798 }
4799
Erik Kline0c04b742016-07-07 16:50:58 +09004800 private NetworkRequestInfo getNriForAppRequest(
4801 NetworkRequest request, int callingUid, String requestedOperation) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08004802 // Looking up the app passed param request in mRequests isn't possible since it may return
4803 // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to
4804 // do the lookup since that will also find per-app default managed requests.
James Mattisd7647592021-02-17 16:13:05 -08004805 // Additionally, this lookup needs to be relatively fast (hence the lookup optimization)
4806 // to avoid potential race conditions when validating a package->uid mapping when sending
4807 // the callback on the very low-chance that an application shuts down prior to the callback
4808 // being sent.
4809 final NetworkRequestInfo nri = mNetworkRequests.get(request) != null
4810 ? mNetworkRequests.get(request) : getNriForAppRequest(request);
Erik Kline0c04b742016-07-07 16:50:58 +09004811
Robert Greenwaltf99b8392014-03-26 16:47:06 -07004812 if (nri != null) {
lucaslin5aad7852021-03-15 15:35:38 +08004813 if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
Erik Kline0c04b742016-07-07 16:50:58 +09004814 log(String.format("UID %d attempted to %s for unowned request %s",
4815 callingUid, requestedOperation, nri));
4816 return null;
Paul Jensen961cb0d2014-05-16 14:31:12 -04004817 }
Erik Kline0c04b742016-07-07 16:50:58 +09004818 }
4819
4820 return nri;
4821 }
4822
James Mattisf7027322020-12-13 16:28:14 -08004823 private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri,
4824 final String callingMethod) {
4825 if (nri.isMultilayerRequest()) {
4826 throw new IllegalStateException(
4827 callingMethod + " does not support multilayer requests.");
Erik Kline155a59a2015-11-25 12:49:38 +09004828 }
4829 }
4830
James Mattisf7027322020-12-13 16:28:14 -08004831 private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) {
Erik Kline0c04b742016-07-07 16:50:58 +09004832 ensureRunningOnConnectivityServiceThread();
James Mattisf7027322020-12-13 16:28:14 -08004833 // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a
4834 // single NetworkRequest and thus does not apply to multilayer requests.
4835 ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest");
4836 if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
Erik Kline0c04b742016-07-07 16:50:58 +09004837 return;
4838 }
James Mattis2516da32021-01-31 17:06:19 -08004839 if (nri.isBeingSatisfied()) {
Erik Kline0c04b742016-07-07 16:50:58 +09004840 return;
4841 }
James Mattisf7027322020-12-13 16:28:14 -08004842 if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
4843 log("releasing " + nri.mRequests.get(0) + " (timeout)");
Erik Kline0c04b742016-07-07 16:50:58 +09004844 }
4845 handleRemoveNetworkRequest(nri);
James Mattisf7027322020-12-13 16:28:14 -08004846 callCallbackForRequest(
4847 nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
Erik Kline0c04b742016-07-07 16:50:58 +09004848 }
4849
James Mattisf7027322020-12-13 16:28:14 -08004850 private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request,
4851 final int callingUid,
4852 final boolean callOnUnavailable) {
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09004853 final NetworkRequestInfo nri =
4854 getNriForAppRequest(request, callingUid, "release NetworkRequest");
4855 if (nri == null) {
4856 return;
Erik Kline155a59a2015-11-25 12:49:38 +09004857 }
James Mattisf7027322020-12-13 16:28:14 -08004858 if (VDBG || (DBG && request.isRequest())) {
4859 log("releasing " + request + " (release request)");
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09004860 }
4861 handleRemoveNetworkRequest(nri);
Etan Cohenfbfdd842019-01-08 12:09:18 -08004862 if (callOnUnavailable) {
4863 callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
4864 }
Erik Kline155a59a2015-11-25 12:49:38 +09004865 }
Erik Kline0c04b742016-07-07 16:50:58 +09004866
James Mattisa076c532020-12-02 14:12:41 -08004867 private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) {
Chalard Jean2c8b3e32019-11-05 14:40:23 +09004868 ensureRunningOnConnectivityServiceThread();
James Mattisa076c532020-12-02 14:12:41 -08004869 for (final NetworkRequest req : nri.mRequests) {
James Mattis8f036802021-06-20 16:26:01 -07004870 if (null == mNetworkRequests.remove(req)) {
4871 logw("Attempted removal of untracked request " + req + " for nri " + nri);
4872 continue;
4873 }
James Mattisa076c532020-12-02 14:12:41 -08004874 if (req.isListen()) {
4875 removeListenRequestFromNetworks(req);
4876 }
4877 }
James Mattis8f036802021-06-20 16:26:01 -07004878 nri.unlinkDeathRecipient();
Chalard Jean738c5bf2021-03-01 22:08:57 +09004879 if (mDefaultNetworkRequests.remove(nri)) {
4880 // If this request was one of the defaults, then the UID rules need to be updated
4881 // WARNING : if the app(s) for which this network request is the default are doing
4882 // traffic, this will kill their connected sockets, even if an equivalent request
4883 // is going to be reinstated right away ; unconnected traffic will go on the default
4884 // until the new default is set, which will happen very soon.
4885 // TODO : The only way out of this is to diff old defaults and new defaults, and only
4886 // remove ranges for those requests that won't have a replacement
4887 final NetworkAgentInfo satisfier = nri.getSatisfier();
4888 if (null != satisfier) {
4889 try {
paulhu0e79d952021-06-09 16:11:35 +08004890 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
4891 satisfier.network.getNetId(),
4892 toUidRangeStableParcels(nri.getUids()),
paulhu48291862021-07-14 14:53:57 +08004893 nri.getPreferenceOrderForNetd()));
Chalard Jean738c5bf2021-03-01 22:08:57 +09004894 } catch (RemoteException e) {
4895 loge("Exception setting network preference default network", e);
4896 }
4897 }
4898 }
Junyu Lai35665cc2022-12-19 17:37:48 +08004899
Junyu Lai00d92df2022-07-05 11:01:52 +08004900 nri.mPerUidCounter.decrementCount(nri.mUid);
Erik Kline0c04b742016-07-07 16:50:58 +09004901 mNetworkRequestInfoLogs.log("RELEASE " + nri);
Chalard Jean524f0b12021-10-25 21:11:56 +09004902 checkNrisConsistency(nri);
James Mattisa076c532020-12-02 14:12:41 -08004903
4904 if (null != nri.getActiveRequest()) {
Lorenzo Colitti96742d92021-01-29 20:18:03 +09004905 if (!nri.getActiveRequest().isListen()) {
James Mattisa076c532020-12-02 14:12:41 -08004906 removeSatisfiedNetworkRequestFromNetwork(nri);
James Mattisa076c532020-12-02 14:12:41 -08004907 }
4908 }
4909
Chalard Jean0354d8c2021-01-12 10:58:56 +09004910 // For all outstanding offers, cancel any of the layers of this NRI that used to be
4911 // needed for this offer.
4912 for (final NetworkOfferInfo noi : mNetworkOffers) {
4913 for (final NetworkRequest req : nri.mRequests) {
4914 if (req.isRequest() && noi.offer.neededFor(req)) {
4915 noi.offer.onNetworkUnneeded(req);
4916 }
4917 }
4918 }
James Mattisa076c532020-12-02 14:12:41 -08004919 }
4920
James Mattis3ce3d3c2021-02-09 18:18:28 -08004921 private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
4922 for (final NetworkRequestInfo nri : nris) {
4923 if (mDefaultRequest == nri) {
4924 // Make sure we never remove the default request.
4925 continue;
4926 }
4927 handleRemoveNetworkRequest(nri);
4928 }
4929 }
4930
James Mattisa076c532020-12-02 14:12:41 -08004931 private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) {
4932 // listens don't have a singular affected Network. Check all networks to see
4933 // if this listen request applies and remove it.
4934 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
4935 nai.removeRequest(req.requestId);
4936 if (req.networkCapabilities.hasSignalStrength()
4937 && nai.satisfiesImmutableCapabilitiesOf(req)) {
4938 updateSignalStrengthThresholds(nai, "RELEASE", req);
4939 }
4940 }
4941 }
4942
4943 /**
4944 * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and
4945 * manage the necessary upkeep (linger, teardown networks, etc.) when doing so.
4946 * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo
4947 */
4948 private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) {
4949 boolean wasKept = false;
4950 final NetworkAgentInfo nai = nri.getSatisfier();
4951 if (nai != null) {
4952 final int requestLegacyType = nri.getActiveRequest().legacyType;
4953 final boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
4954 nai.removeRequest(nri.getActiveRequest().requestId);
4955 if (VDBG || DDBG) {
4956 log(" Removing from current network " + nai.toShortString()
4957 + ", leaving " + nai.numNetworkRequests() + " requests.");
4958 }
4959 // If there are still lingered requests on this network, don't tear it down,
4960 // but resume lingering instead.
4961 final long now = SystemClock.elapsedRealtime();
junyulai2b6f0c22021-02-03 20:15:30 +08004962 if (updateInactivityState(nai, now)) {
James Mattisa076c532020-12-02 14:12:41 -08004963 notifyNetworkLosing(nai, now);
4964 }
4965 if (unneeded(nai, UnneededFor.TEARDOWN)) {
4966 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting");
4967 teardownUnneededNetwork(nai);
4968 } else {
4969 wasKept = true;
4970 }
James Mattisa076c532020-12-02 14:12:41 -08004971 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
4972 // Went from foreground to background.
4973 updateCapabilitiesForNetwork(nai);
Erik Kline0c04b742016-07-07 16:50:58 +09004974 }
4975
Erik Kline0c04b742016-07-07 16:50:58 +09004976 // Maintain the illusion. When this request arrived, we might have pretended
4977 // that a network connected to serve it, even though the network was already
4978 // connected. Now that this request has gone away, we might have to pretend
4979 // that the network disconnected. LegacyTypeTracker will generate that
4980 // phantom disconnect for this type.
James Mattisa076c532020-12-02 14:12:41 -08004981 if (requestLegacyType != TYPE_NONE) {
Erik Kline0c04b742016-07-07 16:50:58 +09004982 boolean doRemove = true;
4983 if (wasKept) {
4984 // check if any of the remaining requests for this network are for the
4985 // same legacy type - if so, don't remove the nai
4986 for (int i = 0; i < nai.numNetworkRequests(); i++) {
4987 NetworkRequest otherRequest = nai.requestAt(i);
James Mattisa076c532020-12-02 14:12:41 -08004988 if (otherRequest.legacyType == requestLegacyType
4989 && otherRequest.isRequest()) {
Erik Kline0c04b742016-07-07 16:50:58 +09004990 if (DBG) log(" still have other legacy request - leaving");
4991 doRemove = false;
Robert Greenwalte8a91242015-01-08 14:43:31 -08004992 }
4993 }
Robert Greenwalt8c5842c2014-08-24 22:52:10 -07004994 }
4995
Erik Kline0c04b742016-07-07 16:50:58 +09004996 if (doRemove) {
James Mattisa076c532020-12-02 14:12:41 -08004997 mLegacyTypeTracker.remove(requestLegacyType, nai, false);
Erik Kline0c04b742016-07-07 16:50:58 +09004998 }
4999 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005000 }
5001 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07005002
Junyu Lai00d92df2022-07-05 11:01:52 +08005003 private RequestInfoPerUidCounter getRequestCounter(NetworkRequestInfo nri) {
Junyu Lai4c6fe232023-04-11 11:33:46 +08005004 return checkAnyPermissionOf(mContext,
Lorenzo Colitti6dba5882021-03-30 19:29:00 +09005005 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
5006 ? mSystemNetworkRequestCounter : mNetworkRequestCounter;
5007 }
5008
Lorenzo Colittid6459092016-07-04 12:55:44 +09005009 @Override
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005010 public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
lucaslin2240ef62019-03-12 13:08:03 +08005011 enforceNetworkStackSettingsOrSetup();
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005012 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
Hugo Benichif4210292017-04-21 15:07:12 +09005013 encodeBool(accept), encodeBool(always), network));
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005014 }
5015
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005016 @Override
lucaslin2240ef62019-03-12 13:08:03 +08005017 public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
5018 enforceNetworkStackSettingsOrSetup();
5019 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
5020 encodeBool(accept), encodeBool(always), network));
5021 }
5022
5023 @Override
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005024 public void setAvoidUnvalidated(Network network) {
lucaslin2240ef62019-03-12 13:08:03 +08005025 enforceNetworkStackSettingsOrSetup();
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005026 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
5027 }
5028
Chiachang Wang6eac9fb2021-06-17 22:11:30 +08005029 @Override
5030 public void setTestAllowBadWifiUntil(long timeMs) {
5031 enforceSettingsPermission();
5032 if (!Build.isDebuggable()) {
5033 throw new IllegalStateException("Does not support in non-debuggable build");
5034 }
5035
5036 if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) {
5037 throw new IllegalArgumentException("It should not exceed "
5038 + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now");
5039 }
5040
5041 mHandler.sendMessage(
5042 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs));
5043 }
5044
chiachangwange0192a72023-02-06 13:25:01 +00005045 @Override
5046 public void setTestLowTcpPollingTimerForKeepalive(long timeMs) {
5047 enforceSettingsPermission();
chiachangwange0192a72023-02-06 13:25:01 +00005048
5049 if (timeMs > System.currentTimeMillis() + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS) {
5050 throw new IllegalArgumentException("Argument should not exceed "
5051 + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS + "ms from now");
5052 }
5053
5054 mHandler.sendMessage(
5055 mHandler.obtainMessage(EVENT_SET_LOW_TCP_POLLING_UNTIL, timeMs));
5056 }
5057
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005058 private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
5059 if (DBG) log("handleSetAcceptUnvalidated network=" + network +
5060 " accept=" + accept + " always=" + always);
5061
5062 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5063 if (nai == null) {
5064 // Nothing to do.
5065 return;
5066 }
5067
Chalard Jean254bd162022-08-25 13:04:51 +09005068 if (nai.everValidated()) {
Lorenzo Colitti74baf412015-05-21 16:17:05 +09005069 // The network validated while the dialog box was up. Take no action.
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005070 return;
5071 }
5072
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005073 if (!nai.networkAgentConfig.explicitlySelected) {
Aaron Huang6616df32020-10-30 22:04:25 +08005074 Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005075 }
5076
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005077 if (accept != nai.networkAgentConfig.acceptUnvalidated) {
5078 nai.networkAgentConfig.acceptUnvalidated = accept;
lucaslin2240ef62019-03-12 13:08:03 +08005079 // If network becomes partial connectivity and user already accepted to use this
5080 // network, we should respect the user's option and don't need to popup the
5081 // PARTIAL_CONNECTIVITY notification to user again.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005082 nai.networkAgentConfig.acceptPartialConnectivity = accept;
Chalard Jean142f0fe2021-03-31 23:19:05 +09005083 nai.updateScoreForNetworkAgentUpdate();
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09005084 rematchAllNetworksAndRequests();
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005085 }
5086
5087 if (always) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09005088 nai.onSaveAcceptUnvalidated(accept);
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005089 }
5090
Lorenzo Colitti74baf412015-05-21 16:17:05 +09005091 if (!accept) {
Paul Jensen57e65702015-07-13 15:19:51 -04005092 // Tell the NetworkAgent to not automatically reconnect to the network.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09005093 nai.onPreventAutomaticReconnect();
Chalard Jean9dd11612018-06-04 16:52:49 +09005094 // Teardown the network.
Paul Jensen57e65702015-07-13 15:19:51 -04005095 teardownUnneededNetwork(nai);
Lorenzo Colitti74baf412015-05-21 16:17:05 +09005096 }
5097
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005098 }
5099
lucaslin2240ef62019-03-12 13:08:03 +08005100 private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
5101 boolean always) {
5102 if (DBG) {
5103 log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
5104 + " always=" + always);
5105 }
5106
5107 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5108 if (nai == null) {
5109 // Nothing to do.
5110 return;
5111 }
5112
Chalard Jean254bd162022-08-25 13:04:51 +09005113 if (nai.isValidated()) {
lucaslin2240ef62019-03-12 13:08:03 +08005114 // The network validated while the dialog box was up. Take no action.
5115 return;
5116 }
5117
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005118 if (accept != nai.networkAgentConfig.acceptPartialConnectivity) {
5119 nai.networkAgentConfig.acceptPartialConnectivity = accept;
lucaslin2240ef62019-03-12 13:08:03 +08005120 }
5121
5122 // TODO: Use the current design or save the user choice into IpMemoryStore.
5123 if (always) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09005124 nai.onSaveAcceptUnvalidated(accept);
lucaslin2240ef62019-03-12 13:08:03 +08005125 }
5126
5127 if (!accept) {
5128 // Tell the NetworkAgent to not automatically reconnect to the network.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09005129 nai.onPreventAutomaticReconnect();
lucaslin2240ef62019-03-12 13:08:03 +08005130 // Tear down the network.
5131 teardownUnneededNetwork(nai);
5132 } else {
lucaslinf9bff5b2019-03-20 18:21:59 +08005133 // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
5134 // result in a partial connectivity result which will be processed by
5135 // maybeHandleNetworkMonitorMessage.
Chiachang Wangeff18972019-05-23 16:29:30 +08005136 //
5137 // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
5138 // per network. Therefore, NetworkMonitor may still do https probe.
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09005139 nai.networkMonitor().setAcceptPartialConnectivity();
lucaslin2240ef62019-03-12 13:08:03 +08005140 }
5141 }
5142
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005143 private void handleSetAvoidUnvalidated(Network network) {
5144 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Chalard Jean254bd162022-08-25 13:04:51 +09005145 if (nai == null || nai.isValidated()) {
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005146 // Nothing to do. The network either disconnected or revalidated.
5147 return;
5148 }
Chalard Jean254bd162022-08-25 13:04:51 +09005149 if (0L == nai.getAvoidUnvalidated()) {
5150 nai.setAvoidUnvalidated();
Chalard Jean142f0fe2021-03-31 23:19:05 +09005151 nai.updateScoreForNetworkAgentUpdate();
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09005152 rematchAllNetworksAndRequests();
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005153 }
5154 }
5155
Chalard Jean5fb43c72022-09-08 19:03:14 +09005156 /** Schedule evaluation timeout */
Chalard Jean4c463082022-09-08 20:52:25 +09005157 @VisibleForTesting
Chalard Jean5fb43c72022-09-08 19:03:14 +09005158 public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) {
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005159 mHandler.sendMessageDelayed(
Chalard Jean5fb43c72022-09-08 19:03:14 +09005160 mHandler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs);
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005161 }
5162
Lorenzo Colitti500dbae2017-04-27 14:30:21 +09005163 @Override
5164 public void startCaptivePortalApp(Network network) {
paulhu8e96a752019-08-12 16:25:11 +08005165 enforceNetworkStackOrSettingsPermission();
Lorenzo Colitti500dbae2017-04-27 14:30:21 +09005166 mHandler.post(() -> {
5167 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5168 if (nai == null) return;
5169 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09005170 nai.networkMonitor().launchCaptivePortalApp();
Lorenzo Colitti500dbae2017-04-27 14:30:21 +09005171 });
5172 }
5173
Remi NGUYEN VAN94ff95b2019-02-04 11:32:20 +09005174 /**
5175 * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
5176 * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005177 * @param network Network on which the captive portal was detected.
Remi NGUYEN VAN94ff95b2019-02-04 11:32:20 +09005178 * @param appExtras Bundle to use as intent extras for the captive portal application.
5179 * Must be treated as opaque to avoid preventing the captive portal app to
5180 * update its arguments.
5181 */
5182 @Override
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005183 public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
paulhude3a2452019-05-14 14:17:44 +08005184 mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
5185 "ConnectivityService");
Remi NGUYEN VAN94ff95b2019-02-04 11:32:20 +09005186
5187 final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
5188 appIntent.putExtras(appExtras);
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005189 appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
5190 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
Remi NGUYEN VAN94ff95b2019-02-04 11:32:20 +09005191 appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
5192
lucaslin75ff7022020-12-17 04:14:35 +08005193 final long token = Binder.clearCallingIdentity();
5194 try {
5195 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT);
5196 } finally {
5197 Binder.restoreCallingIdentity(token);
5198 }
Remi NGUYEN VAN94ff95b2019-02-04 11:32:20 +09005199 }
5200
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005201 private class CaptivePortalImpl extends ICaptivePortal.Stub {
5202 private final Network mNetwork;
5203
5204 private CaptivePortalImpl(Network network) {
5205 mNetwork = network;
5206 }
5207
5208 @Override
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09005209 public void appResponse(final int response) {
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005210 if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
5211 enforceSettingsPermission();
Hansen Kurli55396972022-10-28 03:31:17 +00005212 } else if (response == CaptivePortal.APP_RETURN_UNWANTED) {
5213 mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork));
5214 // Since the network will be disconnected, skip notifying NetworkMonitor
5215 return;
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005216 }
5217
Chiachang Wang938bfba2020-01-09 13:50:55 +08005218 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005219 if (nm == null) return;
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09005220 nm.notifyCaptivePortalAppFinished(response);
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005221 }
5222
5223 @Override
Chiachang Wang938bfba2020-01-09 13:50:55 +08005224 public void appRequest(final int request) {
5225 final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
5226 if (nm == null) return;
5227
5228 if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) {
Chiachang Wangf7a0f122020-02-12 13:44:50 +08005229 checkNetworkStackPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09005230 nm.forceReevaluation(mDeps.getCallingUid());
Chiachang Wang938bfba2020-01-09 13:50:55 +08005231 }
5232 }
5233
5234 @Nullable
5235 private NetworkMonitorManager getNetworkMonitorManager(final Network network) {
5236 // getNetworkAgentInfoForNetwork is thread-safe
5237 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5238 if (nai == null) return null;
5239
5240 // nai.networkMonitor() is thread-safe
5241 return nai.networkMonitor();
5242 }
Remi NGUYEN VANeab0f542019-02-13 20:58:59 +09005243 }
5244
Hugo Benichic9048bc2016-09-14 23:23:08 +00005245 public boolean avoidBadWifi() {
Lorenzo Colittiee6c69e2017-01-24 09:41:36 +09005246 return mMultinetworkPolicyTracker.getAvoidBadWifi();
Lorenzo Colitti21924542016-09-16 23:43:38 +09005247 }
5248
Chalard Jean020b93a2022-09-01 13:20:14 +09005249 private boolean activelyPreferBadWifi() {
5250 return mMultinetworkPolicyTracker.getActivelyPreferBadWifi();
5251 }
5252
Remi NGUYEN VAN1fb7cab2019-03-22 11:14:13 +09005253 /**
5254 * Return whether the device should maintain continuous, working connectivity by switching away
5255 * from WiFi networks having no connectivity.
5256 * @see MultinetworkPolicyTracker#getAvoidBadWifi()
5257 */
5258 public boolean shouldAvoidBadWifi() {
Remi NGUYEN VAN27de63e2019-01-20 20:35:06 +09005259 if (!checkNetworkStackPermission()) {
5260 throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
5261 }
5262 return avoidBadWifi();
5263 }
5264
Chalard Jeanf3ff3622021-03-19 13:49:56 +09005265 private void updateAvoidBadWifi() {
Chalard Jeanbb902a52021-08-18 01:35:19 +09005266 ensureRunningOnConnectivityServiceThread();
5267 // Agent info scores and offer scores depend on whether cells yields to bad wifi.
Chalard Jean1325a632022-09-16 18:01:12 +09005268 final boolean avoidBadWifi = avoidBadWifi();
Chalard Jeanf3ff3622021-03-19 13:49:56 +09005269 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
Chalard Jean142f0fe2021-03-31 23:19:05 +09005270 nai.updateScoreForNetworkAgentUpdate();
Chalard Jean1325a632022-09-16 18:01:12 +09005271 if (avoidBadWifi) {
5272 // If the device is now avoiding bad wifi, remove notifications that might have
5273 // been put up when the device didn't.
5274 mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET);
5275 }
Chalard Jeanf3ff3622021-03-19 13:49:56 +09005276 }
Chalard Jeanbb902a52021-08-18 01:35:19 +09005277 // UpdateOfferScore will update mNetworkOffers inline, so make a copy first.
5278 final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers);
5279 for (final NetworkOfferInfo noi : offersToUpdate) {
5280 updateOfferScore(noi.offer);
5281 }
Chalard Jean020b93a2022-09-01 13:20:14 +09005282 mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi()));
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09005283 rematchAllNetworksAndRequests();
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005284 }
5285
Erik Kline95ecfee2016-10-02 18:02:14 +09005286 // TODO: Evaluate whether this is of interest to other consumers of
Lorenzo Colittiee6c69e2017-01-24 09:41:36 +09005287 // MultinetworkPolicyTracker and worth moving out of here.
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005288 private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
Lorenzo Colittiee6c69e2017-01-24 09:41:36 +09005289 final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005290 if (!configRestrict) {
5291 pw.println("Bad Wi-Fi avoidance: unrestricted");
5292 return;
5293 }
5294
5295 pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
5296 pw.increaseIndent();
Chalard Jeane0fdea32022-09-14 21:44:22 +09005297 pw.println("Config restrict: " + configRestrict);
5298 pw.println("Actively prefer bad wifi: " + activelyPreferBadWifi());
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005299
Chalard Jeane0fdea32022-09-14 21:44:22 +09005300 final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005301 String description;
5302 // Can't use a switch statement because strings are legal case labels, but null is not.
Chalard Jeane0fdea32022-09-14 21:44:22 +09005303 if ("0".equals(settingValue)) {
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005304 description = "get stuck";
Chalard Jeane0fdea32022-09-14 21:44:22 +09005305 } else if (settingValue == null) {
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005306 description = "prompt";
Chalard Jeane0fdea32022-09-14 21:44:22 +09005307 } else if ("1".equals(settingValue)) {
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005308 description = "avoid";
5309 } else {
Chalard Jeane0fdea32022-09-14 21:44:22 +09005310 description = settingValue + " (?)";
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005311 }
Chalard Jeane0fdea32022-09-14 21:44:22 +09005312 pw.println("Avoid bad wifi setting: " + description);
chiachangwang18a6e8c2022-12-01 00:22:34 +00005313
5314 final Boolean configValue = BinderUtils.withCleanCallingIdentity(
5315 () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi());
Chalard Jeane0fdea32022-09-14 21:44:22 +09005316 if (null == configValue) {
5317 description = "unset";
5318 } else if (configValue) {
5319 description = "force true";
5320 } else {
5321 description = "force false";
5322 }
5323 pw.println("Actively prefer bad wifi conf: " + description);
5324 pw.println();
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005325 pw.println("Network overrides:");
5326 pw.increaseIndent();
Hugo Benichia480ba52018-09-03 08:19:02 +09005327 for (NetworkAgentInfo nai : networksSortedById()) {
Chalard Jean254bd162022-08-25 13:04:51 +09005328 if (0L != nai.getAvoidUnvalidated()) {
Chalard Jean49707572019-12-10 21:07:02 +09005329 pw.println(nai.toShortString());
Lorenzo Colittia4e88082016-09-20 16:03:27 +09005330 }
5331 }
5332 pw.decreaseIndent();
5333 pw.decreaseIndent();
5334 }
5335
paulhu7746e4e2020-06-09 19:07:03 +08005336 // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to
5337 // unify the method.
5338 private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) {
5339 final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
5340 final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
5341 return settingsComponent != null
5342 ? settingsComponent.getPackageName() : "com.android.settings";
5343 }
5344
lucaslinb1e8e382019-01-24 15:55:30 +08005345 private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005346 final String action;
Lorenzo Colitti8a2348f2019-06-05 16:08:37 +09005347 final boolean highPriority;
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005348 switch (type) {
5349 case NO_INTERNET:
5350 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
Lorenzo Colitti8a2348f2019-06-05 16:08:37 +09005351 // High priority because it is only displayed for explicitly selected networks.
5352 highPriority = true;
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005353 break;
lucasline117e2e2019-10-22 18:27:33 +08005354 case PRIVATE_DNS_BROKEN:
5355 action = Settings.ACTION_WIRELESS_SETTINGS;
5356 // High priority because we should let user know why there is no internet.
5357 highPriority = true;
5358 break;
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005359 case LOST_INTERNET:
5360 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
Lorenzo Colitti8a2348f2019-06-05 16:08:37 +09005361 // High priority because it could help the user avoid unexpected data usage.
5362 highPriority = true;
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005363 break;
lucaslin2240ef62019-03-12 13:08:03 +08005364 case PARTIAL_CONNECTIVITY:
5365 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
Lorenzo Colitti8a2348f2019-06-05 16:08:37 +09005366 // Don't bother the user with a high-priority notification if the network was not
5367 // explicitly selected by the user.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005368 highPriority = nai.networkAgentConfig.explicitlySelected;
lucaslin2240ef62019-03-12 13:08:03 +08005369 break;
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005370 default:
Aaron Huang6616df32020-10-30 22:04:25 +08005371 Log.wtf(TAG, "Unknown notification type " + type);
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005372 return;
5373 }
5374
5375 Intent intent = new Intent(action);
lucaslin444d43a2020-02-20 16:56:59 +08005376 if (type != NotificationType.PRIVATE_DNS_BROKEN) {
Chiachang Wang08d36912021-03-18 16:20:27 +08005377 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
lucaslinb1e8e382019-01-24 15:55:30 +08005378 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
paulhu7746e4e2020-06-09 19:07:03 +08005379 // Some OEMs have their own Settings package. Thus, need to get the current using
5380 // Settings package name instead of just use default name "com.android.settings".
5381 final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager());
5382 intent.setClassName(settingsPkgName,
5383 settingsPkgName + ".wifi.WifiNoInternetDialog");
lucaslinb1e8e382019-01-24 15:55:30 +08005384 }
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005385
paulhu2af50222020-10-11 22:52:27 +08005386 PendingIntent pendingIntent = PendingIntent.getActivity(
5387 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
paulhu7746e4e2020-06-09 19:07:03 +08005388 0 /* requestCode */,
5389 intent,
paulhu2af50222020-10-11 22:52:27 +08005390 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Lorenzo Colitti8a2348f2019-06-05 16:08:37 +09005391
Serik Beketayevec8ad212020-12-07 22:43:07 -08005392 mNotifier.showNotification(
5393 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority);
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005394 }
5395
Lorenzo Colitti2fca94f2019-06-04 19:29:50 +09005396 private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
5397 // Don't prompt if the network is validated, and don't prompt on captive portals
5398 // because we're already prompting the user to sign in.
Chalard Jean254bd162022-08-25 13:04:51 +09005399 if (nai.everValidated() || nai.everCaptivePortalDetected()) {
Lorenzo Colitti2fca94f2019-06-04 19:29:50 +09005400 return false;
5401 }
5402
5403 // If a network has partial connectivity, always prompt unless the user has already accepted
5404 // partial connectivity and selected don't ask again. This ensures that if the device
5405 // automatically connects to a network that has partial Internet access, the user will
5406 // always be able to use it, either because they've already chosen "don't ask again" or
Chalard Jean254bd162022-08-25 13:04:51 +09005407 // because we have prompted them.
5408 if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) {
Lorenzo Colitti2fca94f2019-06-04 19:29:50 +09005409 return true;
5410 }
5411
5412 // If a network has no Internet access, only prompt if the network was explicitly selected
5413 // and if the user has not already told us to use the network regardless of whether it
5414 // validated or not.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09005415 if (nai.networkAgentConfig.explicitlySelected
5416 && !nai.networkAgentConfig.acceptUnvalidated) {
Lorenzo Colitti2fca94f2019-06-04 19:29:50 +09005417 return true;
5418 }
5419
5420 return false;
5421 }
5422
Chalard Jean5fb43c72022-09-08 19:03:14 +09005423 private void handleInitialEvaluationTimeout(@NonNull final Network network) {
5424 if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network);
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005425
Chalard Jean5fb43c72022-09-08 19:03:14 +09005426 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5427 if (null == nai) return;
5428
5429 if (nai.setEvaluated()) {
5430 // If setEvaluated() returned true, the network never had any form of connectivity.
5431 // This may have an impact on request matching if bad WiFi avoidance is off and the
5432 // network was found not to have Internet access.
5433 nai.updateScoreForNetworkAgentUpdate();
5434 rematchAllNetworksAndRequests();
Chalard Jeane9332c42022-09-13 20:46:19 +09005435
5436 // Also, if this is WiFi and it should be preferred actively, now is the time to
5437 // prompt the user that they walked past and connected to a bad WiFi.
5438 if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI)
5439 && !avoidBadWifi()
5440 && activelyPreferBadWifi()) {
5441 // The notification will be removed if the network validates or disconnects.
5442 showNetworkNotification(nai, NotificationType.LOST_INTERNET);
5443 return;
5444 }
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005445 }
Lorenzo Colitti2f2b9612019-05-30 16:24:31 +09005446
Chalard Jean5fb43c72022-09-08 19:03:14 +09005447 if (!shouldPromptUnvalidated(nai)) return;
5448
Lorenzo Colitti2f2b9612019-05-30 16:24:31 +09005449 // Stop automatically reconnecting to this network in the future. Automatically connecting
5450 // to a network that provides no or limited connectivity is not useful, because the user
5451 // cannot use that network except through the notification shown by this method, and the
5452 // notification is only shown if the network is explicitly selected by the user.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09005453 nai.onPreventAutomaticReconnect();
Lorenzo Colitti2f2b9612019-05-30 16:24:31 +09005454
Chalard Jean254bd162022-08-25 13:04:51 +09005455 if (nai.partialConnectivity()) {
lucasline0118ab2019-03-21 11:59:22 +08005456 showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
lucaslin2240ef62019-03-12 13:08:03 +08005457 } else {
5458 showNetworkNotification(nai, NotificationType.NO_INTERNET);
5459 }
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005460 }
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005461
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005462 private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
5463 NetworkCapabilities nc = nai.networkCapabilities;
Chalard Jean49707572019-12-10 21:07:02 +09005464 if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc);
fionaxu5310c302016-05-23 16:33:16 -07005465
lucaslin2240ef62019-03-12 13:08:03 +08005466 if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
5467 return;
5468 }
5469
5470 if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
lucaslinb1e8e382019-01-24 15:55:30 +08005471 showNetworkNotification(nai, NotificationType.LOST_INTERNET);
Lorenzo Colitti199ecfc2016-09-15 14:02:29 +09005472 }
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005473 }
5474
Lorenzo Colitti48a2a322017-01-24 18:08:41 +09005475 @Override
5476 public int getMultipathPreference(Network network) {
5477 enforceAccessPermission();
5478
5479 NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Jeff Sharkeyadebffc2017-07-12 10:50:42 -06005480 if (nai != null && nai.networkCapabilities
5481 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
Lorenzo Colitti48a2a322017-01-24 18:08:41 +09005482 return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
5483 }
5484
Aaron Huang9a57acf2020-12-08 10:03:29 +08005485 final NetworkPolicyManager netPolicyManager =
5486 mContext.getSystemService(NetworkPolicyManager.class);
5487
Remi NGUYEN VANe2139a02021-03-18 14:23:12 +09005488 final long token = Binder.clearCallingIdentity();
5489 final int networkPreference;
5490 try {
5491 networkPreference = netPolicyManager.getMultipathPreference(network);
5492 } finally {
5493 Binder.restoreCallingIdentity(token);
5494 }
Aaron Huang9a57acf2020-12-08 10:03:29 +08005495 if (networkPreference != 0) {
Lorenzo Colitti389a8142018-01-24 17:35:07 +09005496 return networkPreference;
5497 }
Lorenzo Colitti48a2a322017-01-24 18:08:41 +09005498 return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
5499 }
5500
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09005501 @Override
5502 public NetworkRequest getDefaultRequest() {
Chalard Jean5b409c72021-02-04 13:12:59 +09005503 return mDefaultRequest.mRequests.get(0);
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09005504 }
5505
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07005506 private class InternalHandler extends Handler {
5507 public InternalHandler(Looper looper) {
5508 super(looper);
5509 }
5510
5511 @Override
5512 public void handleMessage(Message msg) {
Jeff Sharkeya1ef1be2012-07-23 13:19:46 -07005513 switch (msg.what) {
Robert Greenwalt520d6dc2014-06-25 16:45:57 -07005514 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
Sreeram Ramachandran1b5a3ac2013-08-27 11:41:19 -07005515 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
Hugo Benichi471b62a2017-03-30 23:18:10 +09005516 handleReleaseNetworkTransitionWakelock(msg.what);
Robert Greenwaltcf1a56c2010-09-09 14:05:10 -07005517 break;
Sreeram Ramachandran1b5a3ac2013-08-27 11:41:19 -07005518 }
Sreeram Ramachandran1b5a3ac2013-08-27 11:41:19 -07005519 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
Chalard Jean09335372018-06-08 14:24:49 +09005520 mProxyTracker.loadDeprecatedGlobalHttpProxy();
Robert Greenwalt34848c02011-03-25 13:09:25 -07005521 break;
5522 }
Jason Monka69f1b02013-10-10 14:02:51 -04005523 case EVENT_PROXY_HAS_CHANGED: {
Aaron Huangf9fa0b92021-01-18 15:28:01 +08005524 final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj;
5525 handleApplyDefaultProxy(arg.second);
Jason Monka69f1b02013-10-10 14:02:51 -04005526 break;
5527 }
Lorenzo Colittia86fae72020-01-10 00:40:28 +09005528 case EVENT_REGISTER_NETWORK_PROVIDER: {
5529 handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj);
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07005530 break;
5531 }
Lorenzo Colittia86fae72020-01-10 00:40:28 +09005532 case EVENT_UNREGISTER_NETWORK_PROVIDER: {
5533 handleUnregisterNetworkProvider((Messenger) msg.obj);
Robert Greenwalt7e45d112014-04-11 15:53:27 -07005534 break;
5535 }
Chalard Jeancdd68bc2021-01-05 08:40:09 +09005536 case EVENT_REGISTER_NETWORK_OFFER: {
5537 handleRegisterNetworkOffer((NetworkOffer) msg.obj);
5538 break;
5539 }
5540 case EVENT_UNREGISTER_NETWORK_OFFER: {
5541 final NetworkOfferInfo offer =
5542 findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
5543 if (null != offer) {
5544 handleUnregisterNetworkOffer(offer);
5545 }
5546 break;
5547 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07005548 case EVENT_REGISTER_NETWORK_AGENT: {
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09005549 final Pair<NetworkAgentInfo, INetworkMonitor> arg =
5550 (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
5551 handleRegisterNetworkAgent(arg.first, arg.second);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07005552 break;
5553 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005554 case EVENT_REGISTER_NETWORK_REQUEST:
5555 case EVENT_REGISTER_NETWORK_LISTENER: {
Erik Kline05f2b402015-04-30 12:58:40 +09005556 handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005557 break;
5558 }
Paul Jensenc8873fc2015-06-17 14:15:39 -04005559 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
5560 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
Jeremy Joslin60d379b2014-11-05 10:32:09 -08005561 handleRegisterNetworkRequestWithIntent(msg);
5562 break;
5563 }
Erik Kline155a59a2015-11-25 12:49:38 +09005564 case EVENT_TIMEOUT_NETWORK_REQUEST: {
5565 NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
5566 handleTimedOutNetworkRequest(nri);
5567 break;
5568 }
Jeremy Joslin60d379b2014-11-05 10:32:09 -08005569 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
5570 handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
5571 break;
5572 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005573 case EVENT_RELEASE_NETWORK_REQUEST: {
Etan Cohenfbfdd842019-01-08 12:09:18 -08005574 handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
5575 /* callOnUnavailable */ false);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005576 break;
5577 }
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005578 case EVENT_SET_ACCEPT_UNVALIDATED: {
Hugo Benichif4210292017-04-21 15:07:12 +09005579 Network network = (Network) msg.obj;
5580 handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005581 break;
5582 }
lucaslin2240ef62019-03-12 13:08:03 +08005583 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
5584 Network network = (Network) msg.obj;
5585 handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
5586 toBool(msg.arg2));
5587 break;
5588 }
Lorenzo Colittic65750c2016-09-19 01:00:19 +09005589 case EVENT_SET_AVOID_UNVALIDATED: {
5590 handleSetAvoidUnvalidated((Network) msg.obj);
5591 break;
5592 }
Chalard Jean5fb43c72022-09-08 19:03:14 +09005593 case EVENT_INITIAL_EVALUATION_TIMEOUT: {
5594 handleInitialEvaluationTimeout((Network) msg.obj);
Lorenzo Colitti6947c062015-04-03 16:38:52 +09005595 break;
5596 }
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07005597 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
5598 handleConfigureAlwaysOnNetworks();
Erik Kline05f2b402015-04-30 12:58:40 +09005599 break;
5600 }
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09005601 // Sent by KeepaliveTracker to process an app request on the state machine thread.
junyulai011b1f12019-01-03 18:50:15 +08005602 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: {
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09005603 mKeepaliveTracker.handleStartKeepalive(msg);
5604 break;
5605 }
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005606 case NetworkAgent.CMD_MONITOR_AUTOMATIC_KEEPALIVE: {
Chalard Jean98732db2023-02-03 21:26:59 +09005607 final AutomaticOnOffKeepalive ki =
5608 mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj);
5609 if (null == ki) return; // The callback was unregistered before the alarm fired
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005610
chiachangwang676c84e2023-02-14 09:22:05 +00005611 final Network underpinnedNetwork = ki.getUnderpinnedNetwork();
Chalard Jean23f1bfd2023-01-24 17:11:27 +09005612 final Network network = ki.getNetwork();
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005613 boolean networkFound = false;
chiachangwang676c84e2023-02-14 09:22:05 +00005614 boolean underpinnedNetworkFound = false;
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005615 for (NetworkAgentInfo n : mNetworkAgentInfos) {
5616 if (n.network.equals(network)) networkFound = true;
chiachangwang676c84e2023-02-14 09:22:05 +00005617 if (n.everConnected() && n.network.equals(underpinnedNetwork)) {
5618 underpinnedNetworkFound = true;
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005619 }
5620 }
5621
5622 // If the network no longer exists, then the keepalive should have been
5623 // cleaned up already. There is no point trying to resume keepalives.
5624 if (!networkFound) return;
5625
chiachangwang676c84e2023-02-14 09:22:05 +00005626 if (underpinnedNetworkFound) {
Chalard Jean23f1bfd2023-01-24 17:11:27 +09005627 mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki,
chiachangwang676c84e2023-02-14 09:22:05 +00005628 underpinnedNetwork.netId);
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005629 } else {
chiachangwang676c84e2023-02-14 09:22:05 +00005630 // If no underpinned network, then make sure the keepalive is running.
Chalard Jean23f1bfd2023-01-24 17:11:27 +09005631 mKeepaliveTracker.handleMaybeResumeKeepalive(ki);
chiachangwang9ef4ffe2023-01-18 01:19:27 +00005632 }
5633 break;
5634 }
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09005635 // Sent by KeepaliveTracker to process an app request on the state machine thread.
junyulai011b1f12019-01-03 18:50:15 +08005636 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
Chalard Jeanf0b261e2023-02-03 22:11:20 +09005637 final AutomaticOnOffKeepalive ki = mKeepaliveTracker.getKeepaliveForBinder(
5638 (IBinder) msg.obj);
5639 if (ki == null) {
5640 Log.e(TAG, "Attempt to stop an already stopped keepalive");
chiachangwangd50f9512023-01-31 06:56:13 +00005641 return;
5642 }
Chalard Jeanf0b261e2023-02-03 22:11:20 +09005643 final int reason = msg.arg2;
5644 mKeepaliveTracker.handleStopKeepalive(ki, reason);
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09005645 break;
5646 }
Cody Kestingf1120be2020-08-03 18:01:40 -07005647 case EVENT_REPORT_NETWORK_CONNECTIVITY: {
5648 handleReportNetworkConnectivity((NetworkAgentInfo) msg.obj, msg.arg1,
5649 toBool(msg.arg2));
Hugo Benichid6b510a2017-04-06 17:22:18 +09005650 break;
5651 }
Erik Kline31b4a9e2018-01-11 21:07:29 +09005652 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
5653 handlePrivateDnsSettingsChanged();
5654 break;
dalyk1720e542018-03-05 12:42:22 -05005655 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
5656 handlePrivateDnsValidationUpdate(
5657 (PrivateDnsValidationUpdate) msg.obj);
5658 break;
Sudheer Shanka9967d462021-03-18 19:09:25 +00005659 case EVENT_UID_BLOCKED_REASON_CHANGED:
5660 handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
junyulaif2c67e42018-08-07 19:50:45 +08005661 break;
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09005662 case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
5663 handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
5664 break;
Chalard Jean5d6e23b2021-03-01 22:00:20 +09005665 case EVENT_SET_OEM_NETWORK_PREFERENCE: {
Chalard Jean6010c002021-03-03 16:37:13 +09005666 final Pair<OemNetworkPreferences, IOnCompleteListener> arg =
5667 (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj;
Chalard Jean5d6e23b2021-03-01 22:00:20 +09005668 handleSetOemNetworkPreference(arg.first, arg.second);
James Mattis45d81842021-01-10 14:24:24 -08005669 break;
Chalard Jean5d6e23b2021-03-01 22:00:20 +09005670 }
Chalard Jeanb5a139f2021-02-25 21:46:34 +09005671 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: {
Chalard Jean0606fc82022-12-14 20:34:43 +09005672 final Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener> arg =
5673 (Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener>) msg.obj;
Chalard Jeanb5a139f2021-02-25 21:46:34 +09005674 handleSetProfileNetworkPreference(arg.first, arg.second);
paulhucbe2b262021-05-05 11:04:59 +08005675 break;
Chalard Jeanb5a139f2021-02-25 21:46:34 +09005676 }
lucaslin1193a5d2021-01-21 02:04:15 +08005677 case EVENT_REPORT_NETWORK_ACTIVITY:
5678 mNetworkActivityTracker.handleReportNetworkActivity();
5679 break;
paulhu51f77dc2021-06-07 02:34:20 +00005680 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED:
5681 handleMobileDataPreferredUidsChanged();
5682 break;
Chiachang Wang6eac9fb2021-06-17 22:11:30 +08005683 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL:
5684 final long timeMs = ((Long) msg.obj).longValue();
5685 mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs);
5686 break;
Patrick Rohr2857ac42022-01-21 14:58:16 +01005687 case EVENT_INGRESS_RATE_LIMIT_CHANGED:
5688 handleIngressRateLimitChanged();
5689 break;
Hansen Kurli55396972022-10-28 03:31:17 +00005690 case EVENT_USER_DOES_NOT_WANT:
5691 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
5692 if (nai == null) break;
5693 nai.onPreventAutomaticReconnect();
5694 nai.disconnect();
5695 break;
lucaslin3ba7cc22022-12-19 02:35:33 +00005696 case EVENT_SET_VPN_NETWORK_PREFERENCE:
5697 handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj);
5698 break;
chiachangwange0192a72023-02-06 13:25:01 +00005699 case EVENT_SET_LOW_TCP_POLLING_UNTIL: {
5700 final long time = ((Long) msg.obj).longValue();
5701 mKeepaliveTracker.handleSetTestLowTcpPollingTimer(time);
5702 break;
5703 }
The Android Open Source Project28527d22009-03-03 19:31:44 -08005704 }
5705 }
5706 }
Robert Greenwalt0c4828c2010-01-26 11:40:34 -08005707
Lorenzo Colittid6459092016-07-04 12:55:44 +09005708 @Override
markchien5776f962019-12-16 20:15:20 +08005709 @Deprecated
Robert Greenwalt4283ded2010-03-02 17:25:02 -08005710 public int getLastTetherError(String iface) {
markchien28160b32021-09-29 22:57:31 +08005711 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005712 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5713 Context.TETHERING_SERVICE);
5714 return tm.getLastTetherError(iface);
Robert Greenwalt8e87f122010-02-11 18:18:40 -08005715 }
5716
Lorenzo Colittid6459092016-07-04 12:55:44 +09005717 @Override
markchien5776f962019-12-16 20:15:20 +08005718 @Deprecated
Robert Greenwalt0c4828c2010-01-26 11:40:34 -08005719 public String[] getTetherableIfaces() {
markchien28160b32021-09-29 22:57:31 +08005720 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005721 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5722 Context.TETHERING_SERVICE);
5723 return tm.getTetherableIfaces();
Robert Greenwalt0c4828c2010-01-26 11:40:34 -08005724 }
5725
Lorenzo Colittid6459092016-07-04 12:55:44 +09005726 @Override
markchien5776f962019-12-16 20:15:20 +08005727 @Deprecated
Robert Greenwalt0c4828c2010-01-26 11:40:34 -08005728 public String[] getTetheredIfaces() {
markchien28160b32021-09-29 22:57:31 +08005729 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005730 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5731 Context.TETHERING_SERVICE);
5732 return tm.getTetheredIfaces();
Robert Greenwalt0c4828c2010-01-26 11:40:34 -08005733 }
Robert Greenwalt8e87f122010-02-11 18:18:40 -08005734
markchien5776f962019-12-16 20:15:20 +08005735
Lorenzo Colittid6459092016-07-04 12:55:44 +09005736 @Override
markchien5776f962019-12-16 20:15:20 +08005737 @Deprecated
Robert Greenwalt4283ded2010-03-02 17:25:02 -08005738 public String[] getTetheringErroredIfaces() {
markchien28160b32021-09-29 22:57:31 +08005739 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005740 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5741 Context.TETHERING_SERVICE);
5742
5743 return tm.getTetheringErroredIfaces();
Robert Greenwalt4283ded2010-03-02 17:25:02 -08005744 }
5745
Lorenzo Colittid6459092016-07-04 12:55:44 +09005746 @Override
markchien5776f962019-12-16 20:15:20 +08005747 @Deprecated
5748 public String[] getTetherableUsbRegexs() {
markchien28160b32021-09-29 22:57:31 +08005749 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005750 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5751 Context.TETHERING_SERVICE);
5752
5753 return tm.getTetherableUsbRegexs();
Robert Greenwalte594a762014-06-23 14:53:42 -07005754 }
5755
Udam Saini8f7d6a72017-06-07 12:06:28 -07005756 @Override
markchien5776f962019-12-16 20:15:20 +08005757 @Deprecated
5758 public String[] getTetherableWifiRegexs() {
markchien28160b32021-09-29 22:57:31 +08005759 enforceAccessPermission();
markchien5776f962019-12-16 20:15:20 +08005760 final TetheringManager tm = (TetheringManager) mContext.getSystemService(
5761 Context.TETHERING_SERVICE);
5762 return tm.getTetherableWifiRegexs();
markchien4ef53e82019-02-27 14:56:11 +08005763 }
5764
Robert Greenwalte0b00512014-07-02 09:59:16 -07005765 // Called when we lose the default network and have no replacement yet.
5766 // This will automatically be cleared after X seconds or a new default network
5767 // becomes CONNECTED, whichever happens first. The timer is started by the
5768 // first caller and not restarted by subsequent callers.
Hugo Benichi471b62a2017-03-30 23:18:10 +09005769 private void ensureNetworkTransitionWakelock(String forWhom) {
Robert Greenwalt93dc1042010-06-15 12:19:37 -07005770 synchronized (this) {
Hugo Benichi471b62a2017-03-30 23:18:10 +09005771 if (mNetTransitionWakeLock.isHeld()) {
5772 return;
5773 }
Robert Greenwalt93dc1042010-06-15 12:19:37 -07005774 mNetTransitionWakeLock.acquire();
Hugo Benichi88f49ac2017-09-05 13:25:07 +09005775 mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
5776 mTotalWakelockAcquisitions++;
Robert Greenwalt93dc1042010-06-15 12:19:37 -07005777 }
Hugo Benichi471b62a2017-03-30 23:18:10 +09005778 mWakelockLogs.log("ACQUIRE for " + forWhom);
5779 Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09005780 final int lockTimeout = mResources.get().getInteger(
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09005781 R.integer.config_networkTransitionTimeout);
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09005782 mHandler.sendMessageDelayed(msg, lockTimeout);
Robert Greenwalt93dc1042010-06-15 12:19:37 -07005783 }
Robert Greenwalt24118e82010-09-09 13:15:32 -07005784
Hugo Benichi471b62a2017-03-30 23:18:10 +09005785 // Called when we gain a new default network to release the network transition wakelock in a
5786 // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
5787 // message is cancelled.
5788 private void scheduleReleaseNetworkTransitionWakelock() {
Hugo Benichi47011212017-03-30 10:46:05 +09005789 synchronized (this) {
Hugo Benichi471b62a2017-03-30 23:18:10 +09005790 if (!mNetTransitionWakeLock.isHeld()) {
5791 return; // expiry message released the lock first.
Hugo Benichi47011212017-03-30 10:46:05 +09005792 }
5793 }
Hugo Benichi471b62a2017-03-30 23:18:10 +09005794 // Cancel self timeout on wakelock hold.
5795 mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
5796 Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
5797 mHandler.sendMessageDelayed(msg, 1000);
5798 }
5799
5800 // Called when either message of ensureNetworkTransitionWakelock or
5801 // scheduleReleaseNetworkTransitionWakelock is processed.
5802 private void handleReleaseNetworkTransitionWakelock(int eventId) {
5803 String event = eventName(eventId);
5804 synchronized (this) {
5805 if (!mNetTransitionWakeLock.isHeld()) {
5806 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
Aaron Huang6616df32020-10-30 22:04:25 +08005807 Log.w(TAG, "expected Net Transition WakeLock to be held");
Hugo Benichi471b62a2017-03-30 23:18:10 +09005808 return;
5809 }
5810 mNetTransitionWakeLock.release();
Hugo Benichi88f49ac2017-09-05 13:25:07 +09005811 long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
5812 mTotalWakelockDurationMs += lockDuration;
5813 mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
5814 mTotalWakelockReleases++;
Hugo Benichi47011212017-03-30 10:46:05 +09005815 }
Hugo Benichi471b62a2017-03-30 23:18:10 +09005816 mWakelockLogs.log(String.format("RELEASE (%s)", event));
Hugo Benichi47011212017-03-30 10:46:05 +09005817 }
5818
Robert Greenwalt986c7412010-09-08 15:24:47 -07005819 // 100 percent is full good, 0 is full bad.
Lorenzo Colittid6459092016-07-04 12:55:44 +09005820 @Override
Robert Greenwalt986c7412010-09-08 15:24:47 -07005821 public void reportInetCondition(int networkType, int percentage) {
Robert Greenwalta1d68e72014-08-06 21:32:18 -07005822 NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
Lorenzo Colitti4e858cb2015-02-11 07:39:20 +09005823 if (nai == null) return;
Paul Jensenb95d7952015-04-07 12:43:13 -04005824 reportNetworkConnectivity(nai.network, percentage > 50);
Robert Greenwalt6a2db8a2010-09-23 10:05:56 -07005825 }
5826
Lorenzo Colittid6459092016-07-04 12:55:44 +09005827 @Override
Paul Jensenb95d7952015-04-07 12:43:13 -04005828 public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
Paul Jensen83f5d572014-08-29 09:54:01 -04005829 enforceAccessPermission();
5830 enforceInternetPermission();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09005831 final int uid = mDeps.getCallingUid();
Hugo Benichif4210292017-04-21 15:07:12 +09005832 final int connectivityInfo = encodeBool(hasConnectivity);
Cody Kesting5a9a2ae2020-01-07 11:18:54 -08005833
5834 final NetworkAgentInfo nai;
5835 if (network == null) {
Chalard Jean5b409c72021-02-04 13:12:59 +09005836 nai = getDefaultNetwork();
Cody Kesting5a9a2ae2020-01-07 11:18:54 -08005837 } else {
5838 nai = getNetworkAgentInfoForNetwork(network);
5839 }
Cody Kesting3d1df812020-06-25 11:13:39 -07005840
5841 mHandler.sendMessage(
Cody Kestingf1120be2020-08-03 18:01:40 -07005842 mHandler.obtainMessage(
5843 EVENT_REPORT_NETWORK_CONNECTIVITY, uid, connectivityInfo, nai));
Hugo Benichid6b510a2017-04-06 17:22:18 +09005844 }
Paul Jensen83f5d572014-08-29 09:54:01 -04005845
Hugo Benichid6b510a2017-04-06 17:22:18 +09005846 private void handleReportNetworkConnectivity(
Cody Kestingf1120be2020-08-03 18:01:40 -07005847 @Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) {
Cody Kestingf1120be2020-08-03 18:01:40 -07005848 if (nai == null
5849 || nai != getNetworkAgentInfoForNetwork(nai.network)
Cody Kestingf1120be2020-08-03 18:01:40 -07005850 || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
Paul Jensen3c3c6e82015-06-25 10:28:34 -04005851 return;
5852 }
Paul Jensenb95d7952015-04-07 12:43:13 -04005853 // Revalidate if the app report does not match our current validated state.
Chalard Jean254bd162022-08-25 13:04:51 +09005854 if (hasConnectivity == nai.isValidated()) {
Cody Kestingf1120be2020-08-03 18:01:40 -07005855 mConnectivityDiagnosticsHandler.sendMessage(
5856 mConnectivityDiagnosticsHandler.obtainMessage(
5857 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
5858 new ReportedNetworkConnectivityInfo(
5859 hasConnectivity, false /* isNetworkRevalidating */, uid, nai)));
Hugo Benichie9d321b2017-04-06 16:01:44 +09005860 return;
5861 }
Paul Jensenb95d7952015-04-07 12:43:13 -04005862 if (DBG) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08005863 int netid = nai.network.getNetId();
Hugo Benichid6b510a2017-04-06 17:22:18 +09005864 log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
Paul Jensenb95d7952015-04-07 12:43:13 -04005865 }
Hugo Benichie9d321b2017-04-06 16:01:44 +09005866 // Validating a network that has not yet connected could result in a call to
5867 // rematchNetworkAndRequests() which is not meant to work on such networks.
Chalard Jean254bd162022-08-25 13:04:51 +09005868 if (!nai.everConnected()) {
Hugo Benichie9d321b2017-04-06 16:01:44 +09005869 return;
Paul Jensen83f5d572014-08-29 09:54:01 -04005870 }
paulhu7aeba372020-12-30 00:42:19 +08005871 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
5872 if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) {
Hugo Benichie9d321b2017-04-06 16:01:44 +09005873 return;
5874 }
Cody Kestingf1120be2020-08-03 18:01:40 -07005875
5876 // Send CONNECTIVITY_REPORTED event before re-validating the Network to force an ordering of
5877 // ConnDiags events. This ensures that #onNetworkConnectivityReported() will be called
5878 // before #onConnectivityReportAvailable(), which is called once Network evaluation is
5879 // completed.
5880 mConnectivityDiagnosticsHandler.sendMessage(
5881 mConnectivityDiagnosticsHandler.obtainMessage(
5882 ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
5883 new ReportedNetworkConnectivityInfo(
5884 hasConnectivity, true /* isNetworkRevalidating */, uid, nai)));
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09005885 nai.networkMonitor().forceReevaluation(uid);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07005886 }
5887
Lorenzo Colitti22c677e2021-03-23 21:01:07 +09005888 // TODO: call into netd.
5889 private boolean queryUserAccess(int uid, Network network) {
5890 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5891 if (nai == null) return false;
5892
5893 // Any UID can use its default network.
5894 if (nai == getDefaultNetworkForUid(uid)) return true;
5895
5896 // Privileged apps can use any network.
5897 if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
5898 return true;
5899 }
5900
5901 // An unprivileged UID can use a VPN iff the VPN applies to it.
5902 if (nai.isVPN()) {
5903 return nai.networkCapabilities.appliesToUid(uid);
5904 }
5905
5906 // An unprivileged UID can bypass the VPN that applies to it only if it can protect its
5907 // sockets, i.e., if it is the owner.
5908 final NetworkAgentInfo vpn = getVpnForUid(uid);
5909 if (vpn != null && !vpn.networkAgentConfig.allowBypass
5910 && uid != vpn.networkCapabilities.getOwnerUid()) {
5911 return false;
5912 }
5913
5914 // The UID's permission must be at least sufficient for the network. Since the restricted
5915 // permission was already checked above, that just leaves background networks.
5916 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
5917 return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
5918 }
5919
5920 // Unrestricted network. Anyone gets to use it.
5921 return true;
5922 }
5923
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005924 /**
5925 * Returns information about the proxy a certain network is using. If given a null network, it
5926 * it will return the proxy for the bound network for the caller app or the default proxy if
5927 * none.
5928 *
5929 * @param network the network we want to get the proxy information for.
5930 * @return Proxy information if a network has a proxy configured, or otherwise null.
5931 */
Lorenzo Colittid6459092016-07-04 12:55:44 +09005932 @Override
Paul Jensendb93dd92015-05-06 07:32:40 -04005933 public ProxyInfo getProxyForNetwork(Network network) {
Chalard Jean777e2e52018-06-07 18:02:37 +09005934 final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
Paul Jensendb93dd92015-05-06 07:32:40 -04005935 if (globalProxy != null) return globalProxy;
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005936 if (network == null) {
5937 // Get the network associated with the calling UID.
Lorenzo Colittif61ca942020-12-15 11:02:22 +09005938 final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(),
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005939 true);
5940 if (activeNetwork == null) {
5941 return null;
5942 }
5943 return getLinkPropertiesProxyInfo(activeNetwork);
Lorenzo Colitti22c677e2021-03-23 21:01:07 +09005944 } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005945 // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
5946 // caller may not have.
5947 return getLinkPropertiesProxyInfo(network);
5948 }
5949 // No proxy info available if the calling UID does not have network access.
5950 return null;
5951 }
5952
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005953
5954 private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
Paul Jensendb93dd92015-05-06 07:32:40 -04005955 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
5956 if (nai == null) return null;
5957 synchronized (nai) {
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005958 final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
5959 return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
Paul Jensendb93dd92015-05-06 07:32:40 -04005960 }
5961 }
5962
Chalard Jean8cbd2dd2018-06-07 18:37:59 +09005963 @Override
Chalard Jean48d60ea2021-03-17 17:03:34 +09005964 public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) {
paulhu3ffffe72021-09-16 10:15:22 +08005965 enforceNetworkStackPermission(mContext);
Chalard Jean8cbd2dd2018-06-07 18:37:59 +09005966 mProxyTracker.setGlobalProxy(proxyProperties);
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07005967 }
5968
Chalard Jean777e2e52018-06-07 18:02:37 +09005969 @Override
5970 @Nullable
Jason Monk4d5e20f2014-04-25 15:00:09 -04005971 public ProxyInfo getGlobalProxy() {
Chalard Jean777e2e52018-06-07 18:02:37 +09005972 return mProxyTracker.getGlobalProxy();
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07005973 }
5974
Junyu Lai970963e2022-10-25 15:46:47 +08005975 private void handleApplyDefaultProxy(@Nullable ProxyInfo proxy) {
Jason Monka5bf2842013-07-03 17:04:33 -04005976 if (proxy != null && TextUtils.isEmpty(proxy.getHost())
Geoffrey Borggaard6ff743e2014-11-20 14:35:32 -05005977 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
Chia-chi Yeh763a11c2011-10-03 15:34:04 -07005978 proxy = null;
5979 }
Chalard Jeand9e70ac2018-06-08 12:20:15 +09005980 mProxyTracker.setDefaultProxy(proxy);
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07005981 }
5982
Irina Dumitrescude132bb2018-12-05 16:19:47 +00005983 // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
5984 // when any network changes proxy.
5985 // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
5986 // multi-network world where an app might be bound to a non-default network.
Junyu Lai970963e2022-10-25 15:46:47 +08005987 private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
5988 ProxyInfo newProxyInfo = newLp.getHttpProxy();
Paul Jensenc0618a62014-12-10 15:12:18 -05005989 ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
5990
Chalard Jean7d97afc2018-06-07 17:41:29 +09005991 if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
Chalard Jean110cb122018-06-08 19:46:44 +09005992 mProxyTracker.sendProxyBroadcast();
Paul Jensenc0618a62014-12-10 15:12:18 -05005993 }
5994 }
5995
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07005996 private static class SettingsObserver extends ContentObserver {
Erik Kline05f2b402015-04-30 12:58:40 +09005997 final private HashMap<Uri, Integer> mUriEventMap;
5998 final private Context mContext;
5999 final private Handler mHandler;
6000
6001 SettingsObserver(Context context, Handler handler) {
6002 super(null);
Chalard Jeand6c33dc2018-06-04 13:33:12 +09006003 mUriEventMap = new HashMap<>();
Erik Kline05f2b402015-04-30 12:58:40 +09006004 mContext = context;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07006005 mHandler = handler;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07006006 }
6007
Erik Kline05f2b402015-04-30 12:58:40 +09006008 void observe(Uri uri, int what) {
6009 mUriEventMap.put(uri, what);
6010 final ContentResolver resolver = mContext.getContentResolver();
6011 resolver.registerContentObserver(uri, false, this);
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07006012 }
6013
6014 @Override
6015 public void onChange(boolean selfChange) {
Aaron Huang6616df32020-10-30 22:04:25 +08006016 Log.wtf(TAG, "Should never be reached.");
Erik Kline05f2b402015-04-30 12:58:40 +09006017 }
6018
6019 @Override
6020 public void onChange(boolean selfChange, Uri uri) {
6021 final Integer what = mUriEventMap.get(uri);
6022 if (what != null) {
Chalard Jeanfbab6d42019-09-26 18:03:47 +09006023 mHandler.obtainMessage(what).sendToTarget();
Erik Kline05f2b402015-04-30 12:58:40 +09006024 } else {
6025 loge("No matching event to send for URI=" + uri);
6026 }
Robert Greenwaltc3c5f862010-10-11 16:00:27 -07006027 }
6028 }
Wink Savillee70c6f52010-12-03 12:01:38 -08006029
Jeff Sharkey6b9021d2012-07-26 18:32:30 -07006030 private static void log(String s) {
Aaron Huang6616df32020-10-30 22:04:25 +08006031 Log.d(TAG, s);
6032 }
6033
6034 private static void logw(String s) {
6035 Log.w(TAG, s);
Wink Savillee70c6f52010-12-03 12:01:38 -08006036 }
6037
Daniel Brightf9e945b2020-06-15 16:10:01 -07006038 private static void logwtf(String s) {
6039 Log.wtf(TAG, s);
6040 }
6041
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +09006042 private static void logwtf(String s, Throwable t) {
6043 Log.wtf(TAG, s, t);
6044 }
6045
Jeff Sharkey6b9021d2012-07-26 18:32:30 -07006046 private static void loge(String s) {
Aaron Huang6616df32020-10-30 22:04:25 +08006047 Log.e(TAG, s);
Wink Savillee70c6f52010-12-03 12:01:38 -08006048 }
Chia-chi Yeh9a4ad7d2011-05-23 17:26:46 -07006049
Hugo Benichi39621362017-02-11 17:04:43 +09006050 private static void loge(String s, Throwable t) {
Aaron Huang6616df32020-10-30 22:04:25 +08006051 Log.e(TAG, s, t);
Hugo Benichi39621362017-02-11 17:04:43 +09006052 }
6053
Chia-chi Yeh75cacd52011-06-15 17:07:27 -07006054 /**
Varun Anandf3fd8dd2019-02-07 14:13:13 -08006055 * Return the information of all ongoing VPNs.
6056 *
6057 * <p>This method is used to update NetworkStatsService.
6058 *
6059 * <p>Must be called on the handler thread.
Wenchao Tonge164e002015-03-04 13:26:38 -08006060 */
junyulai2050bed2021-01-23 09:46:34 +08006061 private UnderlyingNetworkInfo[] getAllVpnInfo() {
Varun Anandf3fd8dd2019-02-07 14:13:13 -08006062 ensureRunningOnConnectivityServiceThread();
Lorenzo Colitticd675292021-02-04 17:32:07 +09006063 if (mLockdownEnabled) {
6064 return new UnderlyingNetworkInfo[0];
Wenchao Tonge164e002015-03-04 13:26:38 -08006065 }
junyulai2050bed2021-01-23 09:46:34 +08006066 List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09006067 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
junyulai2050bed2021-01-23 09:46:34 +08006068 UnderlyingNetworkInfo info = createVpnInfo(nai);
Lorenzo Colitti70b3b912020-12-15 15:47:24 +09006069 if (info != null) {
6070 infoList.add(info);
6071 }
6072 }
junyulai2050bed2021-01-23 09:46:34 +08006073 return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
Wenchao Tonge164e002015-03-04 13:26:38 -08006074 }
6075
6076 /**
6077 * @return VPN information for accounting, or null if we can't retrieve all required
Benedict Wong34857f82019-06-12 17:46:15 +00006078 * information, e.g underlying ifaces.
Wenchao Tonge164e002015-03-04 13:26:38 -08006079 */
junyulai2050bed2021-01-23 09:46:34 +08006080 private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006081 Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
Wenchao Tonge164e002015-03-04 13:26:38 -08006082 // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
6083 // the underlyingNetworks list.
Lorenzo Colittibd079452021-07-02 11:47:57 +09006084 // TODO: stop using propagateUnderlyingCapabilities here, for example, by always
6085 // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array.
6086 if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) {
James Mattis2516da32021-01-31 17:06:19 -08006087 final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
6088 nai.networkCapabilities.getOwnerUid());
Benedict Wong9308cd32019-06-12 17:46:31 +00006089 if (defaultNai != null) {
Benedict Wong34857f82019-06-12 17:46:15 +00006090 underlyingNetworks = new Network[] { defaultNai.network };
Wenchao Tonge164e002015-03-04 13:26:38 -08006091 }
6092 }
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006093
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09006094 if (CollectionUtils.isEmpty(underlyingNetworks)) return null;
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006095
6096 List<String> interfaces = new ArrayList<>();
6097 for (Network network : underlyingNetworks) {
6098 NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network);
6099 if (underlyingNai == null) continue;
6100 LinkProperties lp = underlyingNai.linkProperties;
6101 for (String iface : lp.getAllInterfaceNames()) {
6102 if (!TextUtils.isEmpty(iface)) {
6103 interfaces.add(iface);
Benedict Wong34857f82019-06-12 17:46:15 +00006104 }
6105 }
Benedict Wong34857f82019-06-12 17:46:15 +00006106 }
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006107
6108 if (interfaces.isEmpty()) return null;
6109
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006110 // Must be non-null or NetworkStatsService will crash.
6111 // Cannot happen in production code because Vpn only registers the NetworkAgent after the
6112 // tun or ipsec interface is created.
junyulai2050bed2021-01-23 09:46:34 +08006113 // TODO: Remove this check.
junyulaiacb32972021-01-23 01:09:11 +08006114 if (nai.linkProperties.getInterfaceName() == null) return null;
Lorenzo Colittifee5e4e2020-11-17 15:58:21 +09006115
junyulai2050bed2021-01-23 09:46:34 +08006116 return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
6117 nai.linkProperties.getInterfaceName(), interfaces);
Wenchao Tonge164e002015-03-04 13:26:38 -08006118 }
6119
James Mattisd31bdfa2020-12-23 16:37:26 -08006120 // TODO This needs to be the default network that applies to the NAI.
James Mattis2516da32021-01-31 17:06:19 -08006121 private Network[] underlyingNetworksOrDefault(final int ownerUid,
6122 Network[] underlyingNetworks) {
6123 final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid));
Lorenzo Colitti96dba632020-12-02 00:48:09 +09006124 if (underlyingNetworks == null && defaultNetwork != null) {
6125 // null underlying networks means to track the default.
6126 underlyingNetworks = new Network[] { defaultNetwork };
6127 }
6128 return underlyingNetworks;
6129 }
6130
6131 // Returns true iff |network| is an underlying network of |nai|.
6132 private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) {
6133 // TODO: support more than one level of underlying networks, either via a fixed-depth search
6134 // (e.g., 2 levels of underlying networks), or via loop detection, or....
Lorenzo Colittibd079452021-07-02 11:47:57 +09006135 if (!nai.propagateUnderlyingCapabilities()) return false;
James Mattis2516da32021-01-31 17:06:19 -08006136 final Network[] underlying = underlyingNetworksOrDefault(
6137 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09006138 return CollectionUtils.contains(underlying, network);
Lorenzo Colitti96dba632020-12-02 00:48:09 +09006139 }
6140
Chalard Jeand4f01ca2018-05-18 22:02:56 +09006141 /**
Lorenzo Colitti96dba632020-12-02 00:48:09 +09006142 * Recompute the capabilities for any networks that had a specific network as underlying.
Chalard Jeand4f01ca2018-05-18 22:02:56 +09006143 *
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09006144 * When underlying networks change, such networks may have to update capabilities to reflect
6145 * things like the metered bit, their transports, and so on. The capabilities are calculated
6146 * immediately. This method runs on the ConnectivityService thread.
Chalard Jeand4f01ca2018-05-18 22:02:56 +09006147 */
Lorenzo Colitti96dba632020-12-02 00:48:09 +09006148 private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09006149 ensureRunningOnConnectivityServiceThread();
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09006150 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
Lorenzo Colitti96dba632020-12-02 00:48:09 +09006151 if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09006152 updateCapabilitiesForNetwork(nai);
Chalard Jeand4f01ca2018-05-18 22:02:56 +09006153 }
6154 }
6155 }
6156
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09006157 private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) {
6158 // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies
6159 // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when
6160 // a VPN is not up.
6161 final NetworkAgentInfo vpnNai = getVpnForUid(uid);
6162 if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false;
6163 for (UidRange range : blockedUidRanges) {
6164 if (range.contains(uid)) return true;
6165 }
6166 return false;
6167 }
6168
6169 @Override
6170 public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
lucasline257bce2021-03-22 11:51:27 +08006171 enforceNetworkStackOrSettingsPermission();
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09006172 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
6173 encodeBool(requireVpn), 0 /* arg2 */, ranges));
6174 }
6175
6176 private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
6177 if (DBG) {
6178 Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: "
6179 + Arrays.toString(ranges));
6180 }
6181 // Cannot use a Set since the list of UID ranges might contain duplicates.
6182 final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges);
6183 for (int i = 0; i < ranges.length; i++) {
6184 if (requireVpn) {
6185 newVpnBlockedUidRanges.add(ranges[i]);
6186 } else {
6187 newVpnBlockedUidRanges.remove(ranges[i]);
6188 }
6189 }
6190
6191 try {
6192 mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges));
6193 } catch (RemoteException | ServiceSpecificException e) {
6194 Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", "
6195 + Arrays.toString(ranges) + "): netd command failed: " + e);
6196 }
6197
Motomu Utsumib08654c2022-05-11 05:56:26 +00006198 if (SdkLevel.isAtLeastT()) {
6199 mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges);
6200 }
6201
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09006202 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
6203 final boolean curMetered = nai.networkCapabilities.isMetered();
Sudheer Shanka9967d462021-03-18 19:09:25 +00006204 maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
6205 mVpnBlockedUidRanges, newVpnBlockedUidRanges);
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09006206 }
6207
6208 mVpnBlockedUidRanges = newVpnBlockedUidRanges;
6209 }
6210
Jeff Sharkeyebcc7972012-08-25 00:05:46 -07006211 @Override
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006212 public void setLegacyLockdownVpnEnabled(boolean enabled) {
lucasline257bce2021-03-22 11:51:27 +08006213 enforceNetworkStackOrSettingsPermission();
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006214 mHandler.post(() -> mLockdownEnabled = enabled);
Charles He9369e612017-05-15 17:07:18 +01006215 }
6216
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006217 private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
6218 return mLockdownEnabled
6219 && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY
6220 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
Robin Leee5d5ed52016-01-05 18:03:46 +00006221 }
6222
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006223 private NetworkAgentInfo getLegacyLockdownNai() {
6224 if (!mLockdownEnabled) {
6225 return null;
Robin Leee5d5ed52016-01-05 18:03:46 +00006226 }
Lorenzo Colitti1f4db552021-02-12 10:14:01 +09006227 // The legacy lockdown VPN always only applies to userId 0.
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006228 final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID);
6229 if (nai == null || !isLegacyLockdownNai(nai)) return null;
Robin Leee5d5ed52016-01-05 18:03:46 +00006230
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006231 // The legacy lockdown VPN must always have exactly one underlying network.
Lorenzo Colitti1f4db552021-02-12 10:14:01 +09006232 // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in
6233 // a local variable. There is no need to make a copy because its contents cannot change.
6234 final Network[] underlying = nai.declaredUnderlyingNetworks;
6235 if (underlying == null || underlying.length != 1) {
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006236 return null;
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00006237 }
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00006238
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006239 // The legacy lockdown VPN always uses the default network.
6240 // If the VPN's underlying network is no longer the current default network, it means that
6241 // the default network has just switched, and the VPN is about to disconnect.
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09006242 // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
6243 // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006244 final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
Lorenzo Colitti1f4db552021-02-12 10:14:01 +09006245 if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006246 return null;
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00006247 }
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006248
6249 return nai;
6250 };
6251
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09006252 // TODO: move all callers to filterForLegacyLockdown and delete this method.
6253 // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
6254 // just a DetailedState object.
Lorenzo Colittibcd692f2021-01-15 01:29:01 +09006255 private DetailedState getLegacyLockdownState(DetailedState origState) {
6256 if (origState != DetailedState.CONNECTED) {
6257 return origState;
6258 }
6259 return (mLockdownEnabled && getLegacyLockdownNai() == null)
6260 ? DetailedState.CONNECTING
6261 : DetailedState.CONNECTED;
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00006262 }
6263
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09006264 private void filterForLegacyLockdown(NetworkInfo ni) {
6265 if (!mLockdownEnabled || !ni.isConnected()) return;
6266 // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
6267 // state of its VPN. This is to ensure that when an underlying network connects, apps will
6268 // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
6269 // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
6270 // network, this time with a state of CONNECTED.
6271 //
6272 // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
6273 // to the internal state of the Vpn object, always replace the state with CONNECTING. This
6274 // is not too far off the truth, since an always-on VPN, when not connected, is always
6275 // trying to reconnect.
6276 if (getLegacyLockdownNai() == null) {
6277 ni.setDetailedState(DetailedState.CONNECTING, "", null);
6278 }
6279 }
6280
Pavel Grafov3aeb3f32019-01-25 08:50:06 +00006281 @Override
Wink Saville9a1a7ef2013-08-29 08:55:16 -07006282 public void setProvisioningNotificationVisible(boolean visible, int networkType,
Paul Jensenebeaecd2014-09-15 15:59:36 -04006283 String action) {
paulhu8e96a752019-08-12 16:25:11 +08006284 enforceSettingsPermission();
Hugo Benichiad353f42017-06-20 14:07:59 +09006285 if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
6286 return;
6287 }
Paul Jensenebeaecd2014-09-15 15:59:36 -04006288 final long ident = Binder.clearCallingIdentity();
6289 try {
Lorenzo Colittic5391022016-08-22 22:36:19 +09006290 // Concatenate the range of types onto the range of NetIDs.
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09006291 int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
Lorenzo Colittic5391022016-08-22 22:36:19 +09006292 mNotifier.setProvNotificationVisible(visible, id, action);
Paul Jensenebeaecd2014-09-15 15:59:36 -04006293 } finally {
6294 Binder.restoreCallingIdentity(ident);
6295 }
Wink Saville9a1a7ef2013-08-29 08:55:16 -07006296 }
Wink Savillecb117d32013-08-29 14:57:08 -07006297
Yuhao Zhengb77f15d2013-09-09 17:00:04 -07006298 @Override
6299 public void setAirplaneMode(boolean enable) {
Edward Savage-Jonesd4723692019-11-26 13:18:08 +01006300 enforceAirplaneModePermission();
Yuhao Zhengb77f15d2013-09-09 17:00:04 -07006301 final long ident = Binder.clearCallingIdentity();
6302 try {
Yuhao Zheng239a3b22013-09-11 09:36:41 -07006303 final ContentResolver cr = mContext.getContentResolver();
Hugo Benichif4210292017-04-21 15:07:12 +09006304 Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
Yuhao Zheng239a3b22013-09-11 09:36:41 -07006305 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
6306 intent.putExtra("state", enable);
xinhe5598f9c2014-11-17 11:35:01 -08006307 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Yuhao Zhengb77f15d2013-09-09 17:00:04 -07006308 } finally {
6309 Binder.restoreCallingIdentity(ident);
6310 }
6311 }
6312
James Mattis02220e22021-03-13 19:27:21 -08006313 private void onUserAdded(@NonNull final UserHandle user) {
James Mattisae9aeb02021-03-01 17:09:11 -08006314 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
6315 handleSetOemNetworkPreference(mOemNetworkPreferences, null);
6316 }
Chalard Jeane0abd522023-01-23 16:47:43 +09006317 updateProfileAllowedNetworks();
Fyodor Kupolov6c7a7802015-09-02 13:27:21 -07006318 }
6319
James Mattis02220e22021-03-13 19:27:21 -08006320 private void onUserRemoved(@NonNull final UserHandle user) {
Chalard Jean0f57a492021-03-09 21:09:20 +09006321 // If there was a network preference for this user, remove it.
Sooraj Sasindrane7aee272021-11-24 20:26:55 -08006322 handleSetProfileNetworkPreference(
Junyu Lai35665cc2022-12-19 17:37:48 +08006323 List.of(new ProfileNetworkPreferenceInfo(user, null, true,
6324 false /* blockingNonEnterprise */)),
Chalard Jean0f57a492021-03-09 21:09:20 +09006325 null /* listener */);
James Mattisae9aeb02021-03-01 17:09:11 -08006326 if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
6327 handleSetOemNetworkPreference(mOemNetworkPreferences, null);
6328 }
junyulaid91e7052020-08-28 13:44:33 +08006329 }
6330
James Mattis02220e22021-03-13 19:27:21 -08006331 private void onPackageChanged(@NonNull final String packageName) {
6332 // This is necessary in case a package is added or removed, but also when it's replaced to
6333 // run as a new UID by its manifest rules. Also, if a separate package shares the same UID
6334 // as one in the preferences, then it should follow the same routing as that other package,
6335 // which means updating the rules is never to be needed in this case (whether it joins or
6336 // leaves a UID with a preference).
6337 if (isMappedInOemNetworkPreference(packageName)) {
6338 handleSetOemNetworkPreference(mOemNetworkPreferences, null);
6339 }
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09006340
6341 // Invalidates cache entry when the package is updated.
6342 synchronized (mSelfCertifiedCapabilityCache) {
6343 mSelfCertifiedCapabilityCache.remove(packageName);
6344 }
James Mattis02220e22021-03-13 19:27:21 -08006345 }
6346
6347 private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
Chad Brubakerb7652cd2013-06-14 11:16:51 -07006348 @Override
6349 public void onReceive(Context context, Intent intent) {
Lorenzo Colitti0fd959b2021-02-15 09:36:55 +09006350 ensureRunningOnConnectivityServiceThread();
Chad Brubakerb7652cd2013-06-14 11:16:51 -07006351 final String action = intent.getAction();
Lorenzo Colitti8876a3d2021-02-16 15:42:21 +09006352 final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
junyulaid91e7052020-08-28 13:44:33 +08006353
Lorenzo Colitti8876a3d2021-02-16 15:42:21 +09006354 // User should be filled for below intents, check the existence.
6355 if (user == null) {
6356 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER");
6357 return;
6358 }
Chad Brubakerb7652cd2013-06-14 11:16:51 -07006359
Lorenzo Colitticd675292021-02-04 17:32:07 +09006360 if (Intent.ACTION_USER_ADDED.equals(action)) {
Lorenzo Colitti8876a3d2021-02-16 15:42:21 +09006361 onUserAdded(user);
Fyodor Kupolov6c7a7802015-09-02 13:27:21 -07006362 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
Lorenzo Colitti8876a3d2021-02-16 15:42:21 +09006363 onUserRemoved(user);
Lorenzo Colitticd675292021-02-04 17:32:07 +09006364 } else {
junyulaid91e7052020-08-28 13:44:33 +08006365 Log.wtf(TAG, "received unexpected intent: " + action);
Chad Brubakerb7652cd2013-06-14 11:16:51 -07006366 }
6367 }
6368 };
Vinit Deshapnde30ad2542013-08-21 13:09:01 -07006369
James Mattis02220e22021-03-13 19:27:21 -08006370 private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
6371 @Override
6372 public void onReceive(Context context, Intent intent) {
6373 ensureRunningOnConnectivityServiceThread();
6374 switch (intent.getAction()) {
6375 case Intent.ACTION_PACKAGE_ADDED:
6376 case Intent.ACTION_PACKAGE_REMOVED:
6377 case Intent.ACTION_PACKAGE_REPLACED:
6378 onPackageChanged(intent.getData().getSchemeSpecificPart());
6379 break;
6380 default:
6381 Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
6382 }
6383 }
6384 };
6385
Lorenzo Colittia86fae72020-01-10 00:40:28 +09006386 private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
Chalard Jeand6c33dc2018-06-04 13:33:12 +09006387 private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
Robert Greenwalt7e45d112014-04-11 15:53:27 -07006388
Lorenzo Colittia86fae72020-01-10 00:40:28 +09006389 private static class NetworkProviderInfo {
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006390 public final String name;
6391 public final Messenger messenger;
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09006392 private final IBinder.DeathRecipient mDeathRecipient;
Lorenzo Colittia86fae72020-01-10 00:40:28 +09006393 public final int providerId;
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006394
lifraf3a3492021-03-10 13:58:14 +08006395 NetworkProviderInfo(String name, Messenger messenger, int providerId,
6396 @NonNull IBinder.DeathRecipient deathRecipient) {
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006397 this.name = name;
6398 this.messenger = messenger;
Lorenzo Colittia86fae72020-01-10 00:40:28 +09006399 this.providerId = providerId;
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09006400 mDeathRecipient = deathRecipient;
6401
Remi NGUYEN VAN2f7ba512021-02-04 18:04:43 +09006402 if (mDeathRecipient == null) {
6403 throw new AssertionError("Must pass a deathRecipient");
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09006404 }
6405 }
6406
Lorenzo Colitti78185ea2020-01-07 19:36:24 +09006407 void connect(Context context, Handler handler) {
Remi NGUYEN VAN2f7ba512021-02-04 18:04:43 +09006408 try {
6409 messenger.getBinder().linkToDeath(mDeathRecipient, 0);
6410 } catch (RemoteException e) {
6411 mDeathRecipient.binderDied();
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09006412 }
Lorenzo Colitti78185ea2020-01-07 19:36:24 +09006413 }
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006414 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006415
James Mattis4fce5d12020-11-12 15:53:42 -08006416 private void ensureAllNetworkRequestsHaveType(List<NetworkRequest> requests) {
6417 for (int i = 0; i < requests.size(); i++) {
6418 ensureNetworkRequestHasType(requests.get(i));
6419 }
6420 }
6421
Lorenzo Colitti70964d32016-07-05 01:22:13 +09006422 private void ensureNetworkRequestHasType(NetworkRequest request) {
6423 if (request.type == NetworkRequest.Type.NONE) {
6424 throw new IllegalArgumentException(
6425 "All NetworkRequests in ConnectivityService must have a type");
6426 }
6427 }
6428
Robert Greenwaltc36a74f2014-07-27 10:56:49 -07006429 /**
6430 * Tracks info about the requester.
James Mattisf7027322020-12-13 16:28:14 -08006431 * Also used to notice when the calling process dies so as to self-expire
Robert Greenwaltc36a74f2014-07-27 10:56:49 -07006432 */
James Mattis258ea3c2020-11-15 15:04:40 -08006433 @VisibleForTesting
6434 protected class NetworkRequestInfo implements IBinder.DeathRecipient {
James Mattise3ef1912020-12-20 11:09:58 -08006435 // The requests to be satisfied in priority order. Non-multilayer requests will only have a
6436 // single NetworkRequest in mRequests.
James Mattis60b84b22020-11-03 15:54:33 -08006437 final List<NetworkRequest> mRequests;
James Mattis60b84b22020-11-03 15:54:33 -08006438
James Mattisa076c532020-12-02 14:12:41 -08006439 // mSatisfier and mActiveRequest rely on one another therefore set them together.
6440 void setSatisfier(
6441 @Nullable final NetworkAgentInfo satisfier,
6442 @Nullable final NetworkRequest activeRequest) {
6443 mSatisfier = satisfier;
6444 mActiveRequest = activeRequest;
6445 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006446
James Mattisd31bdfa2020-12-23 16:37:26 -08006447 // The network currently satisfying this NRI. Only one request in an NRI can have a
Lorenzo Colitti96742d92021-01-29 20:18:03 +09006448 // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier.
Chalard Jeandd8adb92019-11-05 15:07:09 +09006449 @Nullable
James Mattisa076c532020-12-02 14:12:41 -08006450 private NetworkAgentInfo mSatisfier;
6451 NetworkAgentInfo getSatisfier() {
6452 return mSatisfier;
6453 }
6454
6455 // The request in mRequests assigned to a network agent. This is null if none of the
6456 // requests in mRequests can be satisfied. This member has the constraint of only being
6457 // accessible on the handler thread.
6458 @Nullable
6459 private NetworkRequest mActiveRequest;
6460 NetworkRequest getActiveRequest() {
6461 return mActiveRequest;
6462 }
6463
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006464 final PendingIntent mPendingIntent;
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08006465 boolean mPendingIntentSent;
James Mattis45d81842021-01-10 14:24:24 -08006466 @Nullable
6467 final Messenger mMessenger;
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006468
6469 // Information about the caller that caused this object to be created.
James Mattis45d81842021-01-10 14:24:24 -08006470 @Nullable
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006471 private final IBinder mBinder;
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006472 final int mPid;
6473 final int mUid;
Roshan Pius951c0032020-12-22 15:10:42 -08006474 final @NetworkCallback.Flag int mCallbackFlags;
Roshan Piusaa24fde2020-12-17 14:53:09 -08006475 @Nullable
6476 final String mCallingAttributionTag;
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006477
Chalard Jeanefbfd7f2021-04-01 16:41:04 +09006478 // Counter keeping track of this NRI.
Junyu Lai00d92df2022-07-05 11:01:52 +08006479 final RequestInfoPerUidCounter mPerUidCounter;
Chalard Jeanefbfd7f2021-04-01 16:41:04 +09006480
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006481 // Effective UID of this request. This is different from mUid when a privileged process
6482 // files a request on behalf of another UID. This UID is used to determine blocked status,
6483 // UID matching, and so on. mUid above is used for permission checks and to enforce the
6484 // maximum limit of registered callbacks per UID.
6485 final int mAsUid;
6486
paulhu48291862021-07-14 14:53:57 +08006487 // Preference order of this request.
6488 final int mPreferenceOrder;
paulhue9913722021-05-26 15:19:20 +08006489
James Mattis3ce3d3c2021-02-09 18:18:28 -08006490 // In order to preserve the mapping of NetworkRequest-to-callback when apps register
6491 // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
6492 // maintained for keying off of. This is only a concern when the original nri
6493 // mNetworkRequests changes which happens currently for apps that register callbacks to
6494 // track the default network. In those cases, the nri is updated to have mNetworkRequests
6495 // that match the per-app default nri that currently tracks the calling app's uid so that
6496 // callbacks are fired at the appropriate time. When the callbacks fire,
6497 // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When
6498 // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue.
6499 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
6500 @NonNull
6501 private final NetworkRequest mNetworkRequestForCallback;
6502 NetworkRequest getNetworkRequestForCallback() {
6503 return mNetworkRequestForCallback;
6504 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006505
James Mattisd31bdfa2020-12-23 16:37:26 -08006506 /**
6507 * Get the list of UIDs this nri applies to.
6508 */
6509 @NonNull
paulhu51f77dc2021-06-07 02:34:20 +00006510 Set<UidRange> getUids() {
James Mattisd31bdfa2020-12-23 16:37:26 -08006511 // networkCapabilities.getUids() returns a defensive copy.
6512 // multilayer requests will all have the same uids so return the first one.
Chiachang Wang8156c4e2021-03-19 00:45:39 +00006513 final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
6514 return (null == uids) ? new ArraySet<>() : uids;
James Mattisd31bdfa2020-12-23 16:37:26 -08006515 }
6516
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006517 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
6518 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
paulhue9913722021-05-26 15:19:20 +08006519 this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag,
paulhu48291862021-07-14 14:53:57 +08006520 PREFERENCE_ORDER_INVALID);
James Mattis45d81842021-01-10 14:24:24 -08006521 }
6522
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006523 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
James Mattis3ce3d3c2021-02-09 18:18:28 -08006524 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
paulhu48291862021-07-14 14:53:57 +08006525 @Nullable String callingAttributionTag, final int preferenceOrder) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08006526 ensureAllNetworkRequestsHaveType(r);
James Mattis60b84b22020-11-03 15:54:33 -08006527 mRequests = initializeRequests(r);
James Mattis3ce3d3c2021-02-09 18:18:28 -08006528 mNetworkRequestForCallback = requestForCallback;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006529 mPendingIntent = pi;
James Mattis45d81842021-01-10 14:24:24 -08006530 mMessenger = null;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006531 mBinder = null;
6532 mPid = getCallingPid();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09006533 mUid = mDeps.getCallingUid();
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006534 mAsUid = asUid;
Chalard Jeanefbfd7f2021-04-01 16:41:04 +09006535 mPerUidCounter = getRequestCounter(this);
6536 mPerUidCounter.incrementCountOrThrow(mUid);
Roshan Pius951c0032020-12-22 15:10:42 -08006537 /**
6538 * Location sensitive data not included in pending intent. Only included in
6539 * {@link NetworkCallback}.
6540 */
6541 mCallbackFlags = NetworkCallback.FLAG_NONE;
Roshan Piusaa24fde2020-12-17 14:53:09 -08006542 mCallingAttributionTag = callingAttributionTag;
paulhu48291862021-07-14 14:53:57 +08006543 mPreferenceOrder = preferenceOrder;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006544 }
6545
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006546 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
Roshan Pius951c0032020-12-22 15:10:42 -08006547 @Nullable final IBinder binder,
6548 @NetworkCallback.Flag int callbackFlags,
6549 @Nullable String callingAttributionTag) {
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006550 this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags,
6551 callingAttributionTag);
James Mattis45d81842021-01-10 14:24:24 -08006552 }
6553
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006554 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
James Mattis3ce3d3c2021-02-09 18:18:28 -08006555 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
Roshan Pius951c0032020-12-22 15:10:42 -08006556 @Nullable final IBinder binder,
6557 @NetworkCallback.Flag int callbackFlags,
6558 @Nullable String callingAttributionTag) {
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006559 super();
James Mattis3ce3d3c2021-02-09 18:18:28 -08006560 ensureAllNetworkRequestsHaveType(r);
James Mattis60b84b22020-11-03 15:54:33 -08006561 mRequests = initializeRequests(r);
James Mattis3ce3d3c2021-02-09 18:18:28 -08006562 mNetworkRequestForCallback = requestForCallback;
James Mattis45d81842021-01-10 14:24:24 -08006563 mMessenger = m;
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006564 mBinder = binder;
6565 mPid = getCallingPid();
Lorenzo Colittif61ca942020-12-15 11:02:22 +09006566 mUid = mDeps.getCallingUid();
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006567 mAsUid = asUid;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006568 mPendingIntent = null;
Chalard Jeanefbfd7f2021-04-01 16:41:04 +09006569 mPerUidCounter = getRequestCounter(this);
6570 mPerUidCounter.incrementCountOrThrow(mUid);
Roshan Pius951c0032020-12-22 15:10:42 -08006571 mCallbackFlags = callbackFlags;
Roshan Piusaa24fde2020-12-17 14:53:09 -08006572 mCallingAttributionTag = callingAttributionTag;
paulhu48291862021-07-14 14:53:57 +08006573 mPreferenceOrder = PREFERENCE_ORDER_INVALID;
James Mattisb1392002021-03-31 13:57:52 -07006574 linkDeathRecipient();
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006575 }
6576
James Mattis3ce3d3c2021-02-09 18:18:28 -08006577 NetworkRequestInfo(@NonNull final NetworkRequestInfo nri,
6578 @NonNull final List<NetworkRequest> r) {
6579 super();
6580 ensureAllNetworkRequestsHaveType(r);
6581 mRequests = initializeRequests(r);
6582 mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
Chalard Jeanb5becbc2021-03-05 19:18:14 +09006583 final NetworkAgentInfo satisfier = nri.getSatisfier();
6584 if (null != satisfier) {
6585 // If the old NRI was satisfied by an NAI, then it may have had an active request.
6586 // The active request is necessary to figure out what callbacks to send, in
Chalard Jean2ddcf602022-02-27 12:16:32 +09006587 // particular when a network updates its capabilities.
Chalard Jeanb5becbc2021-03-05 19:18:14 +09006588 // As this code creates a new NRI with a new set of requests, figure out which of
6589 // the list of requests should be the active request. It is always the first
6590 // request of the list that can be satisfied by the satisfier since the order of
6591 // requests is a priority order.
6592 // Note even in the presence of a satisfier there may not be an active request,
6593 // when the satisfier is the no-service network.
6594 NetworkRequest activeRequest = null;
6595 for (final NetworkRequest candidate : r) {
6596 if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
6597 activeRequest = candidate;
6598 break;
6599 }
6600 }
6601 setSatisfier(satisfier, activeRequest);
6602 }
James Mattis3ce3d3c2021-02-09 18:18:28 -08006603 mMessenger = nri.mMessenger;
6604 mBinder = nri.mBinder;
6605 mPid = nri.mPid;
6606 mUid = nri.mUid;
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006607 mAsUid = nri.mAsUid;
James Mattis3ce3d3c2021-02-09 18:18:28 -08006608 mPendingIntent = nri.mPendingIntent;
Chalard Jean9473c982021-07-29 20:03:04 +09006609 mPerUidCounter = nri.mPerUidCounter;
Chalard Jeanefbfd7f2021-04-01 16:41:04 +09006610 mPerUidCounter.incrementCountOrThrow(mUid);
Roshan Pius951c0032020-12-22 15:10:42 -08006611 mCallbackFlags = nri.mCallbackFlags;
James Mattis3ce3d3c2021-02-09 18:18:28 -08006612 mCallingAttributionTag = nri.mCallingAttributionTag;
paulhu48291862021-07-14 14:53:57 +08006613 mPreferenceOrder = PREFERENCE_ORDER_INVALID;
James Mattisb1392002021-03-31 13:57:52 -07006614 linkDeathRecipient();
James Mattis3ce3d3c2021-02-09 18:18:28 -08006615 }
6616
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006617 NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
paulhu48291862021-07-14 14:53:57 +08006618 this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID);
James Mattis45d81842021-01-10 14:24:24 -08006619 }
6620
paulhue9913722021-05-26 15:19:20 +08006621 NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
paulhu48291862021-07-14 14:53:57 +08006622 final int preferenceOrder) {
paulhue9913722021-05-26 15:19:20 +08006623 this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */,
paulhu48291862021-07-14 14:53:57 +08006624 preferenceOrder);
Cody Kesting73708bf2019-12-18 10:57:50 -08006625 }
6626
James Mattis2516da32021-01-31 17:06:19 -08006627 // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
6628 // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning
6629 // false.
6630 boolean isBeingSatisfied() {
6631 return (null != mSatisfier && null != mActiveRequest);
6632 }
6633
James Mattis3d229892020-11-16 16:46:28 -08006634 boolean isMultilayerRequest() {
6635 return mRequests.size() > 1;
6636 }
6637
James Mattis45d81842021-01-10 14:24:24 -08006638 private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
6639 // Creating a defensive copy to prevent the sender from modifying the list being
6640 // reflected in the return value of this method.
6641 final List<NetworkRequest> tempRequests = new ArrayList<>(r);
James Mattis60b84b22020-11-03 15:54:33 -08006642 return Collections.unmodifiableList(tempRequests);
6643 }
6644
James Mattisb1392002021-03-31 13:57:52 -07006645 void linkDeathRecipient() {
6646 if (null != mBinder) {
6647 try {
6648 mBinder.linkToDeath(this, 0);
6649 } catch (RemoteException e) {
6650 binderDied();
6651 }
6652 }
6653 }
6654
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006655 void unlinkDeathRecipient() {
James Mattisb1392002021-03-31 13:57:52 -07006656 if (null != mBinder) {
Chalard Jean524f0b12021-10-25 21:11:56 +09006657 try {
6658 mBinder.unlinkToDeath(this, 0);
6659 } catch (NoSuchElementException e) {
6660 // Temporary workaround for b/194394697 pending analysis of additional logs
6661 Log.wtf(TAG, "unlinkToDeath for already unlinked NRI " + this);
6662 }
Jeremy Joslin60d379b2014-11-05 10:32:09 -08006663 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006664 }
6665
paulhu48291862021-07-14 14:53:57 +08006666 boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) {
6667 // Compare two preference orders.
6668 return mPreferenceOrder < target.mPreferenceOrder;
paulhuaa0743d2021-05-26 21:56:03 +08006669 }
6670
paulhu48291862021-07-14 14:53:57 +08006671 int getPreferenceOrderForNetd() {
6672 if (mPreferenceOrder >= PREFERENCE_ORDER_NONE
6673 && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) {
6674 return mPreferenceOrder;
paulhuaa0743d2021-05-26 21:56:03 +08006675 }
paulhu48291862021-07-14 14:53:57 +08006676 return PREFERENCE_ORDER_NONE;
paulhuaa0743d2021-05-26 21:56:03 +08006677 }
6678
James Mattis4fce5d12020-11-12 15:53:42 -08006679 @Override
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006680 public void binderDied() {
Chalard Jean5bcc8382021-07-19 19:57:02 +09006681 // As an immutable collection, mRequests cannot change by the time the
6682 // lambda is evaluated on the handler thread so calling .get() from a binder thread
6683 // is acceptable. Use handleReleaseNetworkRequest and not directly
6684 // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case
6685 // the app already unregistered the request.
6686 mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0),
6687 mUid, false /* callOnUnavailable */));
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006688 }
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006689
James Mattis4fce5d12020-11-12 15:53:42 -08006690 @Override
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006691 public String toString() {
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006692 final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid;
6693 return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: "
James Mattisd31bdfa2020-12-23 16:37:26 -08006694 + (mActiveRequest == null ? null : mActiveRequest.requestId)
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006695 + " callbackRequest: "
Chalard Jean5d6e23b2021-03-01 22:00:20 +09006696 + mNetworkRequestForCallback.requestId
James Mattisd31bdfa2020-12-23 16:37:26 -08006697 + " " + mRequests
Roshan Pius951c0032020-12-22 15:10:42 -08006698 + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
paulhuaa0743d2021-05-26 21:56:03 +08006699 + " callback flags: " + mCallbackFlags
paulhu48291862021-07-14 14:53:57 +08006700 + " order: " + mPreferenceOrder;
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07006701 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006702 }
6703
Junyu Lai00d92df2022-07-05 11:01:52 +08006704 // Keep backward compatibility since the ServiceSpecificException is used by
6705 // the API surface, see {@link ConnectivityManager#convertServiceException}.
6706 public static class RequestInfoPerUidCounter extends PerUidCounter {
6707 RequestInfoPerUidCounter(int maxCountPerUid) {
6708 super(maxCountPerUid);
6709 }
6710
6711 @Override
6712 public synchronized void incrementCountOrThrow(int uid) {
6713 try {
6714 super.incrementCountOrThrow(uid);
6715 } catch (IllegalStateException e) {
6716 throw new ServiceSpecificException(
6717 ConnectivityManager.Errors.TOO_MANY_REQUESTS,
6718 "Uid " + uid + " exceeded its allotted requests limit");
6719 }
6720 }
6721
6722 @Override
6723 public synchronized void decrementCountOrThrow(int uid) {
6724 throw new UnsupportedOperationException("Use decrementCount instead.");
6725 }
6726
6727 public synchronized void decrementCount(int uid) {
6728 try {
6729 super.decrementCountOrThrow(uid);
6730 } catch (IllegalStateException e) {
6731 logwtf("Exception when decrement per uid request count: ", e);
6732 }
6733 }
6734 }
6735
Chalard Jeanfbab6d42019-09-26 18:03:47 +09006736 // This checks that the passed capabilities either do not request a
6737 // specific SSID/SignalStrength, or the calling app has permission to do so.
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09006738 private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
Roshan Pius08c94fb2020-01-16 12:17:17 -08006739 int callerPid, int callerUid, String callerPackageName) {
Chalard Jean542e6002020-03-18 15:58:50 +09006740 if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09006741 throw new SecurityException("Insufficient permissions to request a specific SSID");
6742 }
paulhu1a407652019-03-22 16:35:06 +08006743
6744 if (nc.hasSignalStrength()
6745 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
6746 throw new SecurityException(
6747 "Insufficient permissions to request a specific signal strength");
6748 }
Roshan Pius08c94fb2020-01-16 12:17:17 -08006749 mAppOpsManager.checkPackage(callerUid, callerPackageName);
Benedict Wong53de25f2021-03-24 14:01:51 -07006750
junyulai2217bec2021-04-14 23:33:31 +08006751 if (!nc.getSubscriptionIds().isEmpty()) {
Benedict Wong53de25f2021-03-24 14:01:51 -07006752 enforceNetworkFactoryPermission();
6753 }
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09006754 }
6755
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09006756 private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
Chalard Jeand6c33dc2018-06-04 13:33:12 +09006757 final SortedSet<Integer> thresholds = new TreeSet<>();
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09006758 synchronized (nai) {
James Mattisa076c532020-12-02 14:12:41 -08006759 // mNetworkRequests may contain the same value multiple times in case of
6760 // multilayer requests. It won't matter in this case because the thresholds
6761 // will then be the same and be deduplicated as they enter the `thresholds` set.
6762 // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like.
James Mattisd951eec2020-11-18 16:23:25 -08006763 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
6764 for (final NetworkRequest req : nri.mRequests) {
6765 if (req.networkCapabilities.hasSignalStrength()
6766 && nai.satisfiesImmutableCapabilitiesOf(req)) {
6767 thresholds.add(req.networkCapabilities.getSignalStrength());
6768 }
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09006769 }
6770 }
6771 }
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09006772 return CollectionUtils.toIntArray(new ArrayList<>(thresholds));
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09006773 }
6774
Lorenzo Colitti0a6477e2015-09-15 15:56:01 +09006775 private void updateSignalStrengthThresholds(
6776 NetworkAgentInfo nai, String reason, NetworkRequest request) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09006777 final int[] thresholdsArray = getSignalStrengthThresholds(nai);
Lorenzo Colitti0a6477e2015-09-15 15:56:01 +09006778
Lorenzo Colittiebf757d2016-04-08 23:09:09 +09006779 if (VDBG || (DBG && !"CONNECT".equals(reason))) {
Lorenzo Colitti0a6477e2015-09-15 15:56:01 +09006780 String detail;
6781 if (request != null && request.networkCapabilities.hasSignalStrength()) {
6782 detail = reason + " " + request.networkCapabilities.getSignalStrength();
6783 } else {
6784 detail = reason;
6785 }
6786 log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09006787 detail, Arrays.toString(thresholdsArray), nai.toShortString()));
Lorenzo Colitti0a6477e2015-09-15 15:56:01 +09006788 }
6789
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09006790 nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09006791 }
6792
Chalard Jeandd421992021-12-16 23:16:02 +09006793 private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
Etan Cohen1b6d4182017-04-03 17:42:34 -07006794 if (nc == null) {
6795 return;
6796 }
6797 NetworkSpecifier ns = nc.getNetworkSpecifier();
6798 if (ns == null) {
6799 return;
6800 }
lucaslin22f9b9f2021-01-22 15:15:23 +08006801 if (ns instanceof MatchAllNetworkSpecifier) {
6802 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
6803 }
Etan Cohen1b6d4182017-04-03 17:42:34 -07006804 }
6805
Chalard Jeandd421992021-12-16 23:16:02 +09006806 private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) {
lucasline117e2e2019-10-22 18:27:33 +08006807 ensureValidNetworkSpecifier(nc);
6808 if (nc.isPrivateDnsBroken()) {
6809 throw new IllegalArgumentException("Can't request broken private DNS");
6810 }
Chalard Jeande665262022-02-25 16:12:12 +09006811 if (nc.hasAllowedUids()) {
Chalard Jean9a30acf2021-12-13 22:53:51 +09006812 throw new IllegalArgumentException("Can't request access UIDs");
6813 }
lucasline117e2e2019-10-22 18:27:33 +08006814 }
6815
Chalard Jeandd421992021-12-16 23:16:02 +09006816 private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) {
6817 ensureListenableCapabilities(nc);
6818 final String badCapability = nc.describeFirstNonRequestableCapability();
6819 if (badCapability != null) {
6820 throw new IllegalArgumentException("Cannot request network with " + badCapability);
6821 }
6822 }
6823
Chiachang Wang3bc52762021-11-25 14:17:57 +08006824 // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
6825 @TargetApi(Build.VERSION_CODES.S)
Roshan Pius951c0032020-12-22 15:10:42 -08006826 private boolean isTargetSdkAtleast(int version, int callingUid,
6827 @NonNull String callingPackageName) {
6828 final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
paulhu310c9fb2020-12-10 23:32:32 +08006829 final PackageManager pm =
6830 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
markchien9eb93992020-03-27 18:12:39 +08006831 try {
Roshan Pius951c0032020-12-22 15:10:42 -08006832 final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
markchien9eb93992020-03-27 18:12:39 +08006833 if (callingVersion < version) return false;
6834 } catch (PackageManager.NameNotFoundException e) { }
6835 return true;
6836 }
6837
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006838 @Override
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +09006839 public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities,
Chalard Jeana3578a52021-10-25 19:24:48 +09006840 int reqTypeInt, Messenger messenger, int timeoutMs, final IBinder binder,
Roshan Pius951c0032020-12-22 15:10:42 -08006841 int legacyType, int callbackFlags, @NonNull String callingPackageName,
junyulaiad010792021-01-11 16:53:38 +08006842 @Nullable String callingAttributionTag) {
markchienfac84a22020-03-18 21:16:15 +08006843 if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
Roshan Pius951c0032020-12-22 15:10:42 -08006844 if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
6845 callingPackageName)) {
markchien9eb93992020-03-27 18:12:39 +08006846 throw new SecurityException("Insufficient permissions to specify legacy type");
6847 }
markchienfac84a22020-03-18 21:16:15 +08006848 }
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006849 final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
Lorenzo Colittif61ca942020-12-15 11:02:22 +09006850 final int callingUid = mDeps.getCallingUid();
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +09006851 // Privileged callers can track the default network of another UID by passing in a UID.
6852 if (asUid != Process.INVALID_UID) {
6853 enforceSettingsPermission();
6854 } else {
6855 asUid = callingUid;
6856 }
junyulaiad010792021-01-11 16:53:38 +08006857 final NetworkRequest.Type reqType;
6858 try {
6859 reqType = NetworkRequest.Type.values()[reqTypeInt];
6860 } catch (ArrayIndexOutOfBoundsException e) {
6861 throw new IllegalArgumentException("Unsupported request type " + reqTypeInt);
6862 }
6863 switch (reqType) {
6864 case TRACK_DEFAULT:
6865 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +09006866 // is unused and will be replaced by ones appropriate for the UID (usually, the
6867 // calling app). This allows callers to keep track of the default network.
James Mattis3ce3d3c2021-02-09 18:18:28 -08006868 networkCapabilities = copyDefaultNetworkCapabilitiesForUid(
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +09006869 defaultNc, asUid, callingUid, callingPackageName);
junyulaiad010792021-01-11 16:53:38 +08006870 enforceAccessPermission();
6871 break;
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006872 case TRACK_SYSTEM_DEFAULT:
Quang Luong98858d62023-02-11 00:25:24 +00006873 enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission();
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006874 networkCapabilities = new NetworkCapabilities(defaultNc);
6875 break;
Junyu Laia62493f2021-01-19 11:10:56 +00006876 case BACKGROUND_REQUEST:
6877 enforceNetworkStackOrSettingsPermission();
6878 // Fall-through since other checks are the same with normal requests.
junyulaiad010792021-01-11 16:53:38 +08006879 case REQUEST:
6880 networkCapabilities = new NetworkCapabilities(networkCapabilities);
6881 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
junyulai96bd9fe2022-03-08 17:36:42 +08006882 callingAttributionTag, callingUid);
junyulaiad010792021-01-11 16:53:38 +08006883 // TODO: this is incorrect. We mark the request as metered or not depending on
6884 // the state of the app when the request is filed, but we never change the
6885 // request if the app changes network state. http://b/29964605
6886 enforceMeteredApnPolicy(networkCapabilities);
6887 break;
junyulai1b1c8742021-03-12 20:05:08 +08006888 case LISTEN_FOR_BEST:
6889 enforceAccessPermission();
6890 networkCapabilities = new NetworkCapabilities(networkCapabilities);
6891 break;
junyulaiad010792021-01-11 16:53:38 +08006892 default:
6893 throw new IllegalArgumentException("Unsupported request type " + reqType);
Erik Kline23bf99c2016-03-16 15:31:39 +09006894 }
Lorenzo Colitti6b56e9e2015-07-08 12:49:04 +09006895 ensureRequestableCapabilities(networkCapabilities);
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09006896 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Pius08c94fb2020-01-16 12:17:17 -08006897 Binder.getCallingPid(), callingUid, callingPackageName);
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006898
junyulai1b1c8742021-03-12 20:05:08 +08006899 // Enforce FOREGROUND if the caller does not have permission to use background network.
6900 if (reqType == LISTEN_FOR_BEST) {
6901 restrictBackgroundRequestForCaller(networkCapabilities);
6902 }
6903
6904 // Set the UID range for this request to the single UID of the requester, unless the
6905 // requester has the permission to specify other UIDs.
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +09006906 // This will overwrite any allowed UIDs in the requested capabilities. Though there
6907 // are no visible methods to set the UIDs, an app could use reflection to try and get
6908 // networks for other apps so it's essential that the UIDs are overwritten.
junyulai1b1c8742021-03-12 20:05:08 +08006909 // Also set the requester UID and package name in the request.
Roshan Pius08c94fb2020-01-16 12:17:17 -08006910 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
6911 callingUid, callingPackageName);
Robert Greenwaltc36a74f2014-07-27 10:56:49 -07006912
Etan Cohen85000162017-02-05 10:42:27 -08006913 if (timeoutMs < 0) {
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006914 throw new IllegalArgumentException("Bad timeout specified");
6915 }
Etan Cohen9786d922015-11-18 10:56:15 -08006916
James Mattis3ce3d3c2021-02-09 18:18:28 -08006917 final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
junyulaiad010792021-01-11 16:53:38 +08006918 nextNetworkRequestId(), reqType);
James Mattis3ce3d3c2021-02-09 18:18:28 -08006919 final NetworkRequestInfo nri = getNriToRegister(
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +09006920 asUid, networkRequest, messenger, binder, callbackFlags,
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006921 callingAttributionTag);
Erik Klineedf878b2015-07-09 18:24:03 +09006922 if (DBG) log("requestNetwork for " + nri);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006923
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006924 // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
6925 // copied from the default request above. (This is necessary to ensure, for example, that
6926 // the callback does not leak sensitive information to unprivileged apps.) Check that the
6927 // changes don't alter request matching.
6928 if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
6929 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
Lorenzo Colitti4777edc2021-02-10 11:59:07 +09006930 throw new IllegalStateException(
6931 "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
Lorenzo Colitti76b639e2021-01-29 20:14:04 +09006932 + networkCapabilities + " vs. " + defaultNc);
6933 }
6934
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006935 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
Robert Greenwaltf57c03c2014-06-11 16:05:07 -07006936 if (timeoutMs > 0) {
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006937 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
Robert Greenwaltf57c03c2014-06-11 16:05:07 -07006938 nri), timeoutMs);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07006939 }
6940 return networkRequest;
6941 }
6942
James Mattis3ce3d3c2021-02-09 18:18:28 -08006943 /**
6944 * Return the nri to be used when registering a network request. Specifically, this is used with
6945 * requests registered to track the default request. If there is currently a per-app default
6946 * tracking the app requestor, then we need to create a version of this nri that mirrors that of
6947 * the tracking per-app default so that callbacks are sent to the app requestor appropriately.
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006948 * @param asUid the uid on behalf of which to file the request. Different from requestorUid
6949 * when a privileged caller is tracking the default network for another uid.
James Mattis3ce3d3c2021-02-09 18:18:28 -08006950 * @param nr the network request for the nri.
6951 * @param msgr the messenger for the nri.
6952 * @param binder the binder for the nri.
6953 * @param callingAttributionTag the calling attribution tag for the nri.
6954 * @return the nri to register.
6955 */
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006956 private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr,
James Mattis3ce3d3c2021-02-09 18:18:28 -08006957 @Nullable final Messenger msgr, @Nullable final IBinder binder,
Roshan Pius951c0032020-12-22 15:10:42 -08006958 @NetworkCallback.Flag int callbackFlags,
James Mattis3ce3d3c2021-02-09 18:18:28 -08006959 @Nullable String callingAttributionTag) {
6960 final List<NetworkRequest> requests;
6961 if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
6962 requests = copyDefaultNetworkRequestsForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006963 asUid, nr.getRequestorUid(), nr.getRequestorPackageName());
James Mattis3ce3d3c2021-02-09 18:18:28 -08006964 } else {
6965 requests = Collections.singletonList(nr);
6966 }
Roshan Pius951c0032020-12-22 15:10:42 -08006967 return new NetworkRequestInfo(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09006968 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
James Mattis3ce3d3c2021-02-09 18:18:28 -08006969 }
6970
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09006971 private boolean shouldCheckCapabilitiesDeclaration(
6972 @NonNull final NetworkCapabilities networkCapabilities, final int callingUid,
6973 @NonNull final String callingPackageName) {
6974 final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
6975 // Only run the check if the change is enabled.
6976 if (!mDeps.isChangeEnabled(
6977 ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION,
6978 callingPackageName, user)) {
6979 return false;
6980 }
6981
6982 return networkCapabilities.hasCapability(
6983 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
6984 || networkCapabilities.hasCapability(
6985 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY);
6986 }
6987
6988 private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName,
6989 @NonNull final NetworkCapabilities networkCapabilities) {
6990 // This check is added to fix the linter error for "current min is 30", which is not going
6991 // to happen because Connectivity service always run in S+.
6992 if (!SdkLevel.isAtLeastS()) {
6993 Log.wtf(TAG, "Connectivity service should always run in at least SDK S");
6994 return;
6995 }
6996 ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities;
Yuyang Huang2d13d432023-03-13 12:27:40 +09006997 final long ident = Binder.clearCallingIdentity();
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09006998 try {
6999 synchronized (mSelfCertifiedCapabilityCache) {
7000 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get(
7001 callerPackageName);
7002 if (applicationNetworkCapabilities == null) {
7003 final PackageManager packageManager = mContext.getPackageManager();
7004 final PackageManager.Property networkSliceProperty = packageManager.getProperty(
7005 ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
7006 callerPackageName
7007 );
7008 final XmlResourceParser parser = packageManager
7009 .getResourcesForApplication(callerPackageName)
7010 .getXml(networkSliceProperty.getResourceId());
7011 applicationNetworkCapabilities =
7012 ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser);
7013 mSelfCertifiedCapabilityCache.put(callerPackageName,
7014 applicationNetworkCapabilities);
7015 }
7016
7017 }
7018 } catch (PackageManager.NameNotFoundException ne) {
7019 throw new SecurityException(
7020 "Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES
7021 + " property");
7022 } catch (XmlPullParserException | IOException | InvalidTagException e) {
7023 throw new SecurityException(e.getMessage());
Yuyang Huang2d13d432023-03-13 12:27:40 +09007024 } finally {
7025 Binder.restoreCallingIdentity(ident);
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09007026 }
7027
7028 applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared(
7029 networkCapabilities);
7030 }
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07007031 private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
junyulai96bd9fe2022-03-08 17:36:42 +08007032 String callingPackageName, String callingAttributionTag, final int callingUid) {
Yuyang Huang96e8bfe2023-01-27 17:05:07 +09007033 if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid,
7034 callingPackageName)) {
7035 enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities);
7036 }
Lorenzo Colittie97685a2015-05-14 17:28:27 +09007037 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
junyulai96bd9fe2022-03-08 17:36:42 +08007038 // For T+ devices, callers with carrier privilege could request with CBS capabilities.
7039 if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
7040 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities)) {
7041 return;
Sooraj Sasindrane9cd2082022-01-13 15:46:52 -08007042 }
junyulai96bd9fe2022-03-08 17:36:42 +08007043 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007044 } else {
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07007045 enforceChangePermission(callingPackageName, callingAttributionTag);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007046 }
7047 }
7048
fenglu3f357402015-03-20 11:29:56 -07007049 @Override
fenglub00f4882015-04-21 17:12:05 -07007050 public boolean requestBandwidthUpdate(Network network) {
fenglu3f357402015-03-20 11:29:56 -07007051 enforceAccessPermission();
7052 NetworkAgentInfo nai = null;
7053 if (network == null) {
7054 return false;
7055 }
7056 synchronized (mNetworkForNetId) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08007057 nai = mNetworkForNetId.get(network.getNetId());
fenglu3f357402015-03-20 11:29:56 -07007058 }
7059 if (nai != null) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007060 nai.onBandwidthUpdateRequested();
Nathan Haroldb89cbfb2018-07-30 13:38:01 -07007061 synchronized (mBandwidthRequests) {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007062 final int uid = mDeps.getCallingUid();
Nathan Haroldb89cbfb2018-07-30 13:38:01 -07007063 Integer uidReqs = mBandwidthRequests.get(uid);
7064 if (uidReqs == null) {
Chalard Jeanfbab6d42019-09-26 18:03:47 +09007065 uidReqs = 0;
Nathan Haroldb89cbfb2018-07-30 13:38:01 -07007066 }
7067 mBandwidthRequests.put(uid, ++uidReqs);
7068 }
fenglu3f357402015-03-20 11:29:56 -07007069 return true;
7070 }
7071 return false;
7072 }
7073
Felipe Leme0a5ae422016-06-20 16:36:29 -07007074 private boolean isSystem(int uid) {
7075 return uid < Process.FIRST_APPLICATION_UID;
7076 }
fenglu3f357402015-03-20 11:29:56 -07007077
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007078 private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007079 final int uid = mDeps.getCallingUid();
Felipe Leme0a5ae422016-06-20 16:36:29 -07007080 if (isSystem(uid)) {
Hugo Benichi39621362017-02-11 17:04:43 +09007081 // Exemption for system uid.
Felipe Leme0a5ae422016-06-20 16:36:29 -07007082 return;
7083 }
Hugo Benichi39621362017-02-11 17:04:43 +09007084 if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
7085 // Policy already enforced.
7086 return;
7087 }
paulhuaf50d7d2020-12-24 19:47:34 +08007088 final long ident = Binder.clearCallingIdentity();
7089 try {
7090 if (mPolicyManager.isUidRestrictedOnMeteredNetworks(uid)) {
7091 // If UID is restricted, don't allow them to bring up metered APNs.
7092 networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
7093 }
7094 } finally {
7095 Binder.restoreCallingIdentity(ident);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007096 }
7097 }
7098
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007099 @Override
7100 public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07007101 PendingIntent operation, @NonNull String callingPackageName,
7102 @Nullable String callingAttributionTag) {
Daulet Zhanguzinee674252020-03-26 12:30:39 +00007103 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007104 final int callingUid = mDeps.getCallingUid();
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007105 networkCapabilities = new NetworkCapabilities(networkCapabilities);
Philip P. Moltmann7bc33df2020-03-26 11:50:35 -07007106 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
junyulai96bd9fe2022-03-08 17:36:42 +08007107 callingAttributionTag, callingUid);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007108 enforceMeteredApnPolicy(networkCapabilities);
Lorenzo Colitti6b56e9e2015-07-08 12:49:04 +09007109 ensureRequestableCapabilities(networkCapabilities);
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09007110 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Pius08c94fb2020-01-16 12:17:17 -08007111 Binder.getCallingPid(), callingUid, callingPackageName);
Roshan Pius08c94fb2020-01-16 12:17:17 -08007112 restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
7113 callingUid, callingPackageName);
Chalard Jean15228572022-01-28 19:29:12 +09007114
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007115 NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
Lorenzo Colittieafe8572016-07-01 13:19:21 +09007116 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007117 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
7118 callingAttributionTag);
Erik Klineedf878b2015-07-09 18:24:03 +09007119 if (DBG) log("pendingRequest for " + nri);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007120 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
7121 nri));
7122 return networkRequest;
7123 }
7124
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08007125 private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
7126 mHandler.sendMessageDelayed(
7127 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +09007128 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08007129 }
7130
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007131 @Override
7132 public void releasePendingNetworkRequest(PendingIntent operation) {
Daulet Zhanguzinee674252020-03-26 12:30:39 +00007133 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Jeremy Joslin60d379b2014-11-05 10:32:09 -08007134 mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +09007135 mDeps.getCallingUid(), 0, operation));
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007136 }
7137
Lorenzo Colitti7e7decd2015-04-22 10:44:49 +09007138 // In order to implement the compatibility measure for pre-M apps that call
7139 // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
7140 // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
7141 // This ensures it has permission to do so.
7142 private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
7143 if (nc == null) {
7144 return false;
7145 }
7146 int[] transportTypes = nc.getTransportTypes();
7147 if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
7148 return false;
7149 }
7150 try {
7151 mContext.enforceCallingOrSelfPermission(
7152 android.Manifest.permission.ACCESS_WIFI_STATE,
7153 "ConnectivityService");
7154 } catch (SecurityException e) {
7155 return false;
7156 }
7157 return true;
7158 }
7159
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007160 @Override
7161 public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
Roshan Pius951c0032020-12-22 15:10:42 -08007162 Messenger messenger, IBinder binder,
7163 @NetworkCallback.Flag int callbackFlags,
7164 @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007165 final int callingUid = mDeps.getCallingUid();
Lorenzo Colitti7e7decd2015-04-22 10:44:49 +09007166 if (!hasWifiNetworkListenPermission(networkCapabilities)) {
7167 enforceAccessPermission();
7168 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007169
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09007170 NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09007171 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Pius08c94fb2020-01-16 12:17:17 -08007172 Binder.getCallingPid(), callingUid, callingPackageName);
7173 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Chalard Jean38354d12018-03-20 19:13:57 +09007174 // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
7175 // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
7176 // onLost and onAvailable callbacks when networks move in and out of the background.
7177 // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
7178 // can't request networks.
7179 restrictBackgroundRequestForCaller(nc);
Chalard Jeandd421992021-12-16 23:16:02 +09007180 ensureListenableCapabilities(nc);
Etan Cohen89134542017-04-03 12:17:51 -07007181
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09007182 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
Lorenzo Colittieafe8572016-07-01 13:19:21 +09007183 NetworkRequest.Type.LISTEN);
Roshan Piusaa24fde2020-12-17 14:53:09 -08007184 NetworkRequestInfo nri =
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007185 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags,
Roshan Pius951c0032020-12-22 15:10:42 -08007186 callingAttributionTag);
Lorenzo Colittiebf757d2016-04-08 23:09:09 +09007187 if (VDBG) log("listenForNetwork for " + nri);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007188
7189 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
7190 return networkRequest;
7191 }
7192
7193 @Override
7194 public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
Roshan Piusaa24fde2020-12-17 14:53:09 -08007195 PendingIntent operation, @NonNull String callingPackageName,
7196 @Nullable String callingAttributionTag) {
Daulet Zhanguzinee674252020-03-26 12:30:39 +00007197 Objects.requireNonNull(operation, "PendingIntent cannot be null.");
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007198 final int callingUid = mDeps.getCallingUid();
Paul Jensenc8873fc2015-06-17 14:15:39 -04007199 if (!hasWifiNetworkListenPermission(networkCapabilities)) {
7200 enforceAccessPermission();
7201 }
Chalard Jeandd421992021-12-16 23:16:02 +09007202 ensureListenableCapabilities(networkCapabilities);
Chalard Jean3ec2c0f2018-04-11 21:09:10 +09007203 ensureSufficientPermissionsForRequest(networkCapabilities,
Roshan Pius08c94fb2020-01-16 12:17:17 -08007204 Binder.getCallingPid(), callingUid, callingPackageName);
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +09007205 final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
Roshan Pius08c94fb2020-01-16 12:17:17 -08007206 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Chalard Jeanfd3a4ae2018-01-10 21:19:32 +09007207
7208 NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
Lorenzo Colittieafe8572016-07-01 13:19:21 +09007209 NetworkRequest.Type.LISTEN);
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007210 NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
7211 callingAttributionTag);
Lorenzo Colittiebf757d2016-04-08 23:09:09 +09007212 if (VDBG) log("pendingListenForNetwork for " + nri);
Paul Jensenc8873fc2015-06-17 14:15:39 -04007213
WeiZhang1cc3f172021-06-03 19:02:04 -05007214 mHandler.sendMessage(mHandler.obtainMessage(
7215 EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri));
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007216 }
7217
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007218 /** Returns the next Network provider ID. */
7219 public final int nextNetworkProviderId() {
7220 return mNextNetworkProviderId.getAndIncrement();
7221 }
7222
Erik Kline0c04b742016-07-07 16:50:58 +09007223 @Override
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007224 public void releaseNetworkRequest(NetworkRequest networkRequest) {
Lorenzo Colitti70964d32016-07-05 01:22:13 +09007225 ensureNetworkRequestHasType(networkRequest);
Erik Kline0c04b742016-07-07 16:50:58 +09007226 mHandler.sendMessage(mHandler.obtainMessage(
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +09007227 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007228 }
7229
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007230 private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
7231 if (mNetworkProviderInfos.containsKey(npi.messenger)) {
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007232 // Avoid creating duplicates. even if an app makes a direct AIDL call.
7233 // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
7234 // as that will throw if a duplicate provider is registered.
Aaron Huang6616df32020-10-30 22:04:25 +08007235 loge("Attempt to register existing NetworkProviderInfo "
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007236 + mNetworkProviderInfos.get(npi.messenger).name);
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007237 return;
7238 }
7239
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007240 if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
7241 mNetworkProviderInfos.put(npi.messenger, npi);
7242 npi.connect(mContext, mTrackerHandler);
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007243 }
7244
7245 @Override
7246 public int registerNetworkProvider(Messenger messenger, String name) {
Aaron Huangebbfd3c2020-04-14 13:43:49 +08007247 enforceNetworkFactoryOrSettingsPermission();
Aaron Huangc65e7fa2021-04-09 12:06:42 +08007248 Objects.requireNonNull(messenger, "messenger must be non-null");
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007249 NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
lifraf3a3492021-03-10 13:58:14 +08007250 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007251 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
7252 return npi.providerId;
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007253 }
7254
7255 @Override
7256 public void unregisterNetworkProvider(Messenger messenger) {
Aaron Huangebbfd3c2020-04-14 13:43:49 +08007257 enforceNetworkFactoryOrSettingsPermission();
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007258 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07007259 }
7260
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007261 @Override
Chalard Jean30689b82021-03-22 22:44:02 +09007262 public void offerNetwork(final int providerId,
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007263 @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
7264 @NonNull final INetworkOfferCallback callback) {
Chalard Jean0354d8c2021-01-12 10:58:56 +09007265 Objects.requireNonNull(score);
7266 Objects.requireNonNull(caps);
7267 Objects.requireNonNull(callback);
Chalard Jeanbb902a52021-08-18 01:35:19 +09007268 final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007269 final NetworkOffer offer = new NetworkOffer(
Chalard Jeanbb902a52021-08-18 01:35:19 +09007270 FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi),
7271 caps, callback, providerId);
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007272 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
7273 }
7274
Chalard Jeanbb902a52021-08-18 01:35:19 +09007275 private void updateOfferScore(final NetworkOffer offer) {
7276 final boolean yieldToBadWiFi =
7277 offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
7278 final NetworkOffer newOffer = new NetworkOffer(
7279 offer.score.withYieldToBadWiFi(yieldToBadWiFi),
7280 offer.caps, offer.callback, offer.providerId);
7281 if (offer.equals(newOffer)) return;
7282 handleRegisterNetworkOffer(newOffer);
7283 }
7284
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007285 @Override
7286 public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
wangshengrjxtjcb3f6c0b92022-07-22 14:59:44 +08007287 Objects.requireNonNull(callback);
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007288 mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
7289 }
7290
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007291 private void handleUnregisterNetworkProvider(Messenger messenger) {
7292 NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
7293 if (npi == null) {
7294 loge("Failed to find Messenger in unregisterNetworkProvider");
Robert Greenwalt46dcbab2014-05-16 15:49:14 -07007295 return;
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007296 }
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007297 // Unregister all the offers from this provider
7298 final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
7299 for (final NetworkOfferInfo noi : mNetworkOffers) {
Chalard Jean30689b82021-03-22 22:44:02 +09007300 if (noi.offer.providerId == npi.providerId) {
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007301 // Can't call handleUnregisterNetworkOffer here because iteration is in progress
7302 toRemove.add(noi);
7303 }
7304 }
Chalard Jean0354d8c2021-01-12 10:58:56 +09007305 for (final NetworkOfferInfo noi : toRemove) {
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007306 handleUnregisterNetworkOffer(noi);
7307 }
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007308 if (DBG) log("unregisterNetworkProvider for " + npi.name);
Robert Greenwalt7e45d112014-04-11 15:53:27 -07007309 }
7310
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007311 @Override
James Mattisf7027322020-12-13 16:28:14 -08007312 public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) {
Aaron Huangebbfd3c2020-04-14 13:43:49 +08007313 if (request.hasTransport(TRANSPORT_TEST)) {
7314 enforceNetworkFactoryOrTestNetworksPermission();
7315 } else {
7316 enforceNetworkFactoryPermission();
7317 }
James Mattisf7027322020-12-13 16:28:14 -08007318 final NetworkRequestInfo nri = mNetworkRequests.get(request);
7319 if (nri != null) {
7320 // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests.
7321 ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable");
7322 mHandler.post(() -> handleReleaseNetworkRequest(
7323 nri.mRequests.get(0), mDeps.getCallingUid(), true));
7324 }
Lorenzo Colitti6702d4b2020-01-08 00:04:09 +09007325 }
7326
Paul Jensen1f567382015-02-13 14:18:39 -05007327 // NOTE: Accessed on multiple threads, must be synchronized on itself.
7328 @GuardedBy("mNetworkForNetId")
Chalard Jeand6c33dc2018-06-04 13:33:12 +09007329 private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
Paul Jensen1f567382015-02-13 14:18:39 -05007330 // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09007331 // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so
Paul Jensen1f567382015-02-13 14:18:39 -05007332 // there may not be a strict 1:1 correlation between the two.
Remi NGUYEN VAN0d0eb152019-06-13 16:12:02 +09007333 private final NetIdManager mNetIdManager;
Robert Greenwaltf99b8392014-03-26 16:47:06 -07007334
Lorenzo Colittib4bf0152021-06-07 15:32:04 +09007335 // Tracks all NetworkAgents that are currently registered.
Paul Jensen1f567382015-02-13 14:18:39 -05007336 // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007337 private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007338
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09007339 // UID ranges for users that are currently blocked by VPNs.
7340 // This array is accessed and iterated on multiple threads without holding locks, so its
7341 // contents must never be mutated. When the ranges change, the array is replaced with a new one
7342 // (on the handler thread).
7343 private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
7344
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007345 // Must only be accessed on the handler thread
7346 @NonNull
7347 private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
7348
Lorenzo Colittiac136a02016-01-22 04:04:57 +09007349 @GuardedBy("mBlockedAppUids")
Chalard Jeand6c33dc2018-06-04 13:33:12 +09007350 private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
Lorenzo Colittiac136a02016-01-22 04:04:57 +09007351
Chalard Jeanb5a139f2021-02-25 21:46:34 +09007352 // Current OEM network preferences. This object must only be written to on the handler thread.
7353 // Since it is immutable and always non-null, other threads may read it if they only care
7354 // about seeing a consistent object but not that it is current.
James Mattis45d81842021-01-10 14:24:24 -08007355 @NonNull
7356 private OemNetworkPreferences mOemNetworkPreferences =
7357 new OemNetworkPreferences.Builder().build();
Chalard Jeanb5a139f2021-02-25 21:46:34 +09007358 // Current per-profile network preferences. This object follows the same threading rules as
7359 // the OEM network preferences above.
7360 @NonNull
Chalard Jean0606fc82022-12-14 20:34:43 +09007361 private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo>
7362 mProfileNetworkPreferences = new NetworkPreferenceList<>();
James Mattis45d81842021-01-10 14:24:24 -08007363
lucaslin3ba7cc22022-12-19 02:35:33 +00007364 // Current VPN network preferences. This object follows the same threading rules as the OEM
7365 // network preferences above.
7366 @NonNull
7367 private NetworkPreferenceList<String, VpnNetworkPreferenceInfo>
7368 mVpnNetworkPreferences = new NetworkPreferenceList<>();
7369
paulhu51f77dc2021-06-07 02:34:20 +00007370 // A set of UIDs that should use mobile data preferentially if available. This object follows
7371 // the same threading rules as the OEM network preferences above.
7372 @NonNull
7373 private Set<Integer> mMobileDataPreferredUids = new ArraySet<>();
7374
James Mattiscb1e0362021-04-06 17:07:42 -07007375 // OemNetworkPreferences activity String log entries.
7376 private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20;
7377 @NonNull
7378 private final LocalLog mOemNetworkPreferencesLogs =
7379 new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS);
7380
James Mattis02220e22021-03-13 19:27:21 -08007381 /**
7382 * Determine whether a given package has a mapping in the current OemNetworkPreferences.
7383 * @param packageName the package name to check existence of a mapping for.
7384 * @return true if a mapping exists, false otherwise
7385 */
7386 private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) {
7387 return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName);
7388 }
7389
James Mattise3ef1912020-12-20 11:09:58 -08007390 // The always-on request for an Internet-capable network that apps without a specific default
7391 // fall back to.
James Mattis45d81842021-01-10 14:24:24 -08007392 @VisibleForTesting
Chalard Jean2c8b3e32019-11-05 14:40:23 +09007393 @NonNull
James Mattis45d81842021-01-10 14:24:24 -08007394 final NetworkRequestInfo mDefaultRequest;
James Mattise3ef1912020-12-20 11:09:58 -08007395 // Collection of NetworkRequestInfo's used for default networks.
James Mattis45d81842021-01-10 14:24:24 -08007396 @VisibleForTesting
James Mattise3ef1912020-12-20 11:09:58 -08007397 @NonNull
James Mattis45d81842021-01-10 14:24:24 -08007398 final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
Chalard Jeand4f01ca2018-05-18 22:02:56 +09007399
James Mattisd31bdfa2020-12-23 16:37:26 -08007400 private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
7401 return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
7402 }
7403
7404 /**
James Mattis3ce3d3c2021-02-09 18:18:28 -08007405 * Return the default network request currently tracking the given uid.
7406 * @param uid the uid to check.
7407 * @return the NetworkRequestInfo tracking the given uid.
7408 */
7409 @NonNull
James Mattis02220e22021-03-13 19:27:21 -08007410 private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) {
paulhuaa0743d2021-05-26 21:56:03 +08007411 NetworkRequestInfo highestPriorityNri = mDefaultRequest;
James Mattis3ce3d3c2021-02-09 18:18:28 -08007412 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08007413 // Checking the first request is sufficient as only multilayer requests will have more
7414 // than one request and for multilayer, all requests will track the same uids.
7415 if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) {
paulhuaa0743d2021-05-26 21:56:03 +08007416 // Find out the highest priority request.
paulhu48291862021-07-14 14:53:57 +08007417 if (nri.hasHigherOrderThan(highestPriorityNri)) {
paulhuaa0743d2021-05-26 21:56:03 +08007418 highestPriorityNri = nri;
7419 }
James Mattis3ce3d3c2021-02-09 18:18:28 -08007420 }
7421 }
paulhuaa0743d2021-05-26 21:56:03 +08007422 return highestPriorityNri;
James Mattis3ce3d3c2021-02-09 18:18:28 -08007423 }
7424
7425 /**
7426 * Get a copy of the network requests of the default request that is currently tracking the
7427 * given uid.
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007428 * @param asUid the uid on behalf of which to file the request. Different from requestorUid
7429 * when a privileged caller is tracking the default network for another uid.
James Mattis3ce3d3c2021-02-09 18:18:28 -08007430 * @param requestorUid the uid to check the default for.
7431 * @param requestorPackageName the requestor's package name.
7432 * @return a copy of the default's NetworkRequest that is tracking the given uid.
7433 */
7434 @NonNull
7435 private List<NetworkRequest> copyDefaultNetworkRequestsForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007436 final int asUid, final int requestorUid, @NonNull final String requestorPackageName) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08007437 return copyNetworkRequestsForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007438 getDefaultRequestTrackingUid(asUid).mRequests,
7439 asUid, requestorUid, requestorPackageName);
James Mattis3ce3d3c2021-02-09 18:18:28 -08007440 }
7441
7442 /**
7443 * Copy the given nri's NetworkRequest collection.
7444 * @param requestsToCopy the NetworkRequest collection to be copied.
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007445 * @param asUid the uid on behalf of which to file the request. Different from requestorUid
7446 * when a privileged caller is tracking the default network for another uid.
James Mattis3ce3d3c2021-02-09 18:18:28 -08007447 * @param requestorUid the uid to set on the copied collection.
7448 * @param requestorPackageName the package name to set on the copied collection.
7449 * @return the copied NetworkRequest collection.
7450 */
7451 @NonNull
7452 private List<NetworkRequest> copyNetworkRequestsForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007453 @NonNull final List<NetworkRequest> requestsToCopy, final int asUid,
7454 final int requestorUid, @NonNull final String requestorPackageName) {
James Mattis3ce3d3c2021-02-09 18:18:28 -08007455 final List<NetworkRequest> requests = new ArrayList<>();
7456 for (final NetworkRequest nr : requestsToCopy) {
7457 requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007458 nr.networkCapabilities, asUid, requestorUid, requestorPackageName),
James Mattis3ce3d3c2021-02-09 18:18:28 -08007459 nr.legacyType, nextNetworkRequestId(), nr.type));
7460 }
7461 return requests;
7462 }
7463
7464 @NonNull
7465 private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007466 @NonNull final NetworkCapabilities netCapToCopy, final int asUid,
7467 final int requestorUid, @NonNull final String requestorPackageName) {
Lorenzo Colitti84593442021-03-22 02:12:04 +09007468 // These capabilities are for a TRACK_DEFAULT callback, so:
7469 // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
7470 // mDefaultRequest and a per-UID default request.
7471 // TODO: stop depending on the fact that these two unrelated things happen to be the same
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007472 // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will
Lorenzo Colitti84593442021-03-22 02:12:04 +09007473 // not do this in the case of a privileged application.
James Mattis3ce3d3c2021-02-09 18:18:28 -08007474 final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
7475 netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09007476 netCap.setSingleUid(asUid);
James Mattis3ce3d3c2021-02-09 18:18:28 -08007477 restrictRequestUidsForCallerAndSetRequestorInfo(
7478 netCap, requestorUid, requestorPackageName);
7479 return netCap;
7480 }
7481
7482 /**
7483 * Get the nri that is currently being tracked for callbacks by per-app defaults.
7484 * @param nr the network request to check for equality against.
7485 * @return the nri if one exists, null otherwise.
7486 */
7487 @Nullable
7488 private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) {
7489 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
7490 if (nri.getNetworkRequestForCallback().equals(nr)) {
7491 return nri;
7492 }
7493 }
7494 return null;
7495 }
7496
7497 /**
7498 * Check if an nri is currently being managed by per-app default networking.
7499 * @param nri the nri to check.
7500 * @return true if this nri is currently being managed by per-app default networking.
7501 */
7502 private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) {
7503 // nri.mRequests.get(0) is only different from the original request filed in
7504 // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default
7505 // functionality therefore if these two don't match, it means this particular nri is
7506 // currently being managed by a per-app default.
7507 return nri.getNetworkRequestForCallback() != nri.mRequests.get(0);
7508 }
7509
7510 /**
James Mattisd31bdfa2020-12-23 16:37:26 -08007511 * Determine if an nri is a managed default request that disallows default networking.
7512 * @param nri the request to evaluate
7513 * @return true if device-default networking is disallowed
7514 */
7515 private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) {
7516 // Check if this nri is a managed default that supports the default network at its
7517 // lowest priority request.
7518 final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0);
7519 final NetworkCapabilities lowestPriorityNetCap =
7520 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities;
7521 return isPerAppDefaultRequest(nri)
7522 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities(
7523 lowestPriorityNetCap));
7524 }
7525
Erik Kline05f2b402015-04-30 12:58:40 +09007526 // Request used to optionally keep mobile data active even when higher
7527 // priority networks like Wi-Fi are active.
7528 private final NetworkRequest mDefaultMobileDataRequest;
7529
Leif Hendrik Wilden838c6612018-05-02 12:05:24 -07007530 // Request used to optionally keep wifi data active even when higher
7531 // priority networks like ethernet are active.
7532 private final NetworkRequest mDefaultWifiRequest;
7533
Tomasz Wasilczyk54605b82020-12-14 13:42:51 -08007534 // Request used to optionally keep vehicle internal network always active
7535 private final NetworkRequest mDefaultVehicleRequest;
7536
James Mattisd31bdfa2020-12-23 16:37:26 -08007537 // Sentinel NAI used to direct apps with default networks that should have no connectivity to a
7538 // network with no service. This NAI should never be matched against, nor should any public API
7539 // ever return the associated network. For this reason, this NAI is not in the list of available
7540 // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device
7541 // default requests that don't support using the device default network which will ultimately
7542 // allow ConnectivityService to use this no-service network when calling makeDefaultForApps().
7543 @VisibleForTesting
7544 final NetworkAgentInfo mNoServiceNetwork;
7545
Chalard Jean5b409c72021-02-04 13:12:59 +09007546 // The NetworkAgentInfo currently satisfying the default request, if any.
7547 private NetworkAgentInfo getDefaultNetwork() {
7548 return mDefaultRequest.mSatisfier;
Lorenzo Colitti79bd2e22014-11-28 11:21:30 +09007549 }
7550
James Mattis2516da32021-01-31 17:06:19 -08007551 private NetworkAgentInfo getDefaultNetworkForUid(final int uid) {
paulhuaa0743d2021-05-26 21:56:03 +08007552 NetworkRequestInfo highestPriorityNri = mDefaultRequest;
James Mattis2516da32021-01-31 17:06:19 -08007553 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
7554 // Currently, all network requests will have the same uids therefore checking the first
7555 // one is sufficient. If/when uids are tracked at the nri level, this can change.
Chiachang Wang8156c4e2021-03-19 00:45:39 +00007556 final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
James Mattis2516da32021-01-31 17:06:19 -08007557 if (null == uids) {
7558 continue;
7559 }
7560 for (final UidRange range : uids) {
7561 if (range.contains(uid)) {
paulhu48291862021-07-14 14:53:57 +08007562 if (nri.hasHigherOrderThan(highestPriorityNri)) {
paulhuaa0743d2021-05-26 21:56:03 +08007563 highestPriorityNri = nri;
7564 }
James Mattis2516da32021-01-31 17:06:19 -08007565 }
7566 }
7567 }
paulhuaa0743d2021-05-26 21:56:03 +08007568 return highestPriorityNri.getSatisfier();
James Mattis2516da32021-01-31 17:06:19 -08007569 }
7570
Varun Ananddf569952019-02-06 10:13:38 -08007571 @Nullable
7572 private Network getNetwork(@Nullable NetworkAgentInfo nai) {
7573 return nai != null ? nai.network : null;
7574 }
7575
7576 private void ensureRunningOnConnectivityServiceThread() {
7577 if (mHandler.getLooper().getThread() != Thread.currentThread()) {
7578 throw new IllegalStateException(
7579 "Not running on ConnectivityService thread: "
7580 + Thread.currentThread().getName());
7581 }
7582 }
7583
Chalard Jean3a3f5f22019-04-10 23:07:55 +09007584 @VisibleForTesting
Chalard Jean5b409c72021-02-04 13:12:59 +09007585 protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
7586 return nai == getDefaultNetwork();
Robert Greenwalta1d68e72014-08-06 21:32:18 -07007587 }
7588
Chalard Jean29d06db2018-05-02 21:14:54 +09007589 /**
7590 * Register a new agent with ConnectivityService to handle a network.
7591 *
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007592 * @param na a reference for ConnectivityService to contact the agent asynchronously.
Chalard Jean29d06db2018-05-02 21:14:54 +09007593 * @param networkInfo the initial info associated with this network. It can be updated later :
7594 * see {@link #updateNetworkInfo}.
7595 * @param linkProperties the initial link properties of this network. They can be updated
7596 * later : see {@link #updateLinkProperties}.
7597 * @param networkCapabilities the initial capabilites of this network. They can be updated
Chalard Jean2e315442019-12-12 13:56:13 +09007598 * later : see {@link #updateCapabilities}.
Chalard Jeanaa5bc622022-02-26 21:34:48 +09007599 * @param initialScore the initial score of the network. See {@link NetworkAgentInfo#getScore}.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09007600 * @param networkAgentConfig metadata about the network. This is never updated.
Lorenzo Colittia86fae72020-01-10 00:40:28 +09007601 * @param providerId the ID of the provider owning this NetworkAgent.
Chalard Jeanf78c9642019-12-13 19:47:12 +09007602 * @return the network created for this agent.
Chalard Jean29d06db2018-05-02 21:14:54 +09007603 */
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007604 public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
Chalard Jean29d06db2018-05-02 21:14:54 +09007605 LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
Chalard Jean28018572020-12-21 18:36:52 +09007606 @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig,
7607 int providerId) {
Lorenzo Colittibb4d45f2021-01-18 14:15:17 +09007608 Objects.requireNonNull(networkInfo, "networkInfo must not be null");
7609 Objects.requireNonNull(linkProperties, "linkProperties must not be null");
7610 Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null");
Chalard Jean28018572020-12-21 18:36:52 +09007611 Objects.requireNonNull(initialScore, "initialScore must not be null");
Lorenzo Colittibb4d45f2021-01-18 14:15:17 +09007612 Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null");
Chalard Jean5b639762020-03-09 21:25:37 +09007613 if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
paulhu3ffffe72021-09-16 10:15:22 +08007614 enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS);
Lorenzo Colitti8000e032020-11-26 23:42:25 +09007615 } else {
7616 enforceNetworkFactoryPermission();
7617 }
7618
Lorenzo Colittif61ca942020-12-15 11:02:22 +09007619 final int uid = mDeps.getCallingUid();
Lorenzo Colitti8000e032020-11-26 23:42:25 +09007620 final long token = Binder.clearCallingIdentity();
7621 try {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007622 return registerNetworkAgentInternal(na, networkInfo, linkProperties,
Chalard Jean28018572020-12-21 18:36:52 +09007623 networkCapabilities, initialScore, networkAgentConfig, providerId, uid);
Lorenzo Colitti8000e032020-11-26 23:42:25 +09007624 } finally {
7625 Binder.restoreCallingIdentity(token);
7626 }
7627 }
7628
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007629 private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,
Lorenzo Colitti8000e032020-11-26 23:42:25 +09007630 LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
Chalard Jean28018572020-12-21 18:36:52 +09007631 NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
7632 int uid) {
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007633
Chalard Jeandbc46952022-02-02 00:14:18 +09007634 // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them
7635 // and mutate them at any time.
7636 final NetworkInfo niCopy = new NetworkInfo(networkInfo);
7637 final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities);
7638 final LinkProperties lpCopy = new LinkProperties(linkProperties);
7639
Chalard Jean366c5252022-01-25 18:27:53 +09007640 // At this point the capabilities/properties are untrusted and unverified, e.g. checks that
Chalard Jeandbc46952022-02-02 00:14:18 +09007641 // the capabilities' access UIDs comply with security limitations. They will be sanitized
Chalard Jean366c5252022-01-25 18:27:53 +09007642 // as the NAI registration finishes, in handleRegisterNetworkAgent(). This is
7643 // because some of the checks must happen on the handler thread.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007644 final NetworkAgentInfo nai = new NetworkAgentInfo(na,
Chalard Jeandbc46952022-02-02 00:14:18 +09007645 new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy,
Chalard Jean8cdee3a2020-03-04 17:45:08 +09007646 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
Chalard Jean550b5212021-03-05 23:07:53 +09007647 this, mNetd, mDnsResolver, providerId, uid, mLingerDelayMs,
7648 mQosCallbackTracker, mDeps);
Lorenzo Colitti18a58462020-04-16 01:52:40 +09007649
Chalard Jeandbc46952022-02-02 00:14:18 +09007650 final String extraInfo = niCopy.getExtraInfo();
Chalard Jeanf2da1772018-04-26 16:16:10 +09007651 final String name = TextUtils.isEmpty(extraInfo)
Chalard Jean542e6002020-03-18 15:58:50 +09007652 ? nai.networkCapabilities.getSsid() : extraInfo;
Robert Greenwalt419e1b42014-08-27 14:34:02 -07007653 if (DBG) log("registerNetworkAgent " + nai);
Lorenzo Colitti8000e032020-11-26 23:42:25 +09007654 mDeps.getNetworkStack().makeNetworkMonitor(
7655 nai.network, name, new NetworkMonitorCallbacks(nai));
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007656 // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
7657 // If the network disconnects or sends any other event before that, messages are deferred by
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007658 // NetworkAgent until nai.connect(), which will be called when finalizing the
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007659 // registration.
Chalard Jeanf78c9642019-12-13 19:47:12 +09007660 return nai.network;
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007661 }
7662
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007663 private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
Chalard Jean366c5252022-01-25 18:27:53 +09007664 if (VDBG) log("Network Monitor created for " + nai);
Chalard Jeanda7fe572022-02-01 23:47:23 +09007665 // Store a copy of the declared capabilities.
Chalard Jean39b12d42022-02-27 12:08:49 +09007666 nai.setDeclaredCapabilities(nai.networkCapabilities);
Chalard Jeanda7fe572022-02-01 23:47:23 +09007667 // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said.
Chalard Jeandbc46952022-02-02 00:14:18 +09007668 nai.getAndSetNetworkCapabilities(mixInCapabilities(nai,
7669 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator)));
7670 processLinkPropertiesFromAgent(nai, nai.linkProperties);
Chalard Jean366c5252022-01-25 18:27:53 +09007671
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007672 nai.onNetworkMonitorCreated(networkMonitor);
Chalard Jean366c5252022-01-25 18:27:53 +09007673
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007674 mNetworkAgentInfos.add(nai);
Paul Jensen1f567382015-02-13 14:18:39 -05007675 synchronized (mNetworkForNetId) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08007676 mNetworkForNetId.put(nai.network.getNetId(), nai);
Paul Jensen1f567382015-02-13 14:18:39 -05007677 }
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007678
7679 try {
7680 networkMonitor.start();
7681 } catch (RemoteException e) {
Chiachang Wang8c778c92019-04-24 21:44:05 +08007682 e.rethrowAsRuntimeException();
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09007683 }
Chalard Jean366c5252022-01-25 18:27:53 +09007684
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09007685 nai.notifyRegistered();
Erik Kline286974f2018-03-04 21:01:01 +09007686 NetworkInfo networkInfo = nai.networkInfo;
Erik Kline286974f2018-03-04 21:01:01 +09007687 updateNetworkInfo(nai, networkInfo);
Lorenzo Colitti96a3f142022-02-08 16:21:01 +00007688 updateVpnUids(nai, null, nai.networkCapabilities);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007689 }
7690
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007691 private class NetworkOfferInfo implements IBinder.DeathRecipient {
7692 @NonNull public final NetworkOffer offer;
7693
7694 NetworkOfferInfo(@NonNull final NetworkOffer offer) {
7695 this.offer = offer;
7696 }
7697
7698 @Override
7699 public void binderDied() {
7700 mHandler.post(() -> handleUnregisterNetworkOffer(this));
7701 }
7702 }
7703
Chalard Jeandd35f2d2021-03-24 14:31:38 +09007704 private boolean isNetworkProviderWithIdRegistered(final int providerId) {
7705 for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
7706 if (npi.providerId == providerId) return true;
7707 }
7708 return false;
7709 }
7710
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007711 /**
7712 * Register or update a network offer.
7713 * @param newOffer The new offer. If the callback member is the same as an existing
7714 * offer, it is an update of that offer.
7715 */
Chalard Jeanbb902a52021-08-18 01:35:19 +09007716 // TODO : rename this to handleRegisterOrUpdateNetworkOffer
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007717 private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
7718 ensureRunningOnConnectivityServiceThread();
Chalard Jeandd35f2d2021-03-24 14:31:38 +09007719 if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007720 // This may actually happen if a provider updates its score or registers and then
7721 // immediately unregisters. The offer would still be in the handler queue, but the
7722 // provider would have been removed.
7723 if (DBG) log("Received offer from an unregistered provider");
7724 return;
7725 }
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007726 final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
7727 if (null != existingOffer) {
7728 handleUnregisterNetworkOffer(existingOffer);
7729 newOffer.migrateFrom(existingOffer.offer);
Chalard Jeanbb902a52021-08-18 01:35:19 +09007730 if (DBG) {
7731 // handleUnregisterNetworkOffer has already logged the old offer
7732 log("update offer from providerId " + newOffer.providerId + " new : " + newOffer);
7733 }
7734 } else {
7735 if (DBG) {
7736 log("register offer from providerId " + newOffer.providerId + " : " + newOffer);
7737 }
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007738 }
7739 final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
7740 try {
Chalard Jean30689b82021-03-22 22:44:02 +09007741 noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */);
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007742 } catch (RemoteException e) {
7743 noi.binderDied();
7744 return;
7745 }
7746 mNetworkOffers.add(noi);
Chalard Jean0354d8c2021-01-12 10:58:56 +09007747 issueNetworkNeeds(noi);
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007748 }
7749
7750 private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
7751 ensureRunningOnConnectivityServiceThread();
Chalard Jeanbb902a52021-08-18 01:35:19 +09007752 if (DBG) {
7753 log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer);
7754 }
Tyler Wear3ec7e6d2021-08-17 18:25:50 -07007755
7756 // If the provider removes the offer and dies immediately afterwards this
7757 // function may be called twice in a row, but the array will no longer contain
7758 // the offer.
7759 if (!mNetworkOffers.remove(noi)) return;
Chalard Jean30689b82021-03-22 22:44:02 +09007760 noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007761 }
7762
7763 @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
7764 @NonNull final INetworkOfferCallback callback) {
7765 ensureRunningOnConnectivityServiceThread();
7766 for (final NetworkOfferInfo noi : mNetworkOffers) {
Chalard Jean9f6d4472021-04-08 17:37:36 +09007767 if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi;
Chalard Jeancdd68bc2021-01-05 08:40:09 +09007768 }
7769 return null;
7770 }
7771
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09007772 /**
7773 * Called when receiving LinkProperties directly from a NetworkAgent.
7774 * Stores into |nai| any data coming from the agent that might also be written to the network's
7775 * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
7776 * agent is not lost when updateLinkProperties is called.
Lorenzo Colitti96883c92020-12-02 13:58:47 +09007777 * This method should never alter the agent's LinkProperties, only store data in |nai|.
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09007778 */
Lorenzo Colitti18a58462020-04-16 01:52:40 +09007779 private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
7780 lp.ensureDirectlyConnectedRoutes();
Lorenzo Colittie2eade02020-04-01 22:25:16 +09007781 nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
Hai Shalome58bdc62021-01-11 18:45:34 -08007782 nai.networkAgentPortalData = lp.getCaptivePortalData();
Lorenzo Colitti18a58462020-04-16 01:52:40 +09007783 }
7784
Remi NGUYEN VANdf5f3112021-01-28 15:09:22 +09007785 private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp,
Junyu Lai2ed7d412022-10-07 16:52:21 +08007786 @Nullable LinkProperties oldLp) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08007787 int netId = networkAgent.network.getNetId();
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007788
Lorenzo Colittid523d142020-04-01 20:16:30 +09007789 // The NetworkAgent does not know whether clatd is running on its network or not, or whether
7790 // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure
7791 // the LinkProperties for the network are accurate.
Lorenzo Colitti7b0732f2019-01-08 14:43:37 +09007792 networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
Lorenzo Colitticef8aec2014-09-20 13:47:47 +09007793
Suprabh Shukla1e312032023-01-24 03:36:37 -08007794 updateInterfaces(newLp, oldLp, netId, networkAgent);
Lorenzo Colittibad9d912019-04-12 10:48:06 +00007795
7796 // update filtering rules, need to happen after the interface update so netd knows about the
7797 // new interface (the interface name -> index map becomes initialized)
7798 updateVpnFiltering(newLp, oldLp, networkAgent);
7799
Robert Greenwalte20f7a22014-04-18 15:25:25 -07007800 updateMtu(newLp, oldLp);
7801 // TODO - figure out what to do for clat
7802// for (LinkProperties lp : newLp.getStackedLinks()) {
7803// updateMtu(lp, null);
7804// }
Chalard Jean5b409c72021-02-04 13:12:59 +09007805 if (isDefaultNetwork(networkAgent)) {
lucaslin821c9782018-11-28 19:27:52 +08007806 updateTcpBufferSizes(newLp.getTcpBufferSizes());
7807 }
Lorenzo Colitti20068c22014-11-28 20:07:46 +09007808
Erik Klineb9888902016-04-05 13:30:49 +09007809 updateRoutes(newLp, oldLp, netId);
7810 updateDnses(newLp, oldLp, netId);
dalyk1720e542018-03-05 12:42:22 -05007811 // Make sure LinkProperties represents the latest private DNS status.
7812 // This does not need to be done before updateDnses because the
7813 // LinkProperties are not the source of the private DNS configuration.
7814 // updateDnses will fetch the private DNS configuration from DnsManager.
7815 mDnsManager.updatePrivateDnsStatus(netId, newLp);
Lorenzo Colitti20068c22014-11-28 20:07:46 +09007816
Chalard Jean5b409c72021-02-04 13:12:59 +09007817 if (isDefaultNetwork(networkAgent)) {
Paul Jensenc0618a62014-12-10 15:12:18 -05007818 handleApplyDefaultProxy(newLp.getHttpProxy());
7819 } else {
Chalard Jeand6c33dc2018-06-04 13:33:12 +09007820 updateProxy(newLp, oldLp);
Paul Jensenc0618a62014-12-10 15:12:18 -05007821 }
Valentin Iftime9fa35092019-09-24 13:32:13 +02007822
7823 updateWakeOnLan(newLp);
7824
Hai Shalome58bdc62021-01-11 18:45:34 -08007825 // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
7826 // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
7827 // does, it needs to be merged here.
7828 newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
7829 networkAgent.capportApiData));
Remi NGUYEN VAN45e11182019-12-12 12:57:11 +09007830
Robert Greenwalte525a0a2014-09-30 16:50:07 -07007831 // TODO - move this check to cover the whole function
7832 if (!Objects.equals(newLp, oldLp)) {
Chalard Jean8397a842018-05-23 09:07:51 +09007833 synchronized (networkAgent) {
7834 networkAgent.linkProperties = newLp;
7835 }
Lorenzo Colitti84298d82019-02-19 13:21:56 +09007836 // Start or stop DNS64 detection and 464xlat according to network state.
7837 networkAgent.clatd.update();
Junyu Lai2ed7d412022-10-07 16:52:21 +08007838 // Notify NSS when relevant events happened. Currently, NSS only cares about
7839 // interface changed to update clat interfaces accounting.
7840 final boolean interfacesChanged = oldLp == null
7841 || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames());
7842 if (interfacesChanged) {
7843 notifyIfacesChangedForNetworkStats();
7844 }
Remi NGUYEN VANc9f24742020-05-10 16:11:11 +09007845 networkAgent.networkMonitor().notifyLinkPropertiesChanged(
7846 new LinkProperties(newLp, true /* parcelSensitiveFields */));
Lorenzo Colitti275ee602022-08-09 19:29:12 +09007847 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
Robert Greenwalte525a0a2014-09-30 16:50:07 -07007848 }
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09007849
7850 mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
Paul Jensen3927e332014-05-13 11:44:01 -04007851 }
7852
Hai Shalome58bdc62021-01-11 18:45:34 -08007853 /**
7854 * @param naData captive portal data from NetworkAgent
7855 * @param apiData captive portal data from capport API
7856 */
7857 @Nullable
7858 private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
7859 CaptivePortalData apiData) {
7860 if (naData == null || apiData == null) {
7861 return naData == null ? apiData : naData;
7862 }
7863 final CaptivePortalData.Builder captivePortalBuilder =
7864 new CaptivePortalData.Builder(naData);
7865
7866 if (apiData.isCaptive()) {
7867 captivePortalBuilder.setCaptive(true);
7868 }
7869 if (apiData.isSessionExtendable()) {
7870 captivePortalBuilder.setSessionExtendable(true);
7871 }
7872 if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
7873 // Expiry time, bytes remaining, refresh time all need to come from the same source,
7874 // otherwise data would be inconsistent. Prefer the capport API info if present,
7875 // as it can generally be refreshed more often.
7876 captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
7877 captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
7878 captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
7879 } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
7880 // No source has time / bytes remaining information: surface the newest refresh time
7881 // for other fields
7882 captivePortalBuilder.setRefreshTime(
7883 Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
7884 }
7885
Hai Shalom7c6ab402021-02-04 19:34:06 -08007886 // Prioritize the user portal URL from the network agent if the source is authenticated.
7887 if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource()
7888 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
7889 captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(),
7890 apiData.getUserPortalUrlSource());
Hai Shalome58bdc62021-01-11 18:45:34 -08007891 }
Hai Shalom7c6ab402021-02-04 19:34:06 -08007892 // Prioritize the venue information URL from the network agent if the source is
7893 // authenticated.
7894 if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource()
7895 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
7896 captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(),
7897 apiData.getVenueInfoUrlSource());
Hai Shalome58bdc62021-01-11 18:45:34 -08007898 }
7899 return captivePortalBuilder.build();
7900 }
7901
Suprabh Shukla1e312032023-01-24 03:36:37 -08007902 private String makeNflogPrefix(String iface, long networkHandle) {
7903 // This needs to be kept in sync and backwards compatible with the decoding logic in
7904 // NetdEventListenerService, which is non-mainline code.
7905 return SdkLevel.isAtLeastU() ? (networkHandle + ":" + iface) : ("iface:" + iface);
7906 }
7907
7908 private void wakeupModifyInterface(String iface, NetworkAgentInfo nai, boolean add) {
Chalard Jean9dd11612018-06-04 16:52:49 +09007909 // Marks are only available on WiFi interfaces. Checking for
Joel Scherpelza235a812017-05-22 13:47:41 +09007910 // marks on unsupported interfaces is harmless.
Suprabh Shukla1e312032023-01-24 03:36:37 -08007911 if (!nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Joel Scherpelza235a812017-05-22 13:47:41 +09007912 return;
7913 }
Joel Scherpelza235a812017-05-22 13:47:41 +09007914
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09007915 int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark);
7916 int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask);
7917
Joel Scherpelz946a3c92017-06-08 15:35:21 +09007918 // Mask/mark of zero will not detect anything interesting.
7919 // Don't install rules unless both values are nonzero.
7920 if (mark == 0 || mask == 0) {
Joel Scherpelza235a812017-05-22 13:47:41 +09007921 return;
7922 }
Joel Scherpelz946a3c92017-06-08 15:35:21 +09007923
Suprabh Shukla1e312032023-01-24 03:36:37 -08007924 final String prefix = makeNflogPrefix(iface, nai.network.getNetworkHandle());
Joel Scherpelz946a3c92017-06-08 15:35:21 +09007925 try {
7926 if (add) {
Luke Huang46289a22018-09-27 19:33:11 +08007927 mNetd.wakeupAddInterface(iface, prefix, mark, mask);
Joel Scherpelz946a3c92017-06-08 15:35:21 +09007928 } else {
Luke Huang46289a22018-09-27 19:33:11 +08007929 mNetd.wakeupDelInterface(iface, prefix, mark, mask);
Joel Scherpelz946a3c92017-06-08 15:35:21 +09007930 }
7931 } catch (Exception e) {
7932 loge("Exception modifying wakeup packet monitoring: " + e);
7933 }
Joel Scherpelza235a812017-05-22 13:47:41 +09007934 }
7935
Junyu Lai970963e2022-10-25 15:46:47 +08007936 private void updateInterfaces(final @NonNull LinkProperties newLp,
Chalard Jean9589e722019-11-19 19:03:53 +09007937 final @Nullable LinkProperties oldLp, final int netId,
Suprabh Shukla1e312032023-01-24 03:36:37 -08007938 final @NonNull NetworkAgentInfo nai) {
Chalard Jean9589e722019-11-19 19:03:53 +09007939 final CompareResult<String> interfaceDiff = new CompareResult<>(
Junyu Lai970963e2022-10-25 15:46:47 +08007940 oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames());
Chalard Jean9589e722019-11-19 19:03:53 +09007941 if (!interfaceDiff.added.isEmpty()) {
Chalard Jean9589e722019-11-19 19:03:53 +09007942 for (final String iface : interfaceDiff.added) {
7943 try {
7944 if (DBG) log("Adding iface " + iface + " to network " + netId);
Chiachang Wangf83a7182020-10-26 14:23:52 +08007945 mNetd.networkAddInterface(netId, iface);
Suprabh Shukla1e312032023-01-24 03:36:37 -08007946 wakeupModifyInterface(iface, nai, true);
Aaron Huang330a4c02020-10-27 03:36:19 +08007947 mDeps.reportNetworkInterfaceForTransports(mContext, iface,
Suprabh Shukla1e312032023-01-24 03:36:37 -08007948 nai.networkCapabilities.getTransportTypes());
Chalard Jean9589e722019-11-19 19:03:53 +09007949 } catch (Exception e) {
lucaslinecdaf232021-04-01 19:17:08 +08007950 logw("Exception adding interface: " + e);
Chalard Jean9589e722019-11-19 19:03:53 +09007951 }
Paul Jensenbff73492014-04-28 10:33:11 -04007952 }
7953 }
Chalard Jean9589e722019-11-19 19:03:53 +09007954 for (final String iface : interfaceDiff.removed) {
Paul Jensenbff73492014-04-28 10:33:11 -04007955 try {
Robert Greenwalt419e1b42014-08-27 14:34:02 -07007956 if (DBG) log("Removing iface " + iface + " from network " + netId);
Suprabh Shukla1e312032023-01-24 03:36:37 -08007957 wakeupModifyInterface(iface, nai, false);
Chiachang Wangf83a7182020-10-26 14:23:52 +08007958 mNetd.networkRemoveInterface(netId, iface);
Paul Jensenbff73492014-04-28 10:33:11 -04007959 } catch (Exception e) {
7960 loge("Exception removing interface: " + e);
7961 }
7962 }
7963 }
7964
Tyler Weare4314862019-12-05 14:55:30 -08007965 // TODO: move to frameworks/libs/net.
7966 private RouteInfoParcel convertRouteInfo(RouteInfo route) {
7967 final String nextHop;
7968
7969 switch (route.getType()) {
7970 case RouteInfo.RTN_UNICAST:
7971 if (route.hasGateway()) {
7972 nextHop = route.getGateway().getHostAddress();
7973 } else {
7974 nextHop = INetd.NEXTHOP_NONE;
7975 }
7976 break;
7977 case RouteInfo.RTN_UNREACHABLE:
7978 nextHop = INetd.NEXTHOP_UNREACHABLE;
7979 break;
7980 case RouteInfo.RTN_THROW:
7981 nextHop = INetd.NEXTHOP_THROW;
7982 break;
7983 default:
7984 nextHop = INetd.NEXTHOP_NONE;
7985 break;
7986 }
7987
7988 final RouteInfoParcel rip = new RouteInfoParcel();
7989 rip.ifName = route.getInterface();
7990 rip.destination = route.getDestination().toString();
7991 rip.nextHop = nextHop;
7992 rip.mtu = route.getMtu();
7993
7994 return rip;
7995 }
7996
Paul Jensene0fd4a82014-08-06 15:51:33 -04007997 /**
7998 * Have netd update routes from oldLp to newLp.
7999 * @return true if routes changed between oldLp and newLp
8000 */
Junyu Lai970963e2022-10-25 15:46:47 +08008001 private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
8002 int netId) {
Tyler Weare4314862019-12-05 14:55:30 -08008003 // compare the route diff to determine which routes have been updated
junyulaia1493a52020-03-23 20:49:43 +08008004 final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
8005 new CompareOrUpdateResult<>(
8006 oldLp != null ? oldLp.getAllRoutes() : null,
Junyu Lai970963e2022-10-25 15:46:47 +08008007 newLp.getAllRoutes(),
junyulaia1493a52020-03-23 20:49:43 +08008008 (r) -> r.getRouteKey());
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008009
8010 // add routes before removing old in case it helps with continuous connectivity
8011
Chalard Jean9dd11612018-06-04 16:52:49 +09008012 // do this twice, adding non-next-hop routes first, then routes they are dependent on
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008013 for (RouteInfo route : routeDiff.added) {
8014 if (route.hasGateway()) continue;
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09008015 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008016 try {
Tyler Weare4314862019-12-05 14:55:30 -08008017 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008018 } catch (Exception e) {
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008019 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
Tyler Weare4314862019-12-05 14:55:30 -08008020 loge("Exception in networkAddRouteParcel for non-gateway: " + e);
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008021 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008022 }
8023 }
8024 for (RouteInfo route : routeDiff.added) {
Chalard Jeanfbab6d42019-09-26 18:03:47 +09008025 if (!route.hasGateway()) continue;
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09008026 if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008027 try {
Tyler Weare4314862019-12-05 14:55:30 -08008028 mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008029 } catch (Exception e) {
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008030 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
Tyler Weare4314862019-12-05 14:55:30 -08008031 loge("Exception in networkAddRouteParcel for gateway: " + e);
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008032 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008033 }
8034 }
8035
8036 for (RouteInfo route : routeDiff.removed) {
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09008037 if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008038 try {
Tyler Weare4314862019-12-05 14:55:30 -08008039 mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route));
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008040 } catch (Exception e) {
Tyler Weare4314862019-12-05 14:55:30 -08008041 loge("Exception in networkRemoveRouteParcel: " + e);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008042 }
8043 }
Tyler Weare4314862019-12-05 14:55:30 -08008044
8045 for (RouteInfo route : routeDiff.updated) {
8046 if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
8047 try {
8048 mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route));
8049 } catch (Exception e) {
8050 loge("Exception in networkUpdateRouteParcel: " + e);
8051 }
8052 }
8053 return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
8054 || !routeDiff.updated.isEmpty();
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008055 }
Erik Kline0f0dbb82015-06-17 13:19:54 +09008056
Junyu Lai970963e2022-10-25 15:46:47 +08008057 private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
8058 int netId) {
Erik Klineb9888902016-04-05 13:30:49 +09008059 if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
8060 return; // no updating necessary
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008061 }
Erik Klineb9888902016-04-05 13:30:49 +09008062
Erik Kline31b4a9e2018-01-11 21:07:29 +09008063 if (DBG) {
8064 final Collection<InetAddress> dnses = newLp.getDnsServers();
8065 log("Setting DNS servers for network " + netId + " to " + dnses);
8066 }
Erik Klineb9888902016-04-05 13:30:49 +09008067 try {
chenbruce7b2f8982020-02-20 14:28:31 +08008068 mDnsManager.noteDnsServersForNetwork(netId, newLp);
chenbruce7b2f8982020-02-20 14:28:31 +08008069 mDnsManager.flushVmDnsCache();
Erik Klineb9888902016-04-05 13:30:49 +09008070 } catch (Exception e) {
Pierre Imai21664692016-04-28 17:00:04 +09008071 loge("Exception in setDnsConfigurationForNetwork: " + e);
Erik Klineb9888902016-04-05 13:30:49 +09008072 }
Erik Kline54e35c02017-04-07 15:29:29 +09008073 }
8074
Junyu Lai970963e2022-10-25 15:46:47 +08008075 private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
8076 @NonNull NetworkAgentInfo nai) {
Motomu Utsumi77a79482022-05-16 04:04:34 +00008077 final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp);
8078 final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp);
Motomu Utsumib08654c2022-05-11 05:56:26 +00008079 final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface);
8080 final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface);
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008081
8082 if (!wasFiltering && !needsFiltering) {
8083 // Nothing to do.
8084 return;
8085 }
8086
8087 if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
8088 // Nothing changed.
8089 return;
8090 }
8091
Chiachang Wang8156c4e2021-03-19 00:45:39 +00008092 final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
Motomu Utsumib08654c2022-05-11 05:56:26 +00008093 if (ranges == null || ranges.isEmpty()) {
8094 return;
8095 }
8096
Qingxi Libb8da982020-01-17 17:54:27 -08008097 final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008098 // TODO: this create a window of opportunity for apps to receive traffic between the time
8099 // when the old rules are removed and the time when new rules are added. To fix this,
Jeff Sharkey39f8e972020-09-11 15:10:20 -06008100 // make eBPF support two allowlisted interfaces so here new rules can be added before the
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008101 // old rules are being removed.
8102 if (wasFiltering) {
8103 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
8104 }
8105 if (needsFiltering) {
8106 mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
8107 }
8108 }
8109
Valentin Iftime9fa35092019-09-24 13:32:13 +02008110 private void updateWakeOnLan(@NonNull LinkProperties lp) {
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09008111 if (mWolSupportedInterfaces == null) {
8112 mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09008113 R.array.config_wakeonlan_supported_interfaces));
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09008114 }
Valentin Iftime9fa35092019-09-24 13:32:13 +02008115 lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
8116 }
8117
Luke Huangb913c812018-08-24 20:33:16 +08008118 private int getNetworkPermission(NetworkCapabilities nc) {
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09008119 if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
Luke Huangb913c812018-08-24 20:33:16 +08008120 return INetd.PERMISSION_SYSTEM;
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09008121 }
8122 if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
Luke Huangb913c812018-08-24 20:33:16 +08008123 return INetd.PERMISSION_NETWORK;
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09008124 }
Luke Huangb913c812018-08-24 20:33:16 +08008125 return INetd.PERMISSION_NONE;
Lorenzo Colittib8d9f522016-07-28 17:14:11 +09008126 }
8127
Chalard Jean62edfd82019-12-02 18:39:29 +09008128 private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
8129 @NonNull final NetworkCapabilities newNc) {
8130 final int oldPermission = getNetworkPermission(nai.networkCapabilities);
8131 final int newPermission = getNetworkPermission(newNc);
Chalard Jean254bd162022-08-25 13:04:51 +09008132 if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) {
Chalard Jean62edfd82019-12-02 18:39:29 +09008133 try {
Serik Beketayevec8ad212020-12-07 22:43:07 -08008134 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
Chiachang Wangedb833a2020-10-26 19:59:31 +08008135 } catch (RemoteException | ServiceSpecificException e) {
8136 loge("Exception in networkSetPermissionForNetwork: " + e);
Chalard Jean62edfd82019-12-02 18:39:29 +09008137 }
8138 }
8139 }
8140
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008141 /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008142 @VisibleForTesting
Lorenzo Colittid7caf832020-12-01 01:08:37 +09008143 void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008144 @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
James Mattis2516da32021-01-31 17:06:19 -08008145 underlyingNetworks = underlyingNetworksOrDefault(
8146 agentCaps.getOwnerUid(), underlyingNetworks);
Chalard Jean1d420b32022-10-12 16:39:37 +09008147 long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes());
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008148 int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
8149 int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008150 // metered if any underlying is metered, or originally declared metered by the agent.
8151 boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008152 boolean roaming = false; // roaming if any underlying is roaming
8153 boolean congested = false; // congested if any underlying is congested
8154 boolean suspended = true; // suspended if all underlying are suspended
8155
8156 boolean hadUnderlyingNetworks = false;
lucaslin6adf5ac2021-10-19 15:04:56 +08008157 ArrayList<Network> newUnderlyingNetworks = null;
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008158 if (null != underlyingNetworks) {
lucaslin6adf5ac2021-10-19 15:04:56 +08008159 newUnderlyingNetworks = new ArrayList<>();
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008160 for (Network underlyingNetwork : underlyingNetworks) {
8161 final NetworkAgentInfo underlying =
8162 getNetworkAgentInfoForNetwork(underlyingNetwork);
8163 if (underlying == null) continue;
8164
8165 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
8166 hadUnderlyingNetworks = true;
8167 for (int underlyingType : underlyingCaps.getTransportTypes()) {
Remi NGUYEN VAN3d159fc2020-12-01 17:47:12 +09008168 transportTypes |= 1L << underlyingType;
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008169 }
8170
8171 // Merge capabilities of this underlying network. For bandwidth, assume the
8172 // worst case.
8173 downKbps = NetworkCapabilities.minBandwidth(downKbps,
8174 underlyingCaps.getLinkDownstreamBandwidthKbps());
8175 upKbps = NetworkCapabilities.minBandwidth(upKbps,
8176 underlyingCaps.getLinkUpstreamBandwidthKbps());
8177 // If this underlying network is metered, the VPN is metered (it may cost money
8178 // to send packets on this network).
8179 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
8180 // If this underlying network is roaming, the VPN is roaming (the billing structure
8181 // is different than the usual, local one).
8182 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
8183 // If this underlying network is congested, the VPN is congested (the current
8184 // condition of the network affects the performance of this network).
8185 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
8186 // If this network is not suspended, the VPN is not suspended (the VPN
8187 // is able to transfer some data).
8188 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
lucaslin6adf5ac2021-10-19 15:04:56 +08008189 newUnderlyingNetworks.add(underlyingNetwork);
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008190 }
8191 }
8192 if (!hadUnderlyingNetworks) {
8193 // No idea what the underlying networks are; assume reasonable defaults
8194 metered = true;
8195 roaming = false;
8196 congested = false;
8197 suspended = false;
8198 }
8199
Chalard Jean1d420b32022-10-12 16:39:37 +09008200 newNc.setTransportTypes(BitUtils.unpackBits(transportTypes));
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008201 newNc.setLinkDownstreamBandwidthKbps(downKbps);
8202 newNc.setLinkUpstreamBandwidthKbps(upKbps);
8203 newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
8204 newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
8205 newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
8206 newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
lucaslin6adf5ac2021-10-19 15:04:56 +08008207 newNc.setUnderlyingNetworks(newUnderlyingNetworks);
Lorenzo Colitticda101b2020-11-24 21:45:25 +09008208 }
8209
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09008210 /**
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008211 * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
8212 * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
8213 * and foreground status).
Paul Jensen53f08952015-06-16 14:27:36 -04008214 */
Remi NGUYEN VANdf5f3112021-01-28 15:09:22 +09008215 @NonNull
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008216 private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
Hugo Benichi9712eb32017-08-16 13:19:04 +09008217 // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
Lorenzo Colitti614891d2018-05-30 16:44:47 +09008218 // Don't complain for VPNs since they're not driven by requests and there is no risk of
8219 // causing a connect/teardown loop.
Lorenzo Colittia86fae72020-01-10 00:40:28 +09008220 // TODO: remove this altogether and make it the responsibility of the NetworkProviders to
Lorenzo Colitti614891d2018-05-30 16:44:47 +09008221 // avoid connect/teardown loops.
Chalard Jean254bd162022-08-25 13:04:51 +09008222 if (nai.everConnected()
8223 && !nai.isVPN()
8224 && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008225 // TODO: consider not complaining when a network agent degrades its capabilities if this
Hugo Benichi9712eb32017-08-16 13:19:04 +09008226 // does not cause any request (that is not a listen) currently matching that agent to
8227 // stop being matched by the updated agent.
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008228 String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
Hugo Benichid9806e82017-07-25 11:40:56 +09008229 if (!TextUtils.isEmpty(diff)) {
Aaron Huang6616df32020-10-30 22:04:25 +08008230 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
Hugo Benichid9806e82017-07-25 11:40:56 +09008231 }
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008232 }
8233
Paul Jensen53f08952015-06-16 14:27:36 -04008234 // Don't modify caller's NetworkCapabilities.
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008235 final NetworkCapabilities newNc = new NetworkCapabilities(nc);
Chalard Jean254bd162022-08-25 13:04:51 +09008236 if (nai.isValidated()) {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008237 newNc.addCapability(NET_CAPABILITY_VALIDATED);
Paul Jensen53f08952015-06-16 14:27:36 -04008238 } else {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008239 newNc.removeCapability(NET_CAPABILITY_VALIDATED);
Paul Jensen53f08952015-06-16 14:27:36 -04008240 }
Chalard Jean254bd162022-08-25 13:04:51 +09008241 if (nai.captivePortalDetected()) {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008242 newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensen53f08952015-06-16 14:27:36 -04008243 } else {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008244 newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
Paul Jensen53f08952015-06-16 14:27:36 -04008245 }
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008246 if (nai.isBackgroundNetwork()) {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008247 newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008248 } else {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008249 newNc.addCapability(NET_CAPABILITY_FOREGROUND);
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008250 }
Chalard Jean254bd162022-08-25 13:04:51 +09008251 if (nai.partialConnectivity()) {
lucaslin2240ef62019-03-12 13:08:03 +08008252 newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
8253 } else {
8254 newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
8255 }
lucasline117e2e2019-10-22 18:27:33 +08008256 newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008257
Chalard Jeanaf14ca42020-01-15 00:49:43 +09008258 // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
Chalard Jeand61375d2020-01-14 22:46:36 +09008259 if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
8260 newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
Chalard Jeanaf14ca42020-01-15 00:49:43 +09008261 newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
Chalard Jeand61375d2020-01-14 22:46:36 +09008262 }
8263
Lorenzo Colittibd079452021-07-02 11:47:57 +09008264 if (nai.propagateUnderlyingCapabilities()) {
Chalard Jeanda7fe572022-02-01 23:47:23 +09008265 applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks,
Chalard Jean39b12d42022-02-27 12:08:49 +09008266 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator),
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008267 newNc);
Lorenzo Colitti129c01e2020-11-09 10:32:56 +09008268 }
8269
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008270 return newNc;
8271 }
8272
Lorenzo Colitti44840702021-01-11 22:27:57 +09008273 private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai,
8274 NetworkCapabilities prevNc, NetworkCapabilities newNc) {
8275 final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
8276 final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
8277 final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
8278 final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
8279 if (prevSuspended != suspended) {
8280 // TODO (b/73132094) : remove this call once the few users of onSuspended and
8281 // onResumed have been removed.
8282 notifyNetworkCallbacks(nai, suspended ? ConnectivityManager.CALLBACK_SUSPENDED
8283 : ConnectivityManager.CALLBACK_RESUMED);
8284 }
8285 if (prevSuspended != suspended || prevRoaming != roaming) {
8286 // updateNetworkInfo will mix in the suspended info from the capabilities and
8287 // take appropriate action for the network having possibly changed state.
8288 updateNetworkInfo(nai, nai.networkInfo);
8289 }
8290 }
8291
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008292 /**
8293 * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
8294 *
8295 * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
8296 * capabilities we manage and store in {@code nai}, such as validated status and captive
8297 * portal status)
8298 * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
8299 * potentially triggers rematches.
8300 * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
8301 * change.)
8302 *
8303 * @param oldScore score of the network before any of the changes that prompted us
8304 * to call this function.
8305 * @param nai the network having its capabilities updated.
8306 * @param nc the new network capabilities.
8307 */
Chalard Jeanaa5bc622022-02-26 21:34:48 +09008308 private void updateCapabilities(final FullScore oldScore, @NonNull final NetworkAgentInfo nai,
Chalard Jean62edfd82019-12-02 18:39:29 +09008309 @NonNull final NetworkCapabilities nc) {
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008310 NetworkCapabilities newNc = mixInCapabilities(nai, nc);
Lorenzo Colitti46f96cb2018-01-16 00:52:07 +09008311 if (Objects.equals(nai.networkCapabilities, newNc)) return;
Chalard Jean86317d82022-10-12 16:18:04 +09008312 final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities);
8313 if (null != differences) {
8314 Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences);
8315 }
Chalard Jean62edfd82019-12-02 18:39:29 +09008316 updateNetworkPermissions(nai, newNc);
Chalard Jean05edd052019-11-22 22:39:56 +09008317 final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
Jeff Sharkey07e19362017-10-27 17:22:59 -06008318
Lorenzo Colitti96a3f142022-02-08 16:21:01 +00008319 updateVpnUids(nai, prevNc, newNc);
Chalard Jeande665262022-02-25 16:12:12 +09008320 updateAllowedUids(nai, prevNc, newNc);
Chalard Jean142f0fe2021-03-31 23:19:05 +09008321 nai.updateScoreForNetworkAgentUpdate();
Chalard Jeanb2a49912018-01-16 18:43:05 +09008322
Chalard Jeanaa5bc622022-02-26 21:34:48 +09008323 if (nai.getScore().equals(oldScore) && newNc.equalRequestableCapabilities(prevNc)) {
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008324 // If the requestable capabilities haven't changed, and the score hasn't changed, then
8325 // the change we're processing can't affect any requests, it can only affect the listens
8326 // on this network. We might have been called by rematchNetworkAndRequests when a
8327 // network changed foreground state.
Chalard Jean05cbe972019-12-09 11:50:38 +09008328 processListenRequests(nai);
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008329 } else {
8330 // If the requestable capabilities have changed or the score changed, we can't have been
8331 // called by rematchNetworkAndRequests, so it's safe to start a rematch.
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09008332 rematchAllNetworksAndRequests();
Paul Jensende49eb12015-06-25 15:30:08 -04008333 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07008334 }
Lorenzo Colitti44840702021-01-11 22:27:57 +09008335 updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc);
Jeff Sharkey07e19362017-10-27 17:22:59 -06008336
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008337 final boolean oldMetered = prevNc.isMetered();
8338 final boolean newMetered = newNc.isMetered();
8339 final boolean meteredChanged = oldMetered != newMetered;
junyulaif2c67e42018-08-07 19:50:45 +08008340
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008341 if (meteredChanged) {
Sudheer Shanka9967d462021-03-18 19:09:25 +00008342 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
8343 mVpnBlockedUidRanges, mVpnBlockedUidRanges);
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008344 }
junyulaif2c67e42018-08-07 19:50:45 +08008345
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008346 final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
8347 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
junyulaif2c67e42018-08-07 19:50:45 +08008348
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008349 // Report changes that are interesting for network statistics tracking.
Aaron Huangc5a05d12022-12-01 21:11:12 +08008350 if (meteredChanged || roamingChanged) {
Lorenzo Colitti59fa1272021-01-16 00:23:46 +09008351 notifyIfacesChangedForNetworkStats();
Jeff Sharkey07e19362017-10-27 17:22:59 -06008352 }
8353
Lorenzo Colitti96dba632020-12-02 00:48:09 +09008354 // This network might have been underlying another network. Propagate its capabilities.
8355 propagateUnderlyingNetworkCapabilities(nai.network);
chenbruce7b2f8982020-02-20 14:28:31 +08008356
8357 if (!newNc.equalsTransportTypes(prevNc)) {
Serik Beketayevec8ad212020-12-07 22:43:07 -08008358 mDnsManager.updateTransportsForNetwork(
8359 nai.network.getNetId(), newNc.getTransportTypes());
chenbruce7b2f8982020-02-20 14:28:31 +08008360 }
lucaslin53e8a262021-06-08 01:43:59 +08008361
8362 maybeSendProxyBroadcast(nai, prevNc, newNc);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008363 }
8364
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09008365 /** Convenience method to update the capabilities for a given network. */
8366 private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) {
Chalard Jeanaa5bc622022-02-26 21:34:48 +09008367 updateCapabilities(nai.getScore(), nai, nai.networkCapabilities);
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09008368 }
8369
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008370 /**
Motomu Utsumi77a79482022-05-16 04:04:34 +00008371 * Returns the interface which requires VPN isolation (ingress interface filtering).
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008372 *
8373 * Ingress interface filtering enforces that all apps under the given network can only receive
8374 * packets from the network's interface (and loopback). This is important for VPNs because
8375 * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
8376 * non-VPN interfaces.
8377 *
Motomu Utsumi77a79482022-05-16 04:04:34 +00008378 * As a result, this method should return Non-null interface iff
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008379 * 1. the network is an app VPN (not legacy VPN)
8380 * 2. the VPN does not allow bypass
8381 * 3. the VPN is fully-routed
8382 * 4. the VPN interface is non-null
8383 *
Chalard Jeanfbab6d42019-09-26 18:03:47 +09008384 * @see INetd#firewallAddUidInterfaceRules
8385 * @see INetd#firewallRemoveUidInterfaceRules
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008386 */
Motomu Utsumi77a79482022-05-16 04:04:34 +00008387 @Nullable
8388 private String getVpnIsolationInterface(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008389 LinkProperties lp) {
Motomu Utsumi77a79482022-05-16 04:04:34 +00008390 if (nc == null || lp == null) return null;
8391 if (nai.isVPN()
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09008392 && !nai.networkAgentConfig.allowBypass
Qingxi Libb8da982020-01-17 17:54:27 -08008393 && nc.getOwnerUid() != Process.SYSTEM_UID
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008394 && lp.getInterfaceName() != null
lucaslinec9ab792020-11-02 16:05:02 +08008395 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute())
Prerana2b97bbe2022-04-28 04:02:05 +00008396 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute())
Motomu Utsumi77a79482022-05-16 04:04:34 +00008397 && !lp.hasExcludeRoute()) {
8398 return lp.getInterfaceName();
8399 }
8400 return null;
8401 }
8402
8403 /**
8404 * Returns whether we need to set interface filtering rule or not
8405 */
Motomu Utsumib08654c2022-05-11 05:56:26 +00008406 private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp,
Motomu Utsumif8bd82c2022-05-30 12:28:04 +00008407 String isolationIface) {
8408 // Allow rules are always needed if VPN isolation is enabled.
8409 if (isolationIface != null) return true;
8410
8411 // On T and above, allow rules are needed for all VPNs. Allow rule with null iface is a
8412 // wildcard to allow apps to receive packets on all interfaces. This is required to accept
8413 // incoming traffic in Lockdown mode by overriding the Lockdown blocking rule.
8414 return SdkLevel.isAtLeastT() && nai.isVPN() && lp != null && lp.getInterfaceName() != null;
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008415 }
8416
Chiachang Wang28afaff2020-12-10 22:24:47 +08008417 private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
8418 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()];
8419 int index = 0;
8420 for (UidRange range : ranges) {
8421 stableRanges[index] = new UidRangeParcel(range.start, range.stop);
8422 index++;
8423 }
8424 return stableRanges;
8425 }
8426
Chalard Jeane6c95272022-01-25 21:04:21 +09008427 private static UidRangeParcel[] intsToUidRangeStableParcels(
8428 final @NonNull ArraySet<Integer> uids) {
8429 final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()];
8430 int index = 0;
8431 for (int uid : uids) {
8432 stableRanges[index] = new UidRangeParcel(uid, uid);
8433 index++;
8434 }
8435 return stableRanges;
8436 }
8437
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09008438 private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
8439 final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
8440 for (int i = 0; i < ranges.length; i++) {
8441 stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop);
8442 }
8443 return stableRanges;
8444 }
8445
Ken Chen5e65a852020-12-24 12:59:10 +08008446 private void maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges,
8447 int[] exemptUids) {
8448 if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) {
8449 try {
8450 mNetd.socketDestroy(ranges, exemptUids);
8451 } catch (Exception e) {
8452 loge("Exception in socket destroy: ", e);
8453 }
8454 }
8455 }
8456
paulhuaa0743d2021-05-26 21:56:03 +08008457 private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) {
Ken Chen5e65a852020-12-24 12:59:10 +08008458 int[] exemptUids = new int[2];
8459 // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used
8460 // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when
8461 // starting a legacy VPN, and remove VPN_UID here. (b/176542831)
8462 exemptUids[0] = VPN_UID;
8463 exemptUids[1] = nai.networkCapabilities.getOwnerUid();
8464 UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges);
8465
Motomu Utsumi6345e462023-03-13 13:24:50 +09008466 // Close sockets before modifying uid ranges so that RST packets can reach to the server.
Ken Chen5e65a852020-12-24 12:59:10 +08008467 maybeCloseSockets(nai, ranges, exemptUids);
8468 try {
8469 if (add) {
paulhu0e79d952021-06-09 16:11:35 +08008470 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
paulhu48291862021-07-14 14:53:57 +08008471 nai.network.netId, ranges, PREFERENCE_ORDER_VPN));
Ken Chen5e65a852020-12-24 12:59:10 +08008472 } else {
paulhu0e79d952021-06-09 16:11:35 +08008473 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
paulhu48291862021-07-14 14:53:57 +08008474 nai.network.netId, ranges, PREFERENCE_ORDER_VPN));
Ken Chen5e65a852020-12-24 12:59:10 +08008475 }
8476 } catch (Exception e) {
8477 loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
8478 " on netId " + nai.network.netId + ". " + e);
8479 }
Motomu Utsumi6345e462023-03-13 13:24:50 +09008480 // Close sockets that established connection while requesting netd.
Ken Chen5e65a852020-12-24 12:59:10 +08008481 maybeCloseSockets(nai, ranges, exemptUids);
8482 }
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09008483
lucaslin53e8a262021-06-08 01:43:59 +08008484 private boolean isProxySetOnAnyDefaultNetwork() {
8485 ensureRunningOnConnectivityServiceThread();
8486 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
8487 final NetworkAgentInfo nai = nri.getSatisfier();
8488 if (nai != null && nai.linkProperties.getHttpProxy() != null) {
8489 return true;
8490 }
8491 }
8492 return false;
8493 }
8494
8495 private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc,
8496 NetworkCapabilities newNc) {
8497 // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that
8498 // the proxy might be changed since the default network satisfied by the apps might also
8499 // changed.
8500 // TODO: Try to track the default network that apps use and only send a proxy broadcast when
8501 // that happens to prevent false alarms.
Chalard Jeanf4802fa2021-12-13 21:37:12 +09008502 final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges();
8503 final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges();
Chalard Jean254bd162022-08-25 13:04:51 +09008504 if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids)
lucaslin53e8a262021-06-08 01:43:59 +08008505 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
8506 mProxyTracker.sendProxyBroadcast();
8507 }
8508 }
8509
Chalard Jeane6c95272022-01-25 21:04:21 +09008510 private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc,
8511 @Nullable NetworkCapabilities newNc) {
Chiachang Wang8156c4e2021-03-19 00:45:39 +00008512 Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
8513 Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
Chalard Jeanb2a49912018-01-16 18:43:05 +09008514 if (null == prevRanges) prevRanges = new ArraySet<>();
8515 if (null == newRanges) newRanges = new ArraySet<>();
8516 final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
8517
8518 prevRanges.removeAll(newRanges);
8519 newRanges.removeAll(prevRangesCopy);
8520
8521 try {
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008522 // When updating the VPN uid routing rules, add the new range first then remove the old
8523 // range. If old range were removed first, there would be a window between the old
8524 // range being removed and the new range being added, during which UIDs contained
8525 // in both ranges are not subject to any VPN routing rules. Adding new range before
8526 // removing old range works because, unlike the filtering rules below, it's possible to
8527 // add duplicate UID routing rules.
Ken Chen5e65a852020-12-24 12:59:10 +08008528 // TODO: calculate the intersection of add & remove. Imagining that we are trying to
8529 // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is:
8530 // [1-5] & [1-2],[4-5] == [3]
8531 // Then we can do:
8532 // maybeCloseSockets([3])
8533 // mNetd.networkAddUidRanges([1-2],[4-5])
8534 // mNetd.networkRemoveUidRanges([1-5])
8535 // maybeCloseSockets([3])
8536 // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the
8537 // number of binder calls from 6 to 4.
Chalard Jeanb2a49912018-01-16 18:43:05 +09008538 if (!newRanges.isEmpty()) {
paulhuaa0743d2021-05-26 21:56:03 +08008539 updateVpnUidRanges(true, nai, newRanges);
Chalard Jeanb2a49912018-01-16 18:43:05 +09008540 }
8541 if (!prevRanges.isEmpty()) {
paulhuaa0743d2021-05-26 21:56:03 +08008542 updateVpnUidRanges(false, nai, prevRanges);
Chalard Jeanb2a49912018-01-16 18:43:05 +09008543 }
Motomu Utsumi77a79482022-05-16 04:04:34 +00008544 final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties);
8545 final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties);
Motomu Utsumib08654c2022-05-11 05:56:26 +00008546 final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface);
8547 final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface);
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008548 // For VPN uid interface filtering, old ranges need to be removed before new ranges can
Chalard Jeana5ff1132020-05-20 16:11:50 +09008549 // be added, due to the range being expanded and stored as individual UIDs. For example
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008550 // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
8551 // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
8552 // were added first and then newRanges got removed later, there would be only one uid
8553 // 10013 left. A consequence of removing old ranges before adding new ranges is that
8554 // there is now a window of opportunity when the UIDs are not subject to any filtering.
8555 // Note that this is in contrast with the (more robust) update of VPN routing rules
8556 // above, where the addition of new ranges happens before the removal of old ranges.
8557 // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
8558 // to be removed will never overlap with the new range to be added.
8559 if (wasFiltering && !prevRanges.isEmpty()) {
Motomu Utsumi77a79482022-05-16 04:04:34 +00008560 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges,
8561 prevNc.getOwnerUid());
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008562 }
8563 if (shouldFilter && !newRanges.isEmpty()) {
Motomu Utsumi77a79482022-05-16 04:04:34 +00008564 mPermissionMonitor.onVpnUidRangesAdded(newIface, newRanges, newNc.getOwnerUid());
Lorenzo Colittibad9d912019-04-12 10:48:06 +00008565 }
Chalard Jeanb2a49912018-01-16 18:43:05 +09008566 } catch (Exception e) {
8567 // Never crash!
Lorenzo Colitti96a3f142022-02-08 16:21:01 +00008568 loge("Exception in updateVpnUids: ", e);
Chalard Jeanb2a49912018-01-16 18:43:05 +09008569 }
8570 }
8571
Chalard Jeande665262022-02-25 16:12:12 +09008572 private void updateAllowedUids(@NonNull NetworkAgentInfo nai,
Chalard Jeane6c95272022-01-25 21:04:21 +09008573 @Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) {
8574 // In almost all cases both NC code for empty access UIDs. return as fast as possible.
Chalard Jeande665262022-02-25 16:12:12 +09008575 final boolean prevEmpty = null == prevNc || prevNc.getAllowedUidsNoCopy().isEmpty();
8576 final boolean newEmpty = null == newNc || newNc.getAllowedUidsNoCopy().isEmpty();
Chalard Jeane6c95272022-01-25 21:04:21 +09008577 if (prevEmpty && newEmpty) return;
8578
8579 final ArraySet<Integer> prevUids =
Chalard Jeande665262022-02-25 16:12:12 +09008580 null == prevNc ? new ArraySet<>() : prevNc.getAllowedUidsNoCopy();
Chalard Jeane6c95272022-01-25 21:04:21 +09008581 final ArraySet<Integer> newUids =
Chalard Jeande665262022-02-25 16:12:12 +09008582 null == newNc ? new ArraySet<>() : newNc.getAllowedUidsNoCopy();
Chalard Jeane6c95272022-01-25 21:04:21 +09008583
8584 if (prevUids.equals(newUids)) return;
8585
8586 // This implementation is very simple and vastly faster for sets of Integers than
8587 // CompareOrUpdateResult, which is tuned for sets that need to be compared based on
8588 // a key computed from the value and has storage for that.
8589 final ArraySet<Integer> toRemove = new ArraySet<>(prevUids);
8590 final ArraySet<Integer> toAdd = new ArraySet<>(newUids);
8591 toRemove.removeAll(newUids);
8592 toAdd.removeAll(prevUids);
8593
8594 try {
8595 if (!toAdd.isEmpty()) {
8596 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
8597 nai.network.netId,
8598 intsToUidRangeStableParcels(toAdd),
8599 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT));
8600 }
8601 if (!toRemove.isEmpty()) {
8602 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
8603 nai.network.netId,
8604 intsToUidRangeStableParcels(toRemove),
8605 PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT));
8606 }
Lorenzo Colitti96a3f142022-02-08 16:21:01 +00008607 } catch (ServiceSpecificException e) {
8608 // Has the interface disappeared since the network was built ?
8609 Log.i(TAG, "Can't set access UIDs for network " + nai.network, e);
Chalard Jeane6c95272022-01-25 21:04:21 +09008610 } catch (RemoteException e) {
8611 // Netd died. This usually causes a runtime restart anyway.
8612 }
8613 }
8614
Junyu Lai2ed7d412022-10-07 16:52:21 +08008615 public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai,
8616 @NonNull LinkProperties newLp) {
Lorenzo Colittibb6bacc2019-02-20 21:34:01 +09008617 ensureRunningOnConnectivityServiceThread();
8618
Lorenzo Colittib4bf0152021-06-07 15:32:04 +09008619 if (!mNetworkAgentInfos.contains(nai)) {
Hugo Benichi9d35b752017-09-01 01:23:32 +00008620 // Ignore updates for disconnected networks
8621 return;
8622 }
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09008623 if (VDBG || DDBG) {
Chalard Jean49707572019-12-10 21:07:02 +09008624 log("Update of LinkProperties for " + nai.toShortString()
Chalard Jean254bd162022-08-25 13:04:51 +09008625 + "; created=" + nai.getCreatedTime()
8626 + "; firstConnected=" + nai.getConnectedTime());
Hugo Benichi9d35b752017-09-01 01:23:32 +00008627 }
Lorenzo Colitti18a58462020-04-16 01:52:40 +09008628 // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
8629 // modify its oldLp parameter.
lucaslin74fa3972018-11-28 12:51:55 +08008630 updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
Hugo Benichi9d35b752017-09-01 01:23:32 +00008631 }
8632
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008633 private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
8634 int notificationType) {
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08008635 if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008636 Intent intent = new Intent();
Jeremy Joslinde802a22014-11-26 14:24:15 -08008637 intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
James Mattisa076c532020-12-02 14:12:41 -08008638 // If apps could file multi-layer requests with PendingIntents, they'd need to know
8639 // which of the layer is satisfied alongside with some ID for the request. Hence, if
8640 // such an API is ever implemented, there is no doubt the right request to send in
Remi NGUYEN VAN1e238a82021-06-25 16:38:05 +09008641 // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would
8642 // need to be sent as a separate extra.
8643 final NetworkRequest req = nri.isMultilayerRequest()
8644 ? nri.getActiveRequest()
8645 // Non-multilayer listen requests do not have an active request
8646 : nri.mRequests.get(0);
8647 if (req == null) {
8648 Log.wtf(TAG, "No request in NRI " + nri);
8649 }
8650 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req);
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08008651 nri.mPendingIntentSent = true;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008652 sendIntent(nri.mPendingIntent, intent);
8653 }
8654 // else not handled
8655 }
8656
Michael Groover73f69482023-01-27 11:01:25 -06008657 // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
8658 @SuppressLint("NewApi")
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008659 private void sendIntent(PendingIntent pendingIntent, Intent intent) {
8660 mPendingIntentWakeLock.acquire();
8661 try {
8662 if (DBG) log("Sending " + pendingIntent);
chiachangwanga36518c2022-05-26 05:19:41 +00008663 final BroadcastOptions options = BroadcastOptions.makeBasic();
8664 if (SdkLevel.isAtLeastT()) {
8665 // Explicitly disallow the receiver from starting activities, to prevent apps from
8666 // utilizing the PendingIntent as a backdoor to do this.
8667 options.setPendingIntentBackgroundActivityLaunchAllowed(false);
8668 }
8669 pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */,
8670 null /* requiredPermission */,
8671 SdkLevel.isAtLeastT() ? options.toBundle() : null);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008672 } catch (PendingIntent.CanceledException e) {
8673 if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
8674 mPendingIntentWakeLock.release();
8675 releasePendingNetworkRequest(pendingIntent);
8676 }
8677 // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
8678 }
8679
8680 @Override
8681 public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
8682 String resultData, Bundle resultExtras) {
8683 if (DBG) log("Finished sending " + pendingIntent);
8684 mPendingIntentWakeLock.release();
Jeremy Joslin1d3acf92014-12-03 17:15:28 -08008685 // Release with a delay so the receiving client has an opportunity to put in its
8686 // own request.
8687 releasePendingNetworkRequestWithDelay(pendingIntent);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08008688 }
8689
Chalard Jean46bfbf02022-02-02 00:56:25 +09008690 // networkAgent is only allowed to be null if notificationType is
8691 // CALLBACK_UNAVAIL. This is because UNAVAIL is about no network being
8692 // available, while all other cases are about some particular network.
James Mattis212df9e2020-12-03 19:57:41 -08008693 private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
Chalard Jean46bfbf02022-02-02 00:56:25 +09008694 @Nullable final NetworkAgentInfo networkAgent, final int notificationType,
James Mattis212df9e2020-12-03 19:57:41 -08008695 final int arg1) {
James Mattis45d81842021-01-10 14:24:24 -08008696 if (nri.mMessenger == null) {
Cody Kesting73708bf2019-12-18 10:57:50 -08008697 // Default request has no msgr. Also prevents callbacks from being invoked for
8698 // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
8699 // are Type.LISTEN, but should not have NetworkCallbacks invoked.
8700 return;
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09008701 }
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008702 Bundle bundle = new Bundle();
James Mattis212df9e2020-12-03 19:57:41 -08008703 // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09008704 // TODO: check if defensive copies of data is needed.
James Mattis3ce3d3c2021-02-09 18:18:28 -08008705 final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback();
James Mattis212df9e2020-12-03 19:57:41 -08008706 putParcelable(bundle, nrForCallback);
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008707 Message msg = Message.obtain();
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09008708 if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
8709 putParcelable(bundle, networkAgent.network);
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008710 }
Roshan Pius951c0032020-12-22 15:10:42 -08008711 final boolean includeLocationSensitiveInfo =
8712 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008713 switch (notificationType) {
Chalard Jeana23bc9e2018-01-30 22:41:41 +09008714 case ConnectivityManager.CALLBACK_AVAILABLE: {
Qingxi Lib2748102020-01-08 12:51:49 -08008715 final NetworkCapabilities nc =
Roshan Pius9ed14622020-12-28 09:01:49 -08008716 createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Chalard Jean713e38c2022-02-28 10:58:17 +09008717 networkCapabilitiesRestrictedForCallerPermissions(
8718 networkAgent.networkCapabilities, nri.mPid, nri.mUid),
8719 includeLocationSensitiveInfo, nri.mPid, nri.mUid,
Roshan Pius951c0032020-12-22 15:10:42 -08008720 nrForCallback.getRequestorPackageName(),
Chalard Jean713e38c2022-02-28 10:58:17 +09008721 nri.mCallingAttributionTag);
8722 putParcelable(bundle, nc);
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09008723 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
8724 networkAgent.linkProperties, nri.mPid, nri.mUid));
junyulaif2c67e42018-08-07 19:50:45 +08008725 // For this notification, arg1 contains the blocked status.
8726 msg.arg1 = arg1;
Chalard Jeana23bc9e2018-01-30 22:41:41 +09008727 break;
8728 }
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008729 case ConnectivityManager.CALLBACK_LOSING: {
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09008730 msg.arg1 = arg1;
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008731 break;
8732 }
8733 case ConnectivityManager.CALLBACK_CAP_CHANGED: {
Chalard Jean2550e062018-01-26 19:24:40 +09008734 // networkAgent can't be null as it has been accessed a few lines above.
Qingxi Lib2748102020-01-08 12:51:49 -08008735 final NetworkCapabilities netCap =
8736 networkCapabilitiesRestrictedForCallerPermissions(
8737 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
8738 putParcelable(
8739 bundle,
Roshan Pius9ed14622020-12-28 09:01:49 -08008740 createWithLocationInfoSanitizedIfNecessaryWhenParceled(
Roshan Pius98f59ec2021-02-23 08:47:39 -08008741 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
Roshan Pius951c0032020-12-22 15:10:42 -08008742 nrForCallback.getRequestorPackageName(),
Roshan Piusaa24fde2020-12-17 14:53:09 -08008743 nri.mCallingAttributionTag));
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008744 break;
8745 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008746 case ConnectivityManager.CALLBACK_IP_CHANGED: {
Remi NGUYEN VAN0a65eed2019-12-17 16:45:42 +09008747 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
8748 networkAgent.linkProperties, nri.mPid, nri.mUid));
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008749 break;
8750 }
junyulaif2c67e42018-08-07 19:50:45 +08008751 case ConnectivityManager.CALLBACK_BLK_CHANGED: {
Lorenzo Colitti42fe2232021-03-25 23:17:36 +09008752 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
junyulaif2c67e42018-08-07 19:50:45 +08008753 msg.arg1 = arg1;
8754 break;
8755 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008756 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008757 msg.what = notificationType;
Robert Greenwalte525a0a2014-09-30 16:50:07 -07008758 msg.setData(bundle);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008759 try {
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008760 if (VDBG) {
Hugo Benichi8d962922017-03-22 17:07:57 +09008761 String notification = ConnectivityManager.getCallbackName(notificationType);
James Mattis212df9e2020-12-03 19:57:41 -08008762 log("sending notification " + notification + " for " + nrForCallback);
Robert Greenwalt419e1b42014-08-27 14:34:02 -07008763 }
James Mattis45d81842021-01-10 14:24:24 -08008764 nri.mMessenger.send(msg);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008765 } catch (RemoteException e) {
8766 // may occur naturally in the race of binder death.
James Mattis212df9e2020-12-03 19:57:41 -08008767 loge("RemoteException caught trying to send a callback msg for " + nrForCallback);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07008768 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008769 }
8770
Hugo Benichif8a0f9f2017-03-23 22:40:44 +09008771 private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
8772 bundle.putParcelable(t.getClass().getSimpleName(), t);
8773 }
8774
Chalard Jean0702f982021-09-16 21:50:07 +09008775 /**
8776 * Returns whether reassigning a request from an NAI to another can be done gracefully.
8777 *
8778 * When a request should be assigned to a new network, it is normally lingered to give
8779 * time for apps to gracefully migrate their connections. When both networks are on the same
8780 * radio, but that radio can't do time-sharing efficiently, this may end up being
8781 * counter-productive because any traffic on the old network may drastically reduce the
8782 * performance of the new network.
8783 * The stack supports a configuration to let modem vendors state that their radio can't
8784 * do time-sharing efficiently. If this configuration is set, the stack assumes moving
8785 * from one cell network to another can't be done gracefully.
8786 *
8787 * @param oldNai the old network serving the request
8788 * @param newNai the new network serving the request
8789 * @return whether the switch can be graceful
8790 */
8791 private boolean canSupportGracefulNetworkSwitch(@NonNull final NetworkAgentInfo oldSatisfier,
8792 @NonNull final NetworkAgentInfo newSatisfier) {
8793 if (mCellularRadioTimesharingCapable) return true;
8794 return !oldSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)
8795 || !newSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)
8796 || !newSatisfier.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY);
8797 }
8798
Paul Jensenaf94b982014-09-30 15:37:41 -04008799 private void teardownUnneededNetwork(NetworkAgentInfo nai) {
Lorenzo Colitti99236d12016-07-01 01:37:11 +09008800 if (nai.numRequestNetworkRequests() != 0) {
8801 for (int i = 0; i < nai.numNetworkRequests(); i++) {
8802 NetworkRequest nr = nai.requestAt(i);
Lorenzo Colitti96742d92021-01-29 20:18:03 +09008803 // Ignore listening and track default requests.
8804 if (!nr.isRequest()) continue;
Lorenzo Colitti99236d12016-07-01 01:37:11 +09008805 loge("Dead network still had at least " + nr);
8806 break;
8807 }
Paul Jensenaf94b982014-09-30 15:37:41 -04008808 }
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09008809 nai.disconnect();
Paul Jensenaf94b982014-09-30 15:37:41 -04008810 }
8811
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008812 private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
8813 if (oldNetwork == null) {
8814 loge("Unknown NetworkAgentInfo in handleLingerComplete");
8815 return;
8816 }
Chalard Jean49707572019-12-10 21:07:02 +09008817 if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString());
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09008818
8819 // If we get here it means that the last linger timeout for this network expired. So there
8820 // must be no other active linger timers, and we must stop lingering.
junyulai2b6f0c22021-02-03 20:15:30 +08008821 oldNetwork.clearInactivityState();
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09008822
Lorenzo Colitti2666be82016-09-09 18:48:56 +09008823 if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008824 // Tear the network down.
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09008825 teardownUnneededNetwork(oldNetwork);
Lorenzo Colitti0f042202016-07-18 18:40:42 +09008826 } else {
junyulai0ac374f2020-12-14 18:41:52 +08008827 // Put the network in the background if it doesn't satisfy any foreground request.
Lorenzo Colittie4d1e522020-12-10 00:32:04 +09008828 updateCapabilitiesForNetwork(oldNetwork);
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09008829 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07008830 }
8831
James Mattise3ef1912020-12-20 11:09:58 -08008832 private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) {
8833 boolean isDefaultChanged = false;
8834 for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) {
8835 final NetworkReassignment.RequestReassignment reassignment =
8836 changes.getReassignment(defaultRequestInfo);
8837 if (null == reassignment) {
8838 continue;
8839 }
8840 // reassignment only contains those instances where the satisfying network changed.
8841 isDefaultChanged = true;
8842 // Notify system services of the new default.
8843 makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork);
8844 }
Chiachang Wang087fd272018-09-28 22:42:48 +08008845
James Mattise3ef1912020-12-20 11:09:58 -08008846 if (isDefaultChanged) {
8847 // Hold a wakelock for a short time to help apps in migrating to a new default.
8848 scheduleReleaseNetworkTransitionWakelock();
8849 }
8850 }
8851
8852 private void makeDefault(@NonNull final NetworkRequestInfo nri,
8853 @Nullable final NetworkAgentInfo oldDefaultNetwork,
8854 @Nullable final NetworkAgentInfo newDefaultNetwork) {
8855 if (DBG) {
8856 log("Switching to new default network for: " + nri + " using " + newDefaultNetwork);
8857 }
Chalard Jean8e382112019-12-03 20:45:30 +09008858
James Mattisd31bdfa2020-12-23 16:37:26 -08008859 // Fix up the NetworkCapabilities of any networks that have this network as underlying.
8860 if (newDefaultNetwork != null) {
8861 propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
Paul Jensend0464ed2014-07-14 12:03:33 -04008862 }
Lorenzo Colitti24861882018-01-19 00:50:48 +09008863
James Mattisd31bdfa2020-12-23 16:37:26 -08008864 // Set an app level managed default and return since further processing only applies to the
8865 // default network.
8866 if (mDefaultRequest != nri) {
8867 makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork);
8868 return;
8869 }
8870
8871 makeDefaultNetwork(newDefaultNetwork);
8872
James Mattise3ef1912020-12-20 11:09:58 -08008873 if (oldDefaultNetwork != null) {
8874 mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
8875 }
8876 mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
James Mattise3ef1912020-12-20 11:09:58 -08008877 handleApplyDefaultProxy(null != newDefaultNetwork
8878 ? newDefaultNetwork.linkProperties.getHttpProxy() : null);
8879 updateTcpBufferSizes(null != newDefaultNetwork
8880 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
Lorenzo Colitti24861882018-01-19 00:50:48 +09008881 notifyIfacesChangedForNetworkStats();
Paul Jensend0464ed2014-07-14 12:03:33 -04008882 }
8883
James Mattisd31bdfa2020-12-23 16:37:26 -08008884 private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri,
8885 @Nullable final NetworkAgentInfo oldDefaultNetwork,
8886 @Nullable final NetworkAgentInfo newDefaultNetwork) {
8887 try {
8888 if (VDBG) {
8889 log("Setting default network for " + nri
8890 + " using UIDs " + nri.getUids()
8891 + " with old network " + (oldDefaultNetwork != null
8892 ? oldDefaultNetwork.network().getNetId() : "null")
8893 + " and new network " + (newDefaultNetwork != null
8894 ? newDefaultNetwork.network().getNetId() : "null"));
8895 }
8896 if (nri.getUids().isEmpty()) {
8897 throw new IllegalStateException("makeDefaultForApps called without specifying"
8898 + " any applications to set as the default." + nri);
8899 }
8900 if (null != newDefaultNetwork) {
paulhu0e79d952021-06-09 16:11:35 +08008901 mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
James Mattisd31bdfa2020-12-23 16:37:26 -08008902 newDefaultNetwork.network.getNetId(),
paulhu0e79d952021-06-09 16:11:35 +08008903 toUidRangeStableParcels(nri.getUids()),
paulhu48291862021-07-14 14:53:57 +08008904 nri.getPreferenceOrderForNetd()));
James Mattisd31bdfa2020-12-23 16:37:26 -08008905 }
8906 if (null != oldDefaultNetwork) {
paulhu0e79d952021-06-09 16:11:35 +08008907 mNetd.networkRemoveUidRangesParcel(new NativeUidRangeConfig(
James Mattisd31bdfa2020-12-23 16:37:26 -08008908 oldDefaultNetwork.network.getNetId(),
paulhu0e79d952021-06-09 16:11:35 +08008909 toUidRangeStableParcels(nri.getUids()),
paulhu48291862021-07-14 14:53:57 +08008910 nri.getPreferenceOrderForNetd()));
James Mattisd31bdfa2020-12-23 16:37:26 -08008911 }
8912 } catch (RemoteException | ServiceSpecificException e) {
Chalard Jean17215832021-03-01 14:06:28 +09008913 loge("Exception setting app default network", e);
James Mattisd31bdfa2020-12-23 16:37:26 -08008914 }
8915 }
8916
Junyu Lai35665cc2022-12-19 17:37:48 +08008917 /**
8918 * Collect restricted uid ranges for the given network and UserHandle, these uids
8919 * are not restricted for matched enterprise networks but being restricted for non-matched
8920 * enterprise networks and non-enterprise networks.
8921 */
8922 @NonNull
8923 private ArraySet<UidRange> getRestrictedUidRangesForEnterpriseBlocking(
8924 @NonNull NetworkAgentInfo nai, @NonNull UserHandle user) {
8925 final ArraySet<UidRange> restrictedUidRanges = new ArraySet<>();
8926 for (final ProfileNetworkPreferenceInfo pref : mProfileNetworkPreferences) {
8927 if (!pref.user.equals(user) || !pref.blockingNonEnterprise) continue;
8928
8929 if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_ENTERPRISE)) {
8930 // The NC is built from a `ProfileNetworkPreference` which has only one
8931 // enterprise ID, so it's guaranteed to have exactly one.
8932 final int prefId = pref.capabilities.getEnterpriseIds()[0];
8933 if (nai.networkCapabilities.hasEnterpriseId(prefId)) {
8934 continue;
8935 }
8936 }
8937
8938 if (UidRangeUtils.doesRangeSetOverlap(restrictedUidRanges,
8939 pref.capabilities.getUidRanges())) {
8940 throw new IllegalArgumentException(
8941 "Overlapping uid range in preference: " + pref);
8942 }
8943 restrictedUidRanges.addAll(pref.capabilities.getUidRanges());
8944 }
8945 return restrictedUidRanges;
8946 }
8947
8948 private void updateProfileAllowedNetworks() {
Junyu Laic53a1692023-02-20 15:36:54 +08008949 // Netd command is not implemented before U.
8950 if (!SdkLevel.isAtLeastU()) return;
8951
Junyu Lai35665cc2022-12-19 17:37:48 +08008952 ensureRunningOnConnectivityServiceThread();
8953 final ArrayList<NativeUidRangeConfig> configs = new ArrayList<>();
8954 final List<UserHandle> users = mContext.getSystemService(UserManager.class)
8955 .getUserHandles(true /* excludeDying */);
8956 if (users.isEmpty()) {
8957 throw new IllegalStateException("No user is available");
8958 }
8959
8960 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
8961 ArraySet<UidRange> allowedUidRanges = new ArraySet<>();
8962 for (final UserHandle user : users) {
8963 final ArraySet<UidRange> restrictedUidRanges =
8964 getRestrictedUidRangesForEnterpriseBlocking(nai, user);
8965 allowedUidRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange(
8966 UidRange.createForUser(user), restrictedUidRanges));
8967 }
8968
8969 final UidRangeParcel[] rangesParcel = toUidRangeStableParcels(allowedUidRanges);
8970 configs.add(new NativeUidRangeConfig(
8971 nai.network.netId, rangesParcel, 0 /* subPriority */));
8972 }
8973
8974 // The netd API replaces the previous configs with the current configs.
8975 // Thus, for network disconnection or preference removal, no need to
8976 // unset previous config. Instead, collecting all currently needed
8977 // configs and issue to netd.
8978 try {
8979 mNetd.setNetworkAllowlist(configs.toArray(new NativeUidRangeConfig[0]));
8980 } catch (ServiceSpecificException e) {
8981 // Has the interface disappeared since the network was built?
Junyu Laic53a1692023-02-20 15:36:54 +08008982 Log.wtf(TAG, "Unexpected ServiceSpecificException", e);
Junyu Lai35665cc2022-12-19 17:37:48 +08008983 } catch (RemoteException e) {
Junyu Laic53a1692023-02-20 15:36:54 +08008984 // Netd died. This will cause a runtime restart anyway.
8985 Log.wtf(TAG, "Unexpected RemoteException", e);
Junyu Lai35665cc2022-12-19 17:37:48 +08008986 }
8987 }
8988
James Mattisd31bdfa2020-12-23 16:37:26 -08008989 private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) {
8990 try {
8991 if (null != newDefaultNetwork) {
8992 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
8993 } else {
8994 mNetd.networkClearDefault();
8995 }
8996 } catch (RemoteException | ServiceSpecificException e) {
8997 loge("Exception setting default network :" + e);
8998 }
8999 }
9000
Chalard Jean05cbe972019-12-09 11:50:38 +09009001 private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009002 // For consistency with previous behaviour, send onLost callbacks before onAvailable.
Chalard Jeancd397a22019-11-22 22:33:33 +09009003 processNewlyLostListenRequests(nai);
Chalard Jean05cbe972019-12-09 11:50:38 +09009004 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
Chalard Jeancd397a22019-11-22 22:33:33 +09009005 processNewlySatisfiedListenRequests(nai);
9006 }
9007
9008 private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
James Mattisa076c532020-12-02 14:12:41 -08009009 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
9010 if (nri.isMultilayerRequest()) {
9011 continue;
9012 }
9013 final NetworkRequest nr = nri.mRequests.get(0);
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009014 if (!nr.isListen()) continue;
9015 if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
James Mattisa076c532020-12-02 14:12:41 -08009016 nai.removeRequest(nr.requestId);
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009017 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
9018 }
9019 }
Chalard Jeancd397a22019-11-22 22:33:33 +09009020 }
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009021
Chalard Jeancd397a22019-11-22 22:33:33 +09009022 private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
James Mattisa076c532020-12-02 14:12:41 -08009023 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
9024 if (nri.isMultilayerRequest()) {
9025 continue;
9026 }
9027 final NetworkRequest nr = nri.mRequests.get(0);
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009028 if (!nr.isListen()) continue;
9029 if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
9030 nai.addRequest(nr);
Erik Kline99f301b2017-02-15 19:59:17 +09009031 notifyNetworkAvailable(nai, nri);
Lorenzo Colitti0c38d7c2016-07-20 02:39:22 +09009032 }
9033 }
9034 }
9035
Chalard Jean9fc27ea2019-12-02 15:34:05 +09009036 // An accumulator class to gather the list of changes that result from a rematch.
Chalard Jean9fc27ea2019-12-02 15:34:05 +09009037 private static class NetworkReassignment {
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009038 static class RequestReassignment {
James Mattisa076c532020-12-02 14:12:41 -08009039 @NonNull public final NetworkRequestInfo mNetworkRequestInfo;
Chalard Jeana8ac2302021-03-01 22:16:08 +09009040 @Nullable public final NetworkRequest mOldNetworkRequest;
9041 @Nullable public final NetworkRequest mNewNetworkRequest;
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009042 @Nullable public final NetworkAgentInfo mOldNetwork;
9043 @Nullable public final NetworkAgentInfo mNewNetwork;
James Mattisa076c532020-12-02 14:12:41 -08009044 RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo,
Chalard Jeana8ac2302021-03-01 22:16:08 +09009045 @Nullable final NetworkRequest oldNetworkRequest,
9046 @Nullable final NetworkRequest newNetworkRequest,
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009047 @Nullable final NetworkAgentInfo oldNetwork,
9048 @Nullable final NetworkAgentInfo newNetwork) {
James Mattisa076c532020-12-02 14:12:41 -08009049 mNetworkRequestInfo = networkRequestInfo;
9050 mOldNetworkRequest = oldNetworkRequest;
9051 mNewNetworkRequest = newNetworkRequest;
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009052 mOldNetwork = oldNetwork;
9053 mNewNetwork = newNetwork;
9054 }
Chalard Jean49707572019-12-10 21:07:02 +09009055
9056 public String toString() {
Chalard Jeand490b2d2021-03-01 22:06:04 +09009057 final NetworkRequest requestToShow = null != mNewNetworkRequest
9058 ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0);
9059 return requestToShow.requestId + " : "
Serik Beketayevec8ad212020-12-07 22:43:07 -08009060 + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null")
9061 + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null");
Chalard Jean49707572019-12-10 21:07:02 +09009062 }
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009063 }
9064
Chalard Jean46a62372019-12-10 21:25:24 +09009065 @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>();
Chalard Jean9fc27ea2019-12-02 15:34:05 +09009066
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009067 @NonNull Iterable<RequestReassignment> getRequestReassignments() {
Chalard Jean46a62372019-12-10 21:25:24 +09009068 return mReassignments;
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009069 }
9070
9071 void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
Remi NGUYEN VAN10c379a2021-04-07 19:40:31 +09009072 if (Build.isDebuggable()) {
Chalard Jean46a62372019-12-10 21:25:24 +09009073 // The code is never supposed to add two reassignments of the same request. Make
9074 // sure this stays true, but without imposing this expensive check on all
9075 // reassignments on all user devices.
9076 for (final RequestReassignment existing : mReassignments) {
James Mattisa076c532020-12-02 14:12:41 -08009077 if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) {
Chalard Jean46a62372019-12-10 21:25:24 +09009078 throw new IllegalStateException("Trying to reassign ["
9079 + reassignment + "] but already have ["
9080 + existing + "]");
9081 }
9082 }
Chalard Jeanbf91f5f2019-12-03 22:16:26 +09009083 }
Chalard Jean46a62372019-12-10 21:25:24 +09009084 mReassignments.add(reassignment);
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009085 }
9086
Chalard Jean88b2f9e2019-12-03 14:43:57 +09009087 // Will return null if this reassignment does not change the network assigned to
Chalard Jean8e382112019-12-03 20:45:30 +09009088 // the passed request.
9089 @Nullable
9090 private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) {
Chalard Jean88b2f9e2019-12-03 14:43:57 +09009091 for (final RequestReassignment event : getRequestReassignments()) {
James Mattisa076c532020-12-02 14:12:41 -08009092 if (nri == event.mNetworkRequestInfo) return event;
Chalard Jean88b2f9e2019-12-03 14:43:57 +09009093 }
9094 return null;
9095 }
Chalard Jean49707572019-12-10 21:07:02 +09009096
9097 public String toString() {
9098 final StringJoiner sj = new StringJoiner(", " /* delimiter */,
9099 "NetReassign [" /* prefix */, "]" /* suffix */);
Chalard Jeanb10ab412019-12-11 14:12:30 +09009100 if (mReassignments.isEmpty()) return sj.add("no changes").toString();
Chalard Jean49707572019-12-10 21:07:02 +09009101 for (final RequestReassignment rr : getRequestReassignments()) {
9102 sj.add(rr.toString());
9103 }
9104 return sj.toString();
9105 }
9106
9107 public String debugString() {
9108 final StringBuilder sb = new StringBuilder();
9109 sb.append("NetworkReassignment :");
Chalard Jeanb10ab412019-12-11 14:12:30 +09009110 if (mReassignments.isEmpty()) return sb.append(" no changes").toString();
Chalard Jean49707572019-12-10 21:07:02 +09009111 for (final RequestReassignment rr : getRequestReassignments()) {
9112 sb.append("\n ").append(rr);
9113 }
9114 return sb.append("\n").toString();
9115 }
Chalard Jean9fc27ea2019-12-02 15:34:05 +09009116 }
9117
Chalard Jean24344d72019-12-04 13:32:31 +09009118 private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
Chalard Jeana8ac2302021-03-01 22:16:08 +09009119 @Nullable final NetworkRequest previousRequest,
9120 @Nullable final NetworkRequest newRequest,
Chalard Jean24344d72019-12-04 13:32:31 +09009121 @Nullable final NetworkAgentInfo previousSatisfier,
9122 @Nullable final NetworkAgentInfo newSatisfier,
9123 final long now) {
James Mattisd31bdfa2020-12-23 16:37:26 -08009124 if (null != newSatisfier && mNoServiceNetwork != newSatisfier) {
Chalard Jean49707572019-12-10 21:07:02 +09009125 if (VDBG) log("rematch for " + newSatisfier.toShortString());
Chalard Jeana8ac2302021-03-01 22:16:08 +09009126 if (null != previousRequest && null != previousSatisfier) {
Chalard Jean24344d72019-12-04 13:32:31 +09009127 if (VDBG || DDBG) {
Chalard Jean49707572019-12-10 21:07:02 +09009128 log(" accepting network in place of " + previousSatisfier.toShortString());
Chalard Jean24344d72019-12-04 13:32:31 +09009129 }
James Mattisa076c532020-12-02 14:12:41 -08009130 previousSatisfier.removeRequest(previousRequest.requestId);
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09009131 if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier)
Chalard Jean254bd162022-08-25 13:04:51 +09009132 && !previousSatisfier.isDestroyed()) {
Chalard Jean0702f982021-09-16 21:50:07 +09009133 // If this network switch can't be supported gracefully, the request is not
9134 // lingered. This allows letting go of the network sooner to reclaim some
9135 // performance on the new network, since the radio can't do both at the same
9136 // time while preserving good performance.
Lorenzo Colittiffa2ed32022-02-16 14:59:00 +09009137 //
9138 // Also don't linger the request if the old network has been destroyed.
9139 // A destroyed network does not provide actual network connectivity, so
9140 // lingering it is not useful. In particular this ensures that a destroyed
9141 // network is outscored by its replacement,
9142 // then it is torn down immediately instead of being lingered, and any apps that
9143 // were using it immediately get onLost and can connect using the new network.
Chalard Jean0702f982021-09-16 21:50:07 +09009144 previousSatisfier.lingerRequest(previousRequest.requestId, now);
9145 }
Chalard Jean24344d72019-12-04 13:32:31 +09009146 } else {
9147 if (VDBG || DDBG) log(" accepting network in place of null");
9148 }
junyulai0ac374f2020-12-14 18:41:52 +08009149
9150 // To prevent constantly CPU wake up for nascent timer, if a network comes up
9151 // and immediately satisfies a request then remove the timer. This will happen for
9152 // all networks except in the case of an underlying network for a VCN.
9153 if (newSatisfier.isNascent()) {
9154 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE);
junyulai36c02982021-03-26 00:40:48 +08009155 newSatisfier.unsetInactive();
junyulai0ac374f2020-12-14 18:41:52 +08009156 }
9157
Chalard Jean5d6e23b2021-03-01 22:00:20 +09009158 // if newSatisfier is not null, then newRequest may not be null.
James Mattisa076c532020-12-02 14:12:41 -08009159 newSatisfier.unlingerRequest(newRequest.requestId);
9160 if (!newSatisfier.addRequest(newRequest)) {
Aaron Huang6616df32020-10-30 22:04:25 +08009161 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
James Mattisa076c532020-12-02 14:12:41 -08009162 + newRequest);
Chalard Jean24344d72019-12-04 13:32:31 +09009163 }
Chalard Jeana8ac2302021-03-01 22:16:08 +09009164 } else if (null != previousRequest && null != previousSatisfier) {
Chalard Jean24344d72019-12-04 13:32:31 +09009165 if (DBG) {
Chalard Jean49707572019-12-10 21:07:02 +09009166 log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
James Mattisa076c532020-12-02 14:12:41 -08009167 + " request " + previousRequest.requestId);
Chalard Jean24344d72019-12-04 13:32:31 +09009168 }
James Mattisa076c532020-12-02 14:12:41 -08009169 previousSatisfier.removeRequest(previousRequest.requestId);
Chalard Jean24344d72019-12-04 13:32:31 +09009170 }
James Mattisa076c532020-12-02 14:12:41 -08009171 nri.setSatisfier(newSatisfier, newRequest);
Chalard Jean24344d72019-12-04 13:32:31 +09009172 }
9173
James Mattisa076c532020-12-02 14:12:41 -08009174 /**
9175 * This function is triggered when something can affect what network should satisfy what
9176 * request, and it computes the network reassignment from the passed collection of requests to
9177 * network match to the one that the system should now have. That data is encoded in an
9178 * object that is a list of changes, each of them having an NRI, and old satisfier, and a new
9179 * satisfier.
9180 *
9181 * After the reassignment is computed, it is applied to the state objects.
9182 *
9183 * @param networkRequests the nri objects to evaluate for possible network reassignment
9184 * @return NetworkReassignment listing of proposed network assignment changes
9185 */
Chalard Jean57cc7cb2019-12-10 18:56:30 +09009186 @NonNull
James Mattisa076c532020-12-02 14:12:41 -08009187 private NetworkReassignment computeNetworkReassignment(
9188 @NonNull final Collection<NetworkRequestInfo> networkRequests) {
Chalard Jean857a1712019-12-10 21:08:07 +09009189 final NetworkReassignment changes = new NetworkReassignment();
9190
Chalard Jeanc81d4c32021-04-07 17:06:19 +09009191 // Gather the list of all relevant agents.
Chalard Jean857a1712019-12-10 21:08:07 +09009192 final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009193 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
Chalard Jean857a1712019-12-10 21:08:07 +09009194 nais.add(nai);
Chalard Jean857a1712019-12-10 21:08:07 +09009195 }
Chalard Jean857a1712019-12-10 21:08:07 +09009196
James Mattisa076c532020-12-02 14:12:41 -08009197 for (final NetworkRequestInfo nri : networkRequests) {
9198 // Non-multilayer listen requests can be ignored.
9199 if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
9200 continue;
9201 }
9202 NetworkAgentInfo bestNetwork = null;
9203 NetworkRequest bestRequest = null;
9204 for (final NetworkRequest req : nri.mRequests) {
Chalard Jeane4aeac62021-03-29 17:03:59 +09009205 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier());
James Mattisa076c532020-12-02 14:12:41 -08009206 // Stop evaluating as the highest possible priority request is satisfied.
9207 if (null != bestNetwork) {
9208 bestRequest = req;
9209 break;
9210 }
9211 }
James Mattisd31bdfa2020-12-23 16:37:26 -08009212 if (null == bestNetwork && isDefaultBlocked(nri)) {
9213 // Remove default networking if disallowed for managed default requests.
9214 bestNetwork = mNoServiceNetwork;
9215 }
9216 if (nri.getSatisfier() != bestNetwork) {
Chalard Jean96a4f4b2019-12-10 22:16:53 +09009217 // bestNetwork may be null if no network can satisfy this request.
Chalard Jean857a1712019-12-10 21:08:07 +09009218 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
James Mattisa076c532020-12-02 14:12:41 -08009219 nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
Chalard Jean857a1712019-12-10 21:08:07 +09009220 }
Chalard Jean57cc7cb2019-12-10 18:56:30 +09009221 }
9222 return changes;
9223 }
9224
James Mattisa076c532020-12-02 14:12:41 -08009225 private Set<NetworkRequestInfo> getNrisFromGlobalRequests() {
9226 return new HashSet<>(mNetworkRequests.values());
9227 }
9228
Paul Jensenc88b39b2015-06-16 14:27:36 -04009229 /**
James Mattisa076c532020-12-02 14:12:41 -08009230 * Attempt to rematch all Networks with all NetworkRequests. This may result in Networks
Paul Jensenc88b39b2015-06-16 14:27:36 -04009231 * being disconnected.
Paul Jensenc88b39b2015-06-16 14:27:36 -04009232 */
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09009233 private void rematchAllNetworksAndRequests() {
James Mattisa076c532020-12-02 14:12:41 -08009234 rematchNetworksAndRequests(getNrisFromGlobalRequests());
9235 }
9236
9237 /**
9238 * Attempt to rematch all Networks with given NetworkRequests. This may result in Networks
9239 * being disconnected.
9240 */
9241 private void rematchNetworksAndRequests(
9242 @NonNull final Set<NetworkRequestInfo> networkRequests) {
9243 ensureRunningOnConnectivityServiceThread();
Chalard Jean857a1712019-12-10 21:08:07 +09009244 // TODO: This may be slow, and should be optimized.
Chalard Jeanee3fa202022-02-26 13:55:15 +09009245 final long start = SystemClock.elapsedRealtime();
James Mattisa076c532020-12-02 14:12:41 -08009246 final NetworkReassignment changes = computeNetworkReassignment(networkRequests);
Chalard Jeanee3fa202022-02-26 13:55:15 +09009247 final long computed = SystemClock.elapsedRealtime();
9248 applyNetworkReassignment(changes, start);
9249 final long applied = SystemClock.elapsedRealtime();
9250 issueNetworkNeeds();
9251 final long end = SystemClock.elapsedRealtime();
Chalard Jean49707572019-12-10 21:07:02 +09009252 if (VDBG || DDBG) {
Chalard Jeanee3fa202022-02-26 13:55:15 +09009253 log(String.format("Rematched networks [computed %dms] [applied %dms] [issued %d]",
9254 computed - start, applied - computed, end - applied));
Chalard Jean49707572019-12-10 21:07:02 +09009255 log(changes.debugString());
9256 } else if (DBG) {
Chalard Jeanee3fa202022-02-26 13:55:15 +09009257 // Shorter form, only one line of log
9258 log(String.format("%s [c %d] [a %d] [i %d]", changes.toString(),
9259 computed - start, applied - computed, end - applied));
Chalard Jean49707572019-12-10 21:07:02 +09009260 }
Chalard Jeand7f762d2019-12-10 19:01:29 +09009261 }
Chalard Jean64520dc2019-12-04 19:55:32 +09009262
Chalard Jeand7f762d2019-12-10 19:01:29 +09009263 private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
Chalard Jeanf955f8e2019-12-10 22:01:31 +09009264 final long now) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009265 final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos;
Chalard Jeanb10ab412019-12-11 14:12:30 +09009266
9267 // Since most of the time there are only 0 or 1 background networks, it would probably
9268 // be more efficient to just use an ArrayList here. TODO : measure performance
9269 final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>();
9270 for (final NetworkAgentInfo nai : nais) {
9271 if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai);
9272 }
9273
Chalard Jeand7f762d2019-12-10 19:01:29 +09009274 // First, update the lists of satisfied requests in the network agents. This is necessary
9275 // because some code later depends on this state to be correct, most prominently computing
9276 // the linger status.
Chalard Jean64520dc2019-12-04 19:55:32 +09009277 for (final NetworkReassignment.RequestReassignment event :
9278 changes.getRequestReassignments()) {
James Mattisa076c532020-12-02 14:12:41 -08009279 updateSatisfiersForRematchRequest(event.mNetworkRequestInfo,
9280 event.mOldNetworkRequest, event.mNewNetworkRequest,
9281 event.mOldNetwork, event.mNewNetwork,
9282 now);
Chalard Jean0a8afda2019-11-07 19:05:18 +09009283 }
Chalard Jeanf01b2ef2019-11-07 23:16:12 +09009284
James Mattise3ef1912020-12-20 11:09:58 -08009285 // Process default network changes if applicable.
9286 processDefaultNetworkChanges(changes);
Chalard Jeanb9d94052019-11-19 19:16:48 +09009287
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009288 // Notify requested networks are available after the default net is switched, but
9289 // before LegacyTypeTracker sends legacy broadcasts
9290 for (final NetworkReassignment.RequestReassignment event :
9291 changes.getRequestReassignments()) {
9292 if (null != event.mNewNetwork) {
James Mattisa076c532020-12-02 14:12:41 -08009293 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo);
Chalard Jean7c2f15e2019-12-03 15:55:14 +09009294 } else {
James Mattisa076c532020-12-02 14:12:41 -08009295 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork,
Chalard Jean7c2f15e2019-12-03 15:55:14 +09009296 ConnectivityManager.CALLBACK_LOST, 0);
Chalard Jeand8bea3b2019-12-02 18:59:27 +09009297 }
9298 }
9299
junyulai0ac374f2020-12-14 18:41:52 +08009300 // Update the inactivity state before processing listen callbacks, because the background
9301 // computation depends on whether the network is inactive. Don't send the LOSING callbacks
Chalard Jean6a4dfac2019-12-04 20:01:46 +09009302 // just yet though, because they have to be sent after the listens are processed to keep
9303 // backward compatibility.
junyulai0ac374f2020-12-14 18:41:52 +08009304 final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>();
Chalard Jean7807fa22019-11-19 20:01:10 +09009305 for (final NetworkAgentInfo nai : nais) {
junyulai0ac374f2020-12-14 18:41:52 +08009306 // Rematching may have altered the inactivity state of some networks, so update all
9307 // inactivity timers. updateInactivityState reads the state from the network agent
9308 // and does nothing if the state has not changed : the source of truth is controlled
9309 // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which
9310 // have been called while rematching the individual networks above.
junyulai2b6f0c22021-02-03 20:15:30 +08009311 if (updateInactivityState(nai, now)) {
junyulai0ac374f2020-12-14 18:41:52 +08009312 inactiveNetworks.add(nai);
Chalard Jean8fd82ae2019-12-04 18:49:18 +09009313 }
9314 }
9315
Chalard Jeanb10ab412019-12-11 14:12:30 +09009316 for (final NetworkAgentInfo nai : nais) {
Chalard Jeanb10ab412019-12-11 14:12:30 +09009317 final boolean oldBackground = oldBgNetworks.contains(nai);
Chalard Jean6a4dfac2019-12-04 20:01:46 +09009318 // Process listen requests and update capabilities if the background state has
9319 // changed for this network. For consistency with previous behavior, send onLost
9320 // callbacks before onAvailable.
Chalard Jeanb10ab412019-12-11 14:12:30 +09009321 processNewlyLostListenRequests(nai);
9322 if (oldBackground != nai.isBackgroundNetwork()) {
9323 applyBackgroundChangeForRematch(nai);
Chalard Jean6a4dfac2019-12-04 20:01:46 +09009324 }
Chalard Jeanb10ab412019-12-11 14:12:30 +09009325 processNewlySatisfiedListenRequests(nai);
Chalard Jean6a4dfac2019-12-04 20:01:46 +09009326 }
9327
junyulai0ac374f2020-12-14 18:41:52 +08009328 for (final NetworkAgentInfo nai : inactiveNetworks) {
9329 // For nascent networks, if connecting with no foreground request, skip broadcasting
9330 // LOSING for backward compatibility. This is typical when mobile data connected while
9331 // wifi connected with mobile data always-on enabled.
9332 if (nai.isNascent()) continue;
Chalard Jean8fd82ae2019-12-04 18:49:18 +09009333 notifyNetworkLosing(nai, now);
Chalard Jeanf01b2ef2019-11-07 23:16:12 +09009334 }
9335
James Mattise3ef1912020-12-20 11:09:58 -08009336 updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais);
Chalard Jeanf0344532019-11-19 19:23:38 +09009337
Chalard Jeanf01b2ef2019-11-07 23:16:12 +09009338 // Tear down all unneeded networks.
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009339 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
Chalard Jean0a8afda2019-11-07 19:05:18 +09009340 if (unneeded(nai, UnneededFor.TEARDOWN)) {
junyulai2b6f0c22021-02-03 20:15:30 +08009341 if (nai.getInactivityExpiry() > 0) {
Chalard Jean0a8afda2019-11-07 19:05:18 +09009342 // This network has active linger timers and no requests, but is not
9343 // lingering. Linger it.
9344 //
9345 // One way (the only way?) this can happen if this network is unvalidated
9346 // and became unneeded due to another network improving its score to the
9347 // point where this network will no longer be able to satisfy any requests
9348 // even if it validates.
junyulai2b6f0c22021-02-03 20:15:30 +08009349 if (updateInactivityState(nai, now)) {
Chalard Jean8fd82ae2019-12-04 18:49:18 +09009350 notifyNetworkLosing(nai, now);
9351 }
Chalard Jean0a8afda2019-11-07 19:05:18 +09009352 } else {
Chalard Jean49707572019-12-10 21:07:02 +09009353 if (DBG) log("Reaping " + nai.toShortString());
Chalard Jean0a8afda2019-11-07 19:05:18 +09009354 teardownUnneededNetwork(nai);
9355 }
9356 }
Paul Jensen05e85ee2014-09-11 11:00:39 -04009357 }
9358 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009359
Chalard Jean62edfd82019-12-02 18:39:29 +09009360 /**
9361 * Apply a change in background state resulting from rematching networks with requests.
9362 *
9363 * During rematch, a network may change background states by starting to satisfy or stopping
9364 * to satisfy a foreground request. Listens don't count for this. When a network changes
9365 * background states, its capabilities need to be updated and callbacks fired for the
9366 * capability change.
9367 *
9368 * @param nai The network that changed background states
9369 */
9370 private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
9371 final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
9372 if (Objects.equals(nai.networkCapabilities, newNc)) return;
9373 updateNetworkPermissions(nai, newNc);
9374 nai.getAndSetNetworkCapabilities(newNc);
9375 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
9376 }
9377
Chalard Jeanf0344532019-11-19 19:23:38 +09009378 private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
James Mattise3ef1912020-12-20 11:09:58 -08009379 @NonNull final NetworkReassignment changes,
Chalard Jean57cc7cb2019-12-10 18:56:30 +09009380 @NonNull final Collection<NetworkAgentInfo> nais) {
Chalard Jean5b409c72021-02-04 13:12:59 +09009381 final NetworkReassignment.RequestReassignment reassignmentOfDefault =
9382 changes.getReassignment(mDefaultRequest);
9383 final NetworkAgentInfo oldDefaultNetwork =
9384 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null;
9385 final NetworkAgentInfo newDefaultNetwork =
9386 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null;
James Mattise3ef1912020-12-20 11:09:58 -08009387
Chalard Jean5b409c72021-02-04 13:12:59 +09009388 if (oldDefaultNetwork != newDefaultNetwork) {
Chalard Jeanb9d94052019-11-19 19:16:48 +09009389 // Maintain the illusion : since the legacy API only understands one network at a time,
9390 // if the default network changed, apps should see a disconnected broadcast for the
9391 // old default network before they see a connected broadcast for the new one.
Chalard Jean5b409c72021-02-04 13:12:59 +09009392 if (oldDefaultNetwork != null) {
9393 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
9394 oldDefaultNetwork, true);
Chalard Jeanb9d94052019-11-19 19:16:48 +09009395 }
Chalard Jean5b409c72021-02-04 13:12:59 +09009396 if (newDefaultNetwork != null) {
Chalard Jeanb9d94052019-11-19 19:16:48 +09009397 // The new default network can be newly null if and only if the old default
9398 // network doesn't satisfy the default request any more because it lost a
9399 // capability.
Chalard Jean254bd162022-08-25 13:04:51 +09009400 mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0;
James Mattise3ef1912020-12-20 11:09:58 -08009401 mLegacyTypeTracker.add(
Chalard Jean5b409c72021-02-04 13:12:59 +09009402 newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
Chalard Jeanb9d94052019-11-19 19:16:48 +09009403 }
9404 }
9405
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009406 // Now that all the callbacks have been sent, send the legacy network broadcasts
9407 // as needed. This is necessary so that legacy requests correctly bind dns
9408 // requests to this network. The legacy users are listening for this broadcast
9409 // and will generally do a dns request so they can ensureRouteToHost and if
9410 // they do that before the callbacks happen they'll use the default network.
9411 //
9412 // TODO: Is there still a race here? The legacy broadcast will be sent after sending
9413 // callbacks, but if apps can receive the broadcast before the callback, they still might
9414 // have an inconsistent view of networking.
9415 //
9416 // This *does* introduce a race where if the user uses the new api
9417 // (notification callbacks) and then uses the old api (getNetworkInfo(type))
9418 // they may get old info. Reverse this after the old startUsing api is removed.
9419 // This is on top of the multiple intent sequencing referenced in the todo above.
9420 for (NetworkAgentInfo nai : nais) {
Chalard Jean254bd162022-08-25 13:04:51 +09009421 if (nai.everConnected()) {
Chalard Jeanb10ab412019-12-11 14:12:30 +09009422 addNetworkToLegacyTypeTracker(nai);
9423 }
The Android Open Source Project28527d22009-03-03 19:31:44 -08009424 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009425 }
9426
Chalard Jean0354d8c2021-01-12 10:58:56 +09009427 private void issueNetworkNeeds() {
9428 ensureRunningOnConnectivityServiceThread();
9429 for (final NetworkOfferInfo noi : mNetworkOffers) {
9430 issueNetworkNeeds(noi);
9431 }
9432 }
9433
9434 private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) {
9435 ensureRunningOnConnectivityServiceThread();
9436 for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
9437 informOffer(nri, noi.offer, mNetworkRanker);
9438 }
9439 }
9440
9441 /**
9442 * Inform a NetworkOffer about any new situation of a request.
9443 *
9444 * This function handles updates to offers. A number of events may happen that require
9445 * updating the registrant for this offer about the situation :
9446 * • The offer itself was updated. This may lead the offer to no longer being able
9447 * to satisfy a request or beat a satisfier (and therefore be no longer needed),
9448 * or conversely being strengthened enough to beat the satisfier (and therefore
9449 * start being needed)
9450 * • The network satisfying a request changed (including cases where the request
9451 * starts or stops being satisfied). The new network may be a stronger or weaker
9452 * match than the old one, possibly affecting whether the offer is needed.
9453 * • The network satisfying a request updated their score. This may lead the offer
9454 * to no longer be able to beat it if the current satisfier got better, or
9455 * conversely start being a good choice if the current satisfier got weaker.
9456 *
9457 * @param nri The request
9458 * @param offer The offer. This may be an updated offer.
9459 */
9460 private static void informOffer(@NonNull NetworkRequestInfo nri,
9461 @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) {
9462 final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null;
9463 final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null;
Chalard Jean0354d8c2021-01-12 10:58:56 +09009464
9465 // Multi-layer requests have a currently active request, the one being satisfied.
9466 // Since the system will try to bring up a better network than is currently satisfying
9467 // the request, NetworkProviders need to be told the offers matching the requests *above*
9468 // the currently satisfied one are needed, that the ones *below* the satisfied one are
9469 // not needed, and the offer is needed for the active request iff the offer can beat
9470 // the satisfier.
9471 // For non-multilayer requests, the logic above gracefully degenerates to only the
9472 // last case.
9473 // To achieve this, the loop below will proceed in three steps. In a first phase, inform
9474 // providers that the offer is needed for this request, until the active request is found.
9475 // In a second phase, deal with the currently active request. In a third phase, inform
9476 // the providers that offer is unneeded for the remaining requests.
9477
9478 // First phase : inform providers of all requests above the active request.
9479 int i;
9480 for (i = 0; nri.mRequests.size() > i; ++i) {
9481 final NetworkRequest request = nri.mRequests.get(i);
9482 if (activeRequest == request) break; // Found the active request : go to phase 2
9483 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
9484 // Since this request is higher-priority than the one currently satisfied, if the
9485 // offer can satisfy it, the provider should try and bring up the network for sure ;
9486 // no need to even ask the ranker – an offer that can satisfy is always better than
9487 // no network. Hence tell the provider so unless it already knew.
9488 if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) {
9489 offer.onNetworkNeeded(request);
9490 }
9491 }
9492
9493 // Second phase : deal with the active request (if any)
9494 if (null != activeRequest && activeRequest.isRequest()) {
9495 final boolean oldNeeded = offer.neededFor(activeRequest);
Junyu Laidc3a7a32021-05-26 12:23:56 +00009496 // If an offer can satisfy the request, it is considered needed if it is currently
9497 // served by this provider or if this offer can beat the current satisfier.
Chalard Jean0354d8c2021-01-12 10:58:56 +09009498 final boolean currentlyServing = satisfier != null
Junyu Laidc3a7a32021-05-26 12:23:56 +00009499 && satisfier.factorySerialNumber == offer.providerId
9500 && activeRequest.canBeSatisfiedBy(offer.caps);
9501 final boolean newNeeded = currentlyServing
9502 || networkRanker.mightBeat(activeRequest, satisfier, offer);
Chalard Jean0354d8c2021-01-12 10:58:56 +09009503 if (newNeeded != oldNeeded) {
9504 if (newNeeded) {
9505 offer.onNetworkNeeded(activeRequest);
9506 } else {
9507 // The offer used to be able to beat the satisfier. Now it can't.
9508 offer.onNetworkUnneeded(activeRequest);
9509 }
9510 }
9511 }
9512
9513 // Third phase : inform the providers that the offer isn't needed for any request
9514 // below the active one.
9515 for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) {
9516 final NetworkRequest request = nri.mRequests.get(i);
9517 if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
9518 // Since this request is lower-priority than the one currently satisfied, if the
9519 // offer can satisfy it, the provider should not try and bring up the network.
9520 // Hence tell the provider so unless it already knew.
9521 if (offer.neededFor(request)) {
9522 offer.onNetworkUnneeded(request);
9523 }
9524 }
9525 }
9526
Chalard Jean61c79252019-11-07 23:07:32 +09009527 private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
9528 for (int i = 0; i < nai.numNetworkRequests(); i++) {
9529 NetworkRequest nr = nai.requestAt(i);
9530 if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
9531 // legacy type tracker filters out repeat adds
9532 mLegacyTypeTracker.add(nr.legacyType, nai);
9533 }
9534 }
9535
9536 // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
Chalard Jean5b409c72021-02-04 13:12:59 +09009537 // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
Chalard Jean61c79252019-11-07 23:07:32 +09009538 // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
9539 // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
9540 if (nai.isVPN()) {
9541 mLegacyTypeTracker.add(TYPE_VPN, nai);
9542 }
9543 }
9544
Lorenzo Colitti5f82dae2014-12-17 11:26:49 +09009545 private void updateInetCondition(NetworkAgentInfo nai) {
Paul Jensen39fc7d52014-09-05 12:06:44 -04009546 // Don't bother updating until we've graduated to validated at least once.
Chalard Jean254bd162022-08-25 13:04:51 +09009547 if (!nai.everValidated()) return;
Chalard Jean5b409c72021-02-04 13:12:59 +09009548 // For now only update icons for the default connection.
Paul Jensen39fc7d52014-09-05 12:06:44 -04009549 // TODO: Update WiFi and cellular icons separately. b/17237507
Chalard Jean5b409c72021-02-04 13:12:59 +09009550 if (!isDefaultNetwork(nai)) return;
Paul Jensen39fc7d52014-09-05 12:06:44 -04009551
Chalard Jean254bd162022-08-25 13:04:51 +09009552 int newInetCondition = nai.isValidated() ? 100 : 0;
Paul Jensen39fc7d52014-09-05 12:06:44 -04009553 // Don't repeat publish.
9554 if (newInetCondition == mDefaultInetConditionPublished) return;
9555
9556 mDefaultInetConditionPublished = newInetCondition;
9557 sendInetConditionBroadcast(nai.networkInfo);
9558 }
9559
Chalard Jeand61375d2020-01-14 22:46:36 +09009560 @NonNull
9561 private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
9562 final NetworkInfo newInfo = new NetworkInfo(info);
Chalard Jeanaf14ca42020-01-15 00:49:43 +09009563 // The suspended and roaming bits are managed in NetworkCapabilities.
Chalard Jeand61375d2020-01-14 22:46:36 +09009564 final boolean suspended =
9565 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
9566 if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
9567 // Only override the state with SUSPENDED if the network is currently in CONNECTED
9568 // state. This is because the network could have been suspended before connecting,
9569 // or it could be disconnecting while being suspended, and in both these cases
9570 // the state should not be overridden. Note that the only detailed state that
9571 // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to
9572 // worry about multiple different substates of CONNECTED.
9573 newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
9574 info.getExtraInfo());
Chiachang Wangaa88bca2020-02-12 17:01:59 +08009575 } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
9576 // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
9577 // network agent is created, then goes to suspended, then goes out of suspended without
9578 // ever setting connected. Check if network agent is ever connected to update the state.
Chalard Jean254bd162022-08-25 13:04:51 +09009579 newInfo.setDetailedState(nai.everConnected()
Chiachang Wangaa88bca2020-02-12 17:01:59 +08009580 ? NetworkInfo.DetailedState.CONNECTED
9581 : NetworkInfo.DetailedState.CONNECTING,
9582 info.getReason(),
9583 info.getExtraInfo());
Chalard Jeand61375d2020-01-14 22:46:36 +09009584 }
Chalard Jeanaf14ca42020-01-15 00:49:43 +09009585 newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
Chalard Jeand61375d2020-01-14 22:46:36 +09009586 return newInfo;
9587 }
9588
9589 private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {
9590 final NetworkInfo newInfo = mixInInfo(networkAgent, info);
9591
Erik Kline99f301b2017-02-15 19:59:17 +09009592 final NetworkInfo.State state = newInfo.getState();
Robert Greenwalt02fe11e2014-06-23 11:40:00 -07009593 NetworkInfo oldInfo = null;
9594 synchronized (networkAgent) {
9595 oldInfo = networkAgent.networkInfo;
9596 networkAgent.networkInfo = newInfo;
9597 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009598
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009599 if (DBG) {
Chalard Jean49707572019-12-10 21:07:02 +09009600 log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
9601 + oldInfo.getState() + " to " + state);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009602 }
Robert Greenwaltbe46b752014-05-13 21:41:06 -07009603
Chalard Jean254bd162022-08-25 13:04:51 +09009604 if (!networkAgent.isCreated()
Robin Leea8c0b6e2016-05-01 23:00:00 +01009605 && (state == NetworkInfo.State.CONNECTED
9606 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
Lorenzo Colitti0f042202016-07-18 18:40:42 +09009607
9608 // A network that has just connected has zero requests and is thus a foreground network.
9609 networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
9610
Luke Huangfdd11f82019-04-09 18:41:49 +08009611 if (!createNativeNetwork(networkAgent)) return;
Lorenzo Colittibd079452021-07-02 11:47:57 +09009612 if (networkAgent.propagateUnderlyingCapabilities()) {
Lorenzo Colitti96dba632020-12-02 00:48:09 +09009613 // Initialize the network's capabilities to their starting values according to the
9614 // underlying networks. This ensures that the capabilities are correct before
9615 // anything happens to the network.
9616 updateCapabilitiesForNetwork(networkAgent);
Chalard Jeand5687912020-05-07 12:07:03 +09009617 }
Chalard Jean254bd162022-08-25 13:04:51 +09009618 networkAgent.setCreated();
Chiachang Wang3f6cc072021-03-24 18:39:17 +08009619 networkAgent.onNetworkCreated();
Chalard Jeande665262022-02-25 16:12:12 +09009620 updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
Junyu Lai35665cc2022-12-19 17:37:48 +08009621 updateProfileAllowedNetworks();
Robin Leea8c0b6e2016-05-01 23:00:00 +01009622 }
9623
Chalard Jean254bd162022-08-25 13:04:51 +09009624 if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) {
9625 networkAgent.setConnected();
Robin Leea8c0b6e2016-05-01 23:00:00 +01009626
lucaslin45e639b2019-04-03 17:09:28 +08009627 // NetworkCapabilities need to be set before sending the private DNS config to
9628 // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
Chalard Jean05edd052019-11-22 22:39:56 +09009629 networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
9630
Erik Kline9a62f012018-03-21 07:18:33 -07009631 handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
lucaslin74fa3972018-11-28 12:51:55 +08009632 updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
9633 null);
Lorenzo Colitti0f6d6bd2015-04-09 14:35:26 +09009634
Patrick Rohrf1fe8ee2022-03-02 15:14:07 +01009635 // If a rate limit has been configured and is applicable to this network (network
9636 // provides internet connectivity), apply it. The tc police filter cannot be attached
9637 // before the clsact qdisc is added which happens as part of updateLinkProperties ->
9638 // updateInterfaces -> INetd#networkAddInterface.
9639 // Note: in case of a system server crash, the NetworkController constructor in netd
9640 // (called when netd starts up) deletes the clsact qdisc of all interfaces.
9641 if (canNetworkBeRateLimited(networkAgent) && mIngressRateLimit >= 0) {
9642 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(),
9643 mIngressRateLimit);
9644 }
9645
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09009646 // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
9647 // command must be sent after updating LinkProperties to maximize chances of
9648 // NetworkMonitor seeing the correct LinkProperties when starting.
9649 // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
Lorenzo Colittiab2fed72020-01-12 22:28:37 +09009650 if (networkAgent.networkAgentConfig.acceptPartialConnectivity) {
Lorenzo Colitti6edf86c2019-05-31 15:41:29 +09009651 networkAgent.networkMonitor().setAcceptPartialConnectivity();
Remi NGUYEN VAN85391292018-12-27 16:43:56 +09009652 }
Chalard Jeand4900722022-02-06 12:25:38 +09009653 final NetworkMonitorParameters params = new NetworkMonitorParameters();
9654 params.networkAgentConfig = networkAgent.networkAgentConfig;
9655 params.networkCapabilities = networkAgent.networkCapabilities;
9656 params.linkProperties = new LinkProperties(networkAgent.linkProperties,
9657 true /* parcelSensitiveFields */);
Remi NGUYEN VAN9ada1842022-05-31 11:17:02 +09009658 // isAtLeastT() is conservative here, as recent versions of NetworkStack support the
9659 // newer callback even before T. However getInterfaceVersion is a synchronized binder
9660 // call that would cause a Log.wtf to be emitted from the system_server process, and
9661 // in the absence of a satisfactory, scalable solution which follows an easy/standard
9662 // process to check the interface version, just use an SDK check. NetworkStack will
9663 // always be new enough when running on T+.
9664 if (SdkLevel.isAtLeastT()) {
9665 networkAgent.networkMonitor().notifyNetworkConnected(params);
9666 } else {
9667 networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties,
9668 params.networkCapabilities);
9669 }
Chalard Jeane63c42f2022-09-16 19:31:45 +09009670 final long delay = activelyPreferBadWifi()
9671 ? ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS
9672 : DONT_ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS;
9673 scheduleEvaluationTimeout(networkAgent.network, delay);
Lorenzo Colitti0f6d6bd2015-04-09 14:35:26 +09009674
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09009675 // Whether a particular NetworkRequest listen should cause signal strength thresholds to
9676 // be communicated to a particular NetworkAgent depends only on the network's immutable,
9677 // capabilities, so it only needs to be done once on initial connect, not every time the
9678 // network's capabilities change. Note that we do this before rematching the network,
9679 // so we could decide to tear it down immediately afterwards. That's fine though - on
9680 // disconnection NetworkAgents should stop any signal strength monitoring they have been
9681 // doing.
Lorenzo Colitti0a6477e2015-09-15 15:56:01 +09009682 updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
Lorenzo Colitti5d2656c2015-07-06 23:50:27 +09009683
junyulai0ac374f2020-12-14 18:41:52 +08009684 // Before first rematching networks, put an inactivity timer without any request, this
9685 // allows {@code updateInactivityState} to update the state accordingly and prevent
9686 // tearing down for any {@code unneeded} evaluation in this period.
9687 // Note that the timer will not be rescheduled since the expiry time is
9688 // fixed after connection regardless of the network satisfying other requests or not.
9689 // But it will be removed as soon as the network satisfies a request for the first time.
9690 networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE,
9691 SystemClock.elapsedRealtime(), mNascentDelayMs);
junyulai36c02982021-03-26 00:40:48 +08009692 networkAgent.setInactive();
junyulai0ac374f2020-12-14 18:41:52 +08009693
Paul Jensen05e85ee2014-09-11 11:00:39 -04009694 // Consider network even though it is not yet validated.
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09009695 rematchAllNetworksAndRequests();
Lorenzo Colitti0f6d6bd2015-04-09 14:35:26 +09009696
9697 // This has to happen after matching the requests, because callbacks are just requests.
9698 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07009699 } else if (state == NetworkInfo.State.DISCONNECTED) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009700 networkAgent.disconnect();
Paul Jensen8b5fc622014-05-07 15:27:40 -04009701 if (networkAgent.isVPN()) {
Lorenzo Colitti96a3f142022-02-08 16:21:01 +00009702 updateVpnUids(networkAgent, networkAgent.networkCapabilities, null);
Paul Jensen8b5fc622014-05-07 15:27:40 -04009703 }
Chalard Jeand9fffc32018-05-11 20:19:20 +09009704 disconnectAndDestroyNetwork(networkAgent);
Irina Dumitrescude132bb2018-12-05 16:19:47 +00009705 if (networkAgent.isVPN()) {
9706 // As the active or bound network changes for apps, broadcast the default proxy, as
9707 // apps may need to update their proxy data. This is called after disconnecting from
9708 // VPN to make sure we do not broadcast the old proxy data.
9709 // TODO(b/122649188): send the broadcast only to VPN users.
9710 mProxyTracker.sendProxyBroadcast();
9711 }
Chalard Jean254bd162022-08-25 13:04:51 +09009712 } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED
9713 || state == NetworkInfo.State.SUSPENDED)) {
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07009714 mLegacyTypeTracker.update(networkAgent);
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009715 }
9716 }
9717
Chalard Jean28018572020-12-21 18:36:52 +09009718 private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {
Chalard Jean8cdee3a2020-03-04 17:45:08 +09009719 if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
9720 nai.setScore(score);
Chalard Jeanb0b3bc62019-11-07 18:54:49 +09009721 rematchAllNetworksAndRequests();
Robert Greenwalt06c734e2014-05-27 13:20:24 -07009722 }
9723
Erik Kline99f301b2017-02-15 19:59:17 +09009724 // Notify only this one new request of the current state. Transfer all the
9725 // current state by calling NetworkCapabilities and LinkProperties callbacks
9726 // so that callers can be guaranteed to have as close to atomicity in state
9727 // transfer as can be supported by this current API.
9728 protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
Etan Cohen5eba9d72016-10-27 15:05:50 -07009729 mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
Erik Kline99f301b2017-02-15 19:59:17 +09009730 if (nri.mPendingIntent != null) {
9731 sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
9732 // Attempt no subsequent state pushes where intents are involved.
9733 return;
Jeremy Joslin60d379b2014-11-05 10:32:09 -08009734 }
Erik Kline99f301b2017-02-15 19:59:17 +09009735
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009736 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
junyulaif2c67e42018-08-07 19:50:45 +08009737 final boolean metered = nai.networkCapabilities.isMetered();
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009738 final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
9739 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
9740 getBlockedState(blockedReasons, metered, vpnBlocked));
junyulaif2c67e42018-08-07 19:50:45 +08009741 }
9742
Chalard Jean8fd82ae2019-12-04 18:49:18 +09009743 // Notify the requests on this NAI that the network is now lingered.
9744 private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
junyulai2b6f0c22021-02-03 20:15:30 +08009745 final int lingerTime = (int) (nai.getInactivityExpiry() - now);
Chalard Jean8fd82ae2019-12-04 18:49:18 +09009746 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
9747 }
9748
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009749 private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
9750 if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
9751 return vpnBlocked
9752 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
9753 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
9754 }
9755
9756 private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
9757 if (blockedReasons == BLOCKED_REASON_NONE) {
9758 mUidBlockedReasons.delete(uid);
9759 } else {
9760 mUidBlockedReasons.put(uid, blockedReasons);
9761 }
9762 }
9763
junyulaif2c67e42018-08-07 19:50:45 +08009764 /**
9765 * Notify of the blocked state apps with a registered callback matching a given NAI.
9766 *
9767 * Unlike other callbacks, blocked status is different between each individual uid. So for
9768 * any given nai, all requests need to be considered according to the uid who filed it.
9769 *
9770 * @param nai The target NetworkAgentInfo.
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009771 * @param oldMetered True if the previous network capabilities were metered.
9772 * @param newMetered True if the current network capabilities are metered.
9773 * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
9774 * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
junyulaif2c67e42018-08-07 19:50:45 +08009775 */
9776 private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
Sudheer Shanka9967d462021-03-18 19:09:25 +00009777 boolean newMetered, List<UidRange> oldBlockedUidRanges,
9778 List<UidRange> newBlockedUidRanges) {
junyulaif2c67e42018-08-07 19:50:45 +08009779
9780 for (int i = 0; i < nai.numNetworkRequests(); i++) {
9781 NetworkRequest nr = nai.requestAt(i);
9782 NetworkRequestInfo nri = mNetworkRequests.get(nr);
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09009783
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009784 final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
9785 final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
9786 final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09009787 ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09009788 : oldVpnBlocked;
9789
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009790 final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
9791 final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
9792 if (oldBlockedState != newBlockedState) {
junyulaif2c67e42018-08-07 19:50:45 +08009793 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009794 newBlockedState);
junyulaif2c67e42018-08-07 19:50:45 +08009795 }
9796 }
9797 }
9798
9799 /**
Sudheer Shanka9967d462021-03-18 19:09:25 +00009800 * Notify apps with a given UID of the new blocked state according to new uid state.
junyulaif2c67e42018-08-07 19:50:45 +08009801 * @param uid The uid for which the rules changed.
Sudheer Shanka9967d462021-03-18 19:09:25 +00009802 * @param blockedReasons The reasons for why an uid is blocked.
junyulaif2c67e42018-08-07 19:50:45 +08009803 */
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009804 private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009805 for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
junyulaif2c67e42018-08-07 19:50:45 +08009806 final boolean metered = nai.networkCapabilities.isMetered();
Lorenzo Colitti3f54f102020-12-12 00:51:11 +09009807 final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
Sudheer Shanka9967d462021-03-18 19:09:25 +00009808
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009809 final int oldBlockedState = getBlockedState(
9810 mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
9811 final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
9812 if (oldBlockedState == newBlockedState) {
junyulai7509e6e2019-04-08 16:58:22 +08009813 continue;
junyulaif2c67e42018-08-07 19:50:45 +08009814 }
junyulaif2c67e42018-08-07 19:50:45 +08009815 for (int i = 0; i < nai.numNetworkRequests(); i++) {
9816 NetworkRequest nr = nai.requestAt(i);
9817 NetworkRequestInfo nri = mNetworkRequests.get(nr);
Lorenzo Colitti3e367f42021-03-12 22:50:57 +09009818 if (nri != null && nri.mAsUid == uid) {
Lorenzo Colitti79c6f222021-03-18 00:54:57 +09009819 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
9820 newBlockedState);
junyulaif2c67e42018-08-07 19:50:45 +08009821 }
9822 }
9823 }
Robert Greenwaltf99b8392014-03-26 16:47:06 -07009824 }
9825
Chalard Jean3a3f5f22019-04-10 23:07:55 +09009826 @VisibleForTesting
9827 protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
Lorenzo Colitticfb36572014-07-31 23:20:17 +09009828 // The NetworkInfo we actually send out has no bearing on the real
9829 // state of affairs. For example, if the default connection is mobile,
9830 // and a request for HIPRI has just gone away, we need to pretend that
9831 // HIPRI has just disconnected. So we need to set the type to HIPRI and
9832 // the state to DISCONNECTED, even though the network is of type MOBILE
9833 // and is still connected.
9834 NetworkInfo info = new NetworkInfo(nai.networkInfo);
9835 info.setType(type);
Lorenzo Colittie30db8d2021-03-10 00:18:59 +09009836 filterForLegacyLockdown(info);
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07009837 if (state != DetailedState.DISCONNECTED) {
9838 info.setDetailedState(state, null, info.getExtraInfo());
Erik Klineb8836592014-12-08 16:25:20 +09009839 sendConnectedBroadcast(info);
Robert Greenwalt802c1102014-06-02 15:32:02 -07009840 } else {
Robert Greenwalt7fb8adc2015-06-24 13:23:42 -07009841 info.setDetailedState(state, info.getReason(), info.getExtraInfo());
Robert Greenwalt802c1102014-06-02 15:32:02 -07009842 Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
9843 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
9844 intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
9845 if (info.isFailover()) {
9846 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
9847 nai.networkInfo.setFailover(false);
9848 }
9849 if (info.getReason() != null) {
9850 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
9851 }
9852 if (info.getExtraInfo() != null) {
9853 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
9854 }
9855 NetworkAgentInfo newDefaultAgent = null;
Chalard Jean5b409c72021-02-04 13:12:59 +09009856 if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
James Mattis2516da32021-01-31 17:06:19 -08009857 newDefaultAgent = mDefaultRequest.getSatisfier();
Robert Greenwalt802c1102014-06-02 15:32:02 -07009858 if (newDefaultAgent != null) {
9859 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
9860 newDefaultAgent.networkInfo);
9861 } else {
9862 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
9863 }
9864 }
9865 intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
9866 mDefaultInetConditionPublished);
Erik Klineb8836592014-12-08 16:25:20 +09009867 sendStickyBroadcast(intent);
Robert Greenwalt802c1102014-06-02 15:32:02 -07009868 if (newDefaultAgent != null) {
Erik Klineb8836592014-12-08 16:25:20 +09009869 sendConnectedBroadcast(newDefaultAgent.networkInfo);
Robert Greenwalt802c1102014-06-02 15:32:02 -07009870 }
9871 }
9872 }
9873
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09009874 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
hiroaki.yokoyamaa1a397d2018-10-16 12:50:33 +09009875 if (VDBG || DDBG) {
Hugo Benichi8d962922017-03-22 17:07:57 +09009876 String notification = ConnectivityManager.getCallbackName(notifyType);
Chalard Jean49707572019-12-10 21:07:02 +09009877 log("notifyType " + notification + " for " + networkAgent.toShortString());
Hugo Benichi8d962922017-03-22 17:07:57 +09009878 }
Lorenzo Colitti99236d12016-07-01 01:37:11 +09009879 for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
9880 NetworkRequest nr = networkAgent.requestAt(i);
Robert Greenwaltf99b8392014-03-26 16:47:06 -07009881 NetworkRequestInfo nri = mNetworkRequests.get(nr);
9882 if (VDBG) log(" sending notification for " + nr);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08009883 if (nri.mPendingIntent == null) {
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09009884 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
Jeremy Joslin60d379b2014-11-05 10:32:09 -08009885 } else {
9886 sendPendingIntentForRequest(nri, networkAgent, notifyType);
9887 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009888 }
Robert Greenwalte20f7a22014-04-18 15:25:25 -07009889 }
Robert Greenwaltbe46b752014-05-13 21:41:06 -07009890
Lorenzo Colitti79869ea2016-07-01 01:53:25 +09009891 protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
9892 notifyNetworkCallbacks(networkAgent, notifyType, 0);
9893 }
9894
Jeff Sharkeyaa6ff6c2014-12-08 14:50:12 -08009895 /**
Lorenzo Colitti24861882018-01-19 00:50:48 +09009896 * Returns the list of all interfaces that could be used by network traffic that does not
9897 * explicitly specify a network. This includes the default network, but also all VPNs that are
9898 * currently connected.
9899 *
9900 * Must be called on the handler thread.
9901 */
junyulaie7c7d2a2021-01-26 15:29:15 +08009902 @NonNull
9903 private ArrayList<Network> getDefaultNetworks() {
Varun Anandf3fd8dd2019-02-07 14:13:13 -08009904 ensureRunningOnConnectivityServiceThread();
James Mattise3ef1912020-12-20 11:09:58 -08009905 final ArrayList<Network> defaultNetworks = new ArrayList<>();
James Mattis2516da32021-01-31 17:06:19 -08009906 final Set<Integer> activeNetIds = new ArraySet<>();
9907 for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
9908 if (nri.isBeingSatisfied()) {
9909 activeNetIds.add(nri.getSatisfier().network().netId);
9910 }
9911 }
Remi NGUYEN VAN77b0c1c2020-12-23 12:45:08 +09009912 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
Lorenzo Colitti275ee602022-08-09 19:29:12 +09009913 if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) {
Lorenzo Colitti24861882018-01-19 00:50:48 +09009914 defaultNetworks.add(nai.network);
9915 }
9916 }
junyulaie7c7d2a2021-01-26 15:29:15 +08009917 return defaultNetworks;
Lorenzo Colitti24861882018-01-19 00:50:48 +09009918 }
9919
9920 /**
Lorenzo Colittic7563342019-06-24 13:50:45 +09009921 * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
9922 * active iface's tracked properties has changed.
Jeff Sharkeyaa6ff6c2014-12-08 14:50:12 -08009923 */
Jeff Davidsonf73c15c2016-01-20 11:35:38 -08009924 private void notifyIfacesChangedForNetworkStats() {
Varun Anandf3fd8dd2019-02-07 14:13:13 -08009925 ensureRunningOnConnectivityServiceThread();
9926 String activeIface = null;
9927 LinkProperties activeLinkProperties = getActiveLinkProperties();
9928 if (activeLinkProperties != null) {
9929 activeIface = activeLinkProperties.getInterfaceName();
9930 }
Benedict Wong9308cd32019-06-12 17:46:31 +00009931
junyulai2050bed2021-01-23 09:46:34 +08009932 final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
Jeff Sharkeyaa6ff6c2014-12-08 14:50:12 -08009933 try {
junyulaide41fc22021-01-22 22:46:01 +08009934 final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
Chalard Jean46bfbf02022-02-02 00:56:25 +09009935 snapshots.addAll(getAllNetworkStateSnapshots());
junyulaie7c7d2a2021-01-26 15:29:15 +08009936 mStatsManager.notifyNetworkStatus(getDefaultNetworks(),
9937 snapshots, activeIface, Arrays.asList(underlyingNetworkInfos));
Jeff Sharkeyaa6ff6c2014-12-08 14:50:12 -08009938 } catch (Exception ignored) {
9939 }
9940 }
9941
Sreeram Ramachandrane4586322014-07-27 14:18:26 -07009942 @Override
Udam Sainicd645462016-01-04 12:16:14 -08009943 public String getCaptivePortalServerUrl() {
paulhu8e96a752019-08-12 16:25:11 +08009944 enforceNetworkStackOrSettingsPermission();
Remi NGUYEN VAN21c854a2021-03-08 22:05:03 +09009945 String settingUrl = mResources.get().getString(
Remi NGUYEN VAN97fad722021-03-19 17:41:48 +09009946 R.string.config_networkCaptivePortalServerUrl);
Niklas Lindgrenfd6f92e2018-12-07 11:08:04 +01009947
9948 if (!TextUtils.isEmpty(settingUrl)) {
9949 return settingUrl;
9950 }
9951
9952 settingUrl = Settings.Global.getString(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +08009953 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL);
Niklas Lindgrenfd6f92e2018-12-07 11:08:04 +01009954 if (!TextUtils.isEmpty(settingUrl)) {
9955 return settingUrl;
9956 }
9957
9958 return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
Udam Sainicd645462016-01-04 12:16:14 -08009959 }
9960
9961 @Override
junyulai070f9ff2019-01-16 20:23:34 +08009962 public void startNattKeepalive(Network network, int intervalSeconds,
9963 ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09009964 enforceKeepalivePermission();
9965 mKeepaliveTracker.startNattKeepalive(
junyulai7e06ad42019-03-04 22:45:36 +08009966 getNetworkAgentInfoForNetwork(network), null /* fd */,
chiachangwang9ef4ffe2023-01-18 01:19:27 +00009967 intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT,
9968 // Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to
chiachangwang676c84e2023-02-14 09:22:05 +00009969 // false and set the underpinned network to null because there is no way and no
9970 // plan to configure automaticOnOffKeepalives or underpinnedNetwork in this
9971 // deprecated method.
9972 false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */);
Lorenzo Colitti0b798a82015-06-15 14:29:22 +09009973 }
9974
9975 @Override
Chiachang Wang04a34b62021-01-19 15:35:03 +08009976 public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
junyulai070f9ff2019-01-16 20:23:34 +08009977 int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
chiachangwang676c84e2023-02-14 09:22:05 +00009978 String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) {
Josh Gao461a1222020-06-16 15:58:11 -07009979 try {
Chiachang Wang04a34b62021-01-19 15:35:03 +08009980 final FileDescriptor fd = pfd.getFileDescriptor();
Josh Gao461a1222020-06-16 15:58:11 -07009981 mKeepaliveTracker.startNattKeepalive(
9982 getNetworkAgentInfoForNetwork(network), fd, resourceId,
chiachangwang676c84e2023-02-14 09:22:05 +00009983 intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT,
9984 automaticOnOffKeepalives, underpinnedNetwork);
Josh Gao461a1222020-06-16 15:58:11 -07009985 } finally {
9986 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
9987 // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
Chiachang Wang04a34b62021-01-19 15:35:03 +08009988 if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
9989 IoUtils.closeQuietly(pfd);
Josh Gao461a1222020-06-16 15:58:11 -07009990 }
9991 }
junyulaid05a1922019-01-15 11:32:44 +08009992 }
9993
9994 @Override
Chiachang Wang04a34b62021-01-19 15:35:03 +08009995 public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds,
junyulai070f9ff2019-01-16 20:23:34 +08009996 ISocketKeepaliveCallback cb) {
Josh Gao461a1222020-06-16 15:58:11 -07009997 try {
9998 enforceKeepalivePermission();
Chiachang Wang04a34b62021-01-19 15:35:03 +08009999 final FileDescriptor fd = pfd.getFileDescriptor();
Josh Gao461a1222020-06-16 15:58:11 -070010000 mKeepaliveTracker.startTcpKeepalive(
10001 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
10002 } finally {
10003 // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
10004 // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
Chiachang Wang04a34b62021-01-19 15:35:03 +080010005 if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
10006 IoUtils.closeQuietly(pfd);
Josh Gao461a1222020-06-16 15:58:11 -070010007 }
10008 }
junyulai0835a1e2019-01-08 20:04:33 +080010009 }
10010
10011 @Override
Chalard Jeanf0b261e2023-02-03 22:11:20 +090010012 public void stopKeepalive(@NonNull final ISocketKeepaliveCallback cb) {
Lorenzo Colitti0b798a82015-06-15 14:29:22 +090010013 mHandler.sendMessage(mHandler.obtainMessage(
Chalard Jeanf0b261e2023-02-03 22:11:20 +090010014 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, 0, SocketKeepalive.SUCCESS,
10015 Objects.requireNonNull(cb).asBinder()));
Lorenzo Colitti0b798a82015-06-15 14:29:22 +090010016 }
10017
10018 @Override
Stuart Scottd5463642015-04-02 18:00:02 -070010019 public void factoryReset() {
paulhu8e96a752019-08-12 16:25:11 +080010020 enforceSettingsPermission();
Stuart Scottd198fe12015-04-20 14:07:45 -070010021
Chiachang Wangfe28d9b2021-05-19 10:13:22 +080010022 final int uid = mDeps.getCallingUid();
lucaslin75ff7022020-12-17 04:14:35 +080010023 final long token = Binder.clearCallingIdentity();
10024 try {
Chiachang Wangfe28d9b2021-05-19 10:13:22 +080010025 if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET,
10026 UserHandle.getUserHandleForUid(uid))) {
10027 return;
10028 }
10029
Heemin Seogdb8489d2019-06-12 09:21:44 -070010030 final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
10031 ipMemoryStore.factoryReset();
Chiachang Wangfe28d9b2021-05-19 10:13:22 +080010032
10033 // Turn airplane mode off
10034 setAirplaneMode(false);
10035
10036 // restore private DNS settings to default mode (opportunistic)
10037 if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
10038 UserHandle.getUserHandleForUid(uid))) {
10039 ConnectivitySettingsManager.setPrivateDnsMode(mContext,
10040 PRIVATE_DNS_MODE_OPPORTUNISTIC);
10041 }
10042
10043 Settings.Global.putString(mContext.getContentResolver(),
10044 ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null);
lucaslin75ff7022020-12-17 04:14:35 +080010045 } finally {
10046 Binder.restoreCallingIdentity(token);
10047 }
Stuart Scottd5463642015-04-02 18:00:02 -070010048 }
Paul Jensen6eb94e62015-07-01 14:16:32 -040010049
Ricky Wai7097cc92018-01-23 04:09:45 +000010050 @Override
10051 public byte[] getNetworkWatchlistConfigHash() {
10052 NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
10053 if (nwm == null) {
10054 loge("Unable to get NetworkWatchlistManager");
10055 return null;
10056 }
10057 // Redirect it to network watchlist service to access watchlist file and calculate hash.
10058 return nwm.getWatchlistConfigHash();
10059 }
10060
Hugo Benichibe0c7652016-05-31 16:28:06 +090010061 private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
Hugo Benichi2efffd72017-11-11 08:06:43 +090010062 int[] transports = nai.networkCapabilities.getTransportTypes();
Serik Beketayevec8ad212020-12-07 22:43:07 -080010063 mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype));
Erik Klineabdd3f82016-04-14 17:30:59 +090010064 }
Hugo Benichif4210292017-04-21 15:07:12 +090010065
10066 private static boolean toBool(int encodedBoolean) {
10067 return encodedBoolean != 0; // Only 0 means false.
10068 }
10069
10070 private static int encodeBool(boolean b) {
10071 return b ? 1 : 0;
10072 }
mswest4632928412018-03-12 10:34:34 -070010073
10074 @Override
Chiachang Wang77ae8a02020-10-12 15:20:07 +080010075 public int handleShellCommand(@NonNull ParcelFileDescriptor in,
10076 @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
10077 @NonNull String[] args) {
10078 return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(),
10079 err.getFileDescriptor(), args);
mswest4632928412018-03-12 10:34:34 -070010080 }
10081
Chiachang Wang77ae8a02020-10-12 15:20:07 +080010082 private class ShellCmd extends BasicShellCommandHandler {
mswest4632928412018-03-12 10:34:34 -070010083 @Override
10084 public int onCommand(String cmd) {
10085 if (cmd == null) {
10086 return handleDefaultCommands(cmd);
10087 }
10088 final PrintWriter pw = getOutPrintWriter();
10089 try {
10090 switch (cmd) {
10091 case "airplane-mode":
Chalard Jean7a1d7a82021-08-05 21:02:22 +090010092 // Usage : adb shell cmd connectivity airplane-mode [enable|disable]
10093 // If no argument, get and display the current status
mswest4632928412018-03-12 10:34:34 -070010094 final String action = getNextArg();
10095 if ("enable".equals(action)) {
10096 setAirplaneMode(true);
10097 return 0;
10098 } else if ("disable".equals(action)) {
10099 setAirplaneMode(false);
10100 return 0;
10101 } else if (action == null) {
10102 final ContentResolver cr = mContext.getContentResolver();
10103 final int enabled = Settings.Global.getInt(cr,
10104 Settings.Global.AIRPLANE_MODE_ON);
10105 pw.println(enabled == 0 ? "disabled" : "enabled");
10106 return 0;
10107 } else {
10108 onHelp();
10109 return -1;
10110 }
Chalard Jean7a1d7a82021-08-05 21:02:22 +090010111 case "reevaluate":
10112 // Usage : adb shell cmd connectivity reevaluate <netId>
10113 // If netId is omitted, then reevaluate the default network
10114 final String netId = getNextArg();
10115 final NetworkAgentInfo nai;
10116 if (null == netId) {
10117 // Note that the command is running on the wrong thread to call this,
10118 // so this could in principle return stale data. But it can't crash.
10119 nai = getDefaultNetwork();
10120 } else {
10121 // If netId can't be parsed, this throws NumberFormatException, which
10122 // is passed back to adb who prints it.
10123 nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId));
10124 }
10125 if (null == nai) {
10126 pw.println("Unknown network (net ID not found or no default network)");
10127 return 0;
10128 }
10129 Log.d(TAG, "Reevaluating network " + nai.network);
10130 reportNetworkConnectivity(nai.network, !nai.isValidated());
10131 return 0;
mswest4632928412018-03-12 10:34:34 -070010132 default:
10133 return handleDefaultCommands(cmd);
10134 }
10135 } catch (Exception e) {
10136 pw.println(e);
10137 }
10138 return -1;
10139 }
10140
10141 @Override
10142 public void onHelp() {
10143 PrintWriter pw = getOutPrintWriter();
10144 pw.println("Connectivity service commands:");
10145 pw.println(" help");
10146 pw.println(" Print this help text.");
10147 pw.println(" airplane-mode [enable|disable]");
10148 pw.println(" Turn airplane mode on or off.");
10149 pw.println(" airplane-mode");
10150 pw.println(" Get airplane mode.");
10151 }
10152 }
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010153
Remi NGUYEN VAN06830742021-03-06 00:11:24 +090010154 private int getVpnType(@Nullable NetworkAgentInfo vpn) {
Lorenzo Colittia5a903d2021-02-04 00:18:27 +090010155 if (vpn == null) return VpnManager.TYPE_VPN_NONE;
10156 final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
10157 if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
Chiachang Wang6ec9b8d2021-04-20 15:41:24 +080010158 return ((VpnTransportInfo) ti).getType();
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010159 }
10160
Lorenzo Colitti580d0d52022-10-13 19:56:58 +090010161 private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai,
10162 @NonNull NetworkCapabilities nc) {
he_won.hwang881307a2022-03-15 21:23:52 +090010163 final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo();
10164 final TransportInfo newInfo = nc.getTransportInfo();
10165 if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) {
10166 return;
10167 }
10168 if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) {
Chalard Jean254bd162022-08-25 13:04:51 +090010169 nai.lastRoamTime = SystemClock.elapsedRealtime();
he_won.hwang881307a2022-03-15 21:23:52 +090010170 }
10171 }
10172
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010173 /**
10174 * @param connectionInfo the connection to resolve.
10175 * @return {@code uid} if the connection is found and the app has permission to observe it
10176 * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
10177 * connection is not found.
10178 */
10179 public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010180 if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
10181 throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
10182 }
10183
Lorenzo Colitti3be9df12021-02-04 01:47:38 +090010184 final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010185 connectionInfo.local, connectionInfo.remote);
10186
Lorenzo Colittia5a903d2021-02-04 00:18:27 +090010187 if (uid == INVALID_UID) return uid; // Not found.
10188
10189 // Connection owner UIDs are visible only to the network stack and to the VpnService-based
10190 // VPN, if any, that applies to the UID that owns the connection.
10191 if (checkNetworkStackPermission()) return uid;
10192
10193 final NetworkAgentInfo vpn = getVpnForUid(uid);
10194 if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
Lorenzo Colitti9bff86e2021-03-12 22:39:08 +090010195 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
Jeff Vander Stoep39a51e02018-07-23 10:57:53 -070010196 return INVALID_UID;
10197 }
10198
10199 return uid;
10200 }
Pavel Grafove87b7ce2018-12-14 13:51:07 +000010201
Benedict Wong493e04b2018-11-09 14:45:34 -080010202 /**
10203 * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
10204 *
10205 * <p>The TestNetworkService must be run in the system server due to TUN creation.
10206 */
10207 @Override
10208 public IBinder startOrGetTestNetworkService() {
10209 synchronized (mTNSLock) {
10210 TestNetworkService.enforceTestNetworkPermissions(mContext);
10211
10212 if (mTNS == null) {
lucaslin23efc582021-02-24 13:49:42 +080010213 mTNS = new TestNetworkService(mContext);
Benedict Wong493e04b2018-11-09 14:45:34 -080010214 }
10215
10216 return mTNS;
10217 }
10218 }
Cody Kestingd199a9d2019-12-17 12:55:28 -080010219
Cody Kesting73708bf2019-12-18 10:57:50 -080010220 /**
10221 * Handler used for managing all Connectivity Diagnostics related functions.
10222 *
10223 * @see android.net.ConnectivityDiagnosticsManager
10224 *
10225 * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file
10226 */
10227 @VisibleForTesting
10228 class ConnectivityDiagnosticsHandler extends Handler {
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010229 private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
10230
Cody Kesting73708bf2019-12-18 10:57:50 -080010231 /**
10232 * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
10233 * android.net.ConnectivityDiagnosticsManager}.
10234 * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and
10235 * NetworkRequestInfo to be registered
10236 */
10237 private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1;
10238
10239 /**
10240 * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link
10241 * android.net.ConnectivityDiagnosticsManager}.
10242 * obj = the IConnectivityDiagnosticsCallback to be unregistered
10243 * arg1 = the uid of the caller
10244 */
10245 private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2;
10246
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010247 /**
10248 * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
Lorenzo Colitti0261ced2022-02-18 00:23:56 +090010249 * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events.
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010250 * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
10251 * NetworkMonitor.
10252 * data = PersistableBundle of extras passed from NetworkMonitor.
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010253 */
Lorenzo Colitti0261ced2022-02-18 00:23:56 +090010254 private static final int CMD_SEND_CONNECTIVITY_REPORT = 3;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010255
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010256 /**
10257 * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
10258 * been detected on the network.
10259 * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
10260 * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
10261 * arg2 = NetID.
10262 * data = PersistableBundle of extras passed from NetworkMonitor.
10263 */
10264 private static final int EVENT_DATA_STALL_SUSPECTED = 4;
10265
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010266 /**
10267 * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
10268 * the platform. This event will invoke {@link
10269 * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
10270 * callbacks.
Cody Kestingf1120be2020-08-03 18:01:40 -070010271 * obj = ReportedNetworkConnectivityInfo with info on reported Network connectivity.
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010272 */
10273 private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
10274
Cody Kesting73708bf2019-12-18 10:57:50 -080010275 private ConnectivityDiagnosticsHandler(Looper looper) {
10276 super(looper);
10277 }
10278
10279 @Override
10280 public void handleMessage(Message msg) {
10281 switch (msg.what) {
10282 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
10283 handleRegisterConnectivityDiagnosticsCallback(
10284 (ConnectivityDiagnosticsCallbackInfo) msg.obj);
10285 break;
10286 }
10287 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
10288 handleUnregisterConnectivityDiagnosticsCallback(
10289 (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
10290 break;
10291 }
Lorenzo Colitti0261ced2022-02-18 00:23:56 +090010292 case CMD_SEND_CONNECTIVITY_REPORT: {
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010293 final ConnectivityReportEvent reportEvent =
10294 (ConnectivityReportEvent) msg.obj;
10295
Aaron Huang959d3642021-01-21 15:47:41 +080010296 handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010297 break;
10298 }
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010299 case EVENT_DATA_STALL_SUSPECTED: {
10300 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
Aaron Huang959d3642021-01-21 15:47:41 +080010301 final Pair<Long, PersistableBundle> arg =
10302 (Pair<Long, PersistableBundle>) msg.obj;
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010303 if (nai == null) break;
10304
Aaron Huang959d3642021-01-21 15:47:41 +080010305 handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second);
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010306 break;
10307 }
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010308 case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
Cody Kestingf1120be2020-08-03 18:01:40 -070010309 handleNetworkConnectivityReported((ReportedNetworkConnectivityInfo) msg.obj);
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010310 break;
10311 }
10312 default: {
10313 Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
10314 }
Cody Kesting73708bf2019-12-18 10:57:50 -080010315 }
10316 }
10317 }
10318
10319 /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */
10320 @VisibleForTesting
10321 class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient {
10322 @NonNull private final IConnectivityDiagnosticsCallback mCb;
10323 @NonNull private final NetworkRequestInfo mRequestInfo;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010324 @NonNull private final String mCallingPackageName;
Cody Kesting73708bf2019-12-18 10:57:50 -080010325
10326 @VisibleForTesting
10327 ConnectivityDiagnosticsCallbackInfo(
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010328 @NonNull IConnectivityDiagnosticsCallback cb,
10329 @NonNull NetworkRequestInfo nri,
10330 @NonNull String callingPackageName) {
Cody Kesting73708bf2019-12-18 10:57:50 -080010331 mCb = cb;
10332 mRequestInfo = nri;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010333 mCallingPackageName = callingPackageName;
Cody Kesting73708bf2019-12-18 10:57:50 -080010334 }
10335
10336 @Override
10337 public void binderDied() {
10338 log("ConnectivityDiagnosticsCallback IBinder died.");
10339 unregisterConnectivityDiagnosticsCallback(mCb);
10340 }
10341 }
10342
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010343 /**
10344 * Class used for sending information from {@link
10345 * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it.
10346 */
10347 private static class NetworkTestedResults {
10348 private final int mNetId;
10349 private final int mTestResult;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010350 @Nullable private final String mRedirectUrl;
10351
10352 private NetworkTestedResults(
10353 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) {
10354 mNetId = netId;
10355 mTestResult = testResult;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010356 mRedirectUrl = redirectUrl;
10357 }
10358 }
10359
10360 /**
10361 * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link
10362 * ConnectivityDiagnosticsHandler}.
10363 */
10364 private static class ConnectivityReportEvent {
10365 private final long mTimestampMillis;
10366 @NonNull private final NetworkAgentInfo mNai;
Aaron Huang959d3642021-01-21 15:47:41 +080010367 private final PersistableBundle mExtras;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010368
Aaron Huang959d3642021-01-21 15:47:41 +080010369 private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai,
10370 PersistableBundle p) {
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010371 mTimestampMillis = timestampMillis;
10372 mNai = nai;
Aaron Huang959d3642021-01-21 15:47:41 +080010373 mExtras = p;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010374 }
10375 }
10376
Cody Kestingf1120be2020-08-03 18:01:40 -070010377 /**
10378 * Class used for sending info for a call to {@link #reportNetworkConnectivity()} to {@link
10379 * ConnectivityDiagnosticsHandler}.
10380 */
10381 private static class ReportedNetworkConnectivityInfo {
10382 public final boolean hasConnectivity;
10383 public final boolean isNetworkRevalidating;
10384 public final int reporterUid;
10385 @NonNull public final NetworkAgentInfo nai;
10386
10387 private ReportedNetworkConnectivityInfo(
10388 boolean hasConnectivity,
10389 boolean isNetworkRevalidating,
10390 int reporterUid,
10391 @NonNull NetworkAgentInfo nai) {
10392 this.hasConnectivity = hasConnectivity;
10393 this.isNetworkRevalidating = isNetworkRevalidating;
10394 this.reporterUid = reporterUid;
10395 this.nai = nai;
10396 }
10397 }
10398
Cody Kesting73708bf2019-12-18 10:57:50 -080010399 private void handleRegisterConnectivityDiagnosticsCallback(
10400 @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) {
10401 ensureRunningOnConnectivityServiceThread();
10402
10403 final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
Cody Kesting31f1ff62020-03-05 10:46:02 -080010404 final IBinder iCb = cb.asBinder();
Cody Kesting73708bf2019-12-18 10:57:50 -080010405 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
10406
James Mattis64b8b0f2020-11-24 17:40:49 -080010407 // Connectivity Diagnostics are meant to be used with a single network request. It would be
10408 // confusing for these networks to change when an NRI is satisfied in another layer.
10409 if (nri.isMultilayerRequest()) {
10410 throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer "
10411 + "network requests.");
10412 }
10413
Cody Kesting73708bf2019-12-18 10:57:50 -080010414 // This means that the client registered the same callback multiple times. Do
10415 // not override the previous entry, and exit silently.
Cody Kesting31f1ff62020-03-05 10:46:02 -080010416 if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
Cody Kesting73708bf2019-12-18 10:57:50 -080010417 if (VDBG) log("Diagnostics callback is already registered");
10418
10419 // Decrement the reference count for this NetworkRequestInfo. The reference count is
10420 // incremented when the NetworkRequestInfo is created as part of
10421 // enforceRequestCountLimit().
Junyu Lai00d92df2022-07-05 11:01:52 +080010422 nri.mPerUidCounter.decrementCount(nri.mUid);
Cody Kesting73708bf2019-12-18 10:57:50 -080010423 return;
10424 }
10425
Cody Kesting31f1ff62020-03-05 10:46:02 -080010426 mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
Cody Kesting73708bf2019-12-18 10:57:50 -080010427
10428 try {
Cody Kesting31f1ff62020-03-05 10:46:02 -080010429 iCb.linkToDeath(cbInfo, 0);
Cody Kesting73708bf2019-12-18 10:57:50 -080010430 } catch (RemoteException e) {
10431 cbInfo.binderDied();
Cody Kestingb77bf702020-02-12 14:50:58 -080010432 return;
10433 }
10434
10435 // Once registered, provide ConnectivityReports for matching Networks
10436 final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>();
10437 synchronized (mNetworkForNetId) {
10438 for (int i = 0; i < mNetworkForNetId.size(); i++) {
10439 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
James Mattis64b8b0f2020-11-24 17:40:49 -080010440 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0)
10441 if (nai.satisfies(nri.mRequests.get(0))) {
Cody Kestingb77bf702020-02-12 14:50:58 -080010442 matchingNetworks.add(nai);
10443 }
10444 }
10445 }
10446 for (final NetworkAgentInfo nai : matchingNetworks) {
10447 final ConnectivityReport report = nai.getConnectivityReport();
10448 if (report == null) {
10449 continue;
10450 }
10451 if (!checkConnectivityDiagnosticsPermissions(
10452 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
10453 continue;
10454 }
10455
10456 try {
10457 cb.onConnectivityReportAvailable(report);
10458 } catch (RemoteException e) {
10459 // Exception while sending the ConnectivityReport. Move on to the next network.
10460 }
Cody Kesting73708bf2019-12-18 10:57:50 -080010461 }
10462 }
10463
10464 private void handleUnregisterConnectivityDiagnosticsCallback(
10465 @NonNull IConnectivityDiagnosticsCallback cb, int uid) {
10466 ensureRunningOnConnectivityServiceThread();
Cody Kesting31f1ff62020-03-05 10:46:02 -080010467 final IBinder iCb = cb.asBinder();
Cody Kesting73708bf2019-12-18 10:57:50 -080010468
Cody Kesting2b1a61c2020-03-30 12:43:49 -070010469 final ConnectivityDiagnosticsCallbackInfo cbInfo =
10470 mConnectivityDiagnosticsCallbacks.remove(iCb);
10471 if (cbInfo == null) {
Cody Kesting73708bf2019-12-18 10:57:50 -080010472 if (VDBG) log("Removing diagnostics callback that is not currently registered");
10473 return;
10474 }
10475
Cody Kesting2b1a61c2020-03-30 12:43:49 -070010476 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
Cody Kesting73708bf2019-12-18 10:57:50 -080010477
Cody Kesting70fa2b22020-12-02 12:16:56 -080010478 // Caller's UID must either be the registrants (if they are unregistering) or the System's
10479 // (if the Binder died)
10480 if (uid != nri.mUid && uid != Process.SYSTEM_UID) {
10481 if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's");
Cody Kesting73708bf2019-12-18 10:57:50 -080010482 return;
10483 }
10484
Cody Kesting46cb1672020-03-04 13:35:20 -080010485 // Decrement the reference count for this NetworkRequestInfo. The reference count is
10486 // incremented when the NetworkRequestInfo is created as part of
10487 // enforceRequestCountLimit().
Junyu Lai00d92df2022-07-05 11:01:52 +080010488 nri.mPerUidCounter.decrementCount(nri.mUid);
Cody Kesting46cb1672020-03-04 13:35:20 -080010489
Cody Kesting31f1ff62020-03-05 10:46:02 -080010490 iCb.unlinkToDeath(cbInfo, 0);
Cody Kesting73708bf2019-12-18 10:57:50 -080010491 }
10492
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010493 private void handleNetworkTestedWithExtras(
10494 @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) {
10495 final NetworkAgentInfo nai = reportEvent.mNai;
Cody Kesting7febafb2020-02-11 10:03:26 -080010496 final NetworkCapabilities networkCapabilities =
Cody Kestingb1cd3eb2020-03-05 22:13:31 -080010497 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010498 final ConnectivityReport report =
10499 new ConnectivityReport(
10500 reportEvent.mNai.network,
10501 reportEvent.mTimestampMillis,
10502 nai.linkProperties,
Cody Kesting7febafb2020-02-11 10:03:26 -080010503 networkCapabilities,
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010504 extras);
Cody Kestingb77bf702020-02-12 14:50:58 -080010505 nai.setConnectivityReport(report);
Cody Kestingf1120be2020-08-03 18:01:40 -070010506
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010507 final List<IConnectivityDiagnosticsCallback> results =
Cody Kestingf1120be2020-08-03 18:01:40 -070010508 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010509 for (final IConnectivityDiagnosticsCallback cb : results) {
10510 try {
Cody Kestingfa1ef5e2020-03-05 15:19:48 -080010511 cb.onConnectivityReportAvailable(report);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010512 } catch (RemoteException ex) {
Cody Kestingf1120be2020-08-03 18:01:40 -070010513 loge("Error invoking onConnectivityReportAvailable", ex);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010514 }
10515 }
10516 }
10517
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010518 private void handleDataStallSuspected(
10519 @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
10520 @NonNull PersistableBundle extras) {
Cody Kesting7febafb2020-02-11 10:03:26 -080010521 final NetworkCapabilities networkCapabilities =
Cody Kestingb1cd3eb2020-03-05 22:13:31 -080010522 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010523 final DataStallReport report =
Cody Kestingf2852482020-02-04 21:52:09 -080010524 new DataStallReport(
10525 nai.network,
10526 timestampMillis,
10527 detectionMethod,
10528 nai.linkProperties,
Cody Kesting7febafb2020-02-11 10:03:26 -080010529 networkCapabilities,
Cody Kestingf2852482020-02-04 21:52:09 -080010530 extras);
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010531 final List<IConnectivityDiagnosticsCallback> results =
Cody Kestingf1120be2020-08-03 18:01:40 -070010532 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID);
Cody Kestingb12ad4c2020-01-06 16:55:35 -080010533 for (final IConnectivityDiagnosticsCallback cb : results) {
10534 try {
10535 cb.onDataStallSuspected(report);
10536 } catch (RemoteException ex) {
10537 loge("Error invoking onDataStallSuspected", ex);
10538 }
10539 }
10540 }
10541
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010542 private void handleNetworkConnectivityReported(
Cody Kestingf1120be2020-08-03 18:01:40 -070010543 @NonNull ReportedNetworkConnectivityInfo reportedNetworkConnectivityInfo) {
10544 final NetworkAgentInfo nai = reportedNetworkConnectivityInfo.nai;
10545 final ConnectivityReport cachedReport = nai.getConnectivityReport();
10546
10547 // If the Network is being re-validated as a result of this call to
10548 // reportNetworkConnectivity(), notify all permissioned callbacks. Otherwise, only notify
10549 // permissioned callbacks registered by the reporter.
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010550 final List<IConnectivityDiagnosticsCallback> results =
Cody Kestingf1120be2020-08-03 18:01:40 -070010551 getMatchingPermissionedCallbacks(
10552 nai,
10553 reportedNetworkConnectivityInfo.isNetworkRevalidating
10554 ? Process.INVALID_UID
10555 : reportedNetworkConnectivityInfo.reporterUid);
10556
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010557 for (final IConnectivityDiagnosticsCallback cb : results) {
10558 try {
Cody Kestingf1120be2020-08-03 18:01:40 -070010559 cb.onNetworkConnectivityReported(
10560 nai.network, reportedNetworkConnectivityInfo.hasConnectivity);
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010561 } catch (RemoteException ex) {
10562 loge("Error invoking onNetworkConnectivityReported", ex);
10563 }
Cody Kestingf1120be2020-08-03 18:01:40 -070010564
10565 // If the Network isn't re-validating, also provide the cached report. If there is no
10566 // cached report, the Network is still being validated and a report will be sent once
10567 // validation is complete. Note that networks which never undergo validation will still
10568 // have a cached ConnectivityReport with RESULT_SKIPPED.
10569 if (!reportedNetworkConnectivityInfo.isNetworkRevalidating && cachedReport != null) {
10570 try {
10571 cb.onConnectivityReportAvailable(cachedReport);
10572 } catch (RemoteException ex) {
10573 loge("Error invoking onConnectivityReportAvailable", ex);
10574 }
10575 }
Cody Kesting5a9a2ae2020-01-07 11:18:54 -080010576 }
10577 }
10578
Cody Kestingb1cd3eb2020-03-05 22:13:31 -080010579 private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) {
Lorenzo Colitti6424cf22021-05-10 00:49:14 +090010580 final NetworkCapabilities sanitized = new NetworkCapabilities(nc,
10581 NetworkCapabilities.REDACT_ALL);
Cody Kestingb1cd3eb2020-03-05 22:13:31 -080010582 sanitized.setUids(null);
10583 sanitized.setAdministratorUids(new int[0]);
10584 sanitized.setOwnerUid(Process.INVALID_UID);
10585 return sanitized;
Cody Kesting7febafb2020-02-11 10:03:26 -080010586 }
10587
Cody Kestingf1120be2020-08-03 18:01:40 -070010588 /**
10589 * Gets a list of ConnectivityDiagnostics callbacks that match the specified Network and uid.
10590 *
10591 * <p>If Process.INVALID_UID is specified, all matching callbacks will be returned.
10592 */
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010593 private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
Cody Kestingf1120be2020-08-03 18:01:40 -070010594 @NonNull NetworkAgentInfo nai, int uid) {
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010595 final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
Cody Kesting31f1ff62020-03-05 10:46:02 -080010596 for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010597 mConnectivityDiagnosticsCallbacks.entrySet()) {
10598 final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
10599 final NetworkRequestInfo nri = cbInfo.mRequestInfo;
Cody Kestingf1120be2020-08-03 18:01:40 -070010600
James Mattis64b8b0f2020-11-24 17:40:49 -080010601 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0).
Cody Kestingf1120be2020-08-03 18:01:40 -070010602 if (!nai.satisfies(nri.mRequests.get(0))) {
10603 continue;
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010604 }
Cody Kestingf1120be2020-08-03 18:01:40 -070010605
10606 // UID for this callback must either be:
10607 // - INVALID_UID (which sends callbacks to all UIDs), or
10608 // - The callback's owner (the owner called reportNetworkConnectivity() and is being
10609 // notified as a result)
10610 if (uid != Process.INVALID_UID && uid != nri.mUid) {
10611 continue;
10612 }
10613
10614 if (!checkConnectivityDiagnosticsPermissions(
10615 nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
10616 continue;
10617 }
10618
10619 results.add(entry.getValue().mCb);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010620 }
10621 return results;
10622 }
10623
Cody Kesting7474f672021-05-11 14:22:40 -070010624 private boolean isLocationPermissionRequiredForConnectivityDiagnostics(
10625 @NonNull NetworkAgentInfo nai) {
10626 // TODO(b/188483916): replace with a transport-agnostic location-aware check
10627 return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI);
10628 }
10629
Cody Kesting160ef392021-05-05 13:17:22 -070010630 private boolean hasLocationPermission(String packageName, int uid) {
10631 // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
10632 // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
10633 // call in a try-catch.
10634 try {
10635 if (!mLocationPermissionChecker.checkLocationPermission(
10636 packageName, null /* featureId */, uid, null /* message */)) {
10637 return false;
10638 }
10639 } catch (SecurityException e) {
10640 return false;
10641 }
10642
10643 return true;
10644 }
10645
10646 private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
10647 for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
Lorenzo Colittibd079452021-07-02 11:47:57 +090010648 if (virtual.propagateUnderlyingCapabilities()
Cody Kesting160ef392021-05-05 13:17:22 -070010649 && virtual.networkCapabilities.getOwnerUid() == uid
10650 && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) {
10651 return true;
10652 }
10653 }
10654
10655 return false;
10656 }
10657
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010658 @VisibleForTesting
10659 boolean checkConnectivityDiagnosticsPermissions(
10660 int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
10661 if (checkNetworkStackPermission(callbackPid, callbackUid)) {
10662 return true;
10663 }
10664
Cody Kesting160ef392021-05-05 13:17:22 -070010665 // Administrator UIDs also contains the Owner UID
10666 final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
10667 if (!CollectionUtils.contains(administratorUids, callbackUid)
10668 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010669 return false;
10670 }
10671
Cody Kesting7474f672021-05-11 14:22:40 -070010672 return !isLocationPermissionRequiredForConnectivityDiagnostics(nai)
10673 || hasLocationPermission(callbackPackageName, callbackUid);
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010674 }
10675
Cody Kestingd199a9d2019-12-17 12:55:28 -080010676 @Override
10677 public void registerConnectivityDiagnosticsCallback(
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010678 @NonNull IConnectivityDiagnosticsCallback callback,
10679 @NonNull NetworkRequest request,
10680 @NonNull String callingPackageName) {
Benedict Wong30d3ba02021-07-08 23:45:39 -070010681 Objects.requireNonNull(callback, "callback must not be null");
10682 Objects.requireNonNull(request, "request must not be null");
10683 Objects.requireNonNull(callingPackageName, "callingPackageName must not be null");
10684
Cody Kesting73708bf2019-12-18 10:57:50 -080010685 if (request.legacyType != TYPE_NONE) {
10686 throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
10687 + " Please use NetworkCapabilities instead.");
10688 }
Lorenzo Colittif61ca942020-12-15 11:02:22 +090010689 final int callingUid = mDeps.getCallingUid();
Roshan Pius08c94fb2020-01-16 12:17:17 -080010690 mAppOpsManager.checkPackage(callingUid, callingPackageName);
Cody Kesting73708bf2019-12-18 10:57:50 -080010691
10692 // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
10693 // and administrator uids to be safe.
10694 final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
Roshan Pius08c94fb2020-01-16 12:17:17 -080010695 restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName);
Cody Kesting73708bf2019-12-18 10:57:50 -080010696
10697 final NetworkRequest requestWithId =
10698 new NetworkRequest(
10699 nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN);
10700
10701 // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit.
10702 //
10703 // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
10704 // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
10705 // callback's binder death.
Lorenzo Colitti3e367f42021-03-12 22:50:57 +090010706 final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId);
Cody Kesting73708bf2019-12-18 10:57:50 -080010707 final ConnectivityDiagnosticsCallbackInfo cbInfo =
Cody Kesting83bb5fa2020-01-05 14:06:39 -080010708 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
Cody Kesting73708bf2019-12-18 10:57:50 -080010709
10710 mConnectivityDiagnosticsHandler.sendMessage(
10711 mConnectivityDiagnosticsHandler.obtainMessage(
10712 ConnectivityDiagnosticsHandler
10713 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
10714 cbInfo));
Cody Kestingd199a9d2019-12-17 12:55:28 -080010715 }
10716
10717 @Override
10718 public void unregisterConnectivityDiagnosticsCallback(
10719 @NonNull IConnectivityDiagnosticsCallback callback) {
Aaron Huangc65e7fa2021-04-09 12:06:42 +080010720 Objects.requireNonNull(callback, "callback must be non-null");
Cody Kesting73708bf2019-12-18 10:57:50 -080010721 mConnectivityDiagnosticsHandler.sendMessage(
10722 mConnectivityDiagnosticsHandler.obtainMessage(
10723 ConnectivityDiagnosticsHandler
10724 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
Lorenzo Colittif61ca942020-12-15 11:02:22 +090010725 mDeps.getCallingUid(),
Cody Kesting73708bf2019-12-18 10:57:50 -080010726 0,
10727 callback));
Cody Kestingd199a9d2019-12-17 12:55:28 -080010728 }
Cody Kestingf53a0752020-04-15 12:33:28 -070010729
Yan Yanfe96dde2022-12-05 23:00:01 +000010730 private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) {
10731 final List<Network> underlyingNetworks = nc.getUnderlyingNetworks();
10732 if (underlyingNetworks == null) return false;
10733
10734 for (Network network : underlyingNetworks) {
10735 if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) {
10736 return true;
10737 }
10738 }
10739 return false;
10740 }
10741
Cody Kestingf53a0752020-04-15 12:33:28 -070010742 @Override
10743 public void simulateDataStall(int detectionMethod, long timestampMillis,
10744 @NonNull Network network, @NonNull PersistableBundle extras) {
Benedict Wong30d3ba02021-07-08 23:45:39 -070010745 Objects.requireNonNull(network, "network must not be null");
10746 Objects.requireNonNull(extras, "extras must not be null");
10747
paulhu3ffffe72021-09-16 10:15:22 +080010748 enforceAnyPermissionOf(mContext,
10749 android.Manifest.permission.MANAGE_TEST_NETWORKS,
Cody Kestingf53a0752020-04-15 12:33:28 -070010750 android.Manifest.permission.NETWORK_STACK);
10751 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
Yan Yanfe96dde2022-12-05 23:00:01 +000010752 if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) {
10753 throw new SecurityException(
10754 "Data Stall simulation is only possible for test networks or networks built on"
10755 + " top of test networks");
Cody Kestingf53a0752020-04-15 12:33:28 -070010756 }
10757
10758 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
Yan Yanfe96dde2022-12-05 23:00:01 +000010759 if (nai == null
10760 || (nai.creatorUid != mDeps.getCallingUid()
10761 && nai.creatorUid != Process.SYSTEM_UID)) {
10762 throw new SecurityException(
10763 "Data Stall simulation is only possible for network " + "creators");
Cody Kestingf53a0752020-04-15 12:33:28 -070010764 }
10765
Cody Kesting652e3ec2020-05-21 12:08:21 -070010766 // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
10767 // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
10768 // Data Stall information as a DataStallReportParcelable and passing to
10769 // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
10770 // still passed to ConnectivityDiagnostics (with new detection methods masked).
Cody Kestingb37958e2020-05-15 10:36:01 -070010771 final DataStallReportParcelable p = new DataStallReportParcelable();
10772 p.timestampMillis = timestampMillis;
10773 p.detectionMethod = detectionMethod;
10774
10775 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
10776 p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
10777 }
10778 if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
10779 p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
10780 p.tcpMetricsCollectionPeriodMillis = extras.getInt(
10781 KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
10782 }
10783
Serik Beketayevec8ad212020-12-07 22:43:07 -080010784 notifyDataStallSuspected(p, network.getNetId());
Cody Kestingf53a0752020-04-15 12:33:28 -070010785 }
lucaslin1a8b4c62021-01-21 02:02:55 +080010786
lucaslin66f44212021-02-23 01:12:55 +080010787 private class NetdCallback extends BaseNetdUnsolicitedEventListener {
10788 @Override
lucaslin87b58aa2021-02-25 15:10:29 +080010789 public void onInterfaceClassActivityChanged(boolean isActive, int transportType,
lucaslin66f44212021-02-23 01:12:55 +080010790 long timestampNs, int uid) {
lucaslin87b58aa2021-02-25 15:10:29 +080010791 mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs);
lucaslin66f44212021-02-23 01:12:55 +080010792 }
lucaslin37a16d92021-01-21 19:48:09 +080010793
10794 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +090010795 public void onInterfaceLinkStateChanged(@NonNull String iface, boolean up) {
lucaslin87b58aa2021-02-25 15:10:29 +080010796 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
lucaslin37a16d92021-01-21 19:48:09 +080010797 nai.clatd.interfaceLinkStateChanged(iface, up);
10798 }
10799 }
10800
10801 @Override
Chalard Jean46bfbf02022-02-02 00:56:25 +090010802 public void onInterfaceRemoved(@NonNull String iface) {
lucaslin87b58aa2021-02-25 15:10:29 +080010803 for (NetworkAgentInfo nai : mNetworkAgentInfos) {
lucaslin37a16d92021-01-21 19:48:09 +080010804 nai.clatd.interfaceRemoved(iface);
10805 }
lucaslin66f44212021-02-23 01:12:55 +080010806 }
10807 }
10808
lucaslin1a8b4c62021-01-21 02:02:55 +080010809 private final LegacyNetworkActivityTracker mNetworkActivityTracker;
10810
10811 /**
10812 * Class used for updating network activity tracking with netd and notify network activity
10813 * changes.
10814 */
10815 private static final class LegacyNetworkActivityTracker {
lucaslinb961efc2021-01-21 02:03:17 +080010816 private static final int NO_UID = -1;
lucaslin1a8b4c62021-01-21 02:02:55 +080010817 private final Context mContext;
lucaslin1193a5d2021-01-21 02:04:15 +080010818 private final INetd mNetd;
lucaslin1193a5d2021-01-21 02:04:15 +080010819 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
10820 new RemoteCallbackList<>();
10821 // Indicate the current system default network activity is active or not.
10822 @GuardedBy("mActiveIdleTimers")
10823 private boolean mNetworkActive;
10824 @GuardedBy("mActiveIdleTimers")
Chalard Jean46bfbf02022-02-02 00:56:25 +090010825 private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap<>();
lucaslin1193a5d2021-01-21 02:04:15 +080010826 private final Handler mHandler;
lucaslin1a8b4c62021-01-21 02:02:55 +080010827
Chalard Jean46bfbf02022-02-02 00:56:25 +090010828 private static class IdleTimerParams {
lucaslin1193a5d2021-01-21 02:04:15 +080010829 public final int timeout;
10830 public final int transportType;
10831
10832 IdleTimerParams(int timeout, int transport) {
10833 this.timeout = timeout;
10834 this.transportType = transport;
10835 }
10836 }
10837
10838 LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
lucaslind5c2d072021-02-20 18:59:47 +080010839 @NonNull INetd netd) {
lucaslin1a8b4c62021-01-21 02:02:55 +080010840 mContext = context;
lucaslin1193a5d2021-01-21 02:04:15 +080010841 mNetd = netd;
10842 mHandler = handler;
lucaslin1a8b4c62021-01-21 02:02:55 +080010843 }
10844
lucaslin66f44212021-02-23 01:12:55 +080010845 public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) {
10846 sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos);
10847 synchronized (mActiveIdleTimers) {
10848 mNetworkActive = active;
10849 // If there are no idle timers, it means that system is not monitoring
10850 // activity, so the system default network for those default network
10851 // unspecified apps is always considered active.
10852 //
10853 // TODO: If the mActiveIdleTimers is empty, netd will actually not send
10854 // any network activity change event. Whenever this event is received,
10855 // the mActiveIdleTimers should be always not empty. The legacy behavior
10856 // is no-op. Remove to refer to mNetworkActive only.
10857 if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
10858 mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
10859 }
10860 }
10861 }
lucaslin1a8b4c62021-01-21 02:02:55 +080010862
lucaslin1193a5d2021-01-21 02:04:15 +080010863 // The network activity should only be updated from ConnectivityService handler thread
10864 // when mActiveIdleTimers lock is held.
10865 @GuardedBy("mActiveIdleTimers")
10866 private void reportNetworkActive() {
10867 final int length = mNetworkActivityListeners.beginBroadcast();
10868 if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
10869 try {
10870 for (int i = 0; i < length; i++) {
10871 try {
10872 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
10873 } catch (RemoteException | RuntimeException e) {
Chalard Jean46bfbf02022-02-02 00:56:25 +090010874 loge("Fail to send network activity to listener " + e);
lucaslin1193a5d2021-01-21 02:04:15 +080010875 }
10876 }
10877 } finally {
10878 mNetworkActivityListeners.finishBroadcast();
10879 }
10880 }
10881
10882 @GuardedBy("mActiveIdleTimers")
10883 public void handleReportNetworkActivity() {
10884 synchronized (mActiveIdleTimers) {
10885 reportNetworkActive();
10886 }
10887 }
10888
lucaslin1a8b4c62021-01-21 02:02:55 +080010889 // This is deprecated and only to support legacy use cases.
10890 private int transportTypeToLegacyType(int type) {
10891 switch (type) {
10892 case NetworkCapabilities.TRANSPORT_CELLULAR:
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090010893 return TYPE_MOBILE;
lucaslin1a8b4c62021-01-21 02:02:55 +080010894 case NetworkCapabilities.TRANSPORT_WIFI:
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090010895 return TYPE_WIFI;
lucaslin1a8b4c62021-01-21 02:02:55 +080010896 case NetworkCapabilities.TRANSPORT_BLUETOOTH:
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090010897 return TYPE_BLUETOOTH;
lucaslin1a8b4c62021-01-21 02:02:55 +080010898 case NetworkCapabilities.TRANSPORT_ETHERNET:
Remi NGUYEN VAN5a42a5f2021-03-09 13:35:25 +090010899 return TYPE_ETHERNET;
lucaslin1a8b4c62021-01-21 02:02:55 +080010900 default:
10901 loge("Unexpected transport in transportTypeToLegacyType: " + type);
10902 }
10903 return ConnectivityManager.TYPE_NONE;
10904 }
10905
10906 public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
10907 final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
10908 intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
10909 intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
10910 intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
10911 final long ident = Binder.clearCallingIdentity();
10912 try {
10913 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
10914 RECEIVE_DATA_ACTIVITY_CHANGE,
10915 null /* resultReceiver */,
10916 null /* scheduler */,
10917 0 /* initialCode */,
10918 null /* initialData */,
10919 null /* initialExtra */);
10920 } finally {
10921 Binder.restoreCallingIdentity(ident);
10922 }
10923 }
10924
10925 /**
10926 * Setup data activity tracking for the given network.
10927 *
10928 * Every {@code setupDataActivityTracking} should be paired with a
10929 * {@link #removeDataActivityTracking} for cleanup.
10930 */
10931 private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
10932 final String iface = networkAgent.linkProperties.getInterfaceName();
10933
10934 final int timeout;
10935 final int type;
10936
10937 if (networkAgent.networkCapabilities.hasTransport(
10938 NetworkCapabilities.TRANSPORT_CELLULAR)) {
10939 timeout = Settings.Global.getInt(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +080010940 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE,
lucaslin1a8b4c62021-01-21 02:02:55 +080010941 10);
10942 type = NetworkCapabilities.TRANSPORT_CELLULAR;
10943 } else if (networkAgent.networkCapabilities.hasTransport(
10944 NetworkCapabilities.TRANSPORT_WIFI)) {
10945 timeout = Settings.Global.getInt(mContext.getContentResolver(),
paulhu56e09df2021-03-17 20:30:33 +080010946 ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI,
lucaslin1a8b4c62021-01-21 02:02:55 +080010947 15);
10948 type = NetworkCapabilities.TRANSPORT_WIFI;
10949 } else {
10950 return; // do not track any other networks
10951 }
10952
lucaslinb961efc2021-01-21 02:03:17 +080010953 updateRadioPowerState(true /* isActive */, type);
10954
lucaslin1a8b4c62021-01-21 02:02:55 +080010955 if (timeout > 0 && iface != null) {
10956 try {
lucaslin1193a5d2021-01-21 02:04:15 +080010957 synchronized (mActiveIdleTimers) {
10958 // Networks start up.
10959 mNetworkActive = true;
10960 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
10961 mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
10962 reportNetworkActive();
10963 }
lucaslin1a8b4c62021-01-21 02:02:55 +080010964 } catch (Exception e) {
10965 // You shall not crash!
10966 loge("Exception in setupDataActivityTracking " + e);
10967 }
10968 }
10969 }
10970
10971 /**
10972 * Remove data activity tracking when network disconnects.
10973 */
10974 private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
10975 final String iface = networkAgent.linkProperties.getInterfaceName();
10976 final NetworkCapabilities caps = networkAgent.networkCapabilities;
10977
lucaslinb961efc2021-01-21 02:03:17 +080010978 if (iface == null) return;
10979
10980 final int type;
10981 if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
10982 type = NetworkCapabilities.TRANSPORT_CELLULAR;
10983 } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
10984 type = NetworkCapabilities.TRANSPORT_WIFI;
10985 } else {
10986 return; // do not track any other networks
10987 }
10988
10989 try {
10990 updateRadioPowerState(false /* isActive */, type);
lucaslin1193a5d2021-01-21 02:04:15 +080010991 synchronized (mActiveIdleTimers) {
10992 final IdleTimerParams params = mActiveIdleTimers.remove(iface);
10993 // The call fails silently if no idle timer setup for this interface
10994 mNetd.idletimerRemoveInterface(iface, params.timeout,
10995 Integer.toString(params.transportType));
lucaslin1a8b4c62021-01-21 02:02:55 +080010996 }
lucaslinb961efc2021-01-21 02:03:17 +080010997 } catch (Exception e) {
10998 // You shall not crash!
10999 loge("Exception in removeDataActivityTracking " + e);
lucaslin1a8b4c62021-01-21 02:02:55 +080011000 }
11001 }
11002
11003 /**
11004 * Update data activity tracking when network state is updated.
11005 */
11006 public void updateDataActivityTracking(NetworkAgentInfo newNetwork,
11007 NetworkAgentInfo oldNetwork) {
11008 if (newNetwork != null) {
11009 setupDataActivityTracking(newNetwork);
11010 }
11011 if (oldNetwork != null) {
11012 removeDataActivityTracking(oldNetwork);
11013 }
11014 }
lucaslinb961efc2021-01-21 02:03:17 +080011015
11016 private void updateRadioPowerState(boolean isActive, int transportType) {
11017 final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
11018 switch (transportType) {
11019 case NetworkCapabilities.TRANSPORT_CELLULAR:
11020 bs.reportMobileRadioPowerState(isActive, NO_UID);
11021 break;
11022 case NetworkCapabilities.TRANSPORT_WIFI:
11023 bs.reportWifiRadioPowerState(isActive, NO_UID);
11024 break;
11025 default:
11026 logw("Untracked transport type:" + transportType);
11027 }
11028 }
lucaslin1193a5d2021-01-21 02:04:15 +080011029
11030 public boolean isDefaultNetworkActive() {
11031 synchronized (mActiveIdleTimers) {
11032 // If there are no idle timers, it means that system is not monitoring activity,
11033 // so the default network is always considered active.
11034 //
11035 // TODO : Distinguish between the cases where mActiveIdleTimers is empty because
11036 // tracking is disabled (negative idle timer value configured), or no active default
11037 // network. In the latter case, this reports active but it should report inactive.
11038 return mNetworkActive || mActiveIdleTimers.isEmpty();
11039 }
11040 }
11041
11042 public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
11043 mNetworkActivityListeners.register(l);
11044 }
11045
11046 public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
11047 mNetworkActivityListeners.unregister(l);
11048 }
lucaslin012f7a12021-01-21 02:04:35 +080011049
11050 public void dump(IndentingPrintWriter pw) {
11051 synchronized (mActiveIdleTimers) {
11052 pw.print("mNetworkActive="); pw.println(mNetworkActive);
11053 pw.println("Idle timers:");
11054 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
11055 pw.print(" "); pw.print(ent.getKey()); pw.println(":");
11056 final IdleTimerParams params = ent.getValue();
11057 pw.print(" timeout="); pw.print(params.timeout);
11058 pw.print(" type="); pw.println(params.transportType);
11059 }
11060 }
11061 }
lucaslin1a8b4c62021-01-21 02:02:55 +080011062 }
James Mattis47db0582021-01-01 14:13:35 -080011063
Daniel Brightf9e945b2020-06-15 16:10:01 -070011064 /**
11065 * Registers {@link QosSocketFilter} with {@link IQosCallback}.
11066 *
11067 * @param socketInfo the socket information
11068 * @param callback the callback to register
11069 */
11070 @Override
11071 public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo,
11072 @NonNull final IQosCallback callback) {
11073 final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork());
11074 if (nai == null || nai.networkCapabilities == null) {
11075 try {
11076 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
11077 } catch (final RemoteException ex) {
11078 loge("registerQosCallbackInternal: RemoteException", ex);
11079 }
11080 return;
11081 }
11082 registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai);
11083 }
11084
11085 /**
11086 * Register a {@link IQosCallback} with base {@link QosFilter}.
11087 *
11088 * @param filter the filter to register
11089 * @param callback the callback to register
11090 * @param nai the agent information related to the filter's network
11091 */
11092 @VisibleForTesting
11093 public void registerQosCallbackInternal(@NonNull final QosFilter filter,
11094 @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) {
Chalard Jean46bfbf02022-02-02 00:56:25 +090011095 Objects.requireNonNull(filter, "filter must be non-null");
11096 Objects.requireNonNull(callback, "callback must be non-null");
Daniel Brightf9e945b2020-06-15 16:10:01 -070011097
11098 if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
Paul Hu8fc2a552022-05-04 18:44:42 +080011099 // TODO: Check allowed list here and ensure that either a) any QoS callback registered
11100 // on this network is unregistered when the app loses permission or b) no QoS
11101 // callbacks are sent for restricted networks unless the app currently has permission
11102 // to access restricted networks.
11103 enforceConnectivityRestrictedNetworksPermission(false /* checkUidsAllowedList */);
Daniel Brightf9e945b2020-06-15 16:10:01 -070011104 }
11105 mQosCallbackTracker.registerCallback(callback, filter, nai);
11106 }
11107
11108 /**
11109 * Unregisters the given callback.
11110 *
11111 * @param callback the callback to unregister
11112 */
11113 @Override
11114 public void unregisterQosCallback(@NonNull final IQosCallback callback) {
Aaron Huangc65e7fa2021-04-09 12:06:42 +080011115 Objects.requireNonNull(callback, "callback must be non-null");
Daniel Brightf9e945b2020-06-15 16:10:01 -070011116 mQosCallbackTracker.unregisterCallback(callback);
11117 }
James Mattis47db0582021-01-01 14:13:35 -080011118
Sooraj Sasindranbb65aa82022-04-20 21:16:02 -070011119 private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) {
11120 // UserManager.isManagedProfile returns true for all apps in managed user profiles.
11121 // Enterprise device can be fully managed like device owner and such use case
11122 // also should be supported. Calling app check for work profile and fully managed device
11123 // is already done in DevicePolicyManager.
11124 // This check is an extra caution to be sure device is fully managed or not.
11125 final UserManager um = mContext.getSystemService(UserManager.class);
11126 final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
11127 if (um.isManagedProfile(profile.getIdentifier())) {
11128 return true;
11129 }
11130 if (SdkLevel.isAtLeastT() && dpm.getDeviceOwner() != null) return true;
11131 return false;
11132 }
11133
James Mattis45d81842021-01-10 14:24:24 -080011134 /**
Sooraj Sasindranbb65aa82022-04-20 21:16:02 -070011135 * Set a list of default network selection policies for a user profile or device owner.
Chalard Jeanfa45a682021-02-25 17:23:40 +090011136 *
11137 * See the documentation for the individual preferences for a description of the supported
11138 * behaviors.
11139 *
Sooraj Sasindranbb65aa82022-04-20 21:16:02 -070011140 * @param profile If the device owner is set, any profile is allowed.
11141 Otherwise, the given profile can only be managed profile.
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011142 * @param preferences the list of profile network preferences for the
11143 * provided profile.
Chalard Jeanfa45a682021-02-25 17:23:40 +090011144 * @param listener an optional listener to listen for completion of the operation.
11145 */
11146 @Override
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011147 public void setProfileNetworkPreferences(
11148 @NonNull final UserHandle profile,
11149 @NonNull List<ProfileNetworkPreference> preferences,
Chalard Jeanfa45a682021-02-25 17:23:40 +090011150 @Nullable final IOnCompleteListener listener) {
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011151 Objects.requireNonNull(preferences);
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011152 Objects.requireNonNull(profile);
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011153
11154 if (preferences.size() == 0) {
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011155 final ProfileNetworkPreference pref = new ProfileNetworkPreference.Builder()
11156 .setPreference(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT)
11157 .build();
11158 preferences.add(pref);
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011159 }
11160
paulhu3ffffe72021-09-16 10:15:22 +080011161 enforceNetworkStackPermission(mContext);
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011162 if (DBG) {
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011163 log("setProfileNetworkPreferences " + profile + " to " + preferences);
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011164 }
11165 if (profile.getIdentifier() < 0) {
11166 throw new IllegalArgumentException("Must explicitly specify a user handle ("
11167 + "UserHandle.CURRENT not supported)");
11168 }
Sooraj Sasindranbb65aa82022-04-20 21:16:02 -070011169 if (!isNetworkPreferenceAllowedForProfile(profile)) {
11170 throw new IllegalArgumentException("Profile must be a managed profile "
11171 + "or the device owner must be set. ");
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011172 }
paulhuaa0743d2021-05-26 21:56:03 +080011173
Chalard Jean0606fc82022-12-14 20:34:43 +090011174 final List<ProfileNetworkPreferenceInfo> preferenceList = new ArrayList<>();
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011175 boolean hasDefaultPreference = false;
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011176 for (final ProfileNetworkPreference preference : preferences) {
11177 final NetworkCapabilities nc;
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011178 boolean allowFallback = true;
Junyu Lai35665cc2022-12-19 17:37:48 +080011179 boolean blockingNonEnterprise = false;
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011180 switch (preference.getPreference()) {
11181 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT:
11182 nc = null;
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011183 hasDefaultPreference = true;
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080011184 if (preference.getPreferenceEnterpriseId() != 0) {
11185 throw new IllegalArgumentException(
11186 "Invalid enterprise identifier in setProfileNetworkPreferences");
11187 }
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011188 break;
Junyu Lai35665cc2022-12-19 17:37:48 +080011189 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING:
11190 blockingNonEnterprise = true;
11191 // continue to process the enterprise preference.
Sooraj Sasindran06baf4c2021-11-29 12:21:09 -080011192 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK:
11193 allowFallback = false;
11194 // continue to process the enterprise preference.
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011195 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE:
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011196 // This code is needed even though there is a check later on,
11197 // because isRangeAlreadyInPreferenceList assumes that every preference
11198 // has a UID list.
11199 if (hasDefaultPreference) {
11200 throw new IllegalArgumentException(
11201 "Default profile preference should not be set along with other "
11202 + "preference");
11203 }
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080011204 if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) {
11205 throw new IllegalArgumentException(
11206 "Invalid enterprise identifier in setProfileNetworkPreferences");
11207 }
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011208 final Set<UidRange> uidRangeSet =
11209 getUidListToBeAppliedForNetworkPreference(profile, preference);
11210 if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) {
11211 nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet);
11212 } else {
11213 throw new IllegalArgumentException(
11214 "Overlapping uid range in setProfileNetworkPreferences");
11215 }
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011216 nc.addCapability(NET_CAPABILITY_ENTERPRISE);
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080011217 nc.addEnterpriseId(
11218 preference.getPreferenceEnterpriseId());
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011219 nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
11220 break;
11221 default:
11222 throw new IllegalArgumentException(
11223 "Invalid preference in setProfileNetworkPreferences");
11224 }
Junyu Lai35665cc2022-12-19 17:37:48 +080011225 preferenceList.add(new ProfileNetworkPreferenceInfo(
11226 profile, nc, allowFallback, blockingNonEnterprise));
Sooraj Sasindranb0e283c2022-05-09 20:37:31 -070011227 if (hasDefaultPreference && preferenceList.size() > 1) {
11228 throw new IllegalArgumentException(
11229 "Default profile preference should not be set along with other preference");
11230 }
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011231 }
11232 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE,
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011233 new Pair<>(preferenceList, listener)));
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011234 }
11235
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011236 private Set<UidRange> getUidListToBeAppliedForNetworkPreference(
11237 @NonNull final UserHandle profile,
11238 @NonNull final ProfileNetworkPreference profileNetworkPreference) {
11239 final UidRange profileUids = UidRange.createForUser(profile);
Sooraj Sasindran49041762022-03-09 21:59:00 -080011240 Set<UidRange> uidRangeSet = UidRangeUtils.convertArrayToUidRange(
11241 profileNetworkPreference.getIncludedUids());
11242
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011243 if (uidRangeSet.size() > 0) {
11244 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) {
11245 throw new IllegalArgumentException(
11246 "Allow uid range is outside the uid range of profile.");
11247 }
11248 } else {
Sooraj Sasindran49041762022-03-09 21:59:00 -080011249 ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertArrayToUidRange(
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011250 profileNetworkPreference.getExcludedUids());
11251 if (disallowUidRangeSet.size() > 0) {
11252 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) {
11253 throw new IllegalArgumentException(
11254 "disallow uid range is outside the uid range of profile.");
11255 }
11256 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids,
11257 disallowUidRangeSet);
11258 } else {
Chalard Jean46bfbf02022-02-02 00:56:25 +090011259 uidRangeSet = new ArraySet<>();
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011260 uidRangeSet.add(profileUids);
11261 }
11262 }
11263 return uidRangeSet;
11264 }
11265
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080011266 private boolean isEnterpriseIdentifierValid(
11267 @NetworkCapabilities.EnterpriseId int identifier) {
Chalard Jean46bfbf02022-02-02 00:56:25 +090011268 if ((identifier >= NET_ENTERPRISE_ID_1) && (identifier <= NET_ENTERPRISE_ID_5)) {
Sooraj Sasindranf4a58dc2022-01-21 13:37:08 -080011269 return true;
11270 }
11271 return false;
11272 }
11273
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011274 private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences(
Chalard Jean0606fc82022-12-14 20:34:43 +090011275 @NonNull final NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> prefs) {
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011276 final ArraySet<NetworkRequestInfo> result = new ArraySet<>();
Chalard Jean0606fc82022-12-14 20:34:43 +090011277 for (final ProfileNetworkPreferenceInfo pref : prefs) {
Sooraj Sasindran06baf4c2021-11-29 12:21:09 -080011278 // The NRI for a user should contain the request for capabilities.
11279 // If fallback to default network is needed then NRI should include
11280 // the request for the default network. Create an image of it to
11281 // have the correct UIDs in it (also a request can only be part of one NRI, because
11282 // of lookups in 1:1 associations like mNetworkRequests).
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011283 final ArrayList<NetworkRequest> nrs = new ArrayList<>();
11284 nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
Sooraj Sasindran06baf4c2021-11-29 12:21:09 -080011285 if (pref.allowFallback) {
11286 nrs.add(createDefaultInternetRequestForTransport(
11287 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
11288 }
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011289 if (VDBG) {
11290 loge("pref.capabilities.getUids():" + UidRange.fromIntRanges(
11291 pref.capabilities.getUids()));
11292 }
11293
Chiachang Wang8156c4e2021-03-19 00:45:39 +000011294 setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
paulhue9913722021-05-26 15:19:20 +080011295 final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs,
paulhu48291862021-07-14 14:53:57 +080011296 PREFERENCE_ORDER_PROFILE);
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011297 result.add(nri);
11298 }
11299 return result;
11300 }
11301
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011302 /**
11303 * Compare if the given UID range sets have the same UIDs.
11304 *
11305 */
11306 private boolean isRangeAlreadyInPreferenceList(
Chalard Jean0606fc82022-12-14 20:34:43 +090011307 @NonNull List<ProfileNetworkPreferenceInfo> preferenceList,
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011308 @NonNull Set<UidRange> uidRangeSet) {
11309 if (uidRangeSet.size() == 0 || preferenceList.size() == 0) {
11310 return false;
11311 }
Chalard Jean0606fc82022-12-14 20:34:43 +090011312 for (ProfileNetworkPreferenceInfo pref : preferenceList) {
Sooraj Sasindran499117f2021-11-29 12:40:09 -080011313 if (UidRangeUtils.doesRangeSetOverlap(
11314 UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) {
11315 return true;
11316 }
11317 }
11318 return false;
11319 }
11320
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011321 private void handleSetProfileNetworkPreference(
Chalard Jean0606fc82022-12-14 20:34:43 +090011322 @NonNull final List<ProfileNetworkPreferenceInfo> preferenceList,
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011323 @Nullable final IOnCompleteListener listener) {
Sooraj Sasindran9cc129f2022-04-22 00:57:41 -070011324 /*
11325 * handleSetProfileNetworkPreference is always called for single user.
11326 * preferenceList only contains preferences for different uids within the same user
11327 * (enforced by getUidListToBeAppliedForNetworkPreference).
11328 * Clear all the existing preferences for the user before applying new preferences.
11329 *
11330 */
Chalard Jean0606fc82022-12-14 20:34:43 +090011331 mProfileNetworkPreferences = mProfileNetworkPreferences.minus(preferenceList.get(0).user);
11332 for (final ProfileNetworkPreferenceInfo preference : preferenceList) {
Sooraj Sasindrane7aee272021-11-24 20:26:55 -080011333 mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference);
11334 }
Sooraj Sasindran9cc129f2022-04-22 00:57:41 -070011335
paulhu74128522021-09-28 02:29:03 +000011336 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_PROFILE);
11337 addPerAppDefaultNetworkRequests(
11338 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences));
Junyu Lai35665cc2022-12-19 17:37:48 +080011339 updateProfileAllowedNetworks();
Junyu Lai31d38bf2022-07-04 17:28:39 +080011340
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011341 // Finally, rematch.
11342 rematchAllNetworksAndRequests();
11343
11344 if (null != listener) {
11345 try {
11346 listener.onComplete();
11347 } catch (RemoteException e) {
11348 loge("Listener for setProfileNetworkPreference has died");
11349 }
11350 }
11351 }
11352
paulhu51f77dc2021-06-07 02:34:20 +000011353 @VisibleForTesting
11354 @NonNull
11355 ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids(
11356 @NonNull final Set<Integer> uids) {
11357 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
11358 if (uids.size() == 0) {
11359 // Should not create NetworkRequestInfo if no preferences. Without uid range in
11360 // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI.
11361 if (DBG) log("Don't create NetworkRequestInfo because no preferences");
11362 return nris;
11363 }
11364
11365 final List<NetworkRequest> requests = new ArrayList<>();
11366 // The NRI should be comprised of two layers:
11367 // - The request for the mobile network preferred.
11368 // - The request for the default network, for fallback.
11369 requests.add(createDefaultInternetRequestForTransport(
Ansik605e7702021-06-29 19:06:37 +090011370 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST));
paulhu51f77dc2021-06-07 02:34:20 +000011371 requests.add(createDefaultInternetRequestForTransport(
11372 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
11373 final Set<UidRange> ranges = new ArraySet<>();
11374 for (final int uid : uids) {
11375 ranges.add(new UidRange(uid, uid));
11376 }
11377 setNetworkRequestUids(requests, ranges);
paulhue9913722021-05-26 15:19:20 +080011378 nris.add(new NetworkRequestInfo(Process.myUid(), requests,
paulhu48291862021-07-14 14:53:57 +080011379 PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED));
paulhu51f77dc2021-06-07 02:34:20 +000011380 return nris;
11381 }
11382
11383 private void handleMobileDataPreferredUidsChanged() {
paulhu51f77dc2021-06-07 02:34:20 +000011384 mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext);
paulhu74128522021-09-28 02:29:03 +000011385 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
11386 addPerAppDefaultNetworkRequests(
11387 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids));
paulhu51f77dc2021-06-07 02:34:20 +000011388 // Finally, rematch.
11389 rematchAllNetworksAndRequests();
11390 }
11391
Patrick Rohr2857ac42022-01-21 14:58:16 +010011392 private void handleIngressRateLimitChanged() {
11393 final long oldIngressRateLimit = mIngressRateLimit;
11394 mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(
11395 mContext);
11396 for (final NetworkAgentInfo networkAgent : mNetworkAgentInfos) {
11397 if (canNetworkBeRateLimited(networkAgent)) {
11398 // If rate limit has previously been enabled, remove the old limit first.
11399 if (oldIngressRateLimit >= 0) {
11400 mDeps.disableIngressRateLimit(networkAgent.linkProperties.getInterfaceName());
11401 }
11402 if (mIngressRateLimit >= 0) {
11403 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(),
11404 mIngressRateLimit);
11405 }
11406 }
11407 }
11408 }
11409
11410 private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) {
Lorenzo Colittif79dcec2022-03-07 17:48:54 +090011411 // Rate-limiting cannot run correctly before T because the BPF program is not loaded.
11412 if (!SdkLevel.isAtLeastT()) return false;
11413
Patrick Rohrff3b3f82022-02-09 15:15:52 +010011414 final NetworkCapabilities agentCaps = networkAgent.networkCapabilities;
11415 // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide
11416 // internet connectivity can be rate limited.
11417 if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport(
11418 TRANSPORT_TEST)) {
Patrick Rohr2857ac42022-01-21 14:58:16 +010011419 return false;
11420 }
11421
11422 final String iface = networkAgent.linkProperties.getInterfaceName();
11423 if (iface == null) {
Patrick Rohra517f202022-02-15 11:58:41 +010011424 // This may happen in tests, but if there is no interface then there is nothing that
11425 // can be rate limited.
11426 loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null");
Patrick Rohr2857ac42022-01-21 14:58:16 +010011427 return false;
11428 }
11429 return true;
11430 }
11431
James Mattis45d81842021-01-10 14:24:24 -080011432 private void enforceAutomotiveDevice() {
James Mattis4ab1ffc2021-12-26 12:56:52 -080011433 PermissionUtils.enforceSystemFeature(mContext, PackageManager.FEATURE_AUTOMOTIVE,
11434 "setOemNetworkPreference() is only available on automotive devices.");
James Mattis45d81842021-01-10 14:24:24 -080011435 }
11436
11437 /**
11438 * Used by automotive devices to set the network preferences used to direct traffic at an
11439 * application level as per the given OemNetworkPreferences. An example use-case would be an
11440 * automotive OEM wanting to provide connectivity for applications critical to the usage of a
11441 * vehicle via a particular network.
11442 *
11443 * Calling this will overwrite the existing preference.
11444 *
James Mattisda32cfe2021-01-26 16:23:52 -080011445 * @param preference {@link OemNetworkPreferences} The application network preference to be set.
Chalard Jean6010c002021-03-03 16:37:13 +090011446 * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used
James Mattis45d81842021-01-10 14:24:24 -080011447 * to communicate completion of setOemNetworkPreference();
James Mattis45d81842021-01-10 14:24:24 -080011448 */
James Mattis47db0582021-01-01 14:13:35 -080011449 @Override
James Mattis45d81842021-01-10 14:24:24 -080011450 public void setOemNetworkPreference(
11451 @NonNull final OemNetworkPreferences preference,
Chalard Jean6010c002021-03-03 16:37:13 +090011452 @Nullable final IOnCompleteListener listener) {
James Mattis8378aec2021-01-26 14:05:36 -080011453
James Mattisfa270db2021-05-31 17:11:10 -070011454 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
11455 // Only bypass the permission/device checks if this is a valid test request.
11456 if (isValidTestOemNetworkPreference(preference)) {
11457 enforceManageTestNetworksPermission();
11458 } else {
11459 enforceAutomotiveDevice();
11460 enforceOemNetworkPreferencesPermission();
11461 validateOemNetworkPreferences(preference);
11462 }
James Mattis45d81842021-01-10 14:24:24 -080011463
James Mattis45d81842021-01-10 14:24:24 -080011464 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
11465 new Pair<>(preference, listener)));
11466 }
11467
James Mattisfa270db2021-05-31 17:11:10 -070011468 /**
lucaslin3ba7cc22022-12-19 02:35:33 +000011469 * Sets the specified UIDs to get/receive the VPN as the only default network.
11470 *
11471 * Calling this will overwrite the existing network preference for this session, and the
11472 * specified UIDs won't get any default network when no VPN is connected.
11473 *
11474 * @param session The VPN session which manages the passed UIDs.
11475 * @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the
11476 * setting for this session if the array is empty. Null is not allowed, the
11477 * method will use {@link Objects#requireNonNull(Object)} to check this variable.
11478 * @hide
11479 */
11480 @Override
11481 public void setVpnNetworkPreference(String session, UidRange[] ranges) {
11482 Objects.requireNonNull(ranges);
11483 enforceNetworkStackOrSettingsPermission();
11484 final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges);
11485 if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) {
11486 throw new IllegalArgumentException(
11487 "setVpnNetworkPreference: Passed UID ranges overlap");
11488 }
11489
11490 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE,
11491 new VpnNetworkPreferenceInfo(session,
11492 new ArraySet<UidRange>(Arrays.asList(ranges)))));
11493 }
11494
11495 private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) {
11496 Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo);
11497
11498 mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey());
11499 mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo);
11500
11501 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN);
11502 addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences));
11503 // Finally, rematch.
11504 rematchAllNetworksAndRequests();
11505 }
11506
11507 private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference(
11508 @NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) {
11509 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
11510 for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) {
11511 final List<NetworkRequest> requests = new ArrayList<>();
11512 // Request VPN only, so other networks won't be the fallback options when VPN is not
11513 // connected temporarily.
11514 requests.add(createVpnRequest());
11515 final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy());
11516 setNetworkRequestUids(requests, uidRanges);
11517 nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN));
11518 }
11519 return nris;
11520 }
11521
11522 /**
James Mattisfa270db2021-05-31 17:11:10 -070011523 * Check the validity of an OEM network preference to be used for testing purposes.
11524 * @param preference the preference to validate
11525 * @return true if this is a valid OEM network preference test request.
11526 */
11527 private boolean isValidTestOemNetworkPreference(
11528 @NonNull final OemNetworkPreferences preference) {
11529 // Allow for clearing of an existing OemNetworkPreference used for testing.
11530 // This isn't called on the handler thread so it is possible that mOemNetworkPreferences
11531 // changes after this check is complete. This is an unlikely scenario as calling of this API
11532 // is controlled by the OEM therefore the added complexity is not worth adding given those
11533 // circumstances. That said, it is an edge case to be aware of hence this comment.
11534 final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0
11535 && isTestOemNetworkPreference(mOemNetworkPreferences);
11536 return isTestOemNetworkPreference(preference) || isValidTestClearPref;
11537 }
11538
11539 private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
11540 final Map<String, Integer> prefMap = preference.getNetworkPreferences();
11541 return prefMap.size() == 1
11542 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST)
11543 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY));
11544 }
11545
James Mattis45d81842021-01-10 14:24:24 -080011546 private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
11547 for (@OemNetworkPreferences.OemNetworkPreference final int pref
11548 : preference.getNetworkPreferences().values()) {
James Mattisfa270db2021-05-31 17:11:10 -070011549 if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) {
11550 throw new IllegalArgumentException(
11551 OemNetworkPreferences.oemNetworkPreferenceToString(pref)
11552 + " is an invalid value.");
James Mattis45d81842021-01-10 14:24:24 -080011553 }
11554 }
11555 }
11556
11557 private void handleSetOemNetworkPreference(
11558 @NonNull final OemNetworkPreferences preference,
Chalard Jean6010c002021-03-03 16:37:13 +090011559 @Nullable final IOnCompleteListener listener) {
James Mattis45d81842021-01-10 14:24:24 -080011560 Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
11561 if (DBG) {
11562 log("set OEM network preferences :" + preference.toString());
11563 }
Chalard Jeanb5a139f2021-02-25 21:46:34 +090011564
James Mattiscb1e0362021-04-06 17:07:42 -070011565 mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference);
paulhu74128522021-09-28 02:29:03 +000011566 removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_OEM);
11567 addPerAppDefaultNetworkRequests(new OemNetworkRequestFactory()
11568 .createNrisFromOemNetworkPreferences(preference));
James Mattis45d81842021-01-10 14:24:24 -080011569 mOemNetworkPreferences = preference;
James Mattis45d81842021-01-10 14:24:24 -080011570
11571 if (null != listener) {
Chalard Jean5d6e23b2021-03-01 22:00:20 +090011572 try {
11573 listener.onComplete();
11574 } catch (RemoteException e) {
James Mattisae9aeb02021-03-01 17:09:11 -080011575 loge("Can't send onComplete in handleSetOemNetworkPreference", e);
Chalard Jean5d6e23b2021-03-01 22:00:20 +090011576 }
James Mattis45d81842021-01-10 14:24:24 -080011577 }
11578 }
11579
paulhu74128522021-09-28 02:29:03 +000011580 private void removeDefaultNetworkRequestsForPreference(final int preferenceOrder) {
paulhuaa0743d2021-05-26 21:56:03 +080011581 // Skip the requests which are set by other network preference. Because the uid range rules
11582 // should stay in netd.
11583 final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests);
paulhu48291862021-07-14 14:53:57 +080011584 requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder);
paulhuaa0743d2021-05-26 21:56:03 +080011585 handleRemoveNetworkRequests(requests);
James Mattis45d81842021-01-10 14:24:24 -080011586 }
11587
James Mattis3ce3d3c2021-02-09 18:18:28 -080011588 private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
11589 ensureRunningOnConnectivityServiceThread();
11590 mDefaultNetworkRequests.addAll(nris);
11591 final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate =
11592 getPerAppCallbackRequestsToUpdate();
James Mattis3ce3d3c2021-02-09 18:18:28 -080011593 final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris);
paulhu74128522021-09-28 02:29:03 +000011594 handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate);
11595 nrisToRegister.addAll(
11596 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate));
11597 handleRegisterNetworkRequests(nrisToRegister);
James Mattis3ce3d3c2021-02-09 18:18:28 -080011598 }
11599
11600 /**
11601 * All current requests that are tracking the default network need to be assessed as to whether
11602 * or not the current set of per-application default requests will be changing their default
11603 * network. If so, those requests will need to be updated so that they will send callbacks for
11604 * default network changes at the appropriate time. Additionally, those requests tracking the
11605 * default that were previously updated by this flow will need to be reassessed.
11606 * @return the nris which will need to be updated.
11607 */
11608 private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() {
11609 final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>();
11610 // Get the distinct nris to check since for multilayer requests, it is possible to have the
11611 // same nri in the map's values for each of its NetworkRequest objects.
11612 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values());
James Mattis45d81842021-01-10 14:24:24 -080011613 for (final NetworkRequestInfo nri : nris) {
James Mattis3ce3d3c2021-02-09 18:18:28 -080011614 // Include this nri if it is currently being tracked.
11615 if (isPerAppTrackedNri(nri)) {
11616 defaultCallbackRequests.add(nri);
11617 continue;
11618 }
11619 // We only track callbacks for requests tracking the default.
11620 if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) {
11621 continue;
11622 }
11623 // Include this nri if it will be tracked by the new per-app default requests.
11624 final boolean isNriGoingToBeTracked =
Lorenzo Colitti3e367f42021-03-12 22:50:57 +090011625 getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest;
James Mattis3ce3d3c2021-02-09 18:18:28 -080011626 if (isNriGoingToBeTracked) {
11627 defaultCallbackRequests.add(nri);
James Mattis45d81842021-01-10 14:24:24 -080011628 }
11629 }
James Mattis3ce3d3c2021-02-09 18:18:28 -080011630 return defaultCallbackRequests;
James Mattis45d81842021-01-10 14:24:24 -080011631 }
11632
James Mattis3ce3d3c2021-02-09 18:18:28 -080011633 /**
11634 * Create nris for those network requests that are currently tracking the default network that
11635 * are being controlled by a per-application default.
11636 * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the
11637 * foundation when creating the nri. Important items include the calling uid's original
11638 * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These
11639 * requests are assumed to have already been validated as needing to be updated.
11640 * @return the Set of nris to use when registering network requests.
11641 */
11642 private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister(
11643 @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) {
11644 final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>();
11645 for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) {
11646 final NetworkRequestInfo trackingNri =
Lorenzo Colitti3e367f42021-03-12 22:50:57 +090011647 getDefaultRequestTrackingUid(callbackRequest.mAsUid);
James Mattis3ce3d3c2021-02-09 18:18:28 -080011648
Chalard Jean9473c982021-07-29 20:03:04 +090011649 // If this nri is not being tracked, then change it back to an untracked nri.
James Mattis3ce3d3c2021-02-09 18:18:28 -080011650 if (trackingNri == mDefaultRequest) {
11651 callbackRequestsToRegister.add(new NetworkRequestInfo(
11652 callbackRequest,
11653 Collections.singletonList(callbackRequest.getNetworkRequestForCallback())));
11654 continue;
11655 }
11656
Lorenzo Colitti3e367f42021-03-12 22:50:57 +090011657 final NetworkRequest request = callbackRequest.mRequests.get(0);
James Mattis3ce3d3c2021-02-09 18:18:28 -080011658 callbackRequestsToRegister.add(new NetworkRequestInfo(
11659 callbackRequest,
11660 copyNetworkRequestsForUid(
Lorenzo Colitti3e367f42021-03-12 22:50:57 +090011661 trackingNri.mRequests, callbackRequest.mAsUid,
Lorenzo Colitti2a49c5d2021-03-12 22:48:07 +090011662 callbackRequest.mUid, request.getRequestorPackageName())));
James Mattis3ce3d3c2021-02-09 18:18:28 -080011663 }
11664 return callbackRequestsToRegister;
James Mattis45d81842021-01-10 14:24:24 -080011665 }
11666
Chalard Jean17215832021-03-01 14:06:28 +090011667 private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
11668 @NonNull final Set<UidRange> uids) {
Chalard Jean17215832021-03-01 14:06:28 +090011669 for (final NetworkRequest req : requests) {
Chiachang Wang8156c4e2021-03-19 00:45:39 +000011670 req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
Chalard Jean17215832021-03-01 14:06:28 +090011671 }
11672 }
11673
James Mattis45d81842021-01-10 14:24:24 -080011674 /**
11675 * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}.
11676 */
11677 @VisibleForTesting
11678 final class OemNetworkRequestFactory {
James Mattis3ce3d3c2021-02-09 18:18:28 -080011679 ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences(
James Mattis45d81842021-01-10 14:24:24 -080011680 @NonNull final OemNetworkPreferences preference) {
James Mattis3ce3d3c2021-02-09 18:18:28 -080011681 final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
James Mattis45d81842021-01-10 14:24:24 -080011682 final SparseArray<Set<Integer>> uids =
11683 createUidsFromOemNetworkPreferences(preference);
11684 for (int i = 0; i < uids.size(); i++) {
11685 final int key = uids.keyAt(i);
11686 final Set<Integer> value = uids.valueAt(i);
11687 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value);
11688 // No need to add an nri without any requests.
11689 if (0 == nri.mRequests.size()) {
11690 continue;
11691 }
11692 nris.add(nri);
11693 }
11694
11695 return nris;
11696 }
11697
11698 private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
11699 @NonNull final OemNetworkPreferences preference) {
James Mattisb6b6a432021-06-01 22:30:36 -070011700 final SparseArray<Set<Integer>> prefToUids = new SparseArray<>();
James Mattis45d81842021-01-10 14:24:24 -080011701 final PackageManager pm = mContext.getPackageManager();
James Mattisae9aeb02021-03-01 17:09:11 -080011702 final List<UserHandle> users =
11703 mContext.getSystemService(UserManager.class).getUserHandles(true);
11704 if (null == users || users.size() == 0) {
11705 if (VDBG || DDBG) {
11706 log("No users currently available for setting the OEM network preference.");
11707 }
James Mattisb6b6a432021-06-01 22:30:36 -070011708 return prefToUids;
James Mattisae9aeb02021-03-01 17:09:11 -080011709 }
James Mattis45d81842021-01-10 14:24:24 -080011710 for (final Map.Entry<String, Integer> entry :
11711 preference.getNetworkPreferences().entrySet()) {
11712 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
James Mattisb6b6a432021-06-01 22:30:36 -070011713 // Add the rules for all users as this policy is device wide.
11714 for (final UserHandle user : users) {
11715 try {
11716 final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid;
11717 if (!prefToUids.contains(pref)) {
11718 prefToUids.put(pref, new ArraySet<>());
11719 }
11720 prefToUids.get(pref).add(uid);
11721 } catch (PackageManager.NameNotFoundException e) {
11722 // Although this may seem like an error scenario, it is ok that uninstalled
11723 // packages are sent on a network preference as the system will watch for
11724 // package installations associated with this network preference and update
11725 // accordingly. This is done to minimize race conditions on app install.
11726 continue;
James Mattis45d81842021-01-10 14:24:24 -080011727 }
James Mattis45d81842021-01-10 14:24:24 -080011728 }
11729 }
James Mattisb6b6a432021-06-01 22:30:36 -070011730 return prefToUids;
James Mattis45d81842021-01-10 14:24:24 -080011731 }
11732
11733 private NetworkRequestInfo createNriFromOemNetworkPreferences(
11734 @OemNetworkPreferences.OemNetworkPreference final int preference,
11735 @NonNull final Set<Integer> uids) {
11736 final List<NetworkRequest> requests = new ArrayList<>();
11737 // Requests will ultimately be evaluated by order of insertion therefore it matters.
11738 switch (preference) {
11739 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
11740 requests.add(createUnmeteredNetworkRequest());
11741 requests.add(createOemPaidNetworkRequest());
James Mattisa117e282021-04-20 17:26:30 -070011742 requests.add(createDefaultInternetRequestForTransport(
11743 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
James Mattis45d81842021-01-10 14:24:24 -080011744 break;
11745 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
11746 requests.add(createUnmeteredNetworkRequest());
11747 requests.add(createOemPaidNetworkRequest());
11748 break;
11749 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
11750 requests.add(createOemPaidNetworkRequest());
11751 break;
11752 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
11753 requests.add(createOemPrivateNetworkRequest());
11754 break;
James Mattisfa270db2021-05-31 17:11:10 -070011755 case OEM_NETWORK_PREFERENCE_TEST:
11756 requests.add(createUnmeteredNetworkRequest());
11757 requests.add(createTestNetworkRequest());
11758 requests.add(createDefaultRequest());
11759 break;
11760 case OEM_NETWORK_PREFERENCE_TEST_ONLY:
11761 requests.add(createTestNetworkRequest());
11762 break;
James Mattis45d81842021-01-10 14:24:24 -080011763 default:
11764 // This should never happen.
11765 throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
11766 + " called with invalid preference of " + preference);
11767 }
11768
James Mattisfa270db2021-05-31 17:11:10 -070011769 final ArraySet<UidRange> ranges = new ArraySet<>();
Chalard Jean17215832021-03-01 14:06:28 +090011770 for (final int uid : uids) {
11771 ranges.add(new UidRange(uid, uid));
11772 }
11773 setNetworkRequestUids(requests, ranges);
paulhu48291862021-07-14 14:53:57 +080011774 return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM);
James Mattis45d81842021-01-10 14:24:24 -080011775 }
11776
11777 private NetworkRequest createUnmeteredNetworkRequest() {
11778 final NetworkCapabilities netcap = createDefaultPerAppNetCap()
11779 .addCapability(NET_CAPABILITY_NOT_METERED)
11780 .addCapability(NET_CAPABILITY_VALIDATED);
11781 return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap);
11782 }
11783
11784 private NetworkRequest createOemPaidNetworkRequest() {
11785 // NET_CAPABILITY_OEM_PAID is a restricted capability.
11786 final NetworkCapabilities netcap = createDefaultPerAppNetCap()
11787 .addCapability(NET_CAPABILITY_OEM_PAID)
11788 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
11789 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
11790 }
11791
11792 private NetworkRequest createOemPrivateNetworkRequest() {
11793 // NET_CAPABILITY_OEM_PRIVATE is a restricted capability.
11794 final NetworkCapabilities netcap = createDefaultPerAppNetCap()
11795 .addCapability(NET_CAPABILITY_OEM_PRIVATE)
11796 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
11797 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
11798 }
11799
11800 private NetworkCapabilities createDefaultPerAppNetCap() {
James Mattisfa270db2021-05-31 17:11:10 -070011801 final NetworkCapabilities netcap = new NetworkCapabilities();
11802 netcap.addCapability(NET_CAPABILITY_INTERNET);
11803 netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
11804 return netcap;
11805 }
11806
11807 private NetworkRequest createTestNetworkRequest() {
11808 final NetworkCapabilities netcap = new NetworkCapabilities();
11809 netcap.clearAll();
11810 netcap.addTransportType(TRANSPORT_TEST);
11811 return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
James Mattis45d81842021-01-10 14:24:24 -080011812 }
James Mattis47db0582021-01-01 14:13:35 -080011813 }
markchien738ad912021-12-09 18:15:45 +080011814
11815 @Override
11816 public void updateMeteredNetworkAllowList(final int uid, final boolean add) {
11817 enforceNetworkStackOrSettingsPermission();
11818
11819 try {
11820 if (add) {
Wayne Ma2fde98c2022-01-17 18:04:05 +080011821 mBpfNetMaps.addNiceApp(uid);
markchien738ad912021-12-09 18:15:45 +080011822 } else {
Wayne Ma2fde98c2022-01-17 18:04:05 +080011823 mBpfNetMaps.removeNiceApp(uid);
markchien738ad912021-12-09 18:15:45 +080011824 }
Lorenzo Colitti82244fd2022-03-04 23:15:00 +090011825 } catch (ServiceSpecificException e) {
markchien738ad912021-12-09 18:15:45 +080011826 throw new IllegalStateException(e);
11827 }
11828 }
11829
11830 @Override
11831 public void updateMeteredNetworkDenyList(final int uid, final boolean add) {
11832 enforceNetworkStackOrSettingsPermission();
11833
11834 try {
11835 if (add) {
Wayne Ma2fde98c2022-01-17 18:04:05 +080011836 mBpfNetMaps.addNaughtyApp(uid);
markchien738ad912021-12-09 18:15:45 +080011837 } else {
Wayne Ma2fde98c2022-01-17 18:04:05 +080011838 mBpfNetMaps.removeNaughtyApp(uid);
markchien738ad912021-12-09 18:15:45 +080011839 }
Lorenzo Colitti82244fd2022-03-04 23:15:00 +090011840 } catch (ServiceSpecificException e) {
markchien738ad912021-12-09 18:15:45 +080011841 throw new IllegalStateException(e);
11842 }
11843 }
markchiene1561fa2021-12-09 22:00:56 +080011844
11845 @Override
markchien3c04e662022-03-22 16:29:56 +080011846 public void setUidFirewallRule(final int chain, final int uid, final int rule) {
markchiene1561fa2021-12-09 22:00:56 +080011847 enforceNetworkStackOrSettingsPermission();
11848
markchien3c04e662022-03-22 16:29:56 +080011849 // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
11850 int firewallRule = getFirewallRuleType(chain, rule);
11851
11852 if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) {
11853 throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule);
11854 }
11855
markchiene1561fa2021-12-09 22:00:56 +080011856 try {
markchien3c04e662022-03-22 16:29:56 +080011857 mBpfNetMaps.setUidRule(chain, uid, firewallRule);
Lorenzo Colitti82244fd2022-03-04 23:15:00 +090011858 } catch (ServiceSpecificException e) {
markchiene1561fa2021-12-09 22:00:56 +080011859 throw new IllegalStateException(e);
11860 }
11861 }
markchien98a6f952022-01-13 23:43:53 +080011862
Motomu Utsumi900b8062023-01-19 16:16:49 +090011863 @Override
11864 public int getUidFirewallRule(final int chain, final int uid) {
11865 enforceNetworkStackOrSettingsPermission();
11866 return mBpfNetMaps.getUidRule(chain, uid);
11867 }
11868
markchien3c04e662022-03-22 16:29:56 +080011869 private int getFirewallRuleType(int chain, int rule) {
11870 final int defaultRule;
11871 switch (chain) {
11872 case ConnectivityManager.FIREWALL_CHAIN_STANDBY:
Motomu Utsumid9801492022-06-01 13:57:27 +000011873 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1:
11874 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2:
Motomu Utsumi1d9054b2022-06-06 07:44:05 +000011875 case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3:
markchien3c04e662022-03-22 16:29:56 +080011876 defaultRule = FIREWALL_RULE_ALLOW;
11877 break;
11878 case ConnectivityManager.FIREWALL_CHAIN_DOZABLE:
11879 case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE:
11880 case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
11881 case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY:
11882 defaultRule = FIREWALL_RULE_DENY;
11883 break;
11884 default:
11885 throw new IllegalArgumentException("Unsupported firewall chain: " + chain);
11886 }
11887 if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule;
11888
11889 return rule;
11890 }
11891
markchien98a6f952022-01-13 23:43:53 +080011892 @Override
11893 public void setFirewallChainEnabled(final int chain, final boolean enable) {
11894 enforceNetworkStackOrSettingsPermission();
11895
11896 try {
Wayne Ma2fde98c2022-01-17 18:04:05 +080011897 mBpfNetMaps.setChildChain(chain, enable);
Lorenzo Colitti82244fd2022-03-04 23:15:00 +090011898 } catch (ServiceSpecificException e) {
markchien98a6f952022-01-13 23:43:53 +080011899 throw new IllegalStateException(e);
11900 }
11901 }
11902
markchien00a0bed2022-01-13 23:46:13 +080011903 @Override
Motomu Utsumibe3ff1e2022-06-08 10:05:07 +000011904 public boolean getFirewallChainEnabled(final int chain) {
11905 enforceNetworkStackOrSettingsPermission();
11906
Motomu Utsumi25cf86f2022-06-27 08:50:19 +000011907 return mBpfNetMaps.isChainEnabled(chain);
Motomu Utsumibe3ff1e2022-06-08 10:05:07 +000011908 }
11909
11910 @Override
markchien00a0bed2022-01-13 23:46:13 +080011911 public void replaceFirewallChain(final int chain, final int[] uids) {
11912 enforceNetworkStackOrSettingsPermission();
11913
Motomu Utsumi9be2ea02022-07-05 06:14:59 +000011914 mBpfNetMaps.replaceUidChain(chain, uids);
markchien00a0bed2022-01-13 23:46:13 +080011915 }
Igor Chernyshev9dac6602022-12-13 19:28:32 -080011916
11917 @Override
11918 public IBinder getCompanionDeviceManagerProxyService() {
11919 enforceNetworkStackPermission(mContext);
11920 return mCdmps;
11921 }
Nathan Haroldb89cbfb2018-07-30 13:38:01 -070011922}