blob: dfdc2c13dcb7af724188ac445c5a2c28cd13ef09 [file] [log] [blame]
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001/*
2 * Copyright (C) 2011 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.net;
18
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070020import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070021import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
Jeff Sharkeyb74799882017-07-28 16:55:41 -060022import static android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS;
paulhua6af6b62019-08-12 16:25:11 +080023import static android.Manifest.permission.NETWORK_SETTINGS;
24import static android.Manifest.permission.NETWORK_STACK;
25import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
Jeff Sharkey497e4432011-06-14 17:27:29 -070026import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkey22c055e2011-06-12 21:13:51 -070027import static android.Manifest.permission.READ_PHONE_STATE;
Amit Mahajan7c5befa2015-07-14 10:26:00 -070028import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
Jeff Sharkey02e21d62011-07-17 15:53:33 -070029import static android.content.Intent.ACTION_PACKAGE_ADDED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070030import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070031import static android.content.Intent.ACTION_USER_ADDED;
32import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070033import static android.content.Intent.EXTRA_UID;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070034import static android.content.pm.PackageManager.MATCH_ANY_USER;
35import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
36import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
37import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
38import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
paulhua6af6b62019-08-12 16:25:11 +080039import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Erik Klinef851d6d2015-04-20 16:03:48 +090040import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Felipe Leme1b103232016-01-22 09:44:57 -080041import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
42import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
43import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -060044import static android.net.ConnectivityManager.TYPE_MOBILE;
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +090045import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
46import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
47import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
48import static android.net.INetd.FIREWALL_RULE_ALLOW;
49import static android.net.INetd.FIREWALL_RULE_DENY;
Jeff Sharkey64c96ec2017-08-30 16:28:26 -060050import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090051import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
Jeff Sharkey9252b342018-01-19 07:58:35 +090052import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Jeff Sharkey22c055e2011-06-12 21:13:51 -070053import static android.net.NetworkPolicy.LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070054import static android.net.NetworkPolicy.SNOOZE_NEVER;
Jeff Sharkey497e4432011-06-14 17:27:29 -070055import static android.net.NetworkPolicy.WARNING_DISABLED;
Jeff Sharkey14711eb2011-06-15 10:29:17 -070056import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
Jeff Sharkeydc988062015-09-14 10:09:47 -070057import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060058import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
59import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
Felipe Leme46b451f2016-08-19 08:46:17 -070060import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -070061import static android.net.NetworkPolicyManager.POLICY_NONE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070062import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
Felipe Lemed31a97f2016-05-06 14:53:50 -070063import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
Felipe Leme70c57c22016-03-29 10:45:13 -070064import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
Felipe Leme46c4fc32016-05-04 09:21:43 -070065import static android.net.NetworkPolicyManager.RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -070066import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070067import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
Felipe Leme70c57c22016-03-29 10:45:13 -070068import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
Sudheer Shankae359c3d2017-02-22 18:41:29 -080069import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
70import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060071import static android.net.NetworkPolicyManager.resolveNetworkId;
Felipe Lemeb146f762016-08-19 09:52:16 -070072import static android.net.NetworkPolicyManager.uidPoliciesToString;
Felipe Leme46c4fc32016-05-04 09:21:43 -070073import static android.net.NetworkPolicyManager.uidRulesToString;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070074import static android.net.NetworkTemplate.MATCH_MOBILE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070075import static android.net.NetworkTemplate.MATCH_WIFI;
Jeff Sharkey4e814c32011-07-14 20:37:37 -070076import static android.net.NetworkTemplate.buildTemplateMobileAll;
Jeff Sharkey241dde22012-02-03 14:50:07 -080077import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060078import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkey36b414b2018-03-30 11:00:03 -060079import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
80import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
81import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
82import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
83import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
84import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070085import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070086import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060087import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
Jeff Sharkey0a5570d2018-04-10 12:38:29 -060088import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL;
89import static android.telephony.CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL;
90import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL;
Jeff Sharkey9252b342018-01-19 07:58:35 +090091import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Felipe Leme03e689d2016-03-02 16:17:38 -080092
Jeff Sharkey854b2b12012-04-13 16:03:40 -070093import static com.android.internal.util.ArrayUtils.appendInt;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070094import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070095import static com.android.internal.util.XmlUtils.readBooleanAttribute;
96import static com.android.internal.util.XmlUtils.readIntAttribute;
97import static com.android.internal.util.XmlUtils.readLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060098import static com.android.internal.util.XmlUtils.readStringAttribute;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070099import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
100import static com.android.internal.util.XmlUtils.writeIntAttribute;
101import static com.android.internal.util.XmlUtils.writeLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600102import static com.android.internal.util.XmlUtils.writeStringAttribute;
Jeff Sharkey961e3042011-08-29 16:02:57 -0700103import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Sudheer Shanka352dc572017-09-22 17:09:38 -0700104import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT;
105import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED;
junyulai05986c62018-08-07 19:50:45 +0800106import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_SYSTEM;
Sudheer Shanka352dc572017-09-22 17:09:38 -0700107import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST;
108import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST;
109import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT;
110import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BLACKLIST;
111import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_POWER;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700112import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600113
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700114import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
Felipe Lemeb85a6372016-01-14 16:16:16 -0800115import static org.xmlpull.v1.XmlPullParser.END_TAG;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700116import static org.xmlpull.v1.XmlPullParser.START_TAG;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700117
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700118import android.Manifest;
Felipe Lemef3e40642016-06-07 17:28:08 -0700119import android.annotation.IntDef;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900120import android.annotation.NonNull;
Felipe Lemebc853dd2016-09-08 13:26:55 -0700121import android.annotation.Nullable;
Dianne Hackborn497175b2014-07-01 12:56:08 -0700122import android.app.ActivityManager;
Sudheer Shankae7361852017-03-07 11:51:46 -0800123import android.app.ActivityManagerInternal;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700124import android.app.AppGlobals;
Svet Ganov16a16892015-04-16 10:32:04 -0700125import android.app.AppOpsManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700126import android.app.IActivityManager;
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700127import android.app.IUidObserver;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700128import android.app.Notification;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700129import android.app.NotificationManager;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700130import android.app.PendingIntent;
Amith Yamasani15e472352015-04-24 19:06:07 -0700131import android.app.usage.UsageStatsManagerInternal;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700132import android.content.BroadcastReceiver;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700133import android.content.ComponentName;
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600134import android.content.ContentResolver;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700135import android.content.Context;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700136import android.content.Intent;
137import android.content.IntentFilter;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700138import android.content.pm.ApplicationInfo;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700139import android.content.pm.IPackageManager;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700140import android.content.pm.PackageManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700141import android.content.pm.PackageManager.NameNotFoundException;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700142import android.content.pm.UserInfo;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700143import android.content.res.Resources;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700144import android.net.ConnectivityManager;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600145import android.net.ConnectivityManager.NetworkCallback;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700146import android.net.IConnectivityManager;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700147import android.net.INetworkManagementEventObserver;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700148import android.net.INetworkPolicyListener;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700149import android.net.INetworkPolicyManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700150import android.net.INetworkStatsService;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700151import android.net.LinkProperties;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600152import android.net.Network;
153import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700154import android.net.NetworkIdentity;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700155import android.net.NetworkPolicy;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600156import android.net.NetworkPolicyManager;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700157import android.net.NetworkQuotaInfo;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600158import android.net.NetworkRequest;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900159import android.net.NetworkSpecifier;
paulhua6af6b62019-08-12 16:25:11 +0800160import android.net.NetworkStack;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700161import android.net.NetworkState;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700162import android.net.NetworkStats;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700163import android.net.NetworkTemplate;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900164import android.net.StringNetworkSpecifier;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600165import android.net.TrafficStats;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700166import android.net.wifi.WifiConfiguration;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700167import android.net.wifi.WifiManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700168import android.os.BestClock;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700169import android.os.Binder;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700170import android.os.Environment;
171import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700172import android.os.HandlerThread;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700173import android.os.IDeviceIdleController;
Ashish Sharma50fd36d2011-06-15 19:34:53 -0700174import android.os.INetworkManagementService;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700175import android.os.Message;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700176import android.os.MessageQueue.IdleHandler;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700177import android.os.PersistableBundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700178import android.os.PowerManager;
Makoto Onuki2eccd022017-11-01 13:44:23 -0700179import android.os.PowerManager.ServiceType;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700180import android.os.PowerManagerInternal;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600181import android.os.PowerSaveState;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800182import android.os.Process;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700183import android.os.RemoteCallbackList;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700184import android.os.RemoteException;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600185import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700186import android.os.ServiceManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700187import android.os.ShellCallback;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700188import android.os.SystemClock;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600189import android.os.SystemProperties;
Felipe Leme873a83a2016-09-07 11:34:10 -0700190import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700191import android.os.UserHandle;
Amith Yamasani258848d2012-08-10 17:06:33 -0700192import android.os.UserManager;
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700193import android.provider.Settings;
Narayan Kamath94bcdbc2017-07-17 15:32:53 +0100194import android.provider.Settings.Global;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700195import android.telephony.CarrierConfigManager;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600196import android.telephony.SubscriptionInfo;
Jeff Sharkey32566012014-12-02 18:30:14 -0800197import android.telephony.SubscriptionManager;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600198import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600199import android.telephony.SubscriptionPlan;
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700200import android.telephony.TelephonyManager;
Chris Wren8a3d56c2016-08-01 15:52:52 -0400201import android.text.TextUtils;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700202import android.text.format.DateUtils;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700203import android.text.format.Formatter;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700204import android.util.ArrayMap;
205import android.util.ArraySet;
Dianne Hackborn39606a02012-07-31 17:54:35 -0700206import android.util.AtomicFile;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900207import android.util.DataUnit;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600208import android.util.IntArray;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700209import android.util.Log;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700210import android.util.Pair;
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600211import android.util.Range;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600212import android.util.RecurrenceRule;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700213import android.util.Slog;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600214import android.util.SparseArray;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700215import android.util.SparseBooleanArray;
216import android.util.SparseIntArray;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900217import android.util.SparseLongArray;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700218import android.util.Xml;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700219
Jeff Sharkey497e4432011-06-14 17:27:29 -0700220import com.android.internal.R;
Felipe Lemef0823852016-06-08 13:43:08 -0700221import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800222import com.android.internal.annotations.VisibleForTesting;
Chris Wren193ae6b2017-03-31 15:17:11 -0400223import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500224import com.android.internal.notification.SystemNotificationChannels;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700225import com.android.internal.telephony.PhoneConstants;
Jeff Sharkey32566012014-12-02 18:30:14 -0800226import com.android.internal.util.ArrayUtils;
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800227import com.android.internal.util.ConcurrentUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600228import com.android.internal.util.DumpUtils;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700229import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700230import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600231import com.android.internal.util.Preconditions;
Makoto Onuki49392d32018-04-11 13:51:02 -0700232import com.android.internal.util.StatLogger;
Jeff Sharkeydc988062015-09-14 10:09:47 -0700233import com.android.server.EventLogTags;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700234import com.android.server.LocalServices;
Makoto Onuki8e777332017-03-28 11:25:47 -0700235import com.android.server.ServiceThread;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800236import com.android.server.SystemConfig;
Christopher Tateb909c4d52019-10-21 12:50:37 -0700237import com.android.server.usage.AppStandbyInternal;
238import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600239
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600240import libcore.io.IoUtils;
241
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700242import org.xmlpull.v1.XmlPullParser;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700243import org.xmlpull.v1.XmlSerializer;
244
245import java.io.File;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700246import java.io.FileDescriptor;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700247import java.io.FileInputStream;
248import java.io.FileNotFoundException;
249import java.io.FileOutputStream;
250import java.io.IOException;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700251import java.io.PrintWriter;
Felipe Lemef3e40642016-06-07 17:28:08 -0700252import java.lang.annotation.Retention;
253import java.lang.annotation.RetentionPolicy;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100254import java.nio.charset.StandardCharsets;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700255import java.time.Clock;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900256import java.time.Instant;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600257import java.time.ZoneId;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700258import java.time.ZoneOffset;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600259import java.time.ZonedDateTime;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900260import java.time.temporal.ChronoUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700261import java.util.ArrayList;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600262import java.util.Arrays;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700263import java.util.Calendar;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600264import java.util.List;
Chris Wren193ae6b2017-03-31 15:17:11 -0400265import java.util.Objects;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800266import java.util.Set;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800267import java.util.concurrent.CountDownLatch;
268import java.util.concurrent.TimeUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700269
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700270/**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700271 * Service that maintains low-level network policy rules, using
272 * {@link NetworkStatsService} statistics to drive those rules.
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700273 * <p>
274 * Derives active rules by combining a given policy with other system status,
275 * and delivers to listeners, such as {@link ConnectivityManager}, for
276 * enforcement.
Felipe Lemef0823852016-06-08 13:43:08 -0700277 *
278 * <p>
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700279 * This class uses 2 locks to synchronize state:
Felipe Lemef0823852016-06-08 13:43:08 -0700280 * <ul>
281 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
282 * rules).
283 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
284 * as network policies).
Felipe Lemef0823852016-06-08 13:43:08 -0700285 * </ul>
286 *
287 * <p>
288 * As such, methods that require synchronization have the following prefixes:
289 * <ul>
290 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
291 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
Sudheer Shankac9d94072017-02-22 22:13:55 +0000292 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
293 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
Felipe Lemef0823852016-06-08 13:43:08 -0700294 * </ul>
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700295 */
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700296public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Sudheer Shanka352dc572017-09-22 17:09:38 -0700297 static final String TAG = NetworkPolicyLogger.TAG;
298 private static final boolean LOGD = NetworkPolicyLogger.LOGD;
299 private static final boolean LOGV = NetworkPolicyLogger.LOGV;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700300
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +0900301 /**
302 * No opportunistic quota could be calculated from user data plan or data settings.
303 */
304 public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1;
305
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700306 private static final int VERSION_INIT = 1;
307 private static final int VERSION_ADDED_SNOOZE = 2;
Jeff Sharkey46645002011-07-27 21:11:21 -0700308 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800309 private static final int VERSION_ADDED_METERED = 4;
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800310 private static final int VERSION_SPLIT_SNOOZE = 5;
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800311 private static final int VERSION_ADDED_TIMEZONE = 6;
Jeff Sharkey837f9242012-03-20 16:52:20 -0700312 private static final int VERSION_ADDED_INFERRED = 7;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700313 private static final int VERSION_SWITCH_APP_ID = 8;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700314 private static final int VERSION_ADDED_NETWORK_ID = 9;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700315 private static final int VERSION_SWITCH_UID = 10;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600316 private static final int VERSION_ADDED_CYCLE = 11;
317 private static final int VERSION_LATEST = VERSION_ADDED_CYCLE;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700318
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800319 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400320 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800321 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400322 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800323 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400324 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900325 @VisibleForTesting
326 public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700327
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700328 private static final String TAG_POLICY_LIST = "policy-list";
329 private static final String TAG_NETWORK_POLICY = "network-policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600330 private static final String TAG_SUBSCRIPTION_PLAN = "subscription-plan";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700331 private static final String TAG_UID_POLICY = "uid-policy";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700332 private static final String TAG_APP_POLICY = "app-policy";
Felipe Lemeb85a6372016-01-14 16:16:16 -0800333 private static final String TAG_WHITELIST = "whitelist";
334 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
Felipe Lemea9505cc2016-02-26 10:28:41 -0800335 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700336
337 private static final String ATTR_VERSION = "version";
Jeff Sharkey46645002011-07-27 21:11:21 -0700338 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700339 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
340 private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700341 private static final String ATTR_NETWORK_ID = "networkId";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600342 @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
343 @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
344 private static final String ATTR_CYCLE_START = "cycleStart";
345 private static final String ATTR_CYCLE_END = "cycleEnd";
346 private static final String ATTR_CYCLE_PERIOD = "cyclePeriod";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700347 private static final String ATTR_WARNING_BYTES = "warningBytes";
348 private static final String ATTR_LIMIT_BYTES = "limitBytes";
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700349 private static final String ATTR_LAST_SNOOZE = "lastSnooze";
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800350 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
351 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800352 private static final String ATTR_METERED = "metered";
Jeff Sharkey837f9242012-03-20 16:52:20 -0700353 private static final String ATTR_INFERRED = "inferred";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700354 private static final String ATTR_UID = "uid";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700355 private static final String ATTR_APP_ID = "appId";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700356 private static final String ATTR_POLICY = "policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600357 private static final String ATTR_SUB_ID = "subId";
358 private static final String ATTR_TITLE = "title";
359 private static final String ATTR_SUMMARY = "summary";
360 private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
361 private static final String ATTR_USAGE_BYTES = "usageBytes";
362 private static final String ATTR_USAGE_TIME = "usageTime";
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600363 private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700364
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800365 private static final String ACTION_ALLOW_BACKGROUND =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800366 "com.android.server.net.action.ALLOW_BACKGROUND";
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800367 private static final String ACTION_SNOOZE_WARNING =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800368 "com.android.server.net.action.SNOOZE_WARNING";
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700369 private static final String ACTION_SNOOZE_RAPID =
370 "com.android.server.net.action.SNOOZE_RAPID";
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700371
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800372 /**
Sudheer Shankab2ed1c32019-10-07 11:42:59 -0700373 * Indicates the maximum wait time for admin data to be available.
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800374 */
375 private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
376
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600377 private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
378 private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
379 private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
380 private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
381
Svetoslav Ganov24c27752016-08-31 18:09:00 -0700382 private static final int MSG_RULES_CHANGED = 1;
Jeff Sharkey6f7af032011-11-01 18:25:15 -0700383 private static final int MSG_METERED_IFACES_CHANGED = 2;
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -0800384 private static final int MSG_LIMIT_REACHED = 5;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -0800385 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
Jeff Sharkeye19f39b2012-05-24 10:21:16 -0700386 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
Amith Yamasani3646cbd2016-04-13 14:04:53 -0700387 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
388 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700389 private static final int MSG_POLICIES_CHANGED = 13;
Felipe Leme03e95e22016-09-09 09:25:31 -0700390 private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900391 private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800392 private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -0700393 private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
Sarah Chin7af1fd02019-09-26 11:37:13 -0700394 private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700395
Makoto Onuki8e777332017-03-28 11:25:47 -0700396 private static final int UID_MSG_STATE_CHANGED = 100;
397 private static final int UID_MSG_GONE = 101;
398
Jeff Sharkey003d3e62018-03-30 14:35:04 -0600399 private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";
400
Jeff Sharkey75279902011-05-24 18:39:45 -0700401 private final Context mContext;
402 private final IActivityManager mActivityManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700403 private NetworkStatsManagerInternal mNetworkStats;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700404 private final INetworkManagementService mNetworkManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700405 private UsageStatsManagerInternal mUsageStats;
Christopher Tateb909c4d52019-10-21 12:50:37 -0700406 private AppStandbyInternal mAppStandby;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700407 private final Clock mClock;
Stuart Scotte3e314d2015-04-20 14:07:45 -0700408 private final UserManager mUserManager;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700409 private final CarrierConfigManager mCarrierConfigManager;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700410
411 private IConnectivityManager mConnManager;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700412 private PowerManagerInternal mPowerManagerInternal;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700413 private IDeviceIdleController mDeviceIdleController;
Kweku Adams25fa3a72019-07-12 17:00:17 -0700414
415 /** Current cached value of the current Battery Saver mode's setting for restrict background. */
jackqdyulei29c82ab2017-03-10 14:09:16 -0800416 @GuardedBy("mUidRulesFirstLock")
Kweku Adams25fa3a72019-07-12 17:00:17 -0700417 private boolean mRestrictBackgroundLowPowerMode;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800418
419 // Store the status of restrict background before turning on battery saver.
420 // Used to restore mRestrictBackground when battery saver is turned off.
421 private boolean mRestrictBackgroundBeforeBsm;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700422
Sudheer Shanka543339f2017-07-28 15:18:07 -0700423 // Denotes the status of restrict background read from disk.
424 private boolean mLoadedRestrictBackground;
425
Felipe Lemef0823852016-06-08 13:43:08 -0700426 // See main javadoc for instructions on how to use these locks.
427 final Object mUidRulesFirstLock = new Object();
428 final Object mNetworkPoliciesSecondLock = new Object();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700429
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700430 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
431 volatile boolean mSystemReady;
Felipe Lemef0823852016-06-08 13:43:08 -0700432
Felipe Lemef0823852016-06-08 13:43:08 -0700433 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
434 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
435 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800436 // Store whether user flipped restrict background in battery saver mode
437 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700438
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700439 private final boolean mSuppressDefaultPolicy;
440
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800441 private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
442
Sudheer Shanka1536fb62018-07-05 11:52:36 -0700443 private volatile boolean mNetworkManagerReady;
444
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700445 /** Defined network policies. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600446 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800447 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700448
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600449 /** Map from subId to subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600450 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600451 final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600452 /** Map from subId to package name that owns subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600453 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600454 final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600455
Jeff Sharkey9252b342018-01-19 07:58:35 +0900456 /** Map from subId to daily opportunistic quota. */
457 @GuardedBy("mNetworkPoliciesSecondLock")
458 final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray();
459
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700460 /** Defined UID policies. */
Felipe Lemef0823852016-06-08 13:43:08 -0700461 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700462 /** Currently derived rules for each UID. */
Felipe Lemef0823852016-06-08 13:43:08 -0700463 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700464
Felipe Lemef0823852016-06-08 13:43:08 -0700465 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700466 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700467 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700468 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700469 @GuardedBy("mUidRulesFirstLock")
Felipe Leme011b98f2016-02-10 17:28:31 -0800470 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
Jeff Sharkeydc988062015-09-14 10:09:47 -0700471
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700472 /** Set of states for the child firewall chains. True if the chain is active. */
Felipe Lemef0823852016-06-08 13:43:08 -0700473 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700474 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
475
Kweku Adamsa9e55bc2018-11-19 14:59:15 -0800476 // "Power save mode" is the concept used in the DeviceIdleController that includes various
477 // features including Doze and Battery Saver. It include Battery Saver, but "power save mode"
478 // and "battery saver" are not equivalent.
479
Jeff Sharkey32566012014-12-02 18:30:14 -0800480 /**
481 * UIDs that have been white-listed to always be able to have network access
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700482 * in power save mode, except device idle (doze) still applies.
483 * TODO: An int array might be sufficient
484 */
Felipe Lemef0823852016-06-08 13:43:08 -0700485 @GuardedBy("mUidRulesFirstLock")
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700486 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
487
488 /**
489 * UIDs that have been white-listed to always be able to have network access
Jeff Sharkey32566012014-12-02 18:30:14 -0800490 * in power save mode.
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700491 * TODO: An int array might be sufficient
Jeff Sharkey32566012014-12-02 18:30:14 -0800492 */
Felipe Lemef0823852016-06-08 13:43:08 -0700493 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700494 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700495
Felipe Lemef0823852016-06-08 13:43:08 -0700496 @GuardedBy("mUidRulesFirstLock")
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700497 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
498
Felipe Lemeb85a6372016-01-14 16:16:16 -0800499 /**
Kweku Adamsa9e55bc2018-11-19 14:59:15 -0800500 * UIDs that have been white-listed temporarily to be able to have network access despite being
501 * idle. Other power saving restrictions still apply.
502 */
503 @GuardedBy("mUidRulesFirstLock")
504 private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray();
505
506 /**
Felipe Lemea9505cc2016-02-26 10:28:41 -0800507 * UIDs that have been initially white-listed by system to avoid restricted background.
508 */
Felipe Lemef0823852016-06-08 13:43:08 -0700509 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800510 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
511 new SparseBooleanArray();
512
513 /**
514 * UIDs that have been initially white-listed by system to avoid restricted background,
515 * but later revoked by user.
516 */
Felipe Lemef0823852016-06-08 13:43:08 -0700517 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800518 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
519 new SparseBooleanArray();
520
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700521 /** Set of ifaces that are metered. */
Felipe Lemef0823852016-06-08 13:43:08 -0700522 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800523 private ArraySet<String> mMeteredIfaces = new ArraySet<>();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700524 /** Set of over-limit templates that have been notified. */
Felipe Lemef0823852016-06-08 13:43:08 -0700525 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800526 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700527
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700528 /** Set of currently active {@link Notification} tags. */
Felipe Lemef0823852016-06-08 13:43:08 -0700529 @GuardedBy("mNetworkPoliciesSecondLock")
Chris Wren193ae6b2017-03-31 15:17:11 -0400530 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700531
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700532 /** Foreground at UID granularity. */
Felipe Lemef0823852016-06-08 13:43:08 -0700533 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800534 final SparseIntArray mUidState = new SparseIntArray();
Dianne Hackborn497175b2014-07-01 12:56:08 -0700535
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600536 /** Map from network ID to last observed meteredness state */
537 @GuardedBy("mNetworkPoliciesSecondLock")
538 private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900539 /** Map from network ID to last observed roaming state */
540 @GuardedBy("mNetworkPoliciesSecondLock")
541 private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
542
Jeff Sharkey9252b342018-01-19 07:58:35 +0900543 /** Map from netId to subId as of last update */
544 @GuardedBy("mNetworkPoliciesSecondLock")
545 private final SparseIntArray mNetIdToSubId = new SparseIntArray();
546
Jeff Sharkey146bb332018-04-18 15:42:57 -0600547 /** Map from subId to subscriberId as of last update */
548 @GuardedBy("mNetworkPoliciesSecondLock")
549 private final SparseArray<String> mSubIdToSubscriberId = new SparseArray<>();
550 /** Set of all merged subscriberId as of last update */
551 @GuardedBy("mNetworkPoliciesSecondLock")
Malcolm Chen07fcb5b2019-07-02 22:29:35 -0700552 private List<String[]> mMergedSubscriberIds = new ArrayList<>();
Jeff Sharkey146bb332018-04-18 15:42:57 -0600553
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800554 /**
555 * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
556 * userId to restricted uids which belong to that user.
557 */
558 @GuardedBy("mUidRulesFirstLock")
559 private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>();
560
Jeff Sharkey32566012014-12-02 18:30:14 -0800561 private final RemoteCallbackList<INetworkPolicyListener>
562 mListeners = new RemoteCallbackList<>();
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700563
Dianne Hackborn497175b2014-07-01 12:56:08 -0700564 final Handler mHandler;
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700565 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -0800566 final Handler mUidEventHandler;
Makoto Onuki8e777332017-03-28 11:25:47 -0700567
568 private final ServiceThread mUidEventThread;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700569
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700570 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700571 private final AtomicFile mPolicyFile;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700572
Svet Ganov16a16892015-04-16 10:32:04 -0700573 private final AppOpsManager mAppOps;
574
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -0800575 private final IPackageManager mIPm;
576
Sudheer Shankae7361852017-03-07 11:51:46 -0800577 private ActivityManagerInternal mActivityManagerInternal;
578
Sudheer Shanka352dc572017-09-22 17:09:38 -0700579 private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
Felipe Lemeb85a6372016-01-14 16:16:16 -0800580
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700581 // TODO: keep whitelist of system-critical services that should never have
582 // rules enforced, such as system, phone, and radio UIDs.
583
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700584 // TODO: migrate notifications to SystemUI
585
Makoto Onuki49392d32018-04-11 13:51:02 -0700586
587 interface Stats {
588 int UPDATE_NETWORK_ENABLED = 0;
589 int IS_UID_NETWORKING_BLOCKED = 1;
590
591 int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
592 }
593
594 public final StatLogger mStatLogger = new StatLogger(new String[] {
595 "updateNetworkEnabledNL()",
596 "isUidNetworkingBlocked()",
597 });
598
Jeff Sharkey75279902011-05-24 18:39:45 -0700599 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700600 INetworkManagementService networkManagement) {
601 this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
602 getDefaultClock(), getDefaultSystemDir(), false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700603 }
604
Jeff Sharkey9911a282018-02-14 22:29:11 -0700605 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700606 return new File(Environment.getDataDirectory(), "system");
607 }
608
Jeff Sharkey9911a282018-02-14 22:29:11 -0700609 private static @NonNull Clock getDefaultClock() {
610 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
611 Clock.systemUTC());
612 }
613
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700614 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700615 INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
616 File systemDir, boolean suppressDefaultPolicy) {
Jeff Sharkeya4620792011-05-20 15:29:23 -0700617 mContext = checkNotNull(context, "missing context");
618 mActivityManager = checkNotNull(activityManager, "missing activityManager");
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700619 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700620 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
Dianne Hackborn1958e5e2015-06-12 18:11:41 -0700621 Context.DEVICE_IDLE_CONTROLLER));
Jeff Sharkey9911a282018-02-14 22:29:11 -0700622 mClock = checkNotNull(clock, "missing Clock");
Stuart Scotte3e314d2015-04-20 14:07:45 -0700623 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700624 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700625 mIPm = pm;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700626
Amith Yamasani450a16b2013-09-18 16:28:50 -0700627 HandlerThread thread = new HandlerThread(TAG);
628 thread.start();
629 mHandler = new Handler(thread.getLooper(), mHandlerCallback);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700630
Makoto Onuki8e777332017-03-28 11:25:47 -0700631 // We create another thread for the UID events, which are more time-critical.
632 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
633 /*allowIo=*/ false);
634 mUidEventThread.start();
635 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
636
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700637 mSuppressDefaultPolicy = suppressDefaultPolicy;
638
Dianne Hackborne17b4452018-01-10 13:15:40 -0800639 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
Svet Ganov16a16892015-04-16 10:32:04 -0700640
641 mAppOps = context.getSystemService(AppOpsManager.class);
Felipe Lemeb85a6372016-01-14 16:16:16 -0800642
Felipe Lemed17fda42016-04-29 11:12:45 -0700643 // Expose private service for system components to use.
644 LocalServices.addService(NetworkPolicyManagerInternal.class,
645 new NetworkPolicyManagerInternalImpl());
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700646 }
647
648 public void bindConnectivityManager(IConnectivityManager connManager) {
649 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
Jeff Sharkeya4620792011-05-20 15:29:23 -0700650 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700651
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700652 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700653 void updatePowerSaveWhitelistUL() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700654 try {
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700655 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
656 mPowerSaveWhitelistExceptIdleAppIds.clear();
657 if (whitelist != null) {
658 for (int uid : whitelist) {
659 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
660 }
661 }
662 whitelist = mDeviceIdleController.getAppIdWhitelist();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700663 mPowerSaveWhitelistAppIds.clear();
664 if (whitelist != null) {
665 for (int uid : whitelist) {
666 mPowerSaveWhitelistAppIds.put(uid, true);
667 }
668 }
669 } catch (RemoteException e) {
670 }
671 }
672
Felipe Lemea9505cc2016-02-26 10:28:41 -0800673 /**
674 * Whitelists pre-defined apps for restrict background, but only if the user didn't already
675 * revoke the whitelist.
676 *
Felipe Leme46b451f2016-08-19 08:46:17 -0700677 * @return whether any uid has been whitelisted.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800678 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700679 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700680 boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
Felipe Lemea9505cc2016-02-26 10:28:41 -0800681 final List<UserInfo> users = mUserManager.getUsers();
682 final int numberUsers = users.size();
683
Felipe Lemea110eec2016-04-29 09:58:06 -0700684 boolean changed = false;
685 for (int i = 0; i < numberUsers; i++) {
686 final UserInfo user = users.get(i);
Felipe Lemef0823852016-06-08 13:43:08 -0700687 changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
Felipe Lemea110eec2016-04-29 09:58:06 -0700688 }
689 return changed;
690 }
691
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700692 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700693 private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
Felipe Lemea110eec2016-04-29 09:58:06 -0700694 final SystemConfig sysConfig = SystemConfig.getInstance();
695 final PackageManager pm = mContext.getPackageManager();
Felipe Lemea9505cc2016-02-26 10:28:41 -0800696 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
697 boolean changed = false;
698 for (int i = 0; i < allowDataUsage.size(); i++) {
699 final String pkg = allowDataUsage.valueAt(i);
700 if (LOGD)
Felipe Lemea110eec2016-04-29 09:58:06 -0700701 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
702 + " and user " + userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800703 final ApplicationInfo app;
704 try {
Felipe Lemea110eec2016-04-29 09:58:06 -0700705 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800706 } catch (PackageManager.NameNotFoundException e) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700707 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
708 // Ignore it - some apps on allow-in-data-usage-save are optional.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800709 continue;
710 }
711 if (!app.isPrivilegedApp()) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700712 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
713 + "skipping non-privileged app " + pkg);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800714 continue;
715 }
Felipe Lemea110eec2016-04-29 09:58:06 -0700716 final int uid = UserHandle.getUid(userId, app.uid);
717 mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
718 if (LOGD)
719 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
720 + "background whitelist. Revoked status: "
Felipe Lemea9505cc2016-02-26 10:28:41 -0800721 + mRestrictBackgroundWhitelistRevokedUids.get(uid));
Felipe Lemea110eec2016-04-29 09:58:06 -0700722 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700723 if (LOGD)
724 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
725 + userId + ") to restrict background whitelist");
Felipe Leme46b451f2016-08-19 08:46:17 -0700726 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false);
Felipe Lemea110eec2016-04-29 09:58:06 -0700727 changed = true;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800728 }
729 }
730 return changed;
731 }
732
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800733 private void initService(CountDownLatch initCompleteSignal) {
Felipe Leme873a83a2016-09-07 11:34:10 -0700734 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800735 final int oldPriority = Process.getThreadPriority(Process.myTid());
Felipe Leme873a83a2016-09-07 11:34:10 -0700736 try {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800737 // Boost thread's priority during system server init
738 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
Felipe Leme873a83a2016-09-07 11:34:10 -0700739 if (!isBandwidthControlEnabled()) {
740 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
741 return;
742 }
Jeff Sharkey8c1dc722012-05-04 14:49:37 -0700743
Felipe Leme873a83a2016-09-07 11:34:10 -0700744 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
Christopher Tateb909c4d52019-10-21 12:50:37 -0700745 mAppStandby = LocalServices.getService(AppStandbyInternal.class);
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700746 mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
Amith Yamasani15e472352015-04-24 19:06:07 -0700747
Felipe Leme873a83a2016-09-07 11:34:10 -0700748 synchronized (mUidRulesFirstLock) {
749 synchronized (mNetworkPoliciesSecondLock) {
750 updatePowerSaveWhitelistUL();
751 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
752 mPowerManagerInternal.registerLowPowerModeObserver(
753 new PowerManagerInternal.LowPowerModeListener() {
jackqdyulei455e90a2017-02-09 15:29:16 -0800754 @Override
755 public int getServiceType() {
756 return ServiceType.NETWORK_FIREWALL;
Felipe Leme873a83a2016-09-07 11:34:10 -0700757 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800758
759 @Override
760 public void onLowPowerModeChanged(PowerSaveState result) {
761 final boolean enabled = result.batterySaverEnabled;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800762 if (LOGD) {
763 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
764 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800765 synchronized (mUidRulesFirstLock) {
766 if (mRestrictPower != enabled) {
767 mRestrictPower = enabled;
768 updateRulesForRestrictPowerUL();
769 }
770 }
771 }
jackqdyulei29c82ab2017-03-10 14:09:16 -0800772 });
jackqdyulei455e90a2017-02-09 15:29:16 -0800773 mRestrictPower = mPowerManagerInternal.getLowPowerState(
774 ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
Felipe Leme873a83a2016-09-07 11:34:10 -0700775
776 mSystemReady = true;
777
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800778 waitForAdminData();
779
Felipe Leme873a83a2016-09-07 11:34:10 -0700780 // read policy from disk
781 readPolicyAL();
782
jackqdyulei29c82ab2017-03-10 14:09:16 -0800783 // Update the restrictBackground if battery saver is turned on
Sudheer Shanka543339f2017-07-28 15:18:07 -0700784 mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
Kweku Adams25fa3a72019-07-12 17:00:17 -0700785 mRestrictBackgroundLowPowerMode = mPowerManagerInternal
786 .getLowPowerState(ServiceType.DATA_SAVER).batterySaverEnabled;
787 if (mRestrictBackgroundLowPowerMode && !mLoadedRestrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -0700788 mLoadedRestrictBackground = true;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800789 }
790 mPowerManagerInternal.registerLowPowerModeObserver(
791 new PowerManagerInternal.LowPowerModeListener() {
792 @Override
793 public int getServiceType() {
794 return ServiceType.DATA_SAVER;
795 }
796
797 @Override
798 public void onLowPowerModeChanged(PowerSaveState result) {
799 synchronized (mUidRulesFirstLock) {
800 updateRestrictBackgroundByLowPowerModeUL(result);
801 }
802 }
803 });
804
Felipe Leme873a83a2016-09-07 11:34:10 -0700805 if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
806 writePolicyAL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700807 }
Felipe Lemef0823852016-06-08 13:43:08 -0700808
Kweku Adamsdf33ae12019-10-08 11:51:41 -0700809 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, true);
Sudheer Shanka543339f2017-07-28 15:18:07 -0700810 setRestrictBackgroundUL(mLoadedRestrictBackground);
Felipe Leme873a83a2016-09-07 11:34:10 -0700811 updateRulesForGlobalChangeAL(false);
812 updateNotificationsNL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700813 }
Felipe Lemea9505cc2016-02-26 10:28:41 -0800814 }
Felipe Leme873a83a2016-09-07 11:34:10 -0700815
Sudheer Shankae7361852017-03-07 11:51:46 -0800816 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Felipe Leme873a83a2016-09-07 11:34:10 -0700817 try {
818 mActivityManager.registerUidObserver(mUidObserver,
Sudheer Shankac9d94072017-02-22 22:13:55 +0000819 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
Sudheer Shanka6a3c07e2018-09-11 15:21:22 -0700820 NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
Felipe Leme873a83a2016-09-07 11:34:10 -0700821 mNetworkManager.registerObserver(mAlertObserver);
822 } catch (RemoteException e) {
823 // ignored; both services live in system_server
824 }
825
826 // listen for changes to power save whitelist
827 final IntentFilter whitelistFilter = new IntentFilter(
828 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
829 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
830
Felipe Leme873a83a2016-09-07 11:34:10 -0700831 // watch for network interfaces to be claimed
832 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
paulhua6af6b62019-08-12 16:25:11 +0800833 mContext.registerReceiver(mConnReceiver, connFilter, NETWORK_STACK, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700834
835 // listen for package changes to update policy
836 final IntentFilter packageFilter = new IntentFilter();
837 packageFilter.addAction(ACTION_PACKAGE_ADDED);
838 packageFilter.addDataScheme("package");
839 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
840
841 // listen for UID changes to update policy
842 mContext.registerReceiver(
843 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
844
845 // listen for user changes to update policy
846 final IntentFilter userFilter = new IntentFilter();
847 userFilter.addAction(ACTION_USER_ADDED);
848 userFilter.addAction(ACTION_USER_REMOVED);
849 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
850
851 // listen for stats update events
852 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
853 mContext.registerReceiver(
854 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
855
856 // listen for restrict background changes from notifications
857 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
858 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
859
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700860 // Listen for snooze from notifications
861 mContext.registerReceiver(mSnoozeReceiver,
862 new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler);
863 mContext.registerReceiver(mSnoozeReceiver,
864 new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700865
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600866 // listen for configured wifi networks to be loaded
867 final IntentFilter wifiFilter =
868 new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
869 mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700870
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700871 // listen for carrier config changes to update data cycle information
872 final IntentFilter carrierConfigFilter = new IntentFilter(
873 ACTION_CARRIER_CONFIG_CHANGED);
874 mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
875
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600876 // listen for meteredness changes
877 mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
878 new NetworkRequest.Builder().build(), mNetworkCallback);
879
Christopher Tateb909c4d52019-10-21 12:50:37 -0700880 mAppStandby.addListener(new NetPolicyAppIdleStateChangeListener());
Jeff Sharkey146bb332018-04-18 15:42:57 -0600881
882 // Listen for subscriber changes
883 mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
884 new OnSubscriptionsChangedListener(mHandler.getLooper()) {
885 @Override
886 public void onSubscriptionsChanged() {
887 updateNetworksInternal();
888 }
889 });
890
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800891 // tell systemReady() that the service has been initialized
892 initCompleteSignal.countDown();
Felipe Leme873a83a2016-09-07 11:34:10 -0700893 } finally {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800894 // Restore the default priority after init is done
895 Process.setThreadPriority(oldPriority);
Felipe Leme873a83a2016-09-07 11:34:10 -0700896 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700897 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700898 }
899
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800900 public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
Sudheer Shanka1536fb62018-07-05 11:52:36 -0700901 mNetworkManagerReady = true;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800902 final CountDownLatch initCompleteSignal = new CountDownLatch(1);
903 mHandler.post(() -> initService(initCompleteSignal));
904 return initCompleteSignal;
905 }
906
907 public void systemReady(CountDownLatch initCompleteSignal) {
908 // wait for initService to complete
909 try {
910 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
911 throw new IllegalStateException("Service " + TAG +" init timeout");
912 }
913 } catch (InterruptedException e) {
914 Thread.currentThread().interrupt();
915 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
916 }
917 }
918
Sudheer Shankac9d94072017-02-22 22:13:55 +0000919 final private IUidObserver mUidObserver = new IUidObserver.Stub() {
Hui Yu26969322019-08-21 14:56:35 -0700920 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
921 int capability) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700922 mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
923 uid, procState, procStateSeq).sendToTarget();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700924 }
925
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700926 @Override public void onUidGone(int uid, boolean disabled) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700927 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700928 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700929
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700930 @Override public void onUidActive(int uid) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700931 }
932
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700933 @Override public void onUidIdle(int uid, boolean disabled) {
934 }
935
936 @Override public void onUidCachedChanged(int uid, boolean cached) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700937 }
Jeff Sharkeya4620792011-05-20 15:29:23 -0700938 };
939
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700940 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700941 @Override
942 public void onReceive(Context context, Intent intent) {
943 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
Felipe Lemef0823852016-06-08 13:43:08 -0700944 synchronized (mUidRulesFirstLock) {
945 updatePowerSaveWhitelistUL();
946 updateRulesForRestrictPowerUL();
Felipe Leme09700462016-09-08 09:33:48 -0700947 updateRulesForAppIdleUL();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700948 }
949 }
950 };
951
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700952 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700953 @Override
954 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700955 // on background handler thread, and PACKAGE_ADDED is protected
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700956
957 final String action = intent.getAction();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700958 final int uid = intent.getIntExtra(EXTRA_UID, -1);
959 if (uid == -1) return;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700960
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700961 if (ACTION_PACKAGE_ADDED.equals(action)) {
962 // update rules for UID, since it might be subject to
963 // global background data policy
964 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700965 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700966 updateRestrictionRulesForUidUL(uid);
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700967 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700968 }
969 }
970 };
971
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700972 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700973 @Override
974 public void onReceive(Context context, Intent intent) {
975 // on background handler thread, and UID_REMOVED is protected
976
977 final int uid = intent.getIntExtra(EXTRA_UID, -1);
978 if (uid == -1) return;
979
980 // remove any policy and update rules to clean up
981 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700982 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700983 onUidDeletedUL(uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700984 synchronized (mNetworkPoliciesSecondLock) {
985 writePolicyAL();
986 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700987 }
988 }
989 };
990
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700991 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700992 @Override
993 public void onReceive(Context context, Intent intent) {
994 // on background handler thread, and USER_ADDED and USER_REMOVED
995 // broadcasts are protected
996
997 final String action = intent.getAction();
998 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
999 if (userId == -1) return;
1000
Amith Yamasani15e472352015-04-24 19:06:07 -07001001 switch (action) {
1002 case ACTION_USER_REMOVED:
1003 case ACTION_USER_ADDED:
Felipe Lemef0823852016-06-08 13:43:08 -07001004 synchronized (mUidRulesFirstLock) {
Fyodor Kupolova31c5912016-01-22 11:26:09 -08001005 // Remove any persistable state for the given user; both cleaning up after a
Amith Yamasani15e472352015-04-24 19:06:07 -07001006 // USER_REMOVED, and one last sanity check during USER_ADDED
Felipe Lemef0823852016-06-08 13:43:08 -07001007 removeUserStateUL(userId, true);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08001008 // Removing outside removeUserStateUL since that can also be called when
1009 // user resets app preferences.
1010 mMeteredRestrictedUids.remove(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -07001011 if (action == ACTION_USER_ADDED) {
1012 // Add apps that are whitelisted by default.
Felipe Lemef0823852016-06-08 13:43:08 -07001013 addDefaultRestrictBackgroundWhitelistUidsUL(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -07001014 }
1015 // Update global restrict for that user
Felipe Lemef0823852016-06-08 13:43:08 -07001016 synchronized (mNetworkPoliciesSecondLock) {
1017 updateRulesForGlobalChangeAL(true);
1018 }
Amith Yamasani15e472352015-04-24 19:06:07 -07001019 }
1020 break;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07001021 }
1022 }
1023 };
1024
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001025 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001026 * Receiver that watches for {@link INetworkStatsService} updates, which we
1027 * use to check against {@link NetworkPolicy#warningBytes}.
1028 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001029 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
Jeff Sharkey497e4432011-06-14 17:27:29 -07001030 @Override
1031 public void onReceive(Context context, Intent intent) {
1032 // on background handler thread, and verified
1033 // READ_NETWORK_USAGE_HISTORY permission above.
1034
Felipe Lemef0823852016-06-08 13:43:08 -07001035 synchronized (mNetworkPoliciesSecondLock) {
1036 updateNetworkEnabledNL();
1037 updateNotificationsNL();
Jeff Sharkey497e4432011-06-14 17:27:29 -07001038 }
1039 }
1040 };
1041
1042 /**
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07001043 * Receiver that watches for {@link Notification} control of
1044 * {@link #mRestrictBackground}.
1045 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001046 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07001047 @Override
1048 public void onReceive(Context context, Intent intent) {
1049 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1050 // permission above.
1051
1052 setRestrictBackground(false);
1053 }
1054 };
1055
1056 /**
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001057 * Receiver that watches for {@link Notification} control of
1058 * {@link NetworkPolicy#lastWarningSnooze}.
1059 */
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001060 final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001061 @Override
1062 public void onReceive(Context context, Intent intent) {
1063 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1064 // permission above.
1065
1066 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001067 if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) {
1068 performSnooze(template, TYPE_WARNING);
1069 } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) {
1070 performSnooze(template, TYPE_RAPID);
1071 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001072 }
1073 };
1074
1075 /**
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001076 * Receiver that watches for {@link WifiConfiguration} to be loaded so that
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001077 * we can perform upgrade logic. After initial upgrade logic, it updates
1078 * {@link #mMeteredIfaces} based on configuration changes.
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001079 */
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001080 final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001081 @Override
1082 public void onReceive(Context context, Intent intent) {
Hugo Benichi446c9c92017-04-10 09:41:10 +09001083 synchronized (mUidRulesFirstLock) {
1084 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001085 upgradeWifiMeteredOverrideAL();
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001086 }
1087 }
1088 // Only need to perform upgrade logic once
1089 mContext.unregisterReceiver(this);
1090 }
1091 };
1092
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001093 private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue,
1094 Network network) {
1095 final boolean lastValue = lastValues.get(network.netId, false);
1096 final boolean changed = (lastValue != newValue) || lastValues.indexOfKey(network.netId) < 0;
1097 if (changed) {
1098 lastValues.put(network.netId, newValue);
1099 }
1100 return changed;
1101 }
1102
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001103 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
1104 @Override
1105 public void onCapabilitiesChanged(Network network,
1106 NetworkCapabilities networkCapabilities) {
1107 if (network == null || networkCapabilities == null) return;
1108
1109 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001110 final boolean newMetered = !networkCapabilities
1111 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001112 final boolean meteredChanged = updateCapabilityChange(
1113 mNetworkMetered, newMetered, network);
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001114
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001115 final boolean newRoaming = !networkCapabilities
1116 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
1117 final boolean roamingChanged = updateCapabilityChange(
1118 mNetworkRoaming, newRoaming, network);
1119
1120 if (meteredChanged || roamingChanged) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07001121 mLogger.meterednessChanged(network.netId, newMetered);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001122 updateNetworkRulesNL();
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001123 }
1124 }
1125 }
1126 };
1127
1128 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001129 * Observer that watches for {@link INetworkManagementService} alerts.
1130 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001131 final private INetworkManagementEventObserver mAlertObserver
1132 = new BaseNetworkObserver() {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001133 @Override
1134 public void limitReached(String limitName, String iface) {
1135 // only someone like NMS should be calling us
paulhua6af6b62019-08-12 16:25:11 +08001136 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001137
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08001138 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1139 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001140 }
1141 }
1142 };
1143
1144 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001145 * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
1146 * to show visible notifications as needed.
1147 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001148 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001149 void updateNotificationsNL() {
1150 if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001151 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNotificationsNL");
Jeff Sharkey497e4432011-06-14 17:27:29 -07001152
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001153 // keep track of previously active notifications
Chris Wren193ae6b2017-03-31 15:17:11 -04001154 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001155 mActiveNotifs.clear();
Jeff Sharkey497e4432011-06-14 17:27:29 -07001156
1157 // TODO: when switching to kernel notifications, compute next future
1158 // cycle boundary to recompute notifications.
1159
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001160 // examine stats for each active policy
Jeff Sharkey9911a282018-02-14 22:29:11 -07001161 final long now = mClock.millis();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001162 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1163 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey146bb332018-04-18 15:42:57 -06001164 final int subId = findRelevantSubIdNL(policy.template);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001165
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001166 // ignore policies that aren't relevant to user
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001167 if (subId == INVALID_SUBSCRIPTION_ID) continue;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001168 if (!policy.hasCycle()) continue;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001169
Jeff Sharkey53313d72017-07-13 16:47:32 -06001170 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1171 .cycleIterator(policy).next();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001172 final long cycleStart = cycle.first.toInstant().toEpochMilli();
1173 final long cycleEnd = cycle.second.toInstant().toEpochMilli();
1174 final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001175
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001176 // Carrier might want to manage notifications themselves
1177 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
Ammar Aijazib0941aa2019-04-26 18:39:50 -07001178 if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) {
1179 if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false");
1180 // Don't show notifications until we confirm that the loaded config is from an
1181 // identified carrier, which may want to manage their own notifications. This method
1182 // should be called every time the carrier config changes anyways, and there's no
1183 // reason to alert if there isn't a carrier.
1184 return;
1185 }
1186
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001187 final boolean notifyWarning = getBooleanDefeatingNullable(config,
1188 KEY_DATA_WARNING_NOTIFICATION_BOOL, true);
1189 final boolean notifyLimit = getBooleanDefeatingNullable(config,
1190 KEY_DATA_LIMIT_NOTIFICATION_BOOL, true);
1191 final boolean notifyRapid = getBooleanDefeatingNullable(config,
1192 KEY_DATA_RAPID_NOTIFICATION_BOOL, true);
1193
1194 // Notify when data usage is over warning
1195 if (notifyWarning) {
1196 if (policy.isOverWarning(totalBytes) && !policy.isOverLimit(totalBytes)) {
1197 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
1198 if (!snoozedThisCycle) {
1199 enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
1200 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001201 }
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001202 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001203
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001204 // Notify when data usage is over limit
1205 if (notifyLimit) {
1206 if (policy.isOverLimit(totalBytes)) {
1207 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
1208 if (snoozedThisCycle) {
1209 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
1210 } else {
1211 enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
1212 notifyOverLimitNL(policy.template);
1213 }
1214 } else {
1215 notifyUnderLimitNL(policy.template);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001216 }
1217 }
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001218
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001219 // Warn if average usage over last 4 days is on track to blow pretty
1220 // far past the plan limits.
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001221 if (notifyRapid && policy.limitBytes != LIMIT_DISABLED) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001222 final long recentDuration = TimeUnit.DAYS.toMillis(4);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001223 final long recentStart = now - recentDuration;
1224 final long recentEnd = now;
1225 final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001226
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001227 final long cycleDuration = cycleEnd - cycleStart;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001228 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001229 final long alertBytes = (policy.limitBytes * 3) / 2;
1230
1231 if (LOGD) {
1232 Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected "
1233 + projectedBytes + " alert " + alertBytes);
1234 }
1235
1236 final boolean snoozedRecently = policy.lastRapidSnooze >= now
1237 - DateUtils.DAY_IN_MILLIS;
1238 if (projectedBytes > alertBytes && !snoozedRecently) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001239 enqueueNotification(policy, TYPE_RAPID, 0,
1240 findRapidBlame(policy.template, recentStart, recentEnd));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001241 }
1242 }
1243 }
1244
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001245 // cancel stale notifications that we didn't renew above
Dianne Hackborn497175b2014-07-01 12:56:08 -07001246 for (int i = beforeNotifs.size()-1; i >= 0; i--) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001247 final NotificationId notificationId = beforeNotifs.valueAt(i);
1248 if (!mActiveNotifs.contains(notificationId)) {
1249 cancelNotification(notificationId);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001250 }
1251 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001252
1253 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001254 }
1255
1256 /**
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001257 * Attempt to find a specific app to blame for rapid data usage during the
1258 * given time period.
1259 */
1260 private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
1261 long start, long end) {
1262 long totalBytes = 0;
1263 long maxBytes = 0;
1264 int maxUid = 0;
1265
1266 final NetworkStats stats = getNetworkUidBytes(template, start, end);
1267 NetworkStats.Entry entry = null;
1268 for (int i = 0; i < stats.size(); i++) {
1269 entry = stats.getValues(i, entry);
1270 final long bytes = entry.rxBytes + entry.txBytes;
1271 totalBytes += bytes;
1272 if (bytes > maxBytes) {
1273 maxBytes = bytes;
1274 maxUid = entry.uid;
1275 }
1276 }
1277
1278 // Only point blame if the majority of usage was done by a single app.
1279 // TODO: support shared UIDs
1280 if (maxBytes > 0 && maxBytes > totalBytes / 2) {
1281 final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
Jeff Sharkeyd37154e2018-03-26 16:50:59 -06001282 if (packageNames != null && packageNames.length == 1) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001283 try {
1284 return mContext.getPackageManager().getApplicationInfo(packageNames[0],
1285 MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
1286 | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
1287 } catch (NameNotFoundException ignored) {
1288 }
1289 }
1290 }
1291
1292 return null;
1293 }
1294
1295 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001296 * Test if given {@link NetworkTemplate} is relevant to user based on
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001297 * current device state, such as when
1298 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
1299 * data connection status.
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001300 *
1301 * @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no
1302 * matching subId found.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001303 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001304 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey146bb332018-04-18 15:42:57 -06001305 private int findRelevantSubIdNL(NetworkTemplate template) {
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001306 // Mobile template is relevant when any active subscriber matches
Jeff Sharkey146bb332018-04-18 15:42:57 -06001307 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1308 final int subId = mSubIdToSubscriberId.keyAt(i);
1309 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001310 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1311 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1312 true);
1313 if (template.matches(probeIdent)) {
1314 return subId;
Jeff Sharkey32566012014-12-02 18:30:14 -08001315 }
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001316 }
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001317 return INVALID_SUBSCRIPTION_ID;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001318 }
1319
1320 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001321 * Notify that given {@link NetworkTemplate} is over
1322 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1323 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001324 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001325 private void notifyOverLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001326 if (!mOverLimitNotified.contains(template)) {
Wei Liu546cb772016-07-21 16:19:01 -07001327 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001328 mOverLimitNotified.add(template);
1329 }
1330 }
1331
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001332 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001333 private void notifyUnderLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001334 mOverLimitNotified.remove(template);
1335 }
1336
1337 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001338 * Show notification for combined {@link NetworkPolicy} and specific type,
1339 * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1340 */
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001341 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
1342 ApplicationInfo rapidBlame) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001343 final NotificationId notificationId = new NotificationId(policy, type);
Geoffrey Pitschaf759c52017-02-15 09:35:38 -05001344 final Notification.Builder builder =
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001345 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001346 builder.setOnlyAlertOnce(true);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001347 builder.setWhen(0L);
Alan Viverette4a357cd2015-03-18 18:37:18 -07001348 builder.setColor(mContext.getColor(
Selim Cinek255dd042014-08-19 22:29:02 +02001349 com.android.internal.R.color.system_notification_accent_color));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001350
1351 final Resources res = mContext.getResources();
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001352 final CharSequence title;
1353 final CharSequence body;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001354 switch (type) {
1355 case TYPE_WARNING: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001356 title = res.getText(R.string.data_usage_warning_title);
1357 body = res.getString(R.string.data_usage_warning_body,
Anton Hanssona6101e82019-03-29 15:50:09 +00001358 Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001359
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001360 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001361
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001362 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1363 builder.setDeleteIntent(PendingIntent.getBroadcast(
1364 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1365
Wei Liu546cb772016-07-21 16:19:01 -07001366 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Heemin Seogb9820d42019-05-21 16:17:43 -07001367 // TODO: Resolve to single code path.
Eric Jeonge7ead1b2019-07-18 09:37:08 -07001368 if (UserManager.isHeadlessSystemUserMode()) {
Heemin Seogb9820d42019-05-21 16:17:43 -07001369 builder.setContentIntent(PendingIntent.getActivityAsUser(
1370 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT,
1371 /* options= */ null, UserHandle.CURRENT));
1372 } else {
1373 builder.setContentIntent(PendingIntent.getActivity(
1374 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1375 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001376 break;
1377 }
1378 case TYPE_LIMIT: {
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001379 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001380 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001381 title = res.getText(R.string.data_usage_mobile_limit_title);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001382 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001383 case MATCH_WIFI:
1384 title = res.getText(R.string.data_usage_wifi_limit_title);
1385 break;
1386 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001387 return;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001388 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001389 body = res.getText(R.string.data_usage_limit_body);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001390
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001391 builder.setOngoing(true);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001392 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001393
Wei Liu546cb772016-07-21 16:19:01 -07001394 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
Heemin Seogb9820d42019-05-21 16:17:43 -07001395 // TODO: Resolve to single code path.
Eric Jeonge7ead1b2019-07-18 09:37:08 -07001396 if (UserManager.isHeadlessSystemUserMode()) {
Heemin Seogb9820d42019-05-21 16:17:43 -07001397 builder.setContentIntent(PendingIntent.getActivityAsUser(
1398 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT,
1399 /* options= */ null, UserHandle.CURRENT));
1400 } else {
1401 builder.setContentIntent(PendingIntent.getActivity(
1402 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1403 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001404 break;
1405 }
1406 case TYPE_LIMIT_SNOOZED: {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001407 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001408 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001409 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1410 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001411 case MATCH_WIFI:
1412 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1413 break;
1414 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001415 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001416 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001417 final long overBytes = totalBytes - policy.limitBytes;
1418 body = res.getString(R.string.data_usage_limit_snoozed_body,
Anton Hanssona6101e82019-03-29 15:50:09 +00001419 Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001420
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001421 builder.setOngoing(true);
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001422 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001423 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001424
Wei Liu546cb772016-07-21 16:19:01 -07001425 final Intent intent = buildViewDataUsageIntent(res, policy.template);
Heemin Seogb9820d42019-05-21 16:17:43 -07001426 // TODO: Resolve to single code path.
Eric Jeonge7ead1b2019-07-18 09:37:08 -07001427 if (UserManager.isHeadlessSystemUserMode()) {
Heemin Seogb9820d42019-05-21 16:17:43 -07001428 builder.setContentIntent(PendingIntent.getActivityAsUser(
1429 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT,
1430 /* options= */ null, UserHandle.CURRENT));
1431 } else {
1432 builder.setContentIntent(PendingIntent.getActivity(
1433 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1434 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001435 break;
1436 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001437 case TYPE_RAPID: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001438 title = res.getText(R.string.data_usage_rapid_title);
1439 if (rapidBlame != null) {
1440 body = res.getString(R.string.data_usage_rapid_app_body,
1441 rapidBlame.loadLabel(mContext.getPackageManager()));
1442 } else {
1443 body = res.getString(R.string.data_usage_rapid_body);
1444 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001445
Jeff Sharkey2e471452018-01-19 18:02:47 +09001446 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001447
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001448 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
1449 builder.setDeleteIntent(PendingIntent.getBroadcast(
1450 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1451
1452 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Heemin Seogb9820d42019-05-21 16:17:43 -07001453 // TODO: Resolve to single code path.
Eric Jeonge7ead1b2019-07-18 09:37:08 -07001454 if (UserManager.isHeadlessSystemUserMode()) {
Heemin Seogb9820d42019-05-21 16:17:43 -07001455 builder.setContentIntent(PendingIntent.getActivityAsUser(
1456 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT,
1457 /* options= */ null, UserHandle.CURRENT));
1458 } else {
1459 builder.setContentIntent(PendingIntent.getActivity(
1460 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1461 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001462 break;
1463 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001464 default: {
1465 return;
1466 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001467 }
1468
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001469 builder.setTicker(title);
1470 builder.setContentTitle(title);
1471 builder.setContentText(body);
1472 builder.setStyle(new Notification.BigTextStyle().bigText(body));
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001473
1474 mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
1475 notificationId.getId(), builder.build(), UserHandle.ALL);
1476 mActiveNotifs.add(notificationId);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001477 }
1478
Chris Wren193ae6b2017-03-31 15:17:11 -04001479 private void cancelNotification(NotificationId notificationId) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001480 mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(),
1481 notificationId.getId());
Jeff Sharkey497e4432011-06-14 17:27:29 -07001482 }
1483
1484 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001485 * Receiver that watches for {@link IConnectivityManager} to claim network
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001486 * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001487 */
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001488 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001489 @Override
1490 public void onReceive(Context context, Intent intent) {
paulhua6af6b62019-08-12 16:25:11 +08001491 // on background handler thread, and verified NETWORK_STACK
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001492 // permission above.
Jeff Sharkey146bb332018-04-18 15:42:57 -06001493 updateNetworksInternal();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001494 }
1495 };
1496
Jeff Sharkey146bb332018-04-18 15:42:57 -06001497 private void updateNetworksInternal() {
1498 // Get all of our cross-process communication with telephony out of
1499 // the way before we acquire internal locks.
1500 updateSubscriptions();
1501
1502 synchronized (mUidRulesFirstLock) {
1503 synchronized (mNetworkPoliciesSecondLock) {
1504 ensureActiveMobilePolicyAL();
1505 normalizePoliciesNL();
1506 updateNetworkEnabledNL();
1507 updateNetworkRulesNL();
1508 updateNotificationsNL();
1509 }
1510 }
1511 }
1512
Jeff Sharkey2e471452018-01-19 18:02:47 +09001513 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001514 void updateNetworks() throws InterruptedException {
Jeff Sharkey146bb332018-04-18 15:42:57 -06001515 updateNetworksInternal();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001516 final CountDownLatch latch = new CountDownLatch(1);
1517 mHandler.post(() -> {
1518 latch.countDown();
1519 });
1520 latch.await(5, TimeUnit.SECONDS);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001521 }
1522
Sudheer Shankac0f85c12019-10-12 15:01:44 -07001523 @VisibleForTesting
1524 Handler getHandlerForTesting() {
1525 return mHandler;
1526 }
1527
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001528 /**
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001529 * Update mobile policies with data cycle information from {@link CarrierConfigManager}
1530 * if necessary.
1531 *
1532 * @param subId that has its associated NetworkPolicy updated if necessary
1533 * @return if any policies were updated
1534 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001535 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey146bb332018-04-18 15:42:57 -06001536 private boolean maybeUpdateMobilePolicyCycleAL(int subId, String subscriberId) {
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001537 if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001538
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001539 // find and update the mobile NetworkPolicy for this subscriber id
Jeff Sharkey146bb332018-04-18 15:42:57 -06001540 boolean policyUpdated = false;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001541 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001542 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001543 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1544 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1545 if (template.matches(probeIdent)) {
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001546 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1547 policyUpdated |= updateDefaultMobilePolicyAL(subId, policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001548 }
1549 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001550 return policyUpdated;
1551 }
1552
1553 /**
1554 * Returns the cycle day that should be used for a mobile NetworkPolicy.
1555 *
1556 * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
1557 * to do so, it returns the fallback value.
1558 *
1559 * @param config The CarrierConfig to read the value from.
1560 * @param fallbackCycleDay to return if the CarrierConfig can't be read.
1561 * @return cycleDay to use in the mobile NetworkPolicy.
1562 */
1563 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001564 int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001565 int fallbackCycleDay) {
1566 if (config == null) {
1567 return fallbackCycleDay;
1568 }
1569 int cycleDay =
1570 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1571 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1572 return fallbackCycleDay;
1573 }
1574 // validate cycleDay value
1575 final Calendar cal = Calendar.getInstance();
1576 if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
1577 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
1578 Slog.e(TAG, "Invalid date in "
1579 + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
1580 return fallbackCycleDay;
1581 }
1582 return cycleDay;
1583 }
1584
1585 /**
1586 * Returns the warning bytes that should be used for a mobile NetworkPolicy.
1587 *
1588 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1589 * to do so, it returns the fallback value.
1590 *
1591 * @param config The CarrierConfig to read the value from.
1592 * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
1593 * @return warningBytes to use in the mobile NetworkPolicy.
1594 */
1595 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001596 long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001597 long fallbackWarningBytes) {
1598 if (config == null) {
1599 return fallbackWarningBytes;
1600 }
1601 long warningBytes =
1602 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
1603
1604 if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1605 return WARNING_DISABLED;
1606 } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1607 return getPlatformDefaultWarningBytes();
1608 } else if (warningBytes < 0) {
1609 Slog.e(TAG, "Invalid value in "
1610 + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
1611 + "non-negative value but got: " + warningBytes);
1612 return fallbackWarningBytes;
1613 }
1614
1615 return warningBytes;
1616 }
1617
1618 /**
1619 * Returns the limit bytes that should be used for a mobile NetworkPolicy.
1620 *
1621 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1622 * to do so, it returns the fallback value.
1623 *
1624 * @param config The CarrierConfig to read the value from.
1625 * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
1626 * @return limitBytes to use in the mobile NetworkPolicy.
1627 */
1628 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001629 long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001630 long fallbackLimitBytes) {
1631 if (config == null) {
1632 return fallbackLimitBytes;
1633 }
1634 long limitBytes =
1635 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
1636
1637 if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1638 return LIMIT_DISABLED;
1639 } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1640 return getPlatformDefaultLimitBytes();
1641 } else if (limitBytes < 0) {
1642 Slog.e(TAG, "Invalid value in "
1643 + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
1644 + "non-negative value but got: " + limitBytes);
1645 return fallbackLimitBytes;
1646 }
1647 return limitBytes;
1648 }
1649
1650 /**
1651 * Receiver that watches for {@link CarrierConfigManager} to be changed.
1652 */
1653 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
1654 @Override
1655 public void onReceive(Context context, Intent intent) {
1656 // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
1657 // broadcast is protected and can't be spoofed. Runs on a background handler thread.
1658
1659 if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
1660 return;
1661 }
1662 final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
Jeff Sharkey146bb332018-04-18 15:42:57 -06001663
1664 // Get all of our cross-process communication with telephony out of
1665 // the way before we acquire internal locks.
1666 updateSubscriptions();
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001667
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001668 synchronized (mUidRulesFirstLock) {
1669 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey146bb332018-04-18 15:42:57 -06001670 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
1671 if (subscriberId != null) {
1672 ensureActiveMobilePolicyAL(subId, subscriberId);
1673 maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
1674 } else {
1675 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
1676 }
1677
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001678 // update network and notification rules, as the data cycle changed and it's
1679 // possible that we should be triggering warnings/limits now
1680 handleNetworkPoliciesUpdateAL(true);
1681 }
1682 }
1683 }
1684 };
1685
1686 /**
1687 * Handles all tasks that need to be run after a new network policy has been set, or an existing
1688 * one has been updated.
1689 *
1690 * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1691 * update.
1692 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001693 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001694 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1695 if (shouldNormalizePolicies) {
1696 normalizePoliciesNL();
1697 }
1698 updateNetworkEnabledNL();
1699 updateNetworkRulesNL();
1700 updateNotificationsNL();
1701 writePolicyAL();
1702 }
1703
1704 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001705 * Proactively control network data connections when they exceed
1706 * {@link NetworkPolicy#limitBytes}.
1707 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001708 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001709 void updateNetworkEnabledNL() {
1710 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001711 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkEnabledNL");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001712
1713 // TODO: reset any policy-disabled networks when any policy is removed
1714 // completely, which is currently rare case.
1715
Makoto Onuki49392d32018-04-11 13:51:02 -07001716 final long startTime = mStatLogger.getTime();
1717
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001718 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1719 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001720 // shortcut when policy has no limit
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001721 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001722 setNetworkTemplateEnabled(policy.template, true);
1723 continue;
1724 }
1725
Jeff Sharkey53313d72017-07-13 16:47:32 -06001726 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1727 .cycleIterator(policy).next();
1728 final long start = cycle.first.toInstant().toEpochMilli();
1729 final long end = cycle.second.toInstant().toEpochMilli();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001730 final long totalBytes = getTotalBytes(policy.template, start, end);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001731
1732 // disable data connection when over limit and not snoozed
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001733 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
1734 && policy.lastLimitSnooze < start;
1735 final boolean networkEnabled = !overLimitWithoutSnooze;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001736
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001737 setNetworkTemplateEnabled(policy.template, networkEnabled);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001738 }
Makoto Onuki49392d32018-04-11 13:51:02 -07001739
1740 mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001741 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001742 }
1743
1744 /**
Jeff Sharkey32566012014-12-02 18:30:14 -08001745 * Proactively disable networks that match the given
1746 * {@link NetworkTemplate}.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001747 */
1748 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07001749 // Don't call setNetworkTemplateEnabledInner() directly because we may have a lock
1750 // held. Call it via the handler.
1751 mHandler.obtainMessage(MSG_SET_NETWORK_TEMPLATE_ENABLED, enabled ? 1 : 0, 0, template)
1752 .sendToTarget();
1753 }
1754
1755 private void setNetworkTemplateEnabledInner(NetworkTemplate template, boolean enabled) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001756 // TODO: reach into ConnectivityManager to proactively disable bringing
1757 // up this network, since we know that traffic will be blocked.
Jack Yu8781b682016-07-08 14:28:51 -07001758
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001759 if (template.getMatchRule() == MATCH_MOBILE) {
Jack Yu8781b682016-07-08 14:28:51 -07001760 // If mobile data usage hits the limit or if the user resumes the data, we need to
1761 // notify telephony.
Jack Yu8781b682016-07-08 14:28:51 -07001762
Jeff Sharkey146bb332018-04-18 15:42:57 -06001763 final IntArray matchingSubIds = new IntArray();
1764 synchronized (mNetworkPoliciesSecondLock) {
1765 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1766 final int subId = mSubIdToSubscriberId.keyAt(i);
1767 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
1768
1769 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1770 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1771 true);
1772 // Template is matched when subscriber id matches.
1773 if (template.matches(probeIdent)) {
1774 matchingSubIds.add(subId);
1775 }
Jack Yu8781b682016-07-08 14:28:51 -07001776 }
1777 }
Jeff Sharkey146bb332018-04-18 15:42:57 -06001778
1779 // Only talk with telephony outside of locks
1780 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1781 for (int i = 0; i < matchingSubIds.size(); i++) {
1782 final int subId = matchingSubIds.get(i);
1783 tm.setPolicyDataEnabled(enabled, subId);
1784 }
Jack Yu8781b682016-07-08 14:28:51 -07001785 }
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001786 }
1787
1788 /**
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001789 * Collect all ifaces from a {@link NetworkState} into the given set.
1790 */
1791 private static void collectIfaces(ArraySet<String> ifaces, NetworkState state) {
1792 final String baseIface = state.linkProperties.getInterfaceName();
1793 if (baseIface != null) {
1794 ifaces.add(baseIface);
1795 }
1796 for (LinkProperties stackedLink : state.linkProperties.getStackedLinks()) {
1797 final String stackedIface = stackedLink.getInterfaceName();
1798 if (stackedIface != null) {
1799 ifaces.add(stackedIface);
1800 }
1801 }
1802 }
1803
1804 /**
Jeff Sharkey146bb332018-04-18 15:42:57 -06001805 * Examine all currently active subscriptions from
1806 * {@link SubscriptionManager#getActiveSubscriptionIdList()} and update
1807 * internal data structures.
1808 * <p>
1809 * Callers <em>must not</em> hold any locks when this method called.
1810 */
1811 void updateSubscriptions() {
1812 if (LOGV) Slog.v(TAG, "updateSubscriptions()");
1813 Trace.traceBegin(TRACE_TAG_NETWORK, "updateSubscriptions");
1814
1815 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1816 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
1817
1818 final int[] subIds = ArrayUtils.defeatNullable(sm.getActiveSubscriptionIdList());
Malcolm Chen07fcb5b2019-07-02 22:29:35 -07001819 final List<String[]> mergedSubscriberIdsList = new ArrayList();
Jeff Sharkey146bb332018-04-18 15:42:57 -06001820
1821 final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subIds.length);
1822 for (int subId : subIds) {
1823 final String subscriberId = tm.getSubscriberId(subId);
1824 if (!TextUtils.isEmpty(subscriberId)) {
1825 subIdToSubscriberId.put(subId, subscriberId);
1826 } else {
1827 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
1828 }
Malcolm Chen07fcb5b2019-07-02 22:29:35 -07001829
1830 String[] mergedSubscriberId = ArrayUtils.defeatNullable(
1831 tm.createForSubscriptionId(subId).getMergedSubscriberIdsFromGroup());
1832 mergedSubscriberIdsList.add(mergedSubscriberId);
Jeff Sharkey146bb332018-04-18 15:42:57 -06001833 }
1834
1835 synchronized (mNetworkPoliciesSecondLock) {
1836 mSubIdToSubscriberId.clear();
1837 for (int i = 0; i < subIdToSubscriberId.size(); i++) {
1838 mSubIdToSubscriberId.put(subIdToSubscriberId.keyAt(i),
1839 subIdToSubscriberId.valueAt(i));
1840 }
1841
Malcolm Chen07fcb5b2019-07-02 22:29:35 -07001842 mMergedSubscriberIds = mergedSubscriberIdsList;
Jeff Sharkey146bb332018-04-18 15:42:57 -06001843 }
1844
1845 Trace.traceEnd(TRACE_TAG_NETWORK);
1846 }
1847
1848 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001849 * Examine all connected {@link NetworkState}, looking for
1850 * {@link NetworkPolicy} that need to be enforced. When matches found, set
1851 * remaining quota based on usage cycle and historical stats.
1852 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001853 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001854 void updateNetworkRulesNL() {
1855 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001856 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001857
1858 final NetworkState[] states;
1859 try {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001860 states = defeatNullable(mConnManager.getAllNetworkState());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001861 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001862 // ignored; service lives in system_server
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001863 return;
1864 }
1865
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001866 // First, generate identities of all connected networks so we can
1867 // quickly compare them against all defined policies below.
Jeff Sharkey9252b342018-01-19 07:58:35 +09001868 mNetIdToSubId.clear();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001869 final ArrayMap<NetworkState, NetworkIdentity> identified = new ArrayMap<>();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001870 for (NetworkState state : states) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001871 if (state.network != null) {
1872 mNetIdToSubId.put(state.network.netId, parseSubId(state));
1873 }
Wei Liub8eaf452016-01-25 10:32:27 -08001874 if (state.networkInfo != null && state.networkInfo.isConnected()) {
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001875 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1876 true);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001877 identified.put(state, ident);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001878 }
1879 }
1880
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001881 final ArraySet<String> newMeteredIfaces = new ArraySet<>();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001882 long lowestRule = Long.MAX_VALUE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001883
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001884 // For every well-defined policy, compute remaining data based on
1885 // current cycle and historical stats, and push to kernel.
1886 final ArraySet<String> matchingIfaces = new ArraySet<>();
1887 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1888 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1889
1890 // Collect all ifaces that match this policy
1891 matchingIfaces.clear();
1892 for (int j = identified.size() - 1; j >= 0; j--) {
1893 if (policy.template.matches(identified.valueAt(j))) {
1894 collectIfaces(matchingIfaces, identified.keyAt(j));
1895 }
1896 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001897
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001898 if (LOGD) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001899 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001900 }
1901
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001902 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001903 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001904 if (hasLimit || policy.metered) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001905 final long quotaBytes;
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001906 if (hasLimit && policy.hasCycle()) {
1907 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1908 .cycleIterator(policy).next();
1909 final long start = cycle.first.toInstant().toEpochMilli();
1910 final long end = cycle.second.toInstant().toEpochMilli();
1911 final long totalBytes = getTotalBytes(policy.template, start, end);
1912
1913 if (policy.lastLimitSnooze >= start) {
1914 // snoozing past quota, but we still need to restrict apps,
1915 // so push really high quota.
1916 quotaBytes = Long.MAX_VALUE;
1917 } else {
1918 // remaining "quota" bytes are based on total usage in
1919 // current cycle. kernel doesn't like 0-byte rules, so we
1920 // set 1-byte quota and disable the radio later.
1921 quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
1922 }
1923 } else {
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001924 // metered network, but no policy limit; we still need to
1925 // restrict apps, so push really high quota.
1926 quotaBytes = Long.MAX_VALUE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001927 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001928
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001929 if (matchingIfaces.size() > 1) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001930 // TODO: switch to shared quota once NMS supports
1931 Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001932 }
1933
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001934 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1935 final String iface = matchingIfaces.valueAt(j);
1936 setInterfaceQuotaAsync(iface, quotaBytes);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001937 newMeteredIfaces.add(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001938 }
1939 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001940
1941 // keep track of lowest warning or limit of active policies
1942 if (hasWarning && policy.warningBytes < lowestRule) {
1943 lowestRule = policy.warningBytes;
1944 }
1945 if (hasLimit && policy.limitBytes < lowestRule) {
1946 lowestRule = policy.limitBytes;
1947 }
1948 }
1949
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001950 // One final pass to catch any metered ifaces that don't have explicitly
1951 // defined policies; typically Wi-Fi networks.
1952 for (NetworkState state : states) {
1953 if (state.networkInfo != null && state.networkInfo.isConnected()
1954 && !state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
1955 matchingIfaces.clear();
1956 collectIfaces(matchingIfaces, state);
1957 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1958 final String iface = matchingIfaces.valueAt(j);
1959 if (!newMeteredIfaces.contains(iface)) {
1960 setInterfaceQuotaAsync(iface, Long.MAX_VALUE);
1961 newMeteredIfaces.add(iface);
1962 }
1963 }
1964 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001965 }
1966
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001967 // Remove quota from any interfaces that are no longer metered.
Dianne Hackborn497175b2014-07-01 12:56:08 -07001968 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
1969 final String iface = mMeteredIfaces.valueAt(i);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001970 if (!newMeteredIfaces.contains(iface)) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001971 removeInterfaceQuotaAsync(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001972 }
1973 }
1974 mMeteredIfaces = newMeteredIfaces;
1975
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001976 final ContentResolver cr = mContext.getContentResolver();
1977 final boolean quotaEnabled = Settings.Global.getInt(cr,
1978 NETPOLICY_QUOTA_ENABLED, 1) != 0;
1979 final long quotaUnlimited = Settings.Global.getLong(cr,
1980 NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
1981 final float quotaLimited = Settings.Global.getFloat(cr,
1982 NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
1983
Jeff Sharkey9252b342018-01-19 07:58:35 +09001984 // Finally, calculate our opportunistic quotas
Jeff Sharkey9252b342018-01-19 07:58:35 +09001985 mSubscriptionOpportunisticQuota.clear();
1986 for (NetworkState state : states) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001987 if (!quotaEnabled) continue;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001988 if (state.network == null) continue;
Jeff Sharkey9252b342018-01-19 07:58:35 +09001989 final int subId = getSubIdLocked(state.network);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001990 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09001991 if (plan == null) continue;
1992
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001993 final long quotaBytes;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001994 final long limitBytes = plan.getDataLimitBytes();
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001995 if (!state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
1996 // Clamp to 0 when roaming
1997 quotaBytes = 0;
1998 } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001999 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
Jeff Sharkey2e471452018-01-19 18:02:47 +09002000 } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09002001 // Unlimited data; let's use 20MiB/day (600MiB/month)
Jeff Sharkey36b414b2018-03-30 11:00:03 -06002002 quotaBytes = quotaUnlimited;
Jeff Sharkey9252b342018-01-19 07:58:35 +09002003 } else {
2004 // Limited data; let's only use 10% of remaining budget
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002005 final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
2006 final long start = cycle.getLower().toInstant().toEpochMilli();
2007 final long end = cycle.getUpper().toInstant().toEpochMilli();
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09002008 final Instant now = mClock.instant();
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06002009 final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09002010 .truncatedTo(ChronoUnit.DAYS)
2011 .toInstant().toEpochMilli();
Jeff Sharkey9252b342018-01-19 07:58:35 +09002012 final long totalBytes = getTotalBytes(
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09002013 NetworkTemplate.buildTemplateMobileAll(state.subscriberId),
2014 start, startOfDay);
Jeff Sharkey9252b342018-01-19 07:58:35 +09002015 final long remainingBytes = limitBytes - totalBytes;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09002016 // Number of remaining days including current day
2017 final long remainingDays =
2018 1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09002019
Jeff Sharkey36b414b2018-03-30 11:00:03 -06002020 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
Jeff Sharkey9252b342018-01-19 07:58:35 +09002021 }
2022
2023 mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
2024 }
2025
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07002026 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07002027 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06002028
2029 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
Jeff Sharkey00072392018-04-12 14:26:32 -06002030
2031 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002032 }
2033
2034 /**
2035 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
2036 * have at least a default mobile policy defined.
2037 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002038 @GuardedBy("mNetworkPoliciesSecondLock")
Hugo Benichi446c9c92017-04-10 09:41:10 +09002039 private void ensureActiveMobilePolicyAL() {
2040 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07002041 if (mSuppressDefaultPolicy) return;
2042
Jeff Sharkey146bb332018-04-18 15:42:57 -06002043 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
2044 final int subId = mSubIdToSubscriberId.keyAt(i);
2045 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002046
Hugo Benichi446c9c92017-04-10 09:41:10 +09002047 ensureActiveMobilePolicyAL(subId, subscriberId);
Jeff Sharkey32566012014-12-02 18:30:14 -08002048 }
2049 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002050
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002051 /**
2052 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
2053 * have at least a default mobile policy defined.
2054 *
2055 * @param subId to build a default policy for
2056 * @param subscriberId that we check for an existing policy
2057 * @return true if a mobile network policy was added, or false one already existed.
2058 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002059 @GuardedBy("mNetworkPoliciesSecondLock")
Hugo Benichi446c9c92017-04-10 09:41:10 +09002060 private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002061 // Poke around to see if we already have a policy
2062 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09002063 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Jeff Sharkey32566012014-12-02 18:30:14 -08002064 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
2065 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
2066 if (template.matches(probeIdent)) {
2067 if (LOGD) {
2068 Slog.d(TAG, "Found template " + template + " which matches subscriber "
2069 + NetworkIdentity.scrubSubscriberId(subscriberId));
2070 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002071 return false;
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002072 }
2073 }
2074
Jeff Sharkey32566012014-12-02 18:30:14 -08002075 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
2076 + "; generating default policy");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002077 final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
Hugo Benichi446c9c92017-04-10 09:41:10 +09002078 addNetworkPolicyAL(policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002079 return true;
2080 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002081
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002082 private long getPlatformDefaultWarningBytes() {
Fan Zhangda71ca02016-09-12 17:36:22 -07002083 final int dataWarningConfig = mContext.getResources().getInteger(
2084 com.android.internal.R.integer.config_networkPolicyDefaultWarning);
Fan Zhangda71ca02016-09-12 17:36:22 -07002085 if (dataWarningConfig == WARNING_DISABLED) {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002086 return WARNING_DISABLED;
Fan Zhangda71ca02016-09-12 17:36:22 -07002087 } else {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002088 return dataWarningConfig * MB_IN_BYTES;
Fan Zhangda71ca02016-09-12 17:36:22 -07002089 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002090 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002091
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002092 private long getPlatformDefaultLimitBytes() {
2093 return LIMIT_DISABLED;
2094 }
2095
2096 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08002097 NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002098 final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002099 final RecurrenceRule cycleRule = NetworkPolicy
2100 .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002101 final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002102 getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(),
2103 SNOOZE_NEVER, SNOOZE_NEVER, true, true);
2104 synchronized (mUidRulesFirstLock) {
2105 synchronized (mNetworkPoliciesSecondLock) {
2106 updateDefaultMobilePolicyAL(subId, policy);
2107 }
2108 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002109 return policy;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002110 }
2111
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002112 /**
2113 * Update the given {@link NetworkPolicy} based on any carrier-provided
2114 * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}.
2115 * Leaves policy untouched if the user has modified it.
2116 *
2117 * @return if the policy was modified
2118 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002119 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002120 private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
2121 if (!policy.inferred) {
2122 if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
2123 return false;
2124 }
2125
2126 final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
2127 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
2128 policy.lastLimitSnooze, policy.metered, policy.inferred);
2129
2130 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
2131 if (!ArrayUtils.isEmpty(plans)) {
2132 final SubscriptionPlan plan = plans[0];
2133 policy.cycleRule = plan.getCycleRule();
2134 final long planLimitBytes = plan.getDataLimitBytes();
2135 if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
2136 policy.warningBytes = getPlatformDefaultWarningBytes();
2137 policy.limitBytes = getPlatformDefaultLimitBytes();
2138 } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
2139 policy.warningBytes = NetworkPolicy.WARNING_DISABLED;
2140 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2141 } else {
2142 policy.warningBytes = (planLimitBytes * 9) / 10;
2143 switch (plan.getDataLimitBehavior()) {
2144 case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED:
2145 case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED:
2146 policy.limitBytes = planLimitBytes;
2147 break;
2148 default:
2149 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2150 break;
2151 }
2152 }
2153 } else {
2154 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
2155 final int currentCycleDay;
2156 if (policy.cycleRule.isMonthly()) {
2157 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
2158 } else {
2159 currentCycleDay = NetworkPolicy.CYCLE_NONE;
2160 }
2161 final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
2162 policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
2163 policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes);
2164 policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes);
2165 }
2166
2167 if (policy.equals(original)) {
2168 return false;
2169 } else {
2170 Slog.d(TAG, "Updated " + original + " to " + policy);
2171 return true;
2172 }
2173 }
2174
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002175 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07002176 private void readPolicyAL() {
2177 if (LOGV) Slog.v(TAG, "readPolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002178
2179 // clear any existing policy and read from disk
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002180 mNetworkPolicy.clear();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002181 mSubscriptionPlans.clear();
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002182 mSubscriptionPlansOwner.clear();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002183 mUidPolicy.clear();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002184
2185 FileInputStream fis = null;
2186 try {
2187 fis = mPolicyFile.openRead();
2188 final XmlPullParser in = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002189 in.setInput(fis, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002190
Felipe Leme46b451f2016-08-19 08:46:17 -07002191 // Must save the <restrict-background> tags and convert them to <uid-policy> later,
2192 // to skip UIDs that were explicitly blacklisted.
2193 final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray();
2194
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002195 int type;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002196 int version = VERSION_INIT;
Felipe Lemeb85a6372016-01-14 16:16:16 -08002197 boolean insideWhitelist = false;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002198 while ((type = in.next()) != END_DOCUMENT) {
2199 final String tag = in.getName();
2200 if (type == START_TAG) {
2201 if (TAG_POLICY_LIST.equals(tag)) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06002202 final boolean oldValue = mRestrictBackground;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002203 version = readIntAttribute(in, ATTR_VERSION);
Sudheer Shanka543339f2017-07-28 15:18:07 -07002204 mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
2205 && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002206 } else if (TAG_NETWORK_POLICY.equals(tag)) {
2207 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
2208 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002209 final String networkId;
2210 if (version >= VERSION_ADDED_NETWORK_ID) {
2211 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
2212 } else {
2213 networkId = null;
2214 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002215 final RecurrenceRule cycleRule;
2216 if (version >= VERSION_ADDED_CYCLE) {
2217 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2218 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2219 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2220 cycleRule = new RecurrenceRule(
2221 RecurrenceRule.convertZonedDateTime(start),
2222 RecurrenceRule.convertZonedDateTime(end),
2223 RecurrenceRule.convertPeriod(period));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002224 } else {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002225 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
2226 final String cycleTimezone;
2227 if (version >= VERSION_ADDED_TIMEZONE) {
2228 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
2229 } else {
2230 cycleTimezone = "UTC";
2231 }
2232 cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002233 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002234 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
2235 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002236 final long lastLimitSnooze;
2237 if (version >= VERSION_SPLIT_SNOOZE) {
2238 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
2239 } else if (version >= VERSION_ADDED_SNOOZE) {
2240 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002241 } else {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002242 lastLimitSnooze = SNOOZE_NEVER;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002243 }
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002244 final boolean metered;
2245 if (version >= VERSION_ADDED_METERED) {
2246 metered = readBooleanAttribute(in, ATTR_METERED);
2247 } else {
2248 switch (networkTemplate) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07002249 case MATCH_MOBILE:
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002250 metered = true;
2251 break;
2252 default:
2253 metered = false;
2254 }
2255 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002256 final long lastWarningSnooze;
2257 if (version >= VERSION_SPLIT_SNOOZE) {
2258 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
2259 } else {
2260 lastWarningSnooze = SNOOZE_NEVER;
2261 }
Jeff Sharkey837f9242012-03-20 16:52:20 -07002262 final boolean inferred;
2263 if (version >= VERSION_ADDED_INFERRED) {
2264 inferred = readBooleanAttribute(in, ATTR_INFERRED);
2265 } else {
2266 inferred = false;
2267 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002268
Jeff Sharkey32566012014-12-02 18:30:14 -08002269 final NetworkTemplate template = new NetworkTemplate(networkTemplate,
2270 subscriberId, networkId);
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002271 if (template.isPersistable()) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002272 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
2273 warningBytes, limitBytes, lastWarningSnooze,
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002274 lastLimitSnooze, metered, inferred));
2275 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002276
2277 } else if (TAG_SUBSCRIPTION_PLAN.equals(tag)) {
2278 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2279 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2280 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2281 final SubscriptionPlan.Builder builder = new SubscriptionPlan.Builder(
2282 RecurrenceRule.convertZonedDateTime(start),
2283 RecurrenceRule.convertZonedDateTime(end),
2284 RecurrenceRule.convertPeriod(period));
2285 builder.setTitle(readStringAttribute(in, ATTR_TITLE));
2286 builder.setSummary(readStringAttribute(in, ATTR_SUMMARY));
2287
2288 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES,
2289 SubscriptionPlan.BYTES_UNKNOWN);
2290 final int limitBehavior = readIntAttribute(in, ATTR_LIMIT_BEHAVIOR,
2291 SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN);
2292 if (limitBytes != SubscriptionPlan.BYTES_UNKNOWN
2293 && limitBehavior != SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
2294 builder.setDataLimit(limitBytes, limitBehavior);
2295 }
2296
2297 final long usageBytes = readLongAttribute(in, ATTR_USAGE_BYTES,
2298 SubscriptionPlan.BYTES_UNKNOWN);
2299 final long usageTime = readLongAttribute(in, ATTR_USAGE_TIME,
2300 SubscriptionPlan.TIME_UNKNOWN);
2301 if (usageBytes != SubscriptionPlan.BYTES_UNKNOWN
2302 && usageTime != SubscriptionPlan.TIME_UNKNOWN) {
2303 builder.setDataUsage(usageBytes, usageTime);
2304 }
2305
2306 final int subId = readIntAttribute(in, ATTR_SUB_ID);
2307 final SubscriptionPlan plan = builder.build();
2308 mSubscriptionPlans.put(subId, ArrayUtils.appendElement(
2309 SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
2310
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002311 final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
2312 mSubscriptionPlansOwner.put(subId, ownerPackage);
2313
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002314 } else if (TAG_UID_POLICY.equals(tag)) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002315 final int uid = readIntAttribute(in, ATTR_UID);
2316 final int policy = readIntAttribute(in, ATTR_POLICY);
2317
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002318 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002319 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002320 } else {
2321 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
2322 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002323 } else if (TAG_APP_POLICY.equals(tag)) {
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002324 final int appId = readIntAttribute(in, ATTR_APP_ID);
2325 final int policy = readIntAttribute(in, ATTR_POLICY);
2326
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002327 // TODO: set for other users during upgrade
Xiaohui Chenbe3b0672015-09-02 13:29:22 -07002328 // app policy is deprecated so this is only used in pre system user split.
2329 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002330 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002331 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002332 } else {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002333 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002334 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002335 } else if (TAG_WHITELIST.equals(tag)) {
2336 insideWhitelist = true;
2337 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2338 final int uid = readIntAttribute(in, ATTR_UID);
Felipe Leme46b451f2016-08-19 08:46:17 -07002339 whitelistedRestrictBackground.append(uid, true);
Felipe Lemea9505cc2016-02-26 10:28:41 -08002340 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2341 final int uid = readIntAttribute(in, ATTR_UID);
2342 mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002343 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002344 } else if (type == END_TAG) {
2345 if (TAG_WHITELIST.equals(tag)) {
2346 insideWhitelist = false;
2347 }
2348
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002349 }
2350 }
2351
Felipe Leme46b451f2016-08-19 08:46:17 -07002352 final int size = whitelistedRestrictBackground.size();
2353 for (int i = 0; i < size; i++) {
2354 final int uid = whitelistedRestrictBackground.keyAt(i);
2355 final int policy = mUidPolicy.get(uid, POLICY_NONE);
2356 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
2357 Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid
2358 + " because its policy is " + uidPoliciesToString(policy));
2359 continue;
2360 }
2361 if (UserHandle.isApp(uid)) {
2362 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
2363 if (LOGV)
2364 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
2365 setUidPolicyUncheckedUL(uid, newPolicy, false);
2366 } else {
2367 Slog.w(TAG, "unable to update policy on UID " + uid);
2368 }
2369 }
2370
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002371 } catch (FileNotFoundException e) {
2372 // missing policy is okay, probably first boot
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002373 upgradeDefaultBackgroundDataUL();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002374 } catch (Exception e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07002375 Log.wtf(TAG, "problem reading network policy", e);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002376 } finally {
2377 IoUtils.closeQuietly(fis);
2378 }
2379 }
2380
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002381 /**
2382 * Upgrade legacy background data flags, notifying listeners of one last
2383 * change to always-true.
2384 */
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002385 private void upgradeDefaultBackgroundDataUL() {
2386 // This method is only called when we're unable to find the network policy flag, which
2387 // usually happens on first boot of a new device and not one that has received an OTA.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002388
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002389 // Seed from the default value configured for this device.
Sudheer Shanka543339f2017-07-28 15:18:07 -07002390 mLoadedRestrictBackground = Settings.Global.getInt(
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002391 mContext.getContentResolver(), Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 0) == 1;
2392
2393 // NOTE: We used to read the legacy setting here :
2394 //
2395 // final int legacyFlagValue = Settings.Secure.getInt(
2396 // mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..);
2397 //
2398 // This is no longer necessary because we will never upgrade directly from Gingerbread
2399 // to O+. Devices upgrading from ICS onwards to O will have a netpolicy.xml file that
2400 // contains the correct value that we will continue to use.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002401 }
2402
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002403 /**
2404 * Perform upgrade step of moving any user-defined meterness overrides over
2405 * into {@link WifiConfiguration}.
2406 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002407 @GuardedBy({"mNetworkPoliciesSecondLock", "mUidRulesFirstLock"})
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002408 private void upgradeWifiMeteredOverrideAL() {
2409 boolean modified = false;
2410 final WifiManager wm = mContext.getSystemService(WifiManager.class);
2411 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2412 for (int i = 0; i < mNetworkPolicy.size(); ) {
2413 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2414 if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
2415 && !policy.inferred) {
2416 mNetworkPolicy.removeAt(i);
2417 modified = true;
2418
2419 final String networkId = resolveNetworkId(policy.template.getNetworkId());
2420 for (WifiConfiguration config : configs) {
2421 if (Objects.equals(resolveNetworkId(config), networkId)) {
2422 Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint");
2423 config.meteredOverride = policy.metered
2424 ? WifiConfiguration.METERED_OVERRIDE_METERED
2425 : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
2426 wm.updateNetwork(config);
2427 }
2428 }
2429 } else {
2430 i++;
2431 }
2432 }
2433 if (modified) {
2434 writePolicyAL();
2435 }
2436 }
2437
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002438 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07002439 void writePolicyAL() {
2440 if (LOGV) Slog.v(TAG, "writePolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002441
2442 FileOutputStream fos = null;
2443 try {
2444 fos = mPolicyFile.startWrite();
2445
2446 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002447 out.setOutput(fos, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002448 out.startDocument(null, true);
2449
2450 out.startTag(null, TAG_POLICY_LIST);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002451 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
Jeff Sharkey46645002011-07-27 21:11:21 -07002452 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002453
2454 // write all known network policies
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002455 for (int i = 0; i < mNetworkPolicy.size(); i++) {
2456 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002457 final NetworkTemplate template = policy.template;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002458 if (!template.isPersistable()) continue;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002459
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002460 out.startTag(null, TAG_NETWORK_POLICY);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002461 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
2462 final String subscriberId = template.getSubscriberId();
2463 if (subscriberId != null) {
2464 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002465 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002466 final String networkId = template.getNetworkId();
2467 if (networkId != null) {
2468 out.attribute(null, ATTR_NETWORK_ID, networkId);
2469 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002470 writeStringAttribute(out, ATTR_CYCLE_START,
2471 RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
2472 writeStringAttribute(out, ATTR_CYCLE_END,
2473 RecurrenceRule.convertZonedDateTime(policy.cycleRule.end));
2474 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2475 RecurrenceRule.convertPeriod(policy.cycleRule.period));
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002476 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
2477 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002478 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
2479 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002480 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
Jeff Sharkey837f9242012-03-20 16:52:20 -07002481 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002482 out.endTag(null, TAG_NETWORK_POLICY);
2483 }
2484
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002485 // write all known subscription plans
2486 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
2487 final int subId = mSubscriptionPlans.keyAt(i);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002488 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002489 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
2490 if (ArrayUtils.isEmpty(plans)) continue;
2491
2492 for (SubscriptionPlan plan : plans) {
2493 out.startTag(null, TAG_SUBSCRIPTION_PLAN);
2494 writeIntAttribute(out, ATTR_SUB_ID, subId);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002495 writeStringAttribute(out, ATTR_OWNER_PACKAGE, ownerPackage);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002496 final RecurrenceRule cycleRule = plan.getCycleRule();
2497 writeStringAttribute(out, ATTR_CYCLE_START,
2498 RecurrenceRule.convertZonedDateTime(cycleRule.start));
2499 writeStringAttribute(out, ATTR_CYCLE_END,
2500 RecurrenceRule.convertZonedDateTime(cycleRule.end));
2501 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2502 RecurrenceRule.convertPeriod(cycleRule.period));
2503 writeStringAttribute(out, ATTR_TITLE, plan.getTitle());
2504 writeStringAttribute(out, ATTR_SUMMARY, plan.getSummary());
2505 writeLongAttribute(out, ATTR_LIMIT_BYTES, plan.getDataLimitBytes());
2506 writeIntAttribute(out, ATTR_LIMIT_BEHAVIOR, plan.getDataLimitBehavior());
2507 writeLongAttribute(out, ATTR_USAGE_BYTES, plan.getDataUsageBytes());
2508 writeLongAttribute(out, ATTR_USAGE_TIME, plan.getDataUsageTime());
2509 out.endTag(null, TAG_SUBSCRIPTION_PLAN);
2510 }
2511 }
2512
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002513 // write all known uid policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002514 for (int i = 0; i < mUidPolicy.size(); i++) {
2515 final int uid = mUidPolicy.keyAt(i);
2516 final int policy = mUidPolicy.valueAt(i);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002517
Jeff Sharkey497e4432011-06-14 17:27:29 -07002518 // skip writing empty policies
2519 if (policy == POLICY_NONE) continue;
2520
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002521 out.startTag(null, TAG_UID_POLICY);
2522 writeIntAttribute(out, ATTR_UID, uid);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002523 writeIntAttribute(out, ATTR_POLICY, policy);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002524 out.endTag(null, TAG_UID_POLICY);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002525 }
2526
2527 out.endTag(null, TAG_POLICY_LIST);
Felipe Lemeb85a6372016-01-14 16:16:16 -08002528
2529 // write all whitelists
2530 out.startTag(null, TAG_WHITELIST);
2531
Felipe Lemea9505cc2016-02-26 10:28:41 -08002532 // revoked restrict background whitelist
Felipe Leme46b451f2016-08-19 08:46:17 -07002533 int size = mRestrictBackgroundWhitelistRevokedUids.size();
Felipe Lemea9505cc2016-02-26 10:28:41 -08002534 for (int i = 0; i < size; i++) {
2535 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2536 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2537 writeIntAttribute(out, ATTR_UID, uid);
2538 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2539 }
2540
Felipe Lemeb85a6372016-01-14 16:16:16 -08002541 out.endTag(null, TAG_WHITELIST);
2542
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002543 out.endDocument();
2544
2545 mPolicyFile.finishWrite(fos);
2546 } catch (IOException e) {
2547 if (fos != null) {
2548 mPolicyFile.failWrite(fos);
2549 }
2550 }
2551 }
2552
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002553 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002554 public void setUidPolicy(int uid, int policy) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002555 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002556
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002557 if (!UserHandle.isApp(uid)) {
2558 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002559 }
Felipe Lemef0823852016-06-08 13:43:08 -07002560 synchronized (mUidRulesFirstLock) {
Julia Reynolds72f83d62015-07-27 15:10:42 -04002561 final long token = Binder.clearCallingIdentity();
2562 try {
2563 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2564 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002565 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002566 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Julia Reynolds72f83d62015-07-27 15:10:42 -04002567 }
2568 } finally {
2569 Binder.restoreCallingIdentity(token);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002570 }
2571 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07002572 }
2573
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002574 @Override
2575 public void addUidPolicy(int uid, int policy) {
2576 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002577
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002578 if (!UserHandle.isApp(uid)) {
2579 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2580 }
2581
Felipe Lemef0823852016-06-08 13:43:08 -07002582 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002583 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2584 policy |= oldPolicy;
2585 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002586 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002587 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002588 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002589 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002590 }
2591
2592 @Override
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002593 public void removeUidPolicy(int uid, int policy) {
2594 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2595
2596 if (!UserHandle.isApp(uid)) {
2597 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2598 }
2599
Felipe Lemef0823852016-06-08 13:43:08 -07002600 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002601 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2602 policy = oldPolicy & ~policy;
2603 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002604 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002605 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002606 }
2607 }
2608 }
2609
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002610 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002611 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002612 setUidPolicyUncheckedUL(uid, policy, false);
Felipe Leme923845f2016-03-02 13:42:48 -08002613
Felipe Leme57e3d312016-08-23 14:42:52 -07002614 final boolean notifyApp;
2615 if (!isUidValidForWhitelistRules(uid)) {
2616 notifyApp = false;
2617 } else {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002618 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
2619 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
2620 final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
2621 final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND;
Felipe Leme57e3d312016-08-23 14:42:52 -07002622 final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted);
2623 final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted);
Felipe Leme03f90292016-09-08 18:10:32 -07002624 if ((wasWhitelisted && (!isWhitelisted || isBlacklisted))
2625 && mDefaultRestrictBackgroundWhitelistUids.get(uid)
2626 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2627 if (LOGD)
2628 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist");
2629 mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2630 }
Felipe Leme57e3d312016-08-23 14:42:52 -07002631 notifyApp = wasBlocked != isBlocked;
2632 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002633 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2634 .sendToTarget();
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002635 if (persist) {
2636 synchronized (mNetworkPoliciesSecondLock) {
2637 writePolicyAL();
2638 }
2639 }
Felipe Leme923845f2016-03-02 13:42:48 -08002640 }
2641
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002642 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002643 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
Felipe Leme03f90292016-09-08 18:10:32 -07002644 if (policy == POLICY_NONE) {
2645 mUidPolicy.delete(uid);
2646 } else {
2647 mUidPolicy.put(uid, policy);
2648 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002649
2650 // uid policy changed, recompute rules and persist policy.
Sudheer Shankac9d94072017-02-22 22:13:55 +00002651 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002652 if (persist) {
Felipe Lemef0823852016-06-08 13:43:08 -07002653 synchronized (mNetworkPoliciesSecondLock) {
2654 writePolicyAL();
2655 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002656 }
2657 }
2658
2659 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002660 public int getUidPolicy(int uid) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002661 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2662
Felipe Lemef0823852016-06-08 13:43:08 -07002663 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002664 return mUidPolicy.get(uid, POLICY_NONE);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002665 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002666 }
2667
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002668 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002669 public int[] getUidsWithPolicy(int policy) {
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002670 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2671
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002672 int[] uids = new int[0];
Felipe Lemef0823852016-06-08 13:43:08 -07002673 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002674 for (int i = 0; i < mUidPolicy.size(); i++) {
2675 final int uid = mUidPolicy.keyAt(i);
2676 final int uidPolicy = mUidPolicy.valueAt(i);
Felipe Leme6f51a0a2016-08-24 15:11:51 -07002677 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
2678 (uidPolicy & policy) != 0) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002679 uids = appendInt(uids, uid);
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002680 }
2681 }
2682 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002683 return uids;
2684 }
2685
2686 /**
Felipe Lemed17fda42016-04-29 11:12:45 -07002687 * Removes any persistable state associated with given {@link UserHandle}, persisting
2688 * if any changes that are made.
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002689 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002690 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002691 boolean removeUserStateUL(int userId, boolean writePolicy) {
Felipe Lemed17fda42016-04-29 11:12:45 -07002692
Sudheer Shanka352dc572017-09-22 17:09:38 -07002693 mLogger.removingUserState(userId);
Felipe Lemed17fda42016-04-29 11:12:45 -07002694 boolean changed = false;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002695
Felipe Lemea110eec2016-04-29 09:58:06 -07002696 // Remove entries from revoked default restricted background UID whitelist
2697 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
2698 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2699 if (UserHandle.getUserId(uid) == userId) {
2700 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
Felipe Lemed17fda42016-04-29 11:12:45 -07002701 changed = true;
Felipe Lemea110eec2016-04-29 09:58:06 -07002702 }
2703 }
2704
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002705 // Remove associated UID policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002706 int[] uids = new int[0];
2707 for (int i = 0; i < mUidPolicy.size(); i++) {
2708 final int uid = mUidPolicy.keyAt(i);
2709 if (UserHandle.getUserId(uid) == userId) {
2710 uids = appendInt(uids, uid);
2711 }
2712 }
2713
2714 if (uids.length > 0) {
2715 for (int uid : uids) {
2716 mUidPolicy.delete(uid);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002717 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002718 changed = true;
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002719 }
Felipe Lemef0823852016-06-08 13:43:08 -07002720 synchronized (mNetworkPoliciesSecondLock) {
2721 updateRulesForGlobalChangeAL(true);
2722 if (writePolicy && changed) {
2723 writePolicyAL();
2724 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002725 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002726 return changed;
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002727 }
2728
paulhua6af6b62019-08-12 16:25:11 +08002729 private boolean checkAnyPermissionOf(String... permissions) {
2730 for (String permission : permissions) {
2731 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
2732 return true;
2733 }
2734 }
2735 return false;
2736 }
2737
2738 private void enforceAnyPermissionOf(String... permissions) {
2739 if (!checkAnyPermissionOf(permissions)) {
2740 throw new SecurityException("Requires one of the following permissions: "
2741 + String.join(", ", permissions) + ".");
2742 }
2743 }
2744
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002745 @Override
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002746 public void registerListener(INetworkPolicyListener listener) {
paulhua6af6b62019-08-12 16:25:11 +08002747 // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
2748 // have declared OBSERVE_NETWORK_POLICY.
2749 enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002750 mListeners.register(listener);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002751 }
2752
2753 @Override
2754 public void unregisterListener(INetworkPolicyListener listener) {
paulhua6af6b62019-08-12 16:25:11 +08002755 // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
2756 // have declared OBSERVE_NETWORK_POLICY.
2757 enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002758 mListeners.unregister(listener);
2759 }
2760
Jeff Sharkey1b861272011-05-22 00:34:52 -07002761 @Override
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002762 public void setNetworkPolicies(NetworkPolicy[] policies) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002763 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2764
Felipe Leme6a05eee2016-02-19 14:43:51 -08002765 final long token = Binder.clearCallingIdentity();
2766 try {
Felipe Lemef0823852016-06-08 13:43:08 -07002767 synchronized (mUidRulesFirstLock) {
2768 synchronized (mNetworkPoliciesSecondLock) {
2769 normalizePoliciesNL(policies);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002770 handleNetworkPoliciesUpdateAL(false);
Felipe Lemef0823852016-06-08 13:43:08 -07002771 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002772 }
2773 } finally {
2774 Binder.restoreCallingIdentity(token);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002775 }
2776 }
2777
Hugo Benichi446c9c92017-04-10 09:41:10 +09002778 void addNetworkPolicyAL(NetworkPolicy policy) {
Svet Ganov16a16892015-04-16 10:32:04 -07002779 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Jeff Sharkey32566012014-12-02 18:30:14 -08002780 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
2781 setNetworkPolicies(policies);
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07002782 }
2783
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002784 @Override
Svet Ganov16a16892015-04-16 10:32:04 -07002785 public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002786 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002787 try {
Amit Mahajana9e72a72015-07-30 16:04:13 -07002788 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
2789 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
2790 // permission
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002791 } catch (SecurityException e) {
2792 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002793
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002794 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
2795 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2796 return new NetworkPolicy[0];
2797 }
Svet Ganov16a16892015-04-16 10:32:04 -07002798 }
2799
Felipe Lemef0823852016-06-08 13:43:08 -07002800 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002801 final int size = mNetworkPolicy.size();
2802 final NetworkPolicy[] policies = new NetworkPolicy[size];
2803 for (int i = 0; i < size; i++) {
2804 policies[i] = mNetworkPolicy.valueAt(i);
2805 }
2806 return policies;
2807 }
2808 }
2809
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002810 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002811 private void normalizePoliciesNL() {
2812 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
Jeff Sharkey32566012014-12-02 18:30:14 -08002813 }
2814
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002815 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002816 private void normalizePoliciesNL(NetworkPolicy[] policies) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002817 mNetworkPolicy.clear();
2818 for (NetworkPolicy policy : policies) {
Annie Meng20b4d842018-05-18 15:00:49 +01002819 if (policy == null) {
2820 continue;
2821 }
Jeff Sharkey32566012014-12-02 18:30:14 -08002822 // When two normalized templates conflict, prefer the most
2823 // restrictive policy
Jeff Sharkey146bb332018-04-18 15:42:57 -06002824 policy.template = NetworkTemplate.normalize(policy.template, mMergedSubscriberIds);
Jeff Sharkey32566012014-12-02 18:30:14 -08002825 final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
2826 if (existing == null || existing.compareTo(policy) > 0) {
2827 if (existing != null) {
2828 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
2829 }
2830 mNetworkPolicy.put(policy.template, policy);
2831 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002832 }
2833 }
2834
2835 @Override
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002836 public void snoozeLimit(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002837 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkey6c0b4f32012-06-12 21:06:30 -07002838
2839 final long token = Binder.clearCallingIdentity();
2840 try {
2841 performSnooze(template, TYPE_LIMIT);
2842 } finally {
2843 Binder.restoreCallingIdentity(token);
2844 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002845 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002846
Dianne Hackborn497175b2014-07-01 12:56:08 -07002847 void performSnooze(NetworkTemplate template, int type) {
Jeff Sharkey9911a282018-02-14 22:29:11 -07002848 final long currentTime = mClock.millis();
Felipe Lemef0823852016-06-08 13:43:08 -07002849 synchronized (mUidRulesFirstLock) {
2850 synchronized (mNetworkPoliciesSecondLock) {
2851 // find and snooze local policy that matches
2852 final NetworkPolicy policy = mNetworkPolicy.get(template);
2853 if (policy == null) {
2854 throw new IllegalArgumentException("unable to find policy for " + template);
2855 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002856
Felipe Lemef0823852016-06-08 13:43:08 -07002857 switch (type) {
2858 case TYPE_WARNING:
2859 policy.lastWarningSnooze = currentTime;
2860 break;
2861 case TYPE_LIMIT:
2862 policy.lastLimitSnooze = currentTime;
2863 break;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07002864 case TYPE_RAPID:
2865 policy.lastRapidSnooze = currentTime;
2866 break;
Felipe Lemef0823852016-06-08 13:43:08 -07002867 default:
2868 throw new IllegalArgumentException("unexpected type");
2869 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002870
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002871 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07002872 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002873 }
2874 }
2875
2876 @Override
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002877 public void onTetheringChanged(String iface, boolean tethering) {
2878 // No need to enforce permission because setRestrictBackground() will do it.
Felipe Lemef0823852016-06-08 13:43:08 -07002879 synchronized (mUidRulesFirstLock) {
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002880 if (mRestrictBackground && tethering) {
2881 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
2882 setRestrictBackground(false);
2883 }
2884 }
2885 }
2886
2887 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002888 public void setRestrictBackground(boolean restrictBackground) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002889 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
Felipe Leme6a05eee2016-02-19 14:43:51 -08002890 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002891 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2892 final long token = Binder.clearCallingIdentity();
2893 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002894 synchronized (mUidRulesFirstLock) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002895 setRestrictBackgroundUL(restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002896 }
Felipe Leme29e72ea2016-09-08 13:26:55 -07002897 } finally {
2898 Binder.restoreCallingIdentity(token);
Felipe Leme6a05eee2016-02-19 14:43:51 -08002899 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002900 } finally {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002901 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey46645002011-07-27 21:11:21 -07002902 }
2903 }
2904
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002905 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002906 private void setRestrictBackgroundUL(boolean restrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002907 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL");
Felipe Leme70c57c22016-03-29 10:45:13 -07002908 try {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002909 if (restrictBackground == mRestrictBackground) {
2910 // Ideally, UI should never allow this scenario...
2911 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002912 return;
2913 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002914 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
2915 final boolean oldRestrictBackground = mRestrictBackground;
2916 mRestrictBackground = restrictBackground;
2917 // Must whitelist foreground apps before turning data saver mode on.
2918 // TODO: there is no need to iterate through all apps here, just those in the foreground,
2919 // so it could call AM to get the UIDs of such apps, and iterate through them instead.
2920 updateRulesForRestrictBackgroundUL();
2921 try {
2922 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
2923 Slog.e(TAG,
2924 "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
2925 mRestrictBackground = oldRestrictBackground;
2926 // TODO: if it knew the foreground apps (see TODO above), it could call
2927 // updateRulesForRestrictBackgroundUL() again to restore state.
2928 return;
2929 }
2930 } catch (RemoteException e) {
2931 // ignored; service lives in system_server
2932 }
jackqdyulei29c82ab2017-03-10 14:09:16 -08002933
Sudheer Shanka543339f2017-07-28 15:18:07 -07002934 sendRestrictBackgroundChangedMsg();
Sudheer Shanka352dc572017-09-22 17:09:38 -07002935 mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
Sudheer Shanka543339f2017-07-28 15:18:07 -07002936
Kweku Adams25fa3a72019-07-12 17:00:17 -07002937 if (mRestrictBackgroundLowPowerMode) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002938 mRestrictBackgroundChangedInBsm = true;
2939 }
2940 synchronized (mNetworkPoliciesSecondLock) {
2941 updateNotificationsNL();
2942 writePolicyAL();
2943 }
2944 } finally {
2945 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
jackqdyulei29c82ab2017-03-10 14:09:16 -08002946 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002947 }
2948
2949 private void sendRestrictBackgroundChangedMsg() {
2950 mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED);
2951 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0)
2952 .sendToTarget();
Felipe Leme70c57c22016-03-29 10:45:13 -07002953 }
2954
Felipe Lemeb85a6372016-01-14 16:16:16 -08002955 @Override
Felipe Leme1b103232016-01-22 09:44:57 -08002956 public int getRestrictBackgroundByCaller() {
2957 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2958 final int uid = Binder.getCallingUid();
Felipe Leme923845f2016-03-02 13:42:48 -08002959
Felipe Lemef0823852016-06-08 13:43:08 -07002960 synchronized (mUidRulesFirstLock) {
Felipe Leme923845f2016-03-02 13:42:48 -08002961 // Must clear identity because getUidPolicy() is restricted to system.
2962 final long token = Binder.clearCallingIdentity();
2963 final int policy;
2964 try {
2965 policy = getUidPolicy(uid);
2966 } finally {
2967 Binder.restoreCallingIdentity(token);
2968 }
2969 if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2970 // App is blacklisted.
2971 return RESTRICT_BACKGROUND_STATUS_ENABLED;
2972 }
Felipe Leme1b103232016-01-22 09:44:57 -08002973 if (!mRestrictBackground) {
2974 return RESTRICT_BACKGROUND_STATUS_DISABLED;
2975 }
Felipe Leme46b451f2016-08-19 08:46:17 -07002976 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
Felipe Leme1b103232016-01-22 09:44:57 -08002977 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2978 : RESTRICT_BACKGROUND_STATUS_ENABLED;
2979 }
2980 }
2981
2982 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002983 public boolean getRestrictBackground() {
2984 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2985
Felipe Lemef0823852016-06-08 13:43:08 -07002986 synchronized (mUidRulesFirstLock) {
Jeff Sharkey46645002011-07-27 21:11:21 -07002987 return mRestrictBackground;
2988 }
2989 }
2990
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002991 @Override
2992 public void setDeviceIdleMode(boolean enabled) {
2993 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Felipe Leme873a83a2016-09-07 11:34:10 -07002994 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2995 try {
2996 synchronized (mUidRulesFirstLock) {
Felipe Lemeea014392016-09-06 13:59:54 -07002997 if (mDeviceIdleMode == enabled) {
2998 return;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002999 }
Felipe Lemeea014392016-09-06 13:59:54 -07003000 mDeviceIdleMode = enabled;
Sudheer Shanka352dc572017-09-22 17:09:38 -07003001 mLogger.deviceIdleModeEnabled(enabled);
Felipe Lemeea014392016-09-06 13:59:54 -07003002 if (mSystemReady) {
3003 // Device idle change means we need to rebuild rules for all
3004 // known apps, so do a global refresh.
3005 updateRulesForRestrictPowerUL();
3006 }
3007 }
3008 if (enabled) {
3009 EventLogTags.writeDeviceIdleOnPhase("net");
3010 } else {
3011 EventLogTags.writeDeviceIdleOffPhase("net");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003012 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003013 } finally {
3014 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003015 }
3016 }
3017
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07003018 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06003019 public void setWifiMeteredOverride(String networkId, int meteredOverride) {
3020 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07003021 final long token = Binder.clearCallingIdentity();
3022 try {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06003023 final WifiManager wm = mContext.getSystemService(WifiManager.class);
3024 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
3025 for (WifiConfiguration config : configs) {
3026 if (Objects.equals(resolveNetworkId(config), networkId)) {
3027 config.meteredOverride = meteredOverride;
3028 wm.updateNetwork(config);
3029 }
3030 }
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07003031 } finally {
3032 Binder.restoreCallingIdentity(token);
3033 }
3034 }
3035
Jeff Sharkey46645002011-07-27 21:11:21 -07003036 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06003037 @Deprecated
3038 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
3039 Log.w(TAG, "Shame on UID " + Binder.getCallingUid()
3040 + " for calling the hidden API getNetworkQuotaInfo(). Shame!");
3041 return new NetworkQuotaInfo();
Jeff Sharkey9f7cbf02012-04-12 18:34:54 -07003042 }
3043
Jeff Sharkey53313d72017-07-13 16:47:32 -06003044 private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) {
3045 // Verify they're not lying about package name
3046 mAppOps.checkPackage(callingUid, callingPackage);
3047
Jeff Sharkey53313d72017-07-13 16:47:32 -06003048 final SubscriptionInfo si;
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003049 final PersistableBundle config;
Jeff Sharkey53313d72017-07-13 16:47:32 -06003050 final long token = Binder.clearCallingIdentity();
3051 try {
3052 si = mContext.getSystemService(SubscriptionManager.class)
3053 .getActiveSubscriptionInfo(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003054 config = mCarrierConfigManager.getConfigForSubId(subId);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003055 } finally {
3056 Binder.restoreCallingIdentity(token);
3057 }
3058
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003059 // First check: is caller the CarrierService?
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003060 if (si != null) {
3061 if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
3062 return;
3063 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003064 }
3065
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003066 // Second check: has the CarrierService delegated access?
3067 if (config != null) {
3068 final String overridePackage = config
3069 .getString(CarrierConfigManager.KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING, null);
3070 if (!TextUtils.isEmpty(overridePackage)
3071 && Objects.equals(overridePackage, callingPackage)) {
3072 return;
3073 }
3074 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003075
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003076 // Third check: is caller the fallback/default CarrierService?
3077 final String defaultPackage = mCarrierConfigManager.getDefaultCarrierServicePackageName();
3078 if (!TextUtils.isEmpty(defaultPackage)
3079 && Objects.equals(defaultPackage, callingPackage)) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06003080 return;
3081 }
3082
Jeff Sharkey003d3e62018-03-30 14:35:04 -06003083 // Fourth check: is caller a testing app?
3084 final String testPackage = SystemProperties.get(PROP_SUB_PLAN_OWNER + "." + subId, null);
3085 if (!TextUtils.isEmpty(testPackage)
3086 && Objects.equals(testPackage, callingPackage)) {
3087 return;
3088 }
3089
3090 // Fifth check: is caller a legacy testing app?
3091 final String legacyTestPackage = SystemProperties.get("fw.sub_plan_owner." + subId, null);
3092 if (!TextUtils.isEmpty(legacyTestPackage)
3093 && Objects.equals(legacyTestPackage, callingPackage)) {
Jeff Sharkeya7f50462018-02-14 14:26:10 -07003094 return;
3095 }
3096
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003097 // Final check: does the caller hold a permission?
3098 mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003099 }
3100
Sarah Chin7af1fd02019-09-26 11:37:13 -07003101 private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
3102 // nothing to check if no plans
3103 if (plans.length == 0) {
3104 return;
3105 }
3106
3107 long applicableNetworkTypes = 0;
3108 boolean allNetworks = false;
3109 for (SubscriptionPlan plan : plans) {
3110 if (plan.getNetworkTypes() == null) {
3111 allNetworks = true;
3112 } else {
3113 if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) {
3114 throw new IllegalArgumentException(
3115 "Multiple subscription plans defined for a single network type.");
3116 } else {
3117 applicableNetworkTypes |= plan.getNetworkTypesBitMask();
3118 }
3119 }
3120 }
3121
3122 // ensure at least one plan applies for every network type
3123 if (!allNetworks) {
3124 throw new IllegalArgumentException(
3125 "No generic subscription plan that applies to all network types.");
3126 }
3127 }
3128
Jeff Sharkey53313d72017-07-13 16:47:32 -06003129 @Override
3130 public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
3131 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3132
Jeff Sharkey53313d72017-07-13 16:47:32 -06003133 final String fake = SystemProperties.get("fw.fake_plan");
3134 if (!TextUtils.isEmpty(fake)) {
3135 final List<SubscriptionPlan> plans = new ArrayList<>();
3136 if ("month_hard".equals(fake)) {
3137 plans.add(SubscriptionPlan.Builder
3138 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3139 .setTitle("G-Mobile")
Jeff Sharkey53313d72017-07-13 16:47:32 -06003140 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3141 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3142 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
3143 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3144 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003145 plans.add(SubscriptionPlan.Builder
3146 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3147 .setTitle("G-Mobile Happy")
3148 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3149 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3150 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3151 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3152 .build());
3153 plans.add(SubscriptionPlan.Builder
3154 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3155 .setTitle("G-Mobile, Charged after limit")
3156 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3157 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3158 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3159 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3160 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003161 } else if ("month_soft".equals(fake)) {
3162 plans.add(SubscriptionPlan.Builder
3163 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3164 .setTitle("G-Mobile is the carriers name who this plan belongs to")
3165 .setSummary("Crazy unlimited bandwidth plan with incredibly long title "
3166 + "that should be cut off to prevent UI from looking terrible")
Jeff Sharkey53313d72017-07-13 16:47:32 -06003167 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3168 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3169 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
3170 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3171 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003172 plans.add(SubscriptionPlan.Builder
3173 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3174 .setTitle("G-Mobile, Throttled after limit")
3175 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3176 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3177 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3178 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3179 .build());
3180 plans.add(SubscriptionPlan.Builder
3181 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3182 .setTitle("G-Mobile, No data connection after limit")
3183 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3184 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3185 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3186 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3187 .build());
3188
Sundeep Ghuman09e0f572018-03-14 23:20:23 -07003189 } else if ("month_over".equals(fake)) {
3190 plans.add(SubscriptionPlan.Builder
3191 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3192 .setTitle("G-Mobile is the carriers name who this plan belongs to")
3193 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3194 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3195 .setDataUsage(6 * TrafficStats.GB_IN_BYTES,
3196 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3197 .build());
3198 plans.add(SubscriptionPlan.Builder
3199 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3200 .setTitle("G-Mobile, Throttled after limit")
3201 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3202 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3203 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3204 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3205 .build());
3206 plans.add(SubscriptionPlan.Builder
3207 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3208 .setTitle("G-Mobile, No data connection after limit")
3209 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3210 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3211 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3212 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3213 .build());
3214
Jeff Sharkey53313d72017-07-13 16:47:32 -06003215 } else if ("month_none".equals(fake)) {
3216 plans.add(SubscriptionPlan.Builder
3217 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3218 .setTitle("G-Mobile")
3219 .build());
3220 } else if ("prepaid".equals(fake)) {
3221 plans.add(SubscriptionPlan.Builder
3222 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3223 ZonedDateTime.now().plusDays(10))
3224 .setTitle("G-Mobile")
3225 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
3226 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3227 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
3228 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3229 .build());
3230 } else if ("prepaid_crazy".equals(fake)) {
3231 plans.add(SubscriptionPlan.Builder
3232 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3233 ZonedDateTime.now().plusDays(10))
3234 .setTitle("G-Mobile Anytime")
3235 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
3236 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3237 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
3238 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3239 .build());
3240 plans.add(SubscriptionPlan.Builder
3241 .createNonrecurring(ZonedDateTime.now().minusDays(10),
3242 ZonedDateTime.now().plusDays(20))
3243 .setTitle("G-Mobile Nickel Nights")
3244 .setSummary("5¢/GB between 1-5AM")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003245 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3246 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
Jeff Sharkey53313d72017-07-13 16:47:32 -06003247 .setDataUsage(15 * TrafficStats.MB_IN_BYTES,
3248 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
3249 .build());
3250 plans.add(SubscriptionPlan.Builder
3251 .createNonrecurring(ZonedDateTime.now().minusDays(10),
3252 ZonedDateTime.now().plusDays(20))
3253 .setTitle("G-Mobile Bonus 3G")
3254 .setSummary("Unlimited 3G data")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003255 .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
Jeff Sharkey53313d72017-07-13 16:47:32 -06003256 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3257 .setDataUsage(300 * TrafficStats.MB_IN_BYTES,
3258 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3259 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003260 } else if ("unlimited".equals(fake)) {
3261 plans.add(SubscriptionPlan.Builder
3262 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3263 ZonedDateTime.now().plusDays(10))
3264 .setTitle("G-Mobile Awesome")
3265 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3266 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3267 .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
3268 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3269 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003270 }
3271 return plans.toArray(new SubscriptionPlan[plans.size()]);
3272 }
3273
Jeff Sharkey4635f102017-09-01 11:27:13 -06003274 synchronized (mNetworkPoliciesSecondLock) {
3275 // Only give out plan details to the package that defined them,
3276 // so that we don't risk leaking plans between apps. We always
3277 // let in core system components (like the Settings app).
3278 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
3279 if (Objects.equals(ownerPackage, callingPackage)
3280 || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)) {
3281 return mSubscriptionPlans.get(subId);
3282 } else {
3283 Log.w(TAG, "Not returning plans because caller " + callingPackage
3284 + " doesn't match owner " + ownerPackage);
3285 return null;
Jeff Sharkey53313d72017-07-13 16:47:32 -06003286 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003287 }
3288 }
3289
3290 @Override
3291 public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) {
3292 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
Sarah Chin7af1fd02019-09-26 11:37:13 -07003293 enforceSubscriptionPlanValidity(plans);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003294
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003295 for (SubscriptionPlan plan : plans) {
3296 Preconditions.checkNotNull(plan);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003297 }
3298
3299 final long token = Binder.clearCallingIdentity();
3300 try {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003301 synchronized (mUidRulesFirstLock) {
3302 synchronized (mNetworkPoliciesSecondLock) {
3303 mSubscriptionPlans.put(subId, plans);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003304 mSubscriptionPlansOwner.put(subId, callingPackage);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003305
Jeff Sharkey146bb332018-04-18 15:42:57 -06003306 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
3307 if (subscriberId != null) {
3308 ensureActiveMobilePolicyAL(subId, subscriberId);
3309 maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
3310 } else {
3311 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
3312 }
3313
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003314 handleNetworkPoliciesUpdateAL(true);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003315 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003316 }
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07003317
3318 final Intent intent = new Intent(SubscriptionManager.ACTION_SUBSCRIPTION_PLANS_CHANGED);
3319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3320 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3321 mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS);
Sarah Chin7af1fd02019-09-26 11:37:13 -07003322 mHandler.sendMessage(
3323 mHandler.obtainMessage(MSG_SUBSCRIPTION_PLANS_CHANGED, subId, 0, plans));
Jeff Sharkey53313d72017-07-13 16:47:32 -06003324 } finally {
3325 Binder.restoreCallingIdentity(token);
3326 }
3327 }
3328
Jeff Sharkey003d3e62018-03-30 14:35:04 -06003329 /**
3330 * Only visible for testing purposes. This doesn't give any access to
3331 * existing plans; it simply lets the debug package define new plans.
3332 */
3333 void setSubscriptionPlansOwner(int subId, String packageName) {
3334 SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName);
3335 }
3336
Jeff Sharkey53313d72017-07-13 16:47:32 -06003337 @Override
Jeff Sharkey717f52f2018-01-04 16:04:11 -07003338 public String getSubscriptionPlansOwner(int subId) {
3339 if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) {
3340 throw new SecurityException();
3341 }
3342
3343 synchronized (mNetworkPoliciesSecondLock) {
3344 return mSubscriptionPlansOwner.get(subId);
3345 }
3346 }
3347
3348 @Override
Jeff Sharkey9252b342018-01-19 07:58:35 +09003349 public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
Sarah Chin7af1fd02019-09-26 11:37:13 -07003350 long timeoutMillis, String callingPackage) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09003351 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3352
3353 // We can only override when carrier told us about plans
3354 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06003355 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
3356 if (plan == null
3357 || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09003358 throw new IllegalStateException(
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06003359 "Must provide valid SubscriptionPlan to enable overriding");
Jeff Sharkey9252b342018-01-19 07:58:35 +09003360 }
3361 }
3362
Jeff Sharkey36b414b2018-03-30 11:00:03 -06003363 // Only allow overrides when feature is enabled. However, we always
3364 // allow disabling of overrides for safety reasons.
3365 final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
3366 NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
3367 if (overrideEnabled || overrideValue == 0) {
Sarah Chin7af1fd02019-09-26 11:37:13 -07003368 mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3369 overrideMask, overrideValue, subId));
Jeff Sharkey36b414b2018-03-30 11:00:03 -06003370 if (timeoutMillis > 0) {
Sarah Chin7af1fd02019-09-26 11:37:13 -07003371 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3372 overrideMask, 0, subId), timeoutMillis);
Jeff Sharkey36b414b2018-03-30 11:00:03 -06003373 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09003374 }
3375 }
3376
3377 @Override
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003378 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06003379 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Jeff Sharkey1b861272011-05-22 00:34:52 -07003380
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003381 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
3382
Dianne Hackborn497175b2014-07-01 12:56:08 -07003383 final ArraySet<String> argSet = new ArraySet<String>(args.length);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003384 for (String arg : args) {
3385 argSet.add(arg);
3386 }
3387
Felipe Lemef0823852016-06-08 13:43:08 -07003388 synchronized (mUidRulesFirstLock) {
3389 synchronized (mNetworkPoliciesSecondLock) {
3390 if (argSet.contains("--unsnooze")) {
3391 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
3392 mNetworkPolicy.valueAt(i).clearSnooze();
3393 }
3394
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07003395 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07003396
3397 fout.println("Cleared snooze timestamps");
3398 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003399 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08003400
Felipe Lemef0823852016-06-08 13:43:08 -07003401 fout.print("System ready: "); fout.println(mSystemReady);
3402 fout.print("Restrict background: "); fout.println(mRestrictBackground);
3403 fout.print("Restrict power: "); fout.println(mRestrictPower);
3404 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003405 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
3406
3407 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003408 fout.println("Network policies:");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003409 fout.increaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003410 for (int i = 0; i < mNetworkPolicy.size(); i++) {
3411 fout.println(mNetworkPolicy.valueAt(i).toString());
3412 }
3413 fout.decreaseIndent();
3414
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003415 fout.println();
3416 fout.println("Subscription plans:");
3417 fout.increaseIndent();
3418 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
3419 final int subId = mSubscriptionPlans.keyAt(i);
3420 fout.println("Subscriber ID " + subId + ":");
3421 fout.increaseIndent();
3422 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
3423 if (!ArrayUtils.isEmpty(plans)) {
3424 for (SubscriptionPlan plan : plans) {
3425 fout.println(plan);
3426 }
3427 }
3428 fout.decreaseIndent();
3429 }
3430 fout.decreaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003431
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003432 fout.println();
Jeff Sharkey146bb332018-04-18 15:42:57 -06003433 fout.println("Active subscriptions:");
3434 fout.increaseIndent();
3435 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
3436 final int subId = mSubIdToSubscriberId.keyAt(i);
3437 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
3438
3439 fout.println(subId + "=" + NetworkIdentity.scrubSubscriberId(subscriberId));
3440 }
3441 fout.decreaseIndent();
3442
3443 fout.println();
Malcolm Chen07fcb5b2019-07-02 22:29:35 -07003444 for (String[] mergedSubscribers : mMergedSubscriberIds) {
3445 fout.println("Merged subscriptions: " + Arrays.toString(
3446 NetworkIdentity.scrubSubscriberId(mergedSubscribers)));
3447 }
Jeff Sharkey146bb332018-04-18 15:42:57 -06003448
3449 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003450 fout.println("Policy for UIDs:");
3451 fout.increaseIndent();
3452 int size = mUidPolicy.size();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003453 for (int i = 0; i < size; i++) {
Felipe Lemef0823852016-06-08 13:43:08 -07003454 final int uid = mUidPolicy.keyAt(i);
3455 final int policy = mUidPolicy.valueAt(i);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003456 fout.print("UID=");
Felipe Lemef0823852016-06-08 13:43:08 -07003457 fout.print(uid);
3458 fout.print(" policy=");
Felipe Lemeb146f762016-08-19 09:52:16 -07003459 fout.print(uidPoliciesToString(policy));
Felipe Lemef0823852016-06-08 13:43:08 -07003460 fout.println();
3461 }
3462 fout.decreaseIndent();
3463
3464 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3465 if (size > 0) {
3466 fout.println("Power save whitelist (except idle) app ids:");
3467 fout.increaseIndent();
3468 for (int i = 0; i < size; i++) {
3469 fout.print("UID=");
3470 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3471 fout.print(": ");
3472 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
3473 fout.println();
3474 }
3475 fout.decreaseIndent();
3476 }
3477
3478 size = mPowerSaveWhitelistAppIds.size();
3479 if (size > 0) {
3480 fout.println("Power save whitelist app ids:");
3481 fout.increaseIndent();
3482 for (int i = 0; i < size; i++) {
3483 fout.print("UID=");
3484 fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
3485 fout.print(": ");
3486 fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
3487 fout.println();
3488 }
3489 fout.decreaseIndent();
3490 }
3491
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003492 size = mAppIdleTempWhitelistAppIds.size();
3493 if (size > 0) {
3494 fout.println("App idle whitelist app ids:");
3495 fout.increaseIndent();
3496 for (int i = 0; i < size; i++) {
3497 fout.print("UID=");
3498 fout.print(mAppIdleTempWhitelistAppIds.keyAt(i));
3499 fout.print(": ");
3500 fout.print(mAppIdleTempWhitelistAppIds.valueAt(i));
3501 fout.println();
3502 }
3503 fout.decreaseIndent();
3504 }
3505
Felipe Lemef0823852016-06-08 13:43:08 -07003506 size = mDefaultRestrictBackgroundWhitelistUids.size();
3507 if (size > 0) {
3508 fout.println("Default restrict background whitelist uids:");
3509 fout.increaseIndent();
3510 for (int i = 0; i < size; i++) {
3511 fout.print("UID=");
3512 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
3513 fout.println();
3514 }
3515 fout.decreaseIndent();
3516 }
3517
3518 size = mRestrictBackgroundWhitelistRevokedUids.size();
3519 if (size > 0) {
3520 fout.println("Default restrict background whitelist uids revoked by users:");
3521 fout.increaseIndent();
3522 for (int i = 0; i < size; i++) {
3523 fout.print("UID=");
3524 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
3525 fout.println();
3526 }
3527 fout.decreaseIndent();
3528 }
3529
3530 final SparseBooleanArray knownUids = new SparseBooleanArray();
3531 collectKeys(mUidState, knownUids);
3532 collectKeys(mUidRules, knownUids);
3533
3534 fout.println("Status for all known UIDs:");
3535 fout.increaseIndent();
3536 size = knownUids.size();
3537 for (int i = 0; i < size; i++) {
3538 final int uid = knownUids.keyAt(i);
3539 fout.print("UID=");
3540 fout.print(uid);
3541
3542 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3543 fout.print(" state=");
3544 fout.print(state);
3545 if (state <= ActivityManager.PROCESS_STATE_TOP) {
3546 fout.print(" (fg)");
3547 } else {
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -08003548 fout.print(state <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Felipe Lemef0823852016-06-08 13:43:08 -07003549 ? " (fg svc)" : " (bg)");
3550 }
3551
3552 final int uidRules = mUidRules.get(uid, RULE_NONE);
3553 fout.print(" rules=");
3554 fout.print(uidRulesToString(uidRules));
3555 fout.println();
3556 }
3557 fout.decreaseIndent();
3558
3559 fout.println("Status for just UIDs with rules:");
3560 fout.increaseIndent();
3561 size = mUidRules.size();
3562 for (int i = 0; i < size; i++) {
3563 final int uid = mUidRules.keyAt(i);
3564 fout.print("UID=");
3565 fout.print(uid);
3566 final int uidRules = mUidRules.get(uid, RULE_NONE);
3567 fout.print(" rules=");
3568 fout.print(uidRulesToString(uidRules));
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003569 fout.println();
3570 }
3571 fout.decreaseIndent();
Sudheer Shankae7361852017-03-07 11:51:46 -08003572
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003573 fout.println("Admin restricted uids for metered data:");
3574 fout.increaseIndent();
3575 size = mMeteredRestrictedUids.size();
3576 for (int i = 0; i < size; ++i) {
3577 fout.print("u" + mMeteredRestrictedUids.keyAt(i) + ": ");
3578 fout.println(mMeteredRestrictedUids.valueAt(i));
3579 }
3580 fout.decreaseIndent();
3581
Makoto Onuki49392d32018-04-11 13:51:02 -07003582 fout.println();
3583 mStatLogger.dump(fout);
3584
Sudheer Shanka352dc572017-09-22 17:09:38 -07003585 mLogger.dumpLogs(fout);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003586 }
Jeff Sharkey1b861272011-05-22 00:34:52 -07003587 }
3588 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003589
3590 @Override
Felipe Leme50a235e2016-01-15 18:37:06 -08003591 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
Dianne Hackborn354736e2016-08-22 17:00:05 -07003592 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
Felipe Lemeb1a65ee2016-02-08 10:12:01 -08003593 (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
Dianne Hackborn354736e2016-08-22 17:00:05 -07003594 this, in, out, err, args, callback, resultReceiver);
Felipe Leme50a235e2016-01-15 18:37:06 -08003595 }
3596
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003597 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08003598 boolean isUidForeground(int uid) {
Felipe Lemef0823852016-06-08 13:43:08 -07003599 synchronized (mUidRulesFirstLock) {
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003600 return isUidStateForeground(
3601 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003602 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07003603 }
3604
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003605 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003606 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003607 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003608 return isProcStateAllowedWhileOnRestrictBackground(procState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003609 }
3610
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003611 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003612 private boolean isUidForegroundOnRestrictPowerUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07003613 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3614 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
3615 }
3616
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003617 private boolean isUidStateForeground(int state) {
Dianne Hackborn497175b2014-07-01 12:56:08 -07003618 // only really in foreground when screen is also on
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003619 return state <= NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
Dianne Hackborn497175b2014-07-01 12:56:08 -07003620 }
3621
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003622 /**
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003623 * Process state of UID changed; if needed, will trigger
Felipe Lemef0823852016-06-08 13:43:08 -07003624 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
Amith Yamasanid78542b2019-02-19 09:57:32 -08003625 * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003626 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003627 @GuardedBy("mUidRulesFirstLock")
Amith Yamasanid78542b2019-02-19 09:57:32 -08003628 private boolean updateUidStateUL(int uid, int uidState) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003629 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
3630 try {
3631 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3632 if (oldUidState != uidState) {
3633 // state changed, push updated rules
3634 mUidState.put(uid, uidState);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003635 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
3636 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
3637 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
Sudheer Shanka9e77d232017-08-14 14:43:11 -07003638 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003639 if (mDeviceIdleMode) {
3640 updateRuleForDeviceIdleUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003641 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003642 if (mRestrictPower) {
3643 updateRuleForRestrictPowerUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003644 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003645 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003646 }
Amith Yamasanid78542b2019-02-19 09:57:32 -08003647 return true;
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003648 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003649 } finally {
3650 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003651 }
Amith Yamasanid78542b2019-02-19 09:57:32 -08003652 return false;
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003653 }
3654
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003655 @GuardedBy("mUidRulesFirstLock")
Amith Yamasanid78542b2019-02-19 09:57:32 -08003656 private boolean removeUidStateUL(int uid) {
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003657 final int index = mUidState.indexOfKey(uid);
3658 if (index >= 0) {
3659 final int oldUidState = mUidState.valueAt(index);
3660 mUidState.removeAt(index);
3661 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
Felipe Lemef0823852016-06-08 13:43:08 -07003662 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
Sudheer Shankac9d94072017-02-22 22:13:55 +00003663 ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003664 if (mDeviceIdleMode) {
Felipe Lemef0823852016-06-08 13:43:08 -07003665 updateRuleForDeviceIdleUL(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003666 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003667 if (mRestrictPower) {
Felipe Lemef0823852016-06-08 13:43:08 -07003668 updateRuleForRestrictPowerUL(uid);
Felipe Leme011b98f2016-02-10 17:28:31 -08003669 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003670 updateRulesForPowerRestrictionsUL(uid);
Amith Yamasanid78542b2019-02-19 09:57:32 -08003671 return true;
Dianne Hackborn497175b2014-07-01 12:56:08 -07003672 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003673 }
Amith Yamasanid78542b2019-02-19 09:57:32 -08003674 return false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003675 }
3676
Felipe Lemef28983d2016-03-25 12:18:23 -07003677 // adjust stats accounting based on foreground status
3678 private void updateNetworkStats(int uid, boolean uidForeground) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003679 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3680 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3681 "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B"));
3682 }
Felipe Lemef28983d2016-03-25 12:18:23 -07003683 try {
3684 mNetworkStats.setUidForeground(uid, uidForeground);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003685 } finally {
3686 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Lemef28983d2016-03-25 12:18:23 -07003687 }
3688 }
3689
Sudheer Shankac9d94072017-02-22 22:13:55 +00003690 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
3691 int newUidState) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003692 final boolean oldForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003693 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003694 final boolean newForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003695 isProcStateAllowedWhileOnRestrictBackground(newUidState);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003696 if (oldForeground != newForeground) {
Sudheer Shankac9d94072017-02-22 22:13:55 +00003697 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003698 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003699 }
3700
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003701 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003702 void updateRulesForPowerSaveUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003703 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
3704 try {
3705 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
3706 mUidFirewallPowerSaveRules);
3707 } finally {
3708 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3709 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003710 }
3711
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003712 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003713 void updateRuleForRestrictPowerUL(int uid) {
3714 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003715 }
3716
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003717 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003718 void updateRulesForDeviceIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003719 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
3720 try {
3721 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
3722 mUidFirewallDozableRules);
3723 } finally {
3724 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3725 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003726 }
3727
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003728 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003729 void updateRuleForDeviceIdleUL(int uid) {
3730 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003731 }
3732
Felipe Lemef28983d2016-03-25 12:18:23 -07003733 // NOTE: since both fw_dozable and fw_powersave uses the same map
3734 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003735 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003736 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
Felipe Leme011b98f2016-02-10 17:28:31 -08003737 SparseIntArray rules) {
3738 if (enabled) {
3739 // Sync the whitelists before enabling the chain. We don't care about the rules if
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003740 // we are disabling the chain.
Felipe Leme011b98f2016-02-10 17:28:31 -08003741 final SparseIntArray uidRules = rules;
Jeff Sharkeydc988062015-09-14 10:09:47 -07003742 uidRules.clear();
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003743 final List<UserInfo> users = mUserManager.getUsers();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003744 for (int ui = users.size() - 1; ui >= 0; ui--) {
3745 UserInfo user = users.get(ui);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003746 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
3747 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
3748 if (chain == FIREWALL_CHAIN_POWERSAVE) {
3749 updateRulesForWhitelistedAppIds(uidRules,
3750 mPowerSaveWhitelistExceptIdleAppIds, user.id);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003751 }
3752 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003753 for (int i = mUidState.size() - 1; i >= 0; i--) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003754 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003755 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
3756 }
3757 }
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003758 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);
Felipe Lemebc853dd2016-09-08 13:26:55 -07003759 } else {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003760 setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003761 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07003762 }
3763
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003764 private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
3765 final SparseBooleanArray whitelistedAppIds, int userId) {
3766 for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
3767 if (whitelistedAppIds.valueAt(i)) {
3768 final int appId = whitelistedAppIds.keyAt(i);
3769 final int uid = UserHandle.getUid(userId, appId);
3770 uidRules.put(uid, FIREWALL_RULE_ALLOW);
3771 }
3772 }
3773 }
3774
3775 /**
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003776 * Returns whether a uid is whitelisted from power saving restrictions (eg: Battery Saver, Doze
3777 * mode, and app idle).
3778 *
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003779 * @param deviceIdleMode if true then we don't consider
3780 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
3781 * whitelisted.
3782 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003783 @GuardedBy("mUidRulesFirstLock")
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003784 private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) {
Felipe Leme46c4fc32016-05-04 09:21:43 -07003785 final int appId = UserHandle.getAppId(uid);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003786 boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
3787 || mPowerSaveWhitelistAppIds.get(appId);
3788 if (!deviceIdleMode) {
3789 isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
3790 }
3791 return isWhitelisted;
Felipe Leme46c4fc32016-05-04 09:21:43 -07003792 }
3793
Felipe Lemef28983d2016-03-25 12:18:23 -07003794 // NOTE: since both fw_dozable and fw_powersave uses the same map
3795 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003796 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003797 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003798 if (enabled) {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003799 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid,
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003800 chain == FIREWALL_CHAIN_DOZABLE);
3801 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003802 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003803 } else {
Felipe Leme011b98f2016-02-10 17:28:31 -08003804 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003805 }
3806 }
3807 }
3808
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003809 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003810 void updateRulesForAppIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003811 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
3812 try {
3813 final SparseIntArray uidRules = mUidFirewallStandbyRules;
3814 uidRules.clear();
Jeff Sharkeydc988062015-09-14 10:09:47 -07003815
Felipe Leme873a83a2016-09-07 11:34:10 -07003816 // Fully update the app idle firewall chain.
3817 final List<UserInfo> users = mUserManager.getUsers();
3818 for (int ui = users.size() - 1; ui >= 0; ui--) {
3819 UserInfo user = users.get(ui);
3820 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
3821 for (int uid : idleUids) {
3822 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
3823 // quick check: if this uid doesn't have INTERNET permission, it
3824 // doesn't have network access anyway, so it is a waste to mess
3825 // with it here.
3826 if (hasInternetPermissions(uid)) {
3827 uidRules.put(uid, FIREWALL_RULE_DENY);
3828 }
Soi, Yoshinaria065da12015-12-22 12:02:18 +09003829 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003830 }
3831 }
Jeff Sharkeydc988062015-09-14 10:09:47 -07003832
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003833 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
Felipe Leme873a83a2016-09-07 11:34:10 -07003834 } finally {
3835 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3836 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003837 }
3838
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003839 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003840 void updateRuleForAppIdleUL(int uid) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003841 if (!isUidValidForBlacklistRules(uid)) return;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003842
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003843 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3844 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
3845 }
3846 try {
3847 int appId = UserHandle.getAppId(uid);
3848 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
3849 && !isUidForegroundOnRestrictPowerUL(uid)) {
3850 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003851 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003852 } else {
3853 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003854 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT");
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003855 }
3856 } finally {
3857 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003858 }
3859 }
3860
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003861 /**
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003862 * Update rules that might be changed by {@link #mRestrictBackground},
3863 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003864 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003865 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07003866 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003867 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3868 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3869 "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
3870 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003871 try {
Felipe Leme09700462016-09-08 09:33:48 -07003872 updateRulesForAppIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003873 updateRulesForRestrictPowerUL();
3874 updateRulesForRestrictBackgroundUL();
Felipe Leme03e689d2016-03-02 16:17:38 -08003875
Felipe Leme873a83a2016-09-07 11:34:10 -07003876 // If the set of restricted networks may have changed, re-evaluate those.
3877 if (restrictedNetworksChanged) {
3878 normalizePoliciesNL();
3879 updateNetworkRulesNL();
3880 }
3881 } finally {
3882 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Leme76010a32016-03-17 13:03:11 -07003883 }
3884 }
3885
Felipe Leme09700462016-09-08 09:33:48 -07003886 // TODO: rename / document to make it clear these are global (not app-specific) rules
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003887 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003888 private void updateRulesForRestrictPowerUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003889 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
3890 try {
3891 updateRulesForDeviceIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003892 updateRulesForPowerSaveUL();
3893 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
3894 } finally {
3895 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3896 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003897 }
3898
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003899 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003900 private void updateRulesForRestrictBackgroundUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003901 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
3902 try {
3903 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
3904 } finally {
3905 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3906 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003907 }
3908
3909 private static final int TYPE_RESTRICT_BACKGROUND = 1;
3910 private static final int TYPE_RESTRICT_POWER = 2;
3911 @Retention(RetentionPolicy.SOURCE)
3912 @IntDef(flag = false, value = {
3913 TYPE_RESTRICT_BACKGROUND,
3914 TYPE_RESTRICT_POWER,
3915 })
3916 public @interface RestrictType {
3917 }
3918
3919 // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003920 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003921 private void updateRulesForAllAppsUL(@RestrictType int type) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003922 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3923 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
3924 }
3925 try {
Felipe Leme873a83a2016-09-07 11:34:10 -07003926 // update rules for all installed applications
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003927
3928 final PackageManager pm = mContext.getPackageManager();
3929 final List<UserInfo> users;
3930 final List<ApplicationInfo> apps;
3931
3932 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
3933 try {
3934 users = mUserManager.getUsers();
3935 } finally {
3936 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3937 }
3938 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids");
3939 try {
3940 apps = pm.getInstalledApplications(
3941 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS
3942 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3943 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
3944 } finally {
3945 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3946 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003947
Felipe Leme873a83a2016-09-07 11:34:10 -07003948 final int usersSize = users.size();
3949 final int appsSize = apps.size();
3950 for (int i = 0; i < usersSize; i++) {
3951 final UserInfo user = users.get(i);
3952 for (int j = 0; j < appsSize; j++) {
3953 final ApplicationInfo app = apps.get(j);
3954 final int uid = UserHandle.getUid(user.id, app.uid);
3955 switch (type) {
3956 case TYPE_RESTRICT_BACKGROUND:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003957 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003958 break;
3959 case TYPE_RESTRICT_POWER:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003960 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003961 break;
3962 default:
3963 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
3964 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003965 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003966 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003967 } finally {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003968 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003969 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003970 }
3971
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003972 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003973 private void updateRulesForTempWhitelistChangeUL(int appId) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003974 final List<UserInfo> users = mUserManager.getUsers();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003975 final int numUsers = users.size();
3976 for (int i = 0; i < numUsers; i++) {
Felipe Leme03e689d2016-03-02 16:17:38 -08003977 final UserInfo user = users.get(i);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003978 int uid = UserHandle.getUid(user.id, appId);
3979 // Update external firewall rules.
3980 updateRuleForAppIdleUL(uid);
3981 updateRuleForDeviceIdleUL(uid);
3982 updateRuleForRestrictPowerUL(uid);
3983 // Update internal rules.
3984 updateRulesForPowerRestrictionsUL(uid);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003985 }
3986 }
3987
Felipe Leme70c57c22016-03-29 10:45:13 -07003988 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
3989 // methods below could be merged into a isUidValidForRules() method.
3990 private boolean isUidValidForBlacklistRules(int uid) {
3991 // allow rules on specific system services, and any apps
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003992 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
Felipe Leme70c57c22016-03-29 10:45:13 -07003993 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003994 return true;
3995 }
3996
3997 return false;
3998 }
3999
Felipe Leme70c57c22016-03-29 10:45:13 -07004000 private boolean isUidValidForWhitelistRules(int uid) {
4001 return UserHandle.isApp(uid) && hasInternetPermissions(uid);
4002 }
4003
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004004 /**
4005 * Set whether or not an app should be whitelisted for network access while in app idle. Other
4006 * power saving restrictions may still apply.
4007 */
4008 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004009 void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
Sudheer Shankadb02ccd2018-11-29 11:27:21 -08004010 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
4011
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004012 synchronized (mUidRulesFirstLock) {
4013 if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) {
4014 // No change.
4015 return;
4016 }
4017
4018 final long token = Binder.clearCallingIdentity();
4019 try {
4020 mLogger.appIdleWlChanged(uid, shouldWhitelist);
4021 if (shouldWhitelist) {
4022 mAppIdleTempWhitelistAppIds.put(uid, true);
4023 } else {
4024 mAppIdleTempWhitelistAppIds.delete(uid);
4025 }
4026 updateRuleForAppIdleUL(uid);
4027 updateRulesForPowerRestrictionsUL(uid);
4028 } finally {
4029 Binder.restoreCallingIdentity(token);
4030 }
4031 }
4032 }
4033
4034 /** Return the list of UIDs currently in the app idle whitelist. */
4035 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004036 int[] getAppIdleWhitelist() {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004037 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
4038
4039 synchronized (mUidRulesFirstLock) {
4040 final int len = mAppIdleTempWhitelistAppIds.size();
4041 int[] uids = new int[len];
4042 for (int i = 0; i < len; ++i) {
4043 uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i);
4044 }
4045 return uids;
4046 }
4047 }
4048
4049 /** Returns if the UID is currently considered idle. */
4050 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004051 boolean isUidIdle(int uid) {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004052 synchronized (mUidRulesFirstLock) {
4053 if (mAppIdleTempWhitelistAppIds.get(uid)) {
4054 // UID is temporarily whitelisted.
4055 return false;
4056 }
4057 }
4058
Amith Yamasani15e472352015-04-24 19:06:07 -07004059 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
4060 final int userId = UserHandle.getUserId(uid);
4061
songjinshi0655edd2016-05-18 19:55:32 +08004062 if (packages != null) {
Jeff Sharkey377ded0f2016-01-10 13:15:41 -07004063 for (String packageName : packages) {
4064 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
4065 return false;
4066 }
Amith Yamasani15e472352015-04-24 19:06:07 -07004067 }
4068 }
4069 return true;
4070 }
4071
4072 /**
Felipe Leme47585ba2016-02-09 16:56:32 -08004073 * Checks if an uid has INTERNET permissions.
4074 * <p>
4075 * Useful for the cases where the lack of network access can simplify the rules.
Amith Yamasani15e472352015-04-24 19:06:07 -07004076 */
Felipe Leme47585ba2016-02-09 16:56:32 -08004077 private boolean hasInternetPermissions(int uid) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004078 try {
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -08004079 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004080 != PackageManager.PERMISSION_GRANTED) {
Felipe Leme47585ba2016-02-09 16:56:32 -08004081 return false;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004082 }
4083 } catch (RemoteException e) {
4084 }
Felipe Leme47585ba2016-02-09 16:56:32 -08004085 return true;
4086 }
4087
4088 /**
Felipe Leme03e95e22016-09-09 09:25:31 -07004089 * Clears all state - internal and external - associated with an UID.
4090 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004091 @GuardedBy("mUidRulesFirstLock")
Felipe Leme03e95e22016-09-09 09:25:31 -07004092 private void onUidDeletedUL(int uid) {
4093 // First cleanup in-memory state synchronously...
4094 mUidRules.delete(uid);
4095 mUidPolicy.delete(uid);
4096 mUidFirewallStandbyRules.delete(uid);
4097 mUidFirewallDozableRules.delete(uid);
4098 mUidFirewallPowerSaveRules.delete(uid);
4099 mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
4100 mPowerSaveWhitelistAppIds.delete(uid);
4101 mPowerSaveTempWhitelistAppIds.delete(uid);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004102 mAppIdleTempWhitelistAppIds.delete(uid);
Felipe Leme03e95e22016-09-09 09:25:31 -07004103
4104 // ...then update iptables asynchronously.
4105 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
4106 }
4107
4108 /**
Felipe Lemef28983d2016-03-25 12:18:23 -07004109 * Applies network rules to bandwidth and firewall controllers based on uid policy.
Felipe Leme76010a32016-03-17 13:03:11 -07004110 *
Felipe Leme781ba142016-05-09 16:24:48 -07004111 * <p>There are currently 4 types of restriction rules:
Felipe Lemef28983d2016-03-25 12:18:23 -07004112 * <ul>
Felipe Leme781ba142016-05-09 16:24:48 -07004113 * <li>Doze mode
4114 * <li>App idle mode
Felipe Lemef28983d2016-03-25 12:18:23 -07004115 * <li>Battery Saver Mode (also referred as power save).
Felipe Leme46c4fc32016-05-04 09:21:43 -07004116 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
Felipe Lemef28983d2016-03-25 12:18:23 -07004117 * </ul>
Felipe Leme781ba142016-05-09 16:24:48 -07004118 *
4119 * <p>This method changes both the external firewall rules and the internal state.
Felipe Leme47585ba2016-02-09 16:56:32 -08004120 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004121 @GuardedBy("mUidRulesFirstLock")
Felipe Leme03e95e22016-09-09 09:25:31 -07004122 private void updateRestrictionRulesForUidUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07004123 // Methods below only changes the firewall rules for the power-related modes.
Felipe Lemef0823852016-06-08 13:43:08 -07004124 updateRuleForDeviceIdleUL(uid);
4125 updateRuleForAppIdleUL(uid);
4126 updateRuleForRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004127
4128 // Update internal state for power-related modes.
Sudheer Shankac9d94072017-02-22 22:13:55 +00004129 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004130
4131 // Update firewall and internal rules for Data Saver Mode.
Sudheer Shankac9d94072017-02-22 22:13:55 +00004132 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Lemef28983d2016-03-25 12:18:23 -07004133 }
4134
Felipe Leme70c57c22016-03-29 10:45:13 -07004135 /**
4136 * Applies network rules to bandwidth controllers based on process state and user-defined
4137 * restrictions (blacklist / whitelist).
4138 *
4139 * <p>
4140 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
4141 * networks:
4142 * <ul>
4143 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
4144 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
4145 * also blacklisted.
4146 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004147 * no UIDs other than those whitelisted will have access.
Felipe Leme70c57c22016-03-29 10:45:13 -07004148 * <ul>
4149 *
4150 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
4151 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
4152 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
4153 * respectively): these methods set the proper internal state (blacklist / whitelist), then call
Felipe Lemef0823852016-06-08 13:43:08 -07004154 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
Felipe Leme70c57c22016-03-29 10:45:13 -07004155 * {@link INetworkManagementService}, but this method should also be called in events (like
4156 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
4157 * following rules should also be applied:
4158 *
4159 * <ul>
4160 * <li>When Data Saver mode is on, the foreground app should be temporarily added to
4161 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
4162 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
4163 * {@code bw_penalty_box}.
4164 * <li>When the app leaves foreground state, the temporary changes above should be reverted.
4165 * </ul>
4166 *
4167 * <p>For optimization, the rules are only applied on user apps that have internet access
4168 * permission, since there is no need to change the {@code iptables} rule if the app does not
4169 * have permission to use the internet.
4170 *
4171 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
Felipe Lemed31a97f2016-05-06 14:53:50 -07004172 *
Felipe Leme70c57c22016-03-29 10:45:13 -07004173 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00004174 private void updateRulesForDataUsageRestrictionsUL(int uid) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004175 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4176 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4177 "updateRulesForDataUsageRestrictionsUL: " + uid);
4178 }
4179 try {
4180 updateRulesForDataUsageRestrictionsULInner(uid);
4181 } finally {
4182 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4183 }
4184 }
4185
4186 private void updateRulesForDataUsageRestrictionsULInner(int uid) {
Felipe Leme03e95e22016-09-09 09:25:31 -07004187 if (!isUidValidForWhitelistRules(uid)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004188 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004189 return;
Felipe Leme70c57c22016-03-29 10:45:13 -07004190 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004191
Dianne Hackborn497175b2014-07-01 12:56:08 -07004192 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
Felipe Leme46c4fc32016-05-04 09:21:43 -07004193 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
Felipe Lemef0823852016-06-08 13:43:08 -07004194 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004195 final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004196
Felipe Leme781ba142016-05-09 16:24:48 -07004197 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
Felipe Leme46b451f2016-08-19 08:46:17 -07004198 final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
Felipe Leme781ba142016-05-09 16:24:48 -07004199 final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
4200 int newRule = RULE_NONE;
Felipe Leme76010a32016-03-17 13:03:11 -07004201
Felipe Leme70c57c22016-03-29 10:45:13 -07004202 // First step: define the new rule based on user restrictions and foreground state.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004203 if (isRestrictedByAdmin) {
4204 newRule = RULE_REJECT_METERED;
4205 } else if (isForeground) {
Felipe Leme781ba142016-05-09 16:24:48 -07004206 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
4207 newRule = RULE_TEMPORARY_ALLOW_METERED;
4208 } else if (isWhitelisted) {
4209 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004210 }
4211 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07004212 if (isBlacklisted) {
4213 newRule = RULE_REJECT_METERED;
4214 } else if (mRestrictBackground && isWhitelisted) {
4215 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004216 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004217 }
Felipe Leme781ba142016-05-09 16:24:48 -07004218 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
Felipe Leme46c4fc32016-05-04 09:21:43 -07004219
Felipe Lemef28983d2016-03-25 12:18:23 -07004220 if (LOGV) {
Felipe Lemef0823852016-06-08 13:43:08 -07004221 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07004222 + ": isForeground=" +isForeground
4223 + ", isBlacklisted=" + isBlacklisted
4224 + ", isWhitelisted=" + isWhitelisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004225 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Leme781ba142016-05-09 16:24:48 -07004226 + ", oldRule=" + uidRulesToString(oldRule)
4227 + ", newRule=" + uidRulesToString(newRule)
4228 + ", newUidRules=" + uidRulesToString(newUidRules)
4229 + ", oldUidRules=" + uidRulesToString(oldUidRules));
Felipe Lemef28983d2016-03-25 12:18:23 -07004230 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07004231
Felipe Leme46c4fc32016-05-04 09:21:43 -07004232 if (newUidRules == RULE_NONE) {
Jeff Sharkey350083e2011-06-29 10:45:16 -07004233 mUidRules.delete(uid);
4234 } else {
Felipe Leme46c4fc32016-05-04 09:21:43 -07004235 mUidRules.put(uid, newUidRules);
Jeff Sharkey350083e2011-06-29 10:45:16 -07004236 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07004237
Felipe Leme70c57c22016-03-29 10:45:13 -07004238 // Second step: apply bw changes based on change of state.
Felipe Leme781ba142016-05-09 16:24:48 -07004239 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09004240 if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004241 // Temporarily whitelist foreground app, removing from blacklist if necessary
4242 // (since bw_penalty_box prevails over bw_happy_box).
4243
4244 setMeteredNetworkWhitelist(uid, true);
4245 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
4246 // but ideally it should be just:
4247 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07004248 if (isBlacklisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004249 setMeteredNetworkBlacklist(uid, false);
4250 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004251 } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004252 // Remove temporary whitelist from app that is not on foreground anymore.
4253
4254 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
4255 // but ideally they should be just:
4256 // setMeteredNetworkWhitelist(uid, isWhitelisted);
4257 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07004258 if (!isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004259 setMeteredNetworkWhitelist(uid, false);
4260 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004261 if (isBlacklisted || isRestrictedByAdmin) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004262 setMeteredNetworkBlacklist(uid, true);
4263 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004264 } else if (hasRule(newRule, RULE_REJECT_METERED)
4265 || hasRule(oldRule, RULE_REJECT_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004266 // Flip state because app was explicitly added or removed to blacklist.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004267 setMeteredNetworkBlacklist(uid, (isBlacklisted || isRestrictedByAdmin));
Hugo Benichi2966c182017-03-28 17:17:13 +09004268 if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004269 // Since blacklist prevails over whitelist, we need to handle the special case
4270 // where app is whitelisted and blacklisted at the same time (although such
4271 // scenario should be blocked by the UI), then blacklist is removed.
Felipe Leme781ba142016-05-09 16:24:48 -07004272 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07004273 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004274 } else if (hasRule(newRule, RULE_ALLOW_METERED)
4275 || hasRule(oldRule, RULE_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004276 // Flip state because app was explicitly added or removed to whitelist.
Felipe Leme781ba142016-05-09 16:24:48 -07004277 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07004278 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07004279 // All scenarios should have been covered above.
Felipe Leme46c4fc32016-05-04 09:21:43 -07004280 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
4281 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07004282 + ", whitelisted=" + isWhitelisted
4283 + ", blacklisted=" + isBlacklisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004284 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Lemed31a97f2016-05-06 14:53:50 -07004285 + ", newRule=" + uidRulesToString(newUidRules)
4286 + ", oldRule=" + uidRulesToString(oldUidRules));
Felipe Leme70c57c22016-03-29 10:45:13 -07004287 }
Felipe Leme781ba142016-05-09 16:24:48 -07004288
Sudheer Shankac9d94072017-02-22 22:13:55 +00004289 // Dispatch changed rule to existing listeners.
4290 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Felipe Leme781ba142016-05-09 16:24:48 -07004291 }
4292 }
4293
4294 /**
4295 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
4296 * listeners in case of change.
4297 * <p>
4298 * There are 3 power-related rules that affects whether an app has background access on
4299 * non-metered networks, and when the condition applies and the UID is not whitelisted for power
4300 * restriction, it's added to the equivalent firewall chain:
4301 * <ul>
4302 * <li>App is idle: {@code fw_standby} firewall chain.
4303 * <li>Device is idle: {@code fw_dozable} firewall chain.
4304 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
4305 * </ul>
4306 * <p>
4307 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
4308 * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
4309 * <p>
4310 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
4311 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004312 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankac9d94072017-02-22 22:13:55 +00004313 private void updateRulesForPowerRestrictionsUL(int uid) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004314 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
4315
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004316 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004317
Sudheer Shankac9d94072017-02-22 22:13:55 +00004318 if (newUidRules == RULE_NONE) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004319 mUidRules.delete(uid);
4320 } else {
Sudheer Shankac9d94072017-02-22 22:13:55 +00004321 mUidRules.put(uid, newUidRules);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004322 }
4323 }
4324
4325 /**
4326 * Similar to above but ignores idle state if app standby is currently disabled by parole.
4327 *
4328 * @param uid the uid of the app to update rules for
4329 * @param oldUidRules the current rules for the uid, in order to determine if there's a change
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004330 *
Sudheer Shankac9d94072017-02-22 22:13:55 +00004331 * @return the new computed rules for the uid
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004332 */
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004333 private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004334 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4335 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004336 "updateRulesForPowerRestrictionsUL: " + uid + "/" + oldUidRules);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004337 }
4338 try {
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004339 return updateRulesForPowerRestrictionsULInner(uid, oldUidRules);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004340 } finally {
4341 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4342 }
4343 }
4344
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004345 private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules) {
Felipe Leme781ba142016-05-09 16:24:48 -07004346 if (!isUidValidForBlacklistRules(uid)) {
4347 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004348 return RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004349 }
Felipe Lemef28983d2016-03-25 12:18:23 -07004350
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004351 final boolean isIdle = isUidIdle(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004352 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
Felipe Lemef0823852016-06-08 13:43:08 -07004353 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004354
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004355 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
Felipe Leme781ba142016-05-09 16:24:48 -07004356 final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
4357 int newRule = RULE_NONE;
4358
4359 // First step: define the new rule based on user restrictions and foreground state.
4360
4361 // NOTE: if statements below could be inlined, but it's easier to understand the logic
4362 // by considering the foreground and non-foreground states.
4363 if (isForeground) {
4364 if (restrictMode) {
4365 newRule = RULE_ALLOW_ALL;
4366 }
4367 } else if (restrictMode) {
4368 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
4369 }
4370
4371 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
4372
4373 if (LOGV) {
Felipe Leme88f40ad2016-08-10 13:00:32 -07004374 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07004375 + ", isIdle: " + isIdle
4376 + ", mRestrictPower: " + mRestrictPower
4377 + ", mDeviceIdleMode: " + mDeviceIdleMode
4378 + ", isForeground=" + isForeground
4379 + ", isWhitelisted=" + isWhitelisted
4380 + ", oldRule=" + uidRulesToString(oldRule)
4381 + ", newRule=" + uidRulesToString(newRule)
4382 + ", newUidRules=" + uidRulesToString(newUidRules)
4383 + ", oldUidRules=" + uidRulesToString(oldUidRules));
4384 }
4385
Felipe Leme781ba142016-05-09 16:24:48 -07004386 // Second step: notify listeners if state changed.
4387 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09004388 if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004389 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
Hugo Benichi2966c182017-03-28 17:17:13 +09004390 } else if (hasRule(newRule, RULE_REJECT_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004391 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
4392 } else {
4393 // All scenarios should have been covered above
4394 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
4395 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07004396 + ", whitelisted=" + isWhitelisted
Felipe Lemed31a97f2016-05-06 14:53:50 -07004397 + ", newRule=" + uidRulesToString(newUidRules)
4398 + ", oldRule=" + uidRulesToString(oldUidRules));
4399 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004400 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Amith Yamasani15e472352015-04-24 19:06:07 -07004401 }
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004402
Sudheer Shankac9d94072017-02-22 22:13:55 +00004403 return newUidRules;
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004404 }
4405
Christopher Tateb909c4d52019-10-21 12:50:37 -07004406 private class NetPolicyAppIdleStateChangeListener extends AppIdleStateChangeListener {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004407 @Override
Amith Yamasani119be9a2018-02-18 22:23:00 -08004408 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
4409 int reason) {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004410 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07004411 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
4412 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
Felipe Lemef0823852016-06-08 13:43:08 -07004413 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004414 mLogger.appIdleStateChanged(uid, idle);
Felipe Lemef0823852016-06-08 13:43:08 -07004415 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004416 updateRulesForPowerRestrictionsUL(uid);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004417 }
4418 } catch (NameNotFoundException nnfe) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004419 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004420 }
Amith Yamasani15e472352015-04-24 19:06:07 -07004421 }
4422
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004423 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
4424 if (listener != null) {
4425 try {
4426 listener.onUidRulesChanged(uid, uidRules);
4427 } catch (RemoteException ignored) {
4428 }
4429 }
4430 }
4431
4432 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
4433 String[] meteredIfaces) {
4434 if (listener != null) {
4435 try {
4436 listener.onMeteredIfacesChanged(meteredIfaces);
4437 } catch (RemoteException ignored) {
4438 }
4439 }
4440 }
4441
4442 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
4443 boolean restrictBackground) {
4444 if (listener != null) {
4445 try {
4446 listener.onRestrictBackgroundChanged(restrictBackground);
4447 } catch (RemoteException ignored) {
4448 }
4449 }
4450 }
4451
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004452 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
4453 int uidPolicies) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004454 if (listener != null) {
4455 try {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004456 listener.onUidPoliciesChanged(uid, uidPolicies);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004457 } catch (RemoteException ignored) {
4458 }
4459 }
4460 }
4461
Jeff Sharkey9252b342018-01-19 07:58:35 +09004462 private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
Sarah Chin7af1fd02019-09-26 11:37:13 -07004463 int overrideMask, int overrideValue) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09004464 if (listener != null) {
4465 try {
Sarah Chin7af1fd02019-09-26 11:37:13 -07004466 listener.onSubscriptionOverride(subId, overrideMask, overrideValue);
4467 } catch (RemoteException ignored) {
4468 }
4469 }
4470 }
4471
4472 private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
4473 SubscriptionPlan[] plans) {
4474 if (listener != null) {
4475 try {
4476 listener.onSubscriptionPlansChanged(subId, plans);
Jeff Sharkey9252b342018-01-19 07:58:35 +09004477 } catch (RemoteException ignored) {
4478 }
4479 }
4480 }
4481
Makoto Onuki8e777332017-03-28 11:25:47 -07004482 private final Handler.Callback mHandlerCallback = new Handler.Callback() {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07004483 @Override
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004484 public boolean handleMessage(Message msg) {
4485 switch (msg.what) {
4486 case MSG_RULES_CHANGED: {
4487 final int uid = msg.arg1;
4488 final int uidRules = msg.arg2;
Sudheer Shankac9d94072017-02-22 22:13:55 +00004489 final int length = mListeners.beginBroadcast();
4490 for (int i = 0; i < length; i++) {
4491 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4492 dispatchUidRulesChanged(listener, uid, uidRules);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004493 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004494 mListeners.finishBroadcast();
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004495 return true;
4496 }
4497 case MSG_METERED_IFACES_CHANGED: {
4498 final String[] meteredIfaces = (String[]) msg.obj;
4499 final int length = mListeners.beginBroadcast();
4500 for (int i = 0; i < length; i++) {
4501 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004502 dispatchMeteredIfacesChanged(listener, meteredIfaces);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004503 }
4504 mListeners.finishBroadcast();
4505 return true;
4506 }
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004507 case MSG_LIMIT_REACHED: {
4508 final String iface = (String) msg.obj;
4509
Felipe Lemef0823852016-06-08 13:43:08 -07004510 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004511 if (mMeteredIfaces.contains(iface)) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004512 // force stats update to make sure we have
4513 // numbers that caused alert to trigger.
4514 mNetworkStats.forceUpdate();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004515
Felipe Lemef0823852016-06-08 13:43:08 -07004516 updateNetworkEnabledNL();
4517 updateNotificationsNL();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004518 }
4519 }
4520 return true;
4521 }
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004522 case MSG_RESTRICT_BACKGROUND_CHANGED: {
4523 final boolean restrictBackground = msg.arg1 != 0;
4524 final int length = mListeners.beginBroadcast();
4525 for (int i = 0; i < length; i++) {
4526 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004527 dispatchRestrictBackgroundChanged(listener, restrictBackground);
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004528 }
4529 mListeners.finishBroadcast();
Felipe Leme9778f762016-01-27 14:46:39 -08004530 final Intent intent =
4531 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4532 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4533 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4534 return true;
4535 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004536 case MSG_POLICIES_CHANGED: {
Felipe Leme9778f762016-01-27 14:46:39 -08004537 final int uid = msg.arg1;
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004538 final int policy = msg.arg2;
Felipe Leme57e3d312016-08-23 14:42:52 -07004539 final Boolean notifyApp = (Boolean) msg.obj;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004540 // First notify internal listeners...
Felipe Leme57e3d312016-08-23 14:42:52 -07004541 final int length = mListeners.beginBroadcast();
4542 for (int i = 0; i < length; i++) {
4543 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004544 dispatchUidPoliciesChanged(listener, uid, policy);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004545 }
4546 mListeners.finishBroadcast();
Felipe Leme57e3d312016-08-23 14:42:52 -07004547 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
4548 if (notifyApp.booleanValue()) {
4549 broadcastRestrictBackgroundChanged(uid, notifyApp);
4550 }
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004551 return true;
4552 }
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004553 case MSG_ADVISE_PERSIST_THRESHOLD: {
4554 final long lowestRule = (Long) msg.obj;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004555 // make sure stats are recorded frequently enough; we aim
4556 // for 2MB threshold for 2GB/month rules.
4557 final long persistThreshold = lowestRule / 1000;
4558 mNetworkStats.advisePersistThreshold(persistThreshold);
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004559 return true;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004560 }
Amith Yamasani3646cbd2016-04-13 14:04:53 -07004561 case MSG_UPDATE_INTERFACE_QUOTA: {
4562 removeInterfaceQuota((String) msg.obj);
4563 // int params need to be stitched back into a long
4564 setInterfaceQuota((String) msg.obj,
4565 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
4566 return true;
4567 }
4568 case MSG_REMOVE_INTERFACE_QUOTA: {
4569 removeInterfaceQuota((String) msg.obj);
4570 return true;
4571 }
Felipe Leme03e95e22016-09-09 09:25:31 -07004572 case MSG_RESET_FIREWALL_RULES_BY_UID: {
4573 resetUidFirewallRules(msg.arg1);
4574 return true;
4575 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004576 case MSG_SUBSCRIPTION_OVERRIDE: {
Sarah Chin7af1fd02019-09-26 11:37:13 -07004577 final int overrideMask = msg.arg1;
4578 final int overrideValue = msg.arg2;
4579 final int subId = (int) msg.obj;
Jeff Sharkey9252b342018-01-19 07:58:35 +09004580 final int length = mListeners.beginBroadcast();
4581 for (int i = 0; i < length; i++) {
4582 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Sarah Chin7af1fd02019-09-26 11:37:13 -07004583 dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue);
Jeff Sharkey9252b342018-01-19 07:58:35 +09004584 }
4585 mListeners.finishBroadcast();
4586 return true;
4587 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004588 case MSG_METERED_RESTRICTED_PACKAGES_CHANGED: {
4589 final int userId = msg.arg1;
4590 final Set<String> packageNames = (Set<String>) msg.obj;
4591 setMeteredRestrictedPackagesInternal(packageNames, userId);
4592 return true;
4593 }
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07004594 case MSG_SET_NETWORK_TEMPLATE_ENABLED: {
4595 final NetworkTemplate template = (NetworkTemplate) msg.obj;
4596 final boolean enabled = msg.arg1 != 0;
4597 setNetworkTemplateEnabledInner(template, enabled);
4598 return true;
4599 }
Sarah Chin7af1fd02019-09-26 11:37:13 -07004600 case MSG_SUBSCRIPTION_PLANS_CHANGED: {
4601 final SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj;
4602 final int subId = msg.arg1;
4603 final int length = mListeners.beginBroadcast();
4604 for (int i = 0; i < length; i++) {
4605 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4606 dispatchSubscriptionPlansChanged(listener, subId, plans);
4607 }
4608 mListeners.finishBroadcast();
4609 return true;
4610 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004611 default: {
4612 return false;
Jeff Sharkeyaf11d482011-06-13 00:14:31 -07004613 }
4614 }
4615 }
Makoto Onuki8e777332017-03-28 11:25:47 -07004616 };
4617
4618 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
4619 @Override
4620 public boolean handleMessage(Message msg) {
4621 switch (msg.what) {
4622 case UID_MSG_STATE_CHANGED: {
4623 final int uid = msg.arg1;
4624 final int procState = msg.arg2;
4625 final long procStateSeq = (Long) msg.obj;
4626
4627 handleUidChanged(uid, procState, procStateSeq);
4628 return true;
4629 }
4630 case UID_MSG_GONE: {
4631 final int uid = msg.arg1;
4632 handleUidGone(uid);
4633 return true;
4634 }
4635 default: {
4636 return false;
4637 }
4638 }
4639 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004640 };
Jeff Sharkey22c055e2011-06-12 21:13:51 -07004641
Makoto Onuki8e777332017-03-28 11:25:47 -07004642 void handleUidChanged(int uid, int procState, long procStateSeq) {
4643 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
4644 try {
Amith Yamasanid78542b2019-02-19 09:57:32 -08004645 boolean updated;
Makoto Onuki8e777332017-03-28 11:25:47 -07004646 synchronized (mUidRulesFirstLock) {
4647 // We received a uid state change callback, add it to the history so that it
4648 // will be useful for debugging.
Sudheer Shanka352dc572017-09-22 17:09:38 -07004649 mLogger.uidStateChanged(uid, procState, procStateSeq);
Makoto Onuki8e777332017-03-28 11:25:47 -07004650 // Now update the network policy rules as per the updated uid state.
Amith Yamasanid78542b2019-02-19 09:57:32 -08004651 updated = updateUidStateUL(uid, procState);
Makoto Onuki8e777332017-03-28 11:25:47 -07004652 // Updating the network rules is done, so notify AMS about this.
4653 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
4654 }
Amith Yamasanid78542b2019-02-19 09:57:32 -08004655 // Do this without the lock held. handleUidChanged() and handleUidGone() are
4656 // called from the handler, so there's no multi-threading issue.
4657 if (updated) {
4658 updateNetworkStats(uid, isUidStateForeground(procState));
4659 }
Makoto Onuki8e777332017-03-28 11:25:47 -07004660 } finally {
4661 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4662 }
4663 }
4664
4665 void handleUidGone(int uid) {
4666 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
4667 try {
Amith Yamasanid78542b2019-02-19 09:57:32 -08004668 boolean updated;
Makoto Onuki8e777332017-03-28 11:25:47 -07004669 synchronized (mUidRulesFirstLock) {
Amith Yamasanid78542b2019-02-19 09:57:32 -08004670 updated = removeUidStateUL(uid);
4671 }
4672 // Do this without the lock held. handleUidChanged() and handleUidGone() are
4673 // called from the handler, so there's no multi-threading issue.
4674 if (updated) {
4675 updateNetworkStats(uid, false);
Makoto Onuki8e777332017-03-28 11:25:47 -07004676 }
4677 } finally {
4678 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4679 }
4680 }
4681
Felipe Leme57e3d312016-08-23 14:42:52 -07004682 private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
4683 final PackageManager pm = mContext.getPackageManager();
4684 final String[] packages = pm.getPackagesForUid(uid);
4685 if (packages != null) {
4686 final int userId = UserHandle.getUserId(uid);
4687 for (String packageName : packages) {
4688 final Intent intent =
4689 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4690 intent.setPackage(packageName);
4691 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4692 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
4693 }
4694 }
4695 }
4696
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004697 private void setInterfaceQuotaAsync(String iface, long quotaBytes) {
4698 // long quotaBytes split up into two ints to fit in message
4699 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, (int) (quotaBytes >> 32),
4700 (int) (quotaBytes & 0xFFFFFFFF), iface).sendToTarget();
4701 }
4702
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004703 private void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004704 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004705 mNetworkManager.setInterfaceQuota(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004706 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004707 Log.wtf(TAG, "problem setting interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004708 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004709 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004710 }
4711 }
4712
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004713 private void removeInterfaceQuotaAsync(String iface) {
4714 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface).sendToTarget();
4715 }
4716
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004717 private void removeInterfaceQuota(String iface) {
4718 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004719 mNetworkManager.removeInterfaceQuota(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004720 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004721 Log.wtf(TAG, "problem removing interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004722 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004723 // ignored; service lives in system_server
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004724 }
4725 }
4726
Felipe Leme70c57c22016-03-29 10:45:13 -07004727 private void setMeteredNetworkBlacklist(int uid, boolean enable) {
4728 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004729 try {
Felipe Leme70c57c22016-03-29 10:45:13 -07004730 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004731 } catch (IllegalStateException e) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004732 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
4733 } catch (RemoteException e) {
4734 // ignored; service lives in system_server
4735 }
4736 }
4737
4738 private void setMeteredNetworkWhitelist(int uid, boolean enable) {
4739 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
4740 try {
4741 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
4742 } catch (IllegalStateException e) {
4743 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004744 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004745 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004746 }
4747 }
4748
Felipe Lemebc853dd2016-09-08 13:26:55 -07004749 private static final int CHAIN_TOGGLE_NONE = 0;
4750 private static final int CHAIN_TOGGLE_ENABLE = 1;
4751 private static final int CHAIN_TOGGLE_DISABLE = 2;
4752 @Retention(RetentionPolicy.SOURCE)
4753 @IntDef(flag = false, value = {
4754 CHAIN_TOGGLE_NONE,
4755 CHAIN_TOGGLE_ENABLE,
4756 CHAIN_TOGGLE_DISABLE
4757 })
4758 public @interface ChainToggleType {
4759 }
4760
4761 /**
Kweku Adamsdf33ae12019-10-08 11:51:41 -07004762 * Calls {@link #setUidFirewallRulesUL(int, SparseIntArray)} and
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004763 * {@link #enableFirewallChainUL(int, boolean)} synchronously.
Felipe Lemebc853dd2016-09-08 13:26:55 -07004764 *
4765 * @param chain firewall chain.
4766 * @param uidRules new UID rules; if {@code null}, only toggles chain state.
4767 * @param toggle whether the chain should be enabled, disabled, or not changed.
4768 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004769 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004770 private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,
Felipe Lemebc853dd2016-09-08 13:26:55 -07004771 @ChainToggleType int toggle) {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004772 if (uidRules != null) {
4773 setUidFirewallRulesUL(chain, uidRules);
4774 }
4775 if (toggle != CHAIN_TOGGLE_NONE) {
4776 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
4777 }
Felipe Lemebc853dd2016-09-08 13:26:55 -07004778 }
4779
Amith Yamasani15e472352015-04-24 19:06:07 -07004780 /**
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004781 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
4782 * here to netd. It will clean up dead rules and make sure the target chain only contains rules
4783 * specified here.
Amith Yamasani15e472352015-04-24 19:06:07 -07004784 */
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004785 private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004786 try {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004787 int size = uidRules.size();
4788 int[] uids = new int[size];
4789 int[] rules = new int[size];
4790 for(int index = size - 1; index >= 0; --index) {
4791 uids[index] = uidRules.keyAt(index);
4792 rules[index] = uidRules.valueAt(index);
4793 }
4794 mNetworkManager.setFirewallUidRules(chain, uids, rules);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004795 mLogger.firewallRulesChanged(chain, uids, rules);
Amith Yamasani15e472352015-04-24 19:06:07 -07004796 } catch (IllegalStateException e) {
4797 Log.wtf(TAG, "problem setting firewall uid rules", e);
4798 } catch (RemoteException e) {
4799 // ignored; service lives in system_server
4800 }
4801 }
4802
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004803 /**
4804 * Add or remove a uid to the firewall blacklist for all network ifaces.
4805 */
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004806 private void setUidFirewallRule(int chain, int uid, int rule) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004807 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4808 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4809 "setUidFirewallRule: " + chain + "/" + uid + "/" + rule);
Jeff Sharkeydc988062015-09-14 10:09:47 -07004810 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004811 try {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004812 if (chain == FIREWALL_CHAIN_DOZABLE) {
4813 mUidFirewallDozableRules.put(uid, rule);
4814 } else if (chain == FIREWALL_CHAIN_STANDBY) {
4815 mUidFirewallStandbyRules.put(uid, rule);
4816 } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
4817 mUidFirewallPowerSaveRules.put(uid, rule);
4818 }
4819
4820 try {
4821 mNetworkManager.setFirewallUidRule(chain, uid, rule);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004822 mLogger.uidFirewallRuleChanged(chain, uid, rule);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004823 } catch (IllegalStateException e) {
4824 Log.wtf(TAG, "problem setting firewall uid rules", e);
4825 } catch (RemoteException e) {
4826 // ignored; service lives in system_server
4827 }
4828 } finally {
4829 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004830 }
4831 }
4832
4833 /**
4834 * Add or remove a uid to the firewall blacklist for all network ifaces.
4835 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004836 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07004837 private void enableFirewallChainUL(int chain, boolean enable) {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004838 if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
4839 mFirewallChainStates.get(chain) == enable) {
4840 // All is the same, nothing to do.
4841 return;
4842 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004843 mFirewallChainStates.put(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004844 try {
4845 mNetworkManager.setFirewallChainEnabled(chain, enable);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004846 mLogger.firewallChainEnabled(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004847 } catch (IllegalStateException e) {
4848 Log.wtf(TAG, "problem enable firewall chain", e);
4849 } catch (RemoteException e) {
4850 // ignored; service lives in system_server
4851 }
4852 }
4853
Felipe Leme03e95e22016-09-09 09:25:31 -07004854 /**
4855 * Resets all firewall rules associated with an UID.
4856 */
4857 private void resetUidFirewallRules(int uid) {
4858 try {
4859 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
4860 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
4861 mNetworkManager
4862 .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
4863 mNetworkManager.setUidMeteredNetworkWhitelist(uid, false);
4864 mNetworkManager.setUidMeteredNetworkBlacklist(uid, false);
4865 } catch (IllegalStateException e) {
4866 Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
4867 } catch (RemoteException e) {
4868 // ignored; service lives in system_server
4869 }
4870 }
4871
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004872 @Deprecated
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004873 private long getTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004874 return getNetworkTotalBytes(template, start, end);
4875 }
4876
4877 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004878 try {
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -07004879 return mNetworkStats.getNetworkTotalBytes(template, start, end);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004880 } catch (RuntimeException e) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004881 Slog.w(TAG, "Failed to read network stats: " + e);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004882 return 0;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004883 }
4884 }
4885
4886 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
4887 try {
4888 return mNetworkStats.getNetworkUidBytes(template, start, end);
4889 } catch (RuntimeException e) {
4890 Slog.w(TAG, "Failed to read network stats: " + e);
4891 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004892 }
4893 }
4894
Jeff Sharkey8c1dc722012-05-04 14:49:37 -07004895 private boolean isBandwidthControlEnabled() {
4896 final long token = Binder.clearCallingIdentity();
4897 try {
4898 return mNetworkManager.isBandwidthControlEnabled();
4899 } catch (RemoteException e) {
4900 // ignored; service lives in system_server
4901 return false;
4902 } finally {
4903 Binder.restoreCallingIdentity(token);
4904 }
4905 }
4906
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07004907 private static Intent buildAllowBackgroundDataIntent() {
4908 return new Intent(ACTION_ALLOW_BACKGROUND);
4909 }
4910
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004911 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
4912 final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07004913 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4914 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4915 return intent;
4916 }
4917
4918 private static Intent buildSnoozeRapidIntent(NetworkTemplate template) {
4919 final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
4920 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004921 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4922 return intent;
4923 }
4924
Wei Liu546cb772016-07-21 16:19:01 -07004925 private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004926 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004927 intent.setComponent(ComponentName.unflattenFromString(
4928 res.getString(R.string.config_networkOverLimitComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004929 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4930 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4931 return intent;
4932 }
4933
Wei Liu546cb772016-07-21 16:19:01 -07004934 private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004935 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004936 intent.setComponent(ComponentName.unflattenFromString(
4937 res.getString(R.string.config_dataUsageSummaryComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004938 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4939 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4940 return intent;
4941 }
4942
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -08004943 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004944 void addIdleHandler(IdleHandler handler) {
Jeff Sharkey163e6442011-10-31 16:37:52 -07004945 mHandler.getLooper().getQueue().addIdleHandler(handler);
4946 }
4947
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004948 @GuardedBy("mUidRulesFirstLock")
jackqdyulei29c82ab2017-03-10 14:09:16 -08004949 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004950 void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
Kweku Adams25fa3a72019-07-12 17:00:17 -07004951 if (mRestrictBackgroundLowPowerMode == result.batterySaverEnabled) {
4952 // Nothing changed. Nothing to do.
4953 return;
4954 }
4955 mRestrictBackgroundLowPowerMode = result.batterySaverEnabled;
jackqdyulei29c82ab2017-03-10 14:09:16 -08004956
Kweku Adams25fa3a72019-07-12 17:00:17 -07004957 boolean restrictBackground = mRestrictBackgroundLowPowerMode;
jackqdyulei29c82ab2017-03-10 14:09:16 -08004958 boolean shouldInvokeRestrictBackground;
Kweku Adams25fa3a72019-07-12 17:00:17 -07004959 // store the temporary mRestrictBackgroundChangedInBsm and update it at the end.
jackqdyulei29c82ab2017-03-10 14:09:16 -08004960 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
4961
Kweku Adams25fa3a72019-07-12 17:00:17 -07004962 if (mRestrictBackgroundLowPowerMode) {
jackqdyulei29c82ab2017-03-10 14:09:16 -08004963 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
4964 // turn it on.
Kweku Adams25fa3a72019-07-12 17:00:17 -07004965 shouldInvokeRestrictBackground = !mRestrictBackground;
jackqdyulei29c82ab2017-03-10 14:09:16 -08004966 mRestrictBackgroundBeforeBsm = mRestrictBackground;
4967 localRestrictBgChangedInBsm = false;
4968 } else {
4969 // Try to restore the restrictBackground if it doesn't change in bsm
4970 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
4971 restrictBackground = mRestrictBackgroundBeforeBsm;
4972 }
4973
4974 if (shouldInvokeRestrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07004975 setRestrictBackgroundUL(restrictBackground);
jackqdyulei29c82ab2017-03-10 14:09:16 -08004976 }
4977
4978 // Change it at last so setRestrictBackground() won't affect this variable
4979 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
4980 }
4981
Jeff Sharkey1b861272011-05-22 00:34:52 -07004982 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
4983 final int size = source.size();
4984 for (int i = 0; i < size; i++) {
4985 target.put(source.keyAt(i), true);
4986 }
4987 }
4988
Stuart Scottf1fb3972015-04-02 18:00:02 -07004989 @Override
4990 public void factoryReset(String subscriber) {
paulhua6af6b62019-08-12 16:25:11 +08004991 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
Stuart Scottf1fb3972015-04-02 18:00:02 -07004992
Stuart Scotte3e314d2015-04-20 14:07:45 -07004993 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4994 return;
4995 }
4996
Stuart Scottf1fb3972015-04-02 18:00:02 -07004997 // Turn mobile data limit off
Stuart Scott9a9a1d92015-04-20 11:33:06 -07004998 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Stuart Scottf1fb3972015-04-02 18:00:02 -07004999 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
5000 for (NetworkPolicy policy : policies) {
5001 if (policy.template.equals(template)) {
5002 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
5003 policy.inferred = false;
5004 policy.clearSnooze();
5005 }
5006 }
5007 setNetworkPolicies(policies);
5008
5009 // Turn restrict background data off
5010 setRestrictBackground(false);
5011
Stuart Scotte3e314d2015-04-20 14:07:45 -07005012 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
5013 // Remove app's "restrict background data" flag
5014 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
5015 setUidPolicy(uid, POLICY_NONE);
5016 }
Stuart Scottf1fb3972015-04-02 18:00:02 -07005017 }
5018 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08005019
Sudheer Shankab8f23162017-08-04 13:30:10 -07005020 @Override
5021 public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
Makoto Onuki49392d32018-04-11 13:51:02 -07005022 final long startTime = mStatLogger.getTime();
5023
paulhua6af6b62019-08-12 16:25:11 +08005024 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG);
Sudheer Shankab8f23162017-08-04 13:30:10 -07005025 final int uidRules;
5026 final boolean isBackgroundRestricted;
5027 synchronized (mUidRulesFirstLock) {
5028 uidRules = mUidRules.get(uid, RULE_NONE);
5029 isBackgroundRestricted = mRestrictBackground;
5030 }
junyulai05986c62018-08-07 19:50:45 +08005031 final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
5032 isBackgroundRestricted, mLogger);
5033
5034 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
5035
5036 return ret;
5037 }
5038
5039 private static boolean isSystem(int uid) {
5040 return uid < Process.FIRST_APPLICATION_UID;
5041 }
5042
5043 static boolean isUidNetworkingBlockedInternal(int uid, int uidRules, boolean isNetworkMetered,
5044 boolean isBackgroundRestricted, @Nullable NetworkPolicyLogger logger) {
5045 final int reason;
5046 // Networks are never blocked for system components
5047 if (isSystem(uid)) {
5048 reason = NTWK_ALLOWED_SYSTEM;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005049 }
junyulai05986c62018-08-07 19:50:45 +08005050 else if (hasRule(uidRules, RULE_REJECT_ALL)) {
5051 reason = NTWK_BLOCKED_POWER;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005052 }
junyulai05986c62018-08-07 19:50:45 +08005053 else if (!isNetworkMetered) {
5054 reason = NTWK_ALLOWED_NON_METERED;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005055 }
junyulai05986c62018-08-07 19:50:45 +08005056 else if (hasRule(uidRules, RULE_REJECT_METERED)) {
5057 reason = NTWK_BLOCKED_BLACKLIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005058 }
junyulai05986c62018-08-07 19:50:45 +08005059 else if (hasRule(uidRules, RULE_ALLOW_METERED)) {
5060 reason = NTWK_ALLOWED_WHITELIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005061 }
junyulai05986c62018-08-07 19:50:45 +08005062 else if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
5063 reason = NTWK_ALLOWED_TMP_WHITELIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005064 }
junyulai05986c62018-08-07 19:50:45 +08005065 else if (isBackgroundRestricted) {
5066 reason = NTWK_BLOCKED_BG_RESTRICT;
5067 }
5068 else {
5069 reason = NTWK_ALLOWED_DEFAULT;
5070 }
5071
5072 final boolean blocked;
5073 switch(reason) {
5074 case NTWK_ALLOWED_DEFAULT:
5075 case NTWK_ALLOWED_NON_METERED:
5076 case NTWK_ALLOWED_TMP_WHITELIST:
5077 case NTWK_ALLOWED_WHITELIST:
5078 case NTWK_ALLOWED_SYSTEM:
5079 blocked = false;
5080 break;
5081 case NTWK_BLOCKED_POWER:
5082 case NTWK_BLOCKED_BLACKLIST:
5083 case NTWK_BLOCKED_BG_RESTRICT:
5084 blocked = true;
5085 break;
5086 default:
5087 throw new IllegalArgumentException();
5088 }
5089 if (logger != null) {
5090 logger.networkBlocked(uid, reason);
5091 }
5092
5093 return blocked;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005094 }
5095
Felipe Lemed17fda42016-04-29 11:12:45 -07005096 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
5097
5098 @Override
5099 public void resetUserState(int userId) {
Felipe Lemef0823852016-06-08 13:43:08 -07005100 synchronized (mUidRulesFirstLock) {
5101 boolean changed = removeUserStateUL(userId, false);
5102 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
Felipe Lemed17fda42016-04-29 11:12:45 -07005103 if (changed) {
Felipe Lemef0823852016-06-08 13:43:08 -07005104 synchronized (mNetworkPoliciesSecondLock) {
5105 writePolicyAL();
5106 }
Felipe Lemed17fda42016-04-29 11:12:45 -07005107 }
5108 }
5109 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005110
5111 /**
5112 * @return true if the given uid is restricted from doing networking on metered networks.
5113 */
5114 @Override
5115 public boolean isUidRestrictedOnMeteredNetworks(int uid) {
5116 final int uidRules;
5117 final boolean isBackgroundRestricted;
5118 synchronized (mUidRulesFirstLock) {
5119 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
5120 isBackgroundRestricted = mRestrictBackground;
5121 }
5122 return isBackgroundRestricted
5123 && !hasRule(uidRules, RULE_ALLOW_METERED)
5124 && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
5125 }
5126
5127 /**
5128 * @return true if networking is blocked on the given interface for the given uid according
5129 * to current networking policies.
5130 */
5131 @Override
5132 public boolean isUidNetworkingBlocked(int uid, String ifname) {
Makoto Onuki49392d32018-04-11 13:51:02 -07005133 final long startTime = mStatLogger.getTime();
5134
junyulai05986c62018-08-07 19:50:45 +08005135 final int uidRules;
5136 final boolean isBackgroundRestricted;
5137 synchronized (mUidRulesFirstLock) {
5138 uidRules = mUidRules.get(uid, RULE_NONE);
5139 isBackgroundRestricted = mRestrictBackground;
5140 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005141 final boolean isNetworkMetered;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005142 synchronized (mNetworkPoliciesSecondLock) {
5143 isNetworkMetered = mMeteredIfaces.contains(ifname);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005144 }
junyulai05986c62018-08-07 19:50:45 +08005145 final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
5146 isBackgroundRestricted, mLogger);
Makoto Onuki49392d32018-04-11 13:51:02 -07005147
5148 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
5149
5150 return ret;
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005151 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07005152
5153 @Override
5154 public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
5155 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07005156 mLogger.tempPowerSaveWlChanged(appId, added);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07005157 if (added) {
5158 mPowerSaveTempWhitelistAppIds.put(appId, true);
5159 } else {
5160 mPowerSaveTempWhitelistAppIds.delete(appId);
5161 }
5162 updateRulesForTempWhitelistChangeUL(appId);
5163 }
5164 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005165
5166 @Override
5167 public SubscriptionPlan getSubscriptionPlan(Network network) {
5168 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09005169 final int subId = getSubIdLocked(network);
5170 return getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09005171 }
5172 }
5173
5174 @Override
Jeff Sharkey146bb332018-04-18 15:42:57 -06005175 public SubscriptionPlan getSubscriptionPlan(NetworkTemplate template) {
5176 synchronized (mNetworkPoliciesSecondLock) {
5177 final int subId = findRelevantSubIdNL(template);
5178 return getPrimarySubscriptionPlanLocked(subId);
5179 }
5180 }
5181
5182 @Override
Jeff Sharkey9252b342018-01-19 07:58:35 +09005183 public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005184 final long quotaBytes;
Jeff Sharkey9252b342018-01-19 07:58:35 +09005185 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005186 quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09005187 OPPORTUNISTIC_QUOTA_UNKNOWN);
Jeff Sharkey9252b342018-01-19 07:58:35 +09005188 }
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005189 if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
5190 return OPPORTUNISTIC_QUOTA_UNKNOWN;
5191 }
5192
5193 if (quotaType == QUOTA_TYPE_JOBS) {
5194 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
5195 NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
5196 } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
5197 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
5198 NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
5199 } else {
5200 return OPPORTUNISTIC_QUOTA_UNKNOWN;
5201 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005202 }
Sudheer Shankac53c47f2018-01-16 12:01:00 -08005203
5204 @Override
5205 public void onAdminDataAvailable() {
5206 mAdminDataAvailableLatch.countDown();
5207 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005208
5209 @Override
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08005210 public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
5211 NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist);
5212 }
5213
5214 @Override
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005215 public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) {
5216 setMeteredRestrictedPackagesInternal(packageNames, userId);
5217 }
5218
5219 @Override
5220 public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) {
5221 mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
5222 userId, 0, packageNames).sendToTarget();
5223 }
5224 }
5225
5226 private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
5227 synchronized (mUidRulesFirstLock) {
5228 final Set<Integer> newRestrictedUids = new ArraySet<>();
5229 for (String packageName : packageNames) {
5230 final int uid = getUidForPackage(packageName, userId);
5231 if (uid >= 0) {
5232 newRestrictedUids.add(uid);
5233 }
5234 }
5235 final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId);
5236 mMeteredRestrictedUids.put(userId, newRestrictedUids);
5237 handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids);
5238 mLogger.meteredRestrictedPkgsChanged(newRestrictedUids);
5239 }
5240 }
5241
5242 private int getUidForPackage(String packageName, int userId) {
5243 try {
5244 return mContext.getPackageManager().getPackageUidAsUser(packageName,
5245 PackageManager.MATCH_KNOWN_PACKAGES, userId);
5246 } catch (NameNotFoundException e) {
5247 return -1;
5248 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005249 }
5250
5251 private int parseSubId(NetworkState state) {
5252 // TODO: moved to using a legitimate NetworkSpecifier instead of string parsing
5253 int subId = INVALID_SUBSCRIPTION_ID;
5254 if (state != null && state.networkCapabilities != null
5255 && state.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
5256 NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier();
5257 if (spec instanceof StringNetworkSpecifier) {
5258 try {
5259 subId = Integer.parseInt(((StringNetworkSpecifier) spec).specifier);
5260 } catch (NumberFormatException e) {
5261 }
5262 }
5263 }
5264 return subId;
5265 }
5266
Andreas Gampea36dc622018-02-05 17:19:22 -08005267 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey9252b342018-01-19 07:58:35 +09005268 private int getSubIdLocked(Network network) {
5269 return mNetIdToSubId.get(network.netId, INVALID_SUBSCRIPTION_ID);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005270 }
5271
Andreas Gampea36dc622018-02-05 17:19:22 -08005272 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey2e471452018-01-19 18:02:47 +09005273 private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) {
5274 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06005275 if (!ArrayUtils.isEmpty(plans)) {
5276 for (SubscriptionPlan plan : plans) {
5277 if (plan.getCycleRule().isRecurring()) {
5278 // Recurring plans will always have an active cycle
5279 return plan;
5280 } else {
5281 // Non-recurring plans need manual test for active cycle
5282 final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
5283 if (cycle.contains(ZonedDateTime.now(mClock))) {
5284 return plan;
5285 }
5286 }
5287 }
5288 }
5289 return null;
Jeff Sharkey2e471452018-01-19 18:02:47 +09005290 }
5291
Sudheer Shankac53c47f2018-01-16 12:01:00 -08005292 /**
5293 * This will only ever be called once - during device boot.
5294 */
5295 private void waitForAdminData() {
5296 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
5297 ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch,
5298 WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data");
5299 }
5300 }
5301
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005302 private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids,
5303 Set<Integer> newRestrictedUids) {
Sudheer Shanka1536fb62018-07-05 11:52:36 -07005304 if (!mNetworkManagerReady) {
5305 return;
5306 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005307 if (oldRestrictedUids == null) {
5308 for (int uid : newRestrictedUids) {
5309 updateRulesForDataUsageRestrictionsUL(uid);
5310 }
5311 return;
5312 }
5313 for (int uid : oldRestrictedUids) {
5314 if (!newRestrictedUids.contains(uid)) {
5315 updateRulesForDataUsageRestrictionsUL(uid);
5316 }
5317 }
5318 for (int uid : newRestrictedUids) {
5319 if (!oldRestrictedUids.contains(uid)) {
5320 updateRulesForDataUsageRestrictionsUL(uid);
5321 }
5322 }
5323 }
5324
Andreas Gampeaae5aa32018-07-20 12:55:38 -07005325 @GuardedBy("mUidRulesFirstLock")
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005326 private boolean isRestrictedByAdminUL(int uid) {
5327 final Set<Integer> restrictedUids = mMeteredRestrictedUids.get(
5328 UserHandle.getUserId(uid));
5329 return restrictedUids != null && restrictedUids.contains(uid);
5330 }
5331
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005332 private static boolean hasRule(int uidRules, int rule) {
5333 return (uidRules & rule) != 0;
5334 }
5335
Jeff Sharkey2e471452018-01-19 18:02:47 +09005336 private static @NonNull NetworkState[] defeatNullable(@Nullable NetworkState[] val) {
5337 return (val != null) ? val : new NetworkState[0];
5338 }
5339
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06005340 private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle,
5341 String key, boolean defaultValue) {
5342 return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
5343 }
5344
Chris Wren193ae6b2017-03-31 15:17:11 -04005345 private class NotificationId {
5346 private final String mTag;
5347 private final int mId;
5348
5349 NotificationId(NetworkPolicy policy, int type) {
5350 mTag = buildNotificationTag(policy, type);
5351 mId = type;
5352 }
5353
5354 @Override
5355 public boolean equals(Object o) {
5356 if (this == o) return true;
5357 if (!(o instanceof NotificationId)) return false;
5358 NotificationId that = (NotificationId) o;
5359 return Objects.equals(mTag, that.mTag);
5360 }
5361
5362 @Override
5363 public int hashCode() {
5364 return Objects.hash(mTag);
5365 }
5366
5367 /**
5368 * Build unique tag that identifies an active {@link NetworkPolicy}
5369 * notification of a specific type, like {@link #TYPE_LIMIT}.
5370 */
5371 private String buildNotificationTag(NetworkPolicy policy, int type) {
5372 return TAG + ":" + policy.template.hashCode() + ":" + type;
5373 }
5374
5375 public String getTag() {
5376 return mTag;
5377 }
5378
5379 public int getId() {
5380 return mId;
5381 }
5382 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07005383}