blob: af58b195a491a6963e9ae6fb6865fd94a944d61b [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;
Jeff Sharkey497e4432011-06-14 17:27:29 -070023import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkey22c055e2011-06-12 21:13:51 -070024import static android.Manifest.permission.READ_PHONE_STATE;
Amit Mahajan7c5befa2015-07-14 10:26:00 -070025import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
Jeff Sharkey02e21d62011-07-17 15:53:33 -070026import static android.content.Intent.ACTION_PACKAGE_ADDED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070027import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -070028import static android.content.Intent.ACTION_USER_ADDED;
29import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070030import static android.content.Intent.EXTRA_UID;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070031import static android.content.pm.PackageManager.MATCH_ANY_USER;
32import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
33import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
34import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
35import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
Erik Klinef851d6d2015-04-20 16:03:48 +090036import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Felipe Leme1b103232016-01-22 09:44:57 -080037import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
38import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
39import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -060040import static android.net.ConnectivityManager.TYPE_MOBILE;
Remi NGUYEN VANf9a8c2e2019-02-13 18:28:35 +090041import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
42import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
43import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
44import static android.net.INetd.FIREWALL_RULE_ALLOW;
45import static android.net.INetd.FIREWALL_RULE_DENY;
Jeff Sharkey64c96ec2017-08-30 16:28:26 -060046import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090047import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
Jeff Sharkey9252b342018-01-19 07:58:35 +090048import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Jeff Sharkey22c055e2011-06-12 21:13:51 -070049import static android.net.NetworkPolicy.LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070050import static android.net.NetworkPolicy.SNOOZE_NEVER;
Jeff Sharkey497e4432011-06-14 17:27:29 -070051import static android.net.NetworkPolicy.WARNING_DISABLED;
Jeff Sharkey14711eb2011-06-15 10:29:17 -070052import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
Jeff Sharkeydc988062015-09-14 10:09:47 -070053import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060054import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
55import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
Felipe Leme46b451f2016-08-19 08:46:17 -070056import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -070057import static android.net.NetworkPolicyManager.POLICY_NONE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070058import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
Felipe Lemed31a97f2016-05-06 14:53:50 -070059import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
Felipe Leme70c57c22016-03-29 10:45:13 -070060import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
Felipe Leme46c4fc32016-05-04 09:21:43 -070061import static android.net.NetworkPolicyManager.RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -070062import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070063import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
Felipe Leme70c57c22016-03-29 10:45:13 -070064import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
Sudheer Shankae359c3d2017-02-22 18:41:29 -080065import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
66import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060067import static android.net.NetworkPolicyManager.resolveNetworkId;
Felipe Lemeb146f762016-08-19 09:52:16 -070068import static android.net.NetworkPolicyManager.uidPoliciesToString;
Felipe Leme46c4fc32016-05-04 09:21:43 -070069import static android.net.NetworkPolicyManager.uidRulesToString;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070070import static android.net.NetworkTemplate.MATCH_MOBILE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070071import static android.net.NetworkTemplate.MATCH_WIFI;
Jeff Sharkey4e814c32011-07-14 20:37:37 -070072import static android.net.NetworkTemplate.buildTemplateMobileAll;
Jeff Sharkey241dde22012-02-03 14:50:07 -080073import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060074import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkey36b414b2018-03-30 11:00:03 -060075import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
76import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
77import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
78import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
79import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
80import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070081import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070082import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060083import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
Jeff Sharkey0a5570d2018-04-10 12:38:29 -060084import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL;
85import static android.telephony.CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL;
86import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL;
Jeff Sharkey9252b342018-01-19 07:58:35 +090087import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Felipe Leme03e689d2016-03-02 16:17:38 -080088
Jeff Sharkey854b2b12012-04-13 16:03:40 -070089import static com.android.internal.util.ArrayUtils.appendInt;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070090import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070091import static com.android.internal.util.XmlUtils.readBooleanAttribute;
92import static com.android.internal.util.XmlUtils.readIntAttribute;
93import static com.android.internal.util.XmlUtils.readLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060094import static com.android.internal.util.XmlUtils.readStringAttribute;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070095import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
96import static com.android.internal.util.XmlUtils.writeIntAttribute;
97import static com.android.internal.util.XmlUtils.writeLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060098import static com.android.internal.util.XmlUtils.writeStringAttribute;
Jeff Sharkey961e3042011-08-29 16:02:57 -070099import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Sudheer Shanka352dc572017-09-22 17:09:38 -0700100import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT;
101import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED;
junyulai05986c62018-08-07 19:50:45 +0800102import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_SYSTEM;
Sudheer Shanka352dc572017-09-22 17:09:38 -0700103import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST;
104import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST;
105import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT;
106import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BLACKLIST;
107import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_POWER;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700108import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600109
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700110import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
Felipe Lemeb85a6372016-01-14 16:16:16 -0800111import static org.xmlpull.v1.XmlPullParser.END_TAG;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700112import static org.xmlpull.v1.XmlPullParser.START_TAG;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700113
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700114import android.Manifest;
Felipe Lemef3e40642016-06-07 17:28:08 -0700115import android.annotation.IntDef;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900116import android.annotation.NonNull;
Felipe Lemebc853dd2016-09-08 13:26:55 -0700117import android.annotation.Nullable;
Dianne Hackborn497175b2014-07-01 12:56:08 -0700118import android.app.ActivityManager;
Sudheer Shankae7361852017-03-07 11:51:46 -0800119import android.app.ActivityManagerInternal;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700120import android.app.AppGlobals;
Svet Ganov16a16892015-04-16 10:32:04 -0700121import android.app.AppOpsManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700122import android.app.IActivityManager;
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700123import android.app.IUidObserver;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700124import android.app.Notification;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700125import android.app.NotificationManager;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700126import android.app.PendingIntent;
Amith Yamasani15e472352015-04-24 19:06:07 -0700127import android.app.usage.UsageStatsManagerInternal;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700128import android.content.BroadcastReceiver;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700129import android.content.ComponentName;
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600130import android.content.ContentResolver;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700131import android.content.Context;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700132import android.content.Intent;
133import android.content.IntentFilter;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700134import android.content.pm.ApplicationInfo;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700135import android.content.pm.IPackageManager;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700136import android.content.pm.PackageManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700137import android.content.pm.PackageManager.NameNotFoundException;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700138import android.content.pm.UserInfo;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700139import android.content.res.Resources;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700140import android.net.ConnectivityManager;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600141import android.net.ConnectivityManager.NetworkCallback;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700142import android.net.IConnectivityManager;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700143import android.net.INetworkManagementEventObserver;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700144import android.net.INetworkPolicyListener;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700145import android.net.INetworkPolicyManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700146import android.net.INetworkStatsService;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700147import android.net.LinkProperties;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600148import android.net.Network;
149import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700150import android.net.NetworkIdentity;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700151import android.net.NetworkPolicy;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600152import android.net.NetworkPolicyManager;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700153import android.net.NetworkQuotaInfo;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600154import android.net.NetworkRequest;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900155import android.net.NetworkSpecifier;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700156import android.net.NetworkState;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700157import android.net.NetworkStats;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700158import android.net.NetworkTemplate;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900159import android.net.StringNetworkSpecifier;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600160import android.net.TrafficStats;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700161import android.net.wifi.WifiConfiguration;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700162import android.net.wifi.WifiManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700163import android.os.BestClock;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700164import android.os.Binder;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700165import android.os.Environment;
166import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700167import android.os.HandlerThread;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700168import android.os.IDeviceIdleController;
Ashish Sharma50fd36d2011-06-15 19:34:53 -0700169import android.os.INetworkManagementService;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700170import android.os.Message;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700171import android.os.MessageQueue.IdleHandler;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700172import android.os.PersistableBundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700173import android.os.PowerManager;
Makoto Onuki2eccd022017-11-01 13:44:23 -0700174import android.os.PowerManager.ServiceType;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700175import android.os.PowerManagerInternal;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600176import android.os.PowerSaveState;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800177import android.os.Process;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700178import android.os.RemoteCallbackList;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700179import android.os.RemoteException;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600180import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700181import android.os.ServiceManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700182import android.os.ShellCallback;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700183import android.os.SystemClock;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600184import android.os.SystemProperties;
Felipe Leme873a83a2016-09-07 11:34:10 -0700185import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700186import android.os.UserHandle;
Amith Yamasani258848d2012-08-10 17:06:33 -0700187import android.os.UserManager;
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700188import android.provider.Settings;
Narayan Kamath94bcdbc2017-07-17 15:32:53 +0100189import android.provider.Settings.Global;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700190import android.telephony.CarrierConfigManager;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600191import android.telephony.SubscriptionInfo;
Jeff Sharkey32566012014-12-02 18:30:14 -0800192import android.telephony.SubscriptionManager;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600193import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600194import android.telephony.SubscriptionPlan;
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700195import android.telephony.TelephonyManager;
Chris Wren8a3d56c2016-08-01 15:52:52 -0400196import android.text.TextUtils;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700197import android.text.format.DateUtils;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700198import android.text.format.Formatter;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700199import android.util.ArrayMap;
200import android.util.ArraySet;
Dianne Hackborn39606a02012-07-31 17:54:35 -0700201import android.util.AtomicFile;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900202import android.util.DataUnit;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600203import android.util.IntArray;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700204import android.util.Log;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700205import android.util.Pair;
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600206import android.util.Range;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600207import android.util.RecurrenceRule;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700208import android.util.Slog;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600209import android.util.SparseArray;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700210import android.util.SparseBooleanArray;
211import android.util.SparseIntArray;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900212import android.util.SparseLongArray;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700213import android.util.Xml;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700214
Jeff Sharkey497e4432011-06-14 17:27:29 -0700215import com.android.internal.R;
Felipe Lemef0823852016-06-08 13:43:08 -0700216import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800217import com.android.internal.annotations.VisibleForTesting;
Chris Wren193ae6b2017-03-31 15:17:11 -0400218import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500219import com.android.internal.notification.SystemNotificationChannels;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700220import com.android.internal.telephony.PhoneConstants;
Jeff Sharkey32566012014-12-02 18:30:14 -0800221import com.android.internal.util.ArrayUtils;
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800222import com.android.internal.util.ConcurrentUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600223import com.android.internal.util.DumpUtils;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700224import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700225import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600226import com.android.internal.util.Preconditions;
Makoto Onuki49392d32018-04-11 13:51:02 -0700227import com.android.internal.util.StatLogger;
Jeff Sharkeydc988062015-09-14 10:09:47 -0700228import com.android.server.EventLogTags;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700229import com.android.server.LocalServices;
Makoto Onuki8e777332017-03-28 11:25:47 -0700230import com.android.server.ServiceThread;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800231import com.android.server.SystemConfig;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600232
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600233import libcore.io.IoUtils;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600234import libcore.util.EmptyArray;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600235
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700236import org.xmlpull.v1.XmlPullParser;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700237import org.xmlpull.v1.XmlSerializer;
238
239import java.io.File;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700240import java.io.FileDescriptor;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700241import java.io.FileInputStream;
242import java.io.FileNotFoundException;
243import java.io.FileOutputStream;
244import java.io.IOException;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700245import java.io.PrintWriter;
Felipe Lemef3e40642016-06-07 17:28:08 -0700246import java.lang.annotation.Retention;
247import java.lang.annotation.RetentionPolicy;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100248import java.nio.charset.StandardCharsets;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700249import java.time.Clock;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900250import java.time.Instant;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600251import java.time.ZoneId;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700252import java.time.ZoneOffset;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600253import java.time.ZonedDateTime;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900254import java.time.temporal.ChronoUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700255import java.util.ArrayList;
Jeff Sharkey146bb332018-04-18 15:42:57 -0600256import java.util.Arrays;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700257import java.util.Calendar;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600258import java.util.List;
Chris Wren193ae6b2017-03-31 15:17:11 -0400259import java.util.Objects;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800260import java.util.Set;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800261import java.util.concurrent.CountDownLatch;
262import java.util.concurrent.TimeUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700263
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700264/**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700265 * Service that maintains low-level network policy rules, using
266 * {@link NetworkStatsService} statistics to drive those rules.
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700267 * <p>
268 * Derives active rules by combining a given policy with other system status,
269 * and delivers to listeners, such as {@link ConnectivityManager}, for
270 * enforcement.
Felipe Lemef0823852016-06-08 13:43:08 -0700271 *
272 * <p>
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700273 * This class uses 2 locks to synchronize state:
Felipe Lemef0823852016-06-08 13:43:08 -0700274 * <ul>
275 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
276 * rules).
277 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
278 * as network policies).
Felipe Lemef0823852016-06-08 13:43:08 -0700279 * </ul>
280 *
281 * <p>
282 * As such, methods that require synchronization have the following prefixes:
283 * <ul>
284 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
285 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
Sudheer Shankac9d94072017-02-22 22:13:55 +0000286 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
287 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
Felipe Lemef0823852016-06-08 13:43:08 -0700288 * </ul>
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700289 */
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700290public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Sudheer Shanka352dc572017-09-22 17:09:38 -0700291 static final String TAG = NetworkPolicyLogger.TAG;
292 private static final boolean LOGD = NetworkPolicyLogger.LOGD;
293 private static final boolean LOGV = NetworkPolicyLogger.LOGV;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700294
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +0900295 /**
296 * No opportunistic quota could be calculated from user data plan or data settings.
297 */
298 public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1;
299
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700300 private static final int VERSION_INIT = 1;
301 private static final int VERSION_ADDED_SNOOZE = 2;
Jeff Sharkey46645002011-07-27 21:11:21 -0700302 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800303 private static final int VERSION_ADDED_METERED = 4;
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800304 private static final int VERSION_SPLIT_SNOOZE = 5;
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800305 private static final int VERSION_ADDED_TIMEZONE = 6;
Jeff Sharkey837f9242012-03-20 16:52:20 -0700306 private static final int VERSION_ADDED_INFERRED = 7;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700307 private static final int VERSION_SWITCH_APP_ID = 8;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700308 private static final int VERSION_ADDED_NETWORK_ID = 9;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700309 private static final int VERSION_SWITCH_UID = 10;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600310 private static final int VERSION_ADDED_CYCLE = 11;
311 private static final int VERSION_LATEST = VERSION_ADDED_CYCLE;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700312
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800313 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400314 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800315 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400316 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800317 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400318 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900319 @VisibleForTesting
320 public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700321
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700322 private static final String TAG_POLICY_LIST = "policy-list";
323 private static final String TAG_NETWORK_POLICY = "network-policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600324 private static final String TAG_SUBSCRIPTION_PLAN = "subscription-plan";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700325 private static final String TAG_UID_POLICY = "uid-policy";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700326 private static final String TAG_APP_POLICY = "app-policy";
Felipe Lemeb85a6372016-01-14 16:16:16 -0800327 private static final String TAG_WHITELIST = "whitelist";
328 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
Felipe Lemea9505cc2016-02-26 10:28:41 -0800329 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700330
331 private static final String ATTR_VERSION = "version";
Jeff Sharkey46645002011-07-27 21:11:21 -0700332 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700333 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
334 private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700335 private static final String ATTR_NETWORK_ID = "networkId";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600336 @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
337 @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
338 private static final String ATTR_CYCLE_START = "cycleStart";
339 private static final String ATTR_CYCLE_END = "cycleEnd";
340 private static final String ATTR_CYCLE_PERIOD = "cyclePeriod";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700341 private static final String ATTR_WARNING_BYTES = "warningBytes";
342 private static final String ATTR_LIMIT_BYTES = "limitBytes";
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700343 private static final String ATTR_LAST_SNOOZE = "lastSnooze";
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800344 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
345 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800346 private static final String ATTR_METERED = "metered";
Jeff Sharkey837f9242012-03-20 16:52:20 -0700347 private static final String ATTR_INFERRED = "inferred";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700348 private static final String ATTR_UID = "uid";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700349 private static final String ATTR_APP_ID = "appId";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700350 private static final String ATTR_POLICY = "policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600351 private static final String ATTR_SUB_ID = "subId";
352 private static final String ATTR_TITLE = "title";
353 private static final String ATTR_SUMMARY = "summary";
354 private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
355 private static final String ATTR_USAGE_BYTES = "usageBytes";
356 private static final String ATTR_USAGE_TIME = "usageTime";
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600357 private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700358
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800359 private static final String ACTION_ALLOW_BACKGROUND =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800360 "com.android.server.net.action.ALLOW_BACKGROUND";
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800361 private static final String ACTION_SNOOZE_WARNING =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800362 "com.android.server.net.action.SNOOZE_WARNING";
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700363 private static final String ACTION_SNOOZE_RAPID =
364 "com.android.server.net.action.SNOOZE_RAPID";
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700365
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800366 /**
367 * Indicates the maximum wait time for admin data to be available;
368 */
369 private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
370
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600371 private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
372 private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
373 private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
374 private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
375
Svetoslav Ganov24c27752016-08-31 18:09:00 -0700376 private static final int MSG_RULES_CHANGED = 1;
Jeff Sharkey6f7af032011-11-01 18:25:15 -0700377 private static final int MSG_METERED_IFACES_CHANGED = 2;
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -0800378 private static final int MSG_LIMIT_REACHED = 5;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -0800379 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
Jeff Sharkeye19f39b2012-05-24 10:21:16 -0700380 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
Amith Yamasani3646cbd2016-04-13 14:04:53 -0700381 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
382 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700383 private static final int MSG_POLICIES_CHANGED = 13;
Felipe Leme03e95e22016-09-09 09:25:31 -0700384 private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900385 private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800386 private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -0700387 private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700388
Makoto Onuki8e777332017-03-28 11:25:47 -0700389 private static final int UID_MSG_STATE_CHANGED = 100;
390 private static final int UID_MSG_GONE = 101;
391
Jeff Sharkey003d3e62018-03-30 14:35:04 -0600392 private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";
393
Jeff Sharkey75279902011-05-24 18:39:45 -0700394 private final Context mContext;
395 private final IActivityManager mActivityManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700396 private NetworkStatsManagerInternal mNetworkStats;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700397 private final INetworkManagementService mNetworkManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700398 private UsageStatsManagerInternal mUsageStats;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700399 private final Clock mClock;
Stuart Scotte3e314d2015-04-20 14:07:45 -0700400 private final UserManager mUserManager;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700401 private final CarrierConfigManager mCarrierConfigManager;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700402
403 private IConnectivityManager mConnManager;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700404 private PowerManagerInternal mPowerManagerInternal;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700405 private IDeviceIdleController mDeviceIdleController;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800406 @GuardedBy("mUidRulesFirstLock")
407 private PowerSaveState mRestrictBackgroundPowerState;
408
409 // Store the status of restrict background before turning on battery saver.
410 // Used to restore mRestrictBackground when battery saver is turned off.
411 private boolean mRestrictBackgroundBeforeBsm;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700412
Sudheer Shanka543339f2017-07-28 15:18:07 -0700413 // Denotes the status of restrict background read from disk.
414 private boolean mLoadedRestrictBackground;
415
Felipe Lemef0823852016-06-08 13:43:08 -0700416 // See main javadoc for instructions on how to use these locks.
417 final Object mUidRulesFirstLock = new Object();
418 final Object mNetworkPoliciesSecondLock = new Object();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700419
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700420 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
421 volatile boolean mSystemReady;
Felipe Lemef0823852016-06-08 13:43:08 -0700422
Felipe Lemef0823852016-06-08 13:43:08 -0700423 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
424 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
425 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800426 // Store whether user flipped restrict background in battery saver mode
427 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700428
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700429 private final boolean mSuppressDefaultPolicy;
430
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800431 private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
432
Sudheer Shanka1536fb62018-07-05 11:52:36 -0700433 private volatile boolean mNetworkManagerReady;
434
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700435 /** Defined network policies. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600436 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800437 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700438
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600439 /** Map from subId to subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600440 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600441 final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600442 /** Map from subId to package name that owns subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600443 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600444 final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600445
Jeff Sharkey9252b342018-01-19 07:58:35 +0900446 /** Map from subId to daily opportunistic quota. */
447 @GuardedBy("mNetworkPoliciesSecondLock")
448 final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray();
449
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700450 /** Defined UID policies. */
Felipe Lemef0823852016-06-08 13:43:08 -0700451 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700452 /** Currently derived rules for each UID. */
Felipe Lemef0823852016-06-08 13:43:08 -0700453 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700454
Felipe Lemef0823852016-06-08 13:43:08 -0700455 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700456 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700457 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700458 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700459 @GuardedBy("mUidRulesFirstLock")
Felipe Leme011b98f2016-02-10 17:28:31 -0800460 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
Jeff Sharkeydc988062015-09-14 10:09:47 -0700461
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700462 /** Set of states for the child firewall chains. True if the chain is active. */
Felipe Lemef0823852016-06-08 13:43:08 -0700463 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700464 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
465
Kweku Adamsa9e55bc2018-11-19 14:59:15 -0800466 // "Power save mode" is the concept used in the DeviceIdleController that includes various
467 // features including Doze and Battery Saver. It include Battery Saver, but "power save mode"
468 // and "battery saver" are not equivalent.
469
Jeff Sharkey32566012014-12-02 18:30:14 -0800470 /**
471 * UIDs that have been white-listed to always be able to have network access
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700472 * in power save mode, except device idle (doze) still applies.
473 * TODO: An int array might be sufficient
474 */
Felipe Lemef0823852016-06-08 13:43:08 -0700475 @GuardedBy("mUidRulesFirstLock")
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700476 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
477
478 /**
479 * UIDs that have been white-listed to always be able to have network access
Jeff Sharkey32566012014-12-02 18:30:14 -0800480 * in power save mode.
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700481 * TODO: An int array might be sufficient
Jeff Sharkey32566012014-12-02 18:30:14 -0800482 */
Felipe Lemef0823852016-06-08 13:43:08 -0700483 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700484 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700485
Felipe Lemef0823852016-06-08 13:43:08 -0700486 @GuardedBy("mUidRulesFirstLock")
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700487 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
488
Felipe Lemeb85a6372016-01-14 16:16:16 -0800489 /**
Kweku Adamsa9e55bc2018-11-19 14:59:15 -0800490 * UIDs that have been white-listed temporarily to be able to have network access despite being
491 * idle. Other power saving restrictions still apply.
492 */
493 @GuardedBy("mUidRulesFirstLock")
494 private final SparseBooleanArray mAppIdleTempWhitelistAppIds = new SparseBooleanArray();
495
496 /**
Felipe Lemea9505cc2016-02-26 10:28:41 -0800497 * UIDs that have been initially white-listed by system to avoid restricted background.
498 */
Felipe Lemef0823852016-06-08 13:43:08 -0700499 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800500 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
501 new SparseBooleanArray();
502
503 /**
504 * UIDs that have been initially white-listed by system to avoid restricted background,
505 * but later revoked by user.
506 */
Felipe Lemef0823852016-06-08 13:43:08 -0700507 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800508 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
509 new SparseBooleanArray();
510
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700511 /** Set of ifaces that are metered. */
Felipe Lemef0823852016-06-08 13:43:08 -0700512 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800513 private ArraySet<String> mMeteredIfaces = new ArraySet<>();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700514 /** Set of over-limit templates that have been notified. */
Felipe Lemef0823852016-06-08 13:43:08 -0700515 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800516 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700517
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700518 /** Set of currently active {@link Notification} tags. */
Felipe Lemef0823852016-06-08 13:43:08 -0700519 @GuardedBy("mNetworkPoliciesSecondLock")
Chris Wren193ae6b2017-03-31 15:17:11 -0400520 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700521
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700522 /** Foreground at UID granularity. */
Felipe Lemef0823852016-06-08 13:43:08 -0700523 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800524 final SparseIntArray mUidState = new SparseIntArray();
Dianne Hackborn497175b2014-07-01 12:56:08 -0700525
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600526 /** Map from network ID to last observed meteredness state */
527 @GuardedBy("mNetworkPoliciesSecondLock")
528 private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900529 /** Map from network ID to last observed roaming state */
530 @GuardedBy("mNetworkPoliciesSecondLock")
531 private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
532
Jeff Sharkey9252b342018-01-19 07:58:35 +0900533 /** Map from netId to subId as of last update */
534 @GuardedBy("mNetworkPoliciesSecondLock")
535 private final SparseIntArray mNetIdToSubId = new SparseIntArray();
536
Jeff Sharkey146bb332018-04-18 15:42:57 -0600537 /** Map from subId to subscriberId as of last update */
538 @GuardedBy("mNetworkPoliciesSecondLock")
539 private final SparseArray<String> mSubIdToSubscriberId = new SparseArray<>();
540 /** Set of all merged subscriberId as of last update */
541 @GuardedBy("mNetworkPoliciesSecondLock")
542 private String[] mMergedSubscriberIds = EmptyArray.STRING;
543
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800544 /**
545 * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
546 * userId to restricted uids which belong to that user.
547 */
548 @GuardedBy("mUidRulesFirstLock")
549 private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>();
550
Jeff Sharkey32566012014-12-02 18:30:14 -0800551 private final RemoteCallbackList<INetworkPolicyListener>
552 mListeners = new RemoteCallbackList<>();
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700553
Dianne Hackborn497175b2014-07-01 12:56:08 -0700554 final Handler mHandler;
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700555 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -0800556 final Handler mUidEventHandler;
Makoto Onuki8e777332017-03-28 11:25:47 -0700557
558 private final ServiceThread mUidEventThread;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700559
Andreas Gampee8e2ebd2018-10-24 19:42:52 -0700560 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700561 private final AtomicFile mPolicyFile;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700562
Svet Ganov16a16892015-04-16 10:32:04 -0700563 private final AppOpsManager mAppOps;
564
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -0800565 private final IPackageManager mIPm;
566
Sudheer Shankae7361852017-03-07 11:51:46 -0800567 private ActivityManagerInternal mActivityManagerInternal;
568
Sudheer Shanka352dc572017-09-22 17:09:38 -0700569 private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
Felipe Lemeb85a6372016-01-14 16:16:16 -0800570
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700571 // TODO: keep whitelist of system-critical services that should never have
572 // rules enforced, such as system, phone, and radio UIDs.
573
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700574 // TODO: migrate notifications to SystemUI
575
Makoto Onuki49392d32018-04-11 13:51:02 -0700576
577 interface Stats {
578 int UPDATE_NETWORK_ENABLED = 0;
579 int IS_UID_NETWORKING_BLOCKED = 1;
580
581 int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
582 }
583
584 public final StatLogger mStatLogger = new StatLogger(new String[] {
585 "updateNetworkEnabledNL()",
586 "isUidNetworkingBlocked()",
587 });
588
Jeff Sharkey75279902011-05-24 18:39:45 -0700589 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700590 INetworkManagementService networkManagement) {
591 this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
592 getDefaultClock(), getDefaultSystemDir(), false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700593 }
594
Jeff Sharkey9911a282018-02-14 22:29:11 -0700595 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700596 return new File(Environment.getDataDirectory(), "system");
597 }
598
Jeff Sharkey9911a282018-02-14 22:29:11 -0700599 private static @NonNull Clock getDefaultClock() {
600 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
601 Clock.systemUTC());
602 }
603
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700604 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700605 INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
606 File systemDir, boolean suppressDefaultPolicy) {
Jeff Sharkeya4620792011-05-20 15:29:23 -0700607 mContext = checkNotNull(context, "missing context");
608 mActivityManager = checkNotNull(activityManager, "missing activityManager");
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700609 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700610 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
Dianne Hackborn1958e5e2015-06-12 18:11:41 -0700611 Context.DEVICE_IDLE_CONTROLLER));
Jeff Sharkey9911a282018-02-14 22:29:11 -0700612 mClock = checkNotNull(clock, "missing Clock");
Stuart Scotte3e314d2015-04-20 14:07:45 -0700613 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700614 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700615 mIPm = pm;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700616
Amith Yamasani450a16b2013-09-18 16:28:50 -0700617 HandlerThread thread = new HandlerThread(TAG);
618 thread.start();
619 mHandler = new Handler(thread.getLooper(), mHandlerCallback);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700620
Makoto Onuki8e777332017-03-28 11:25:47 -0700621 // We create another thread for the UID events, which are more time-critical.
622 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
623 /*allowIo=*/ false);
624 mUidEventThread.start();
625 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
626
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700627 mSuppressDefaultPolicy = suppressDefaultPolicy;
628
Dianne Hackborne17b4452018-01-10 13:15:40 -0800629 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
Svet Ganov16a16892015-04-16 10:32:04 -0700630
631 mAppOps = context.getSystemService(AppOpsManager.class);
Felipe Lemeb85a6372016-01-14 16:16:16 -0800632
Felipe Lemed17fda42016-04-29 11:12:45 -0700633 // Expose private service for system components to use.
634 LocalServices.addService(NetworkPolicyManagerInternal.class,
635 new NetworkPolicyManagerInternalImpl());
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700636 }
637
638 public void bindConnectivityManager(IConnectivityManager connManager) {
639 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
Jeff Sharkeya4620792011-05-20 15:29:23 -0700640 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700641
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700642 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700643 void updatePowerSaveWhitelistUL() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700644 try {
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700645 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
646 mPowerSaveWhitelistExceptIdleAppIds.clear();
647 if (whitelist != null) {
648 for (int uid : whitelist) {
649 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
650 }
651 }
652 whitelist = mDeviceIdleController.getAppIdWhitelist();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700653 mPowerSaveWhitelistAppIds.clear();
654 if (whitelist != null) {
655 for (int uid : whitelist) {
656 mPowerSaveWhitelistAppIds.put(uid, true);
657 }
658 }
659 } catch (RemoteException e) {
660 }
661 }
662
Felipe Lemea9505cc2016-02-26 10:28:41 -0800663 /**
664 * Whitelists pre-defined apps for restrict background, but only if the user didn't already
665 * revoke the whitelist.
666 *
Felipe Leme46b451f2016-08-19 08:46:17 -0700667 * @return whether any uid has been whitelisted.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800668 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700669 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700670 boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
Felipe Lemea9505cc2016-02-26 10:28:41 -0800671 final List<UserInfo> users = mUserManager.getUsers();
672 final int numberUsers = users.size();
673
Felipe Lemea110eec2016-04-29 09:58:06 -0700674 boolean changed = false;
675 for (int i = 0; i < numberUsers; i++) {
676 final UserInfo user = users.get(i);
Felipe Lemef0823852016-06-08 13:43:08 -0700677 changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
Felipe Lemea110eec2016-04-29 09:58:06 -0700678 }
679 return changed;
680 }
681
Andreas Gampeaae5aa32018-07-20 12:55:38 -0700682 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -0700683 private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
Felipe Lemea110eec2016-04-29 09:58:06 -0700684 final SystemConfig sysConfig = SystemConfig.getInstance();
685 final PackageManager pm = mContext.getPackageManager();
Felipe Lemea9505cc2016-02-26 10:28:41 -0800686 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
687 boolean changed = false;
688 for (int i = 0; i < allowDataUsage.size(); i++) {
689 final String pkg = allowDataUsage.valueAt(i);
690 if (LOGD)
Felipe Lemea110eec2016-04-29 09:58:06 -0700691 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
692 + " and user " + userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800693 final ApplicationInfo app;
694 try {
Felipe Lemea110eec2016-04-29 09:58:06 -0700695 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800696 } catch (PackageManager.NameNotFoundException e) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700697 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
698 // Ignore it - some apps on allow-in-data-usage-save are optional.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800699 continue;
700 }
701 if (!app.isPrivilegedApp()) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700702 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
703 + "skipping non-privileged app " + pkg);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800704 continue;
705 }
Felipe Lemea110eec2016-04-29 09:58:06 -0700706 final int uid = UserHandle.getUid(userId, app.uid);
707 mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
708 if (LOGD)
709 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
710 + "background whitelist. Revoked status: "
Felipe Lemea9505cc2016-02-26 10:28:41 -0800711 + mRestrictBackgroundWhitelistRevokedUids.get(uid));
Felipe Lemea110eec2016-04-29 09:58:06 -0700712 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700713 if (LOGD)
714 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
715 + userId + ") to restrict background whitelist");
Felipe Leme46b451f2016-08-19 08:46:17 -0700716 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false);
Felipe Lemea110eec2016-04-29 09:58:06 -0700717 changed = true;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800718 }
719 }
720 return changed;
721 }
722
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800723 private void initService(CountDownLatch initCompleteSignal) {
Felipe Leme873a83a2016-09-07 11:34:10 -0700724 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800725 final int oldPriority = Process.getThreadPriority(Process.myTid());
Felipe Leme873a83a2016-09-07 11:34:10 -0700726 try {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800727 // Boost thread's priority during system server init
728 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
Felipe Leme873a83a2016-09-07 11:34:10 -0700729 if (!isBandwidthControlEnabled()) {
730 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
731 return;
732 }
Jeff Sharkey8c1dc722012-05-04 14:49:37 -0700733
Felipe Leme873a83a2016-09-07 11:34:10 -0700734 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700735 mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
Amith Yamasani15e472352015-04-24 19:06:07 -0700736
Felipe Leme873a83a2016-09-07 11:34:10 -0700737 synchronized (mUidRulesFirstLock) {
738 synchronized (mNetworkPoliciesSecondLock) {
739 updatePowerSaveWhitelistUL();
740 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
741 mPowerManagerInternal.registerLowPowerModeObserver(
742 new PowerManagerInternal.LowPowerModeListener() {
jackqdyulei455e90a2017-02-09 15:29:16 -0800743 @Override
744 public int getServiceType() {
745 return ServiceType.NETWORK_FIREWALL;
Felipe Leme873a83a2016-09-07 11:34:10 -0700746 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800747
748 @Override
749 public void onLowPowerModeChanged(PowerSaveState result) {
750 final boolean enabled = result.batterySaverEnabled;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800751 if (LOGD) {
752 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
753 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800754 synchronized (mUidRulesFirstLock) {
755 if (mRestrictPower != enabled) {
756 mRestrictPower = enabled;
757 updateRulesForRestrictPowerUL();
758 }
759 }
760 }
jackqdyulei29c82ab2017-03-10 14:09:16 -0800761 });
jackqdyulei455e90a2017-02-09 15:29:16 -0800762 mRestrictPower = mPowerManagerInternal.getLowPowerState(
763 ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
Felipe Leme873a83a2016-09-07 11:34:10 -0700764
765 mSystemReady = true;
766
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800767 waitForAdminData();
768
Felipe Leme873a83a2016-09-07 11:34:10 -0700769 // read policy from disk
770 readPolicyAL();
771
jackqdyulei29c82ab2017-03-10 14:09:16 -0800772 // Update the restrictBackground if battery saver is turned on
Sudheer Shanka543339f2017-07-28 15:18:07 -0700773 mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800774 mRestrictBackgroundPowerState = mPowerManagerInternal
775 .getLowPowerState(ServiceType.DATA_SAVER);
776 final boolean localRestrictBackground =
777 mRestrictBackgroundPowerState.batterySaverEnabled;
Sudheer Shanka543339f2017-07-28 15:18:07 -0700778 if (localRestrictBackground && !mLoadedRestrictBackground) {
779 mLoadedRestrictBackground = true;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800780 }
781 mPowerManagerInternal.registerLowPowerModeObserver(
782 new PowerManagerInternal.LowPowerModeListener() {
783 @Override
784 public int getServiceType() {
785 return ServiceType.DATA_SAVER;
786 }
787
788 @Override
789 public void onLowPowerModeChanged(PowerSaveState result) {
790 synchronized (mUidRulesFirstLock) {
791 updateRestrictBackgroundByLowPowerModeUL(result);
792 }
793 }
794 });
795
Felipe Leme873a83a2016-09-07 11:34:10 -0700796 if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
797 writePolicyAL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700798 }
Felipe Lemef0823852016-06-08 13:43:08 -0700799
Sudheer Shanka543339f2017-07-28 15:18:07 -0700800 setRestrictBackgroundUL(mLoadedRestrictBackground);
Felipe Leme873a83a2016-09-07 11:34:10 -0700801 updateRulesForGlobalChangeAL(false);
802 updateNotificationsNL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700803 }
Felipe Lemea9505cc2016-02-26 10:28:41 -0800804 }
Felipe Leme873a83a2016-09-07 11:34:10 -0700805
Sudheer Shankae7361852017-03-07 11:51:46 -0800806 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Felipe Leme873a83a2016-09-07 11:34:10 -0700807 try {
808 mActivityManager.registerUidObserver(mUidObserver,
Sudheer Shankac9d94072017-02-22 22:13:55 +0000809 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
Sudheer Shanka6a3c07e2018-09-11 15:21:22 -0700810 NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
Felipe Leme873a83a2016-09-07 11:34:10 -0700811 mNetworkManager.registerObserver(mAlertObserver);
812 } catch (RemoteException e) {
813 // ignored; both services live in system_server
814 }
815
816 // listen for changes to power save whitelist
817 final IntentFilter whitelistFilter = new IntentFilter(
818 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
819 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
820
Felipe Leme873a83a2016-09-07 11:34:10 -0700821 // watch for network interfaces to be claimed
822 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
823 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
824
825 // listen for package changes to update policy
826 final IntentFilter packageFilter = new IntentFilter();
827 packageFilter.addAction(ACTION_PACKAGE_ADDED);
828 packageFilter.addDataScheme("package");
829 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
830
831 // listen for UID changes to update policy
832 mContext.registerReceiver(
833 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
834
835 // listen for user changes to update policy
836 final IntentFilter userFilter = new IntentFilter();
837 userFilter.addAction(ACTION_USER_ADDED);
838 userFilter.addAction(ACTION_USER_REMOVED);
839 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
840
841 // listen for stats update events
842 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
843 mContext.registerReceiver(
844 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
845
846 // listen for restrict background changes from notifications
847 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
848 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
849
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700850 // Listen for snooze from notifications
851 mContext.registerReceiver(mSnoozeReceiver,
852 new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler);
853 mContext.registerReceiver(mSnoozeReceiver,
854 new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700855
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600856 // listen for configured wifi networks to be loaded
857 final IntentFilter wifiFilter =
858 new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
859 mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700860
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700861 // listen for carrier config changes to update data cycle information
862 final IntentFilter carrierConfigFilter = new IntentFilter(
863 ACTION_CARRIER_CONFIG_CHANGED);
864 mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
865
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600866 // listen for meteredness changes
867 mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
868 new NetworkRequest.Builder().build(), mNetworkCallback);
869
Felipe Leme873a83a2016-09-07 11:34:10 -0700870 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
Jeff Sharkey146bb332018-04-18 15:42:57 -0600871
872 // Listen for subscriber changes
873 mContext.getSystemService(SubscriptionManager.class).addOnSubscriptionsChangedListener(
874 new OnSubscriptionsChangedListener(mHandler.getLooper()) {
875 @Override
876 public void onSubscriptionsChanged() {
877 updateNetworksInternal();
878 }
879 });
880
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800881 // tell systemReady() that the service has been initialized
882 initCompleteSignal.countDown();
Felipe Leme873a83a2016-09-07 11:34:10 -0700883 } finally {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800884 // Restore the default priority after init is done
885 Process.setThreadPriority(oldPriority);
Felipe Leme873a83a2016-09-07 11:34:10 -0700886 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700887 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700888 }
889
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800890 public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
Sudheer Shanka1536fb62018-07-05 11:52:36 -0700891 mNetworkManagerReady = true;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800892 final CountDownLatch initCompleteSignal = new CountDownLatch(1);
893 mHandler.post(() -> initService(initCompleteSignal));
894 return initCompleteSignal;
895 }
896
897 public void systemReady(CountDownLatch initCompleteSignal) {
898 // wait for initService to complete
899 try {
900 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
901 throw new IllegalStateException("Service " + TAG +" init timeout");
902 }
903 } catch (InterruptedException e) {
904 Thread.currentThread().interrupt();
905 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
906 }
907 }
908
Sudheer Shankac9d94072017-02-22 22:13:55 +0000909 final private IUidObserver mUidObserver = new IUidObserver.Stub() {
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700910 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700911 mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
912 uid, procState, procStateSeq).sendToTarget();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700913 }
914
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700915 @Override public void onUidGone(int uid, boolean disabled) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700916 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700917 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700918
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700919 @Override public void onUidActive(int uid) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700920 }
921
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700922 @Override public void onUidIdle(int uid, boolean disabled) {
923 }
924
925 @Override public void onUidCachedChanged(int uid, boolean cached) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700926 }
Jeff Sharkeya4620792011-05-20 15:29:23 -0700927 };
928
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700929 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700930 @Override
931 public void onReceive(Context context, Intent intent) {
932 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
Felipe Lemef0823852016-06-08 13:43:08 -0700933 synchronized (mUidRulesFirstLock) {
934 updatePowerSaveWhitelistUL();
935 updateRulesForRestrictPowerUL();
Felipe Leme09700462016-09-08 09:33:48 -0700936 updateRulesForAppIdleUL();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700937 }
938 }
939 };
940
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700941 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700942 @Override
943 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700944 // on background handler thread, and PACKAGE_ADDED is protected
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700945
946 final String action = intent.getAction();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700947 final int uid = intent.getIntExtra(EXTRA_UID, -1);
948 if (uid == -1) return;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700949
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700950 if (ACTION_PACKAGE_ADDED.equals(action)) {
951 // update rules for UID, since it might be subject to
952 // global background data policy
953 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700954 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700955 updateRestrictionRulesForUidUL(uid);
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700956 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700957 }
958 }
959 };
960
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700961 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700962 @Override
963 public void onReceive(Context context, Intent intent) {
964 // on background handler thread, and UID_REMOVED is protected
965
966 final int uid = intent.getIntExtra(EXTRA_UID, -1);
967 if (uid == -1) return;
968
969 // remove any policy and update rules to clean up
970 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700971 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700972 onUidDeletedUL(uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700973 synchronized (mNetworkPoliciesSecondLock) {
974 writePolicyAL();
975 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700976 }
977 }
978 };
979
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700980 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700981 @Override
982 public void onReceive(Context context, Intent intent) {
983 // on background handler thread, and USER_ADDED and USER_REMOVED
984 // broadcasts are protected
985
986 final String action = intent.getAction();
987 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
988 if (userId == -1) return;
989
Amith Yamasani15e472352015-04-24 19:06:07 -0700990 switch (action) {
991 case ACTION_USER_REMOVED:
992 case ACTION_USER_ADDED:
Felipe Lemef0823852016-06-08 13:43:08 -0700993 synchronized (mUidRulesFirstLock) {
Fyodor Kupolova31c5912016-01-22 11:26:09 -0800994 // Remove any persistable state for the given user; both cleaning up after a
Amith Yamasani15e472352015-04-24 19:06:07 -0700995 // USER_REMOVED, and one last sanity check during USER_ADDED
Felipe Lemef0823852016-06-08 13:43:08 -0700996 removeUserStateUL(userId, true);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800997 // Removing outside removeUserStateUL since that can also be called when
998 // user resets app preferences.
999 mMeteredRestrictedUids.remove(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -07001000 if (action == ACTION_USER_ADDED) {
1001 // Add apps that are whitelisted by default.
Felipe Lemef0823852016-06-08 13:43:08 -07001002 addDefaultRestrictBackgroundWhitelistUidsUL(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -07001003 }
1004 // Update global restrict for that user
Felipe Lemef0823852016-06-08 13:43:08 -07001005 synchronized (mNetworkPoliciesSecondLock) {
1006 updateRulesForGlobalChangeAL(true);
1007 }
Amith Yamasani15e472352015-04-24 19:06:07 -07001008 }
1009 break;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07001010 }
1011 }
1012 };
1013
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001014 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001015 * Receiver that watches for {@link INetworkStatsService} updates, which we
1016 * use to check against {@link NetworkPolicy#warningBytes}.
1017 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001018 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
Jeff Sharkey497e4432011-06-14 17:27:29 -07001019 @Override
1020 public void onReceive(Context context, Intent intent) {
1021 // on background handler thread, and verified
1022 // READ_NETWORK_USAGE_HISTORY permission above.
1023
Felipe Lemef0823852016-06-08 13:43:08 -07001024 synchronized (mNetworkPoliciesSecondLock) {
1025 updateNetworkEnabledNL();
1026 updateNotificationsNL();
Jeff Sharkey497e4432011-06-14 17:27:29 -07001027 }
1028 }
1029 };
1030
1031 /**
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07001032 * Receiver that watches for {@link Notification} control of
1033 * {@link #mRestrictBackground}.
1034 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001035 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07001036 @Override
1037 public void onReceive(Context context, Intent intent) {
1038 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1039 // permission above.
1040
1041 setRestrictBackground(false);
1042 }
1043 };
1044
1045 /**
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001046 * Receiver that watches for {@link Notification} control of
1047 * {@link NetworkPolicy#lastWarningSnooze}.
1048 */
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001049 final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001050 @Override
1051 public void onReceive(Context context, Intent intent) {
1052 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1053 // permission above.
1054
1055 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001056 if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) {
1057 performSnooze(template, TYPE_WARNING);
1058 } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) {
1059 performSnooze(template, TYPE_RAPID);
1060 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001061 }
1062 };
1063
1064 /**
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001065 * Receiver that watches for {@link WifiConfiguration} to be loaded so that
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001066 * we can perform upgrade logic. After initial upgrade logic, it updates
1067 * {@link #mMeteredIfaces} based on configuration changes.
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001068 */
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001069 final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001070 @Override
1071 public void onReceive(Context context, Intent intent) {
Hugo Benichi446c9c92017-04-10 09:41:10 +09001072 synchronized (mUidRulesFirstLock) {
1073 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001074 upgradeWifiMeteredOverrideAL();
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001075 }
1076 }
1077 // Only need to perform upgrade logic once
1078 mContext.unregisterReceiver(this);
1079 }
1080 };
1081
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001082 private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue,
1083 Network network) {
1084 final boolean lastValue = lastValues.get(network.netId, false);
1085 final boolean changed = (lastValue != newValue) || lastValues.indexOfKey(network.netId) < 0;
1086 if (changed) {
1087 lastValues.put(network.netId, newValue);
1088 }
1089 return changed;
1090 }
1091
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001092 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
1093 @Override
1094 public void onCapabilitiesChanged(Network network,
1095 NetworkCapabilities networkCapabilities) {
1096 if (network == null || networkCapabilities == null) return;
1097
1098 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001099 final boolean newMetered = !networkCapabilities
1100 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001101 final boolean meteredChanged = updateCapabilityChange(
1102 mNetworkMetered, newMetered, network);
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001103
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001104 final boolean newRoaming = !networkCapabilities
1105 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
1106 final boolean roamingChanged = updateCapabilityChange(
1107 mNetworkRoaming, newRoaming, network);
1108
1109 if (meteredChanged || roamingChanged) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07001110 mLogger.meterednessChanged(network.netId, newMetered);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001111 updateNetworkRulesNL();
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001112 }
1113 }
1114 }
1115 };
1116
1117 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001118 * Observer that watches for {@link INetworkManagementService} alerts.
1119 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001120 final private INetworkManagementEventObserver mAlertObserver
1121 = new BaseNetworkObserver() {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001122 @Override
1123 public void limitReached(String limitName, String iface) {
1124 // only someone like NMS should be calling us
1125 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1126
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08001127 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1128 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001129 }
1130 }
1131 };
1132
1133 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001134 * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
1135 * to show visible notifications as needed.
1136 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001137 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001138 void updateNotificationsNL() {
1139 if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001140 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNotificationsNL");
Jeff Sharkey497e4432011-06-14 17:27:29 -07001141
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001142 // keep track of previously active notifications
Chris Wren193ae6b2017-03-31 15:17:11 -04001143 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001144 mActiveNotifs.clear();
Jeff Sharkey497e4432011-06-14 17:27:29 -07001145
1146 // TODO: when switching to kernel notifications, compute next future
1147 // cycle boundary to recompute notifications.
1148
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001149 // examine stats for each active policy
Jeff Sharkey9911a282018-02-14 22:29:11 -07001150 final long now = mClock.millis();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001151 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1152 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey146bb332018-04-18 15:42:57 -06001153 final int subId = findRelevantSubIdNL(policy.template);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001154
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001155 // ignore policies that aren't relevant to user
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001156 if (subId == INVALID_SUBSCRIPTION_ID) continue;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001157 if (!policy.hasCycle()) continue;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001158
Jeff Sharkey53313d72017-07-13 16:47:32 -06001159 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1160 .cycleIterator(policy).next();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001161 final long cycleStart = cycle.first.toInstant().toEpochMilli();
1162 final long cycleEnd = cycle.second.toInstant().toEpochMilli();
1163 final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001164
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001165 // Carrier might want to manage notifications themselves
1166 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
1167 final boolean notifyWarning = getBooleanDefeatingNullable(config,
1168 KEY_DATA_WARNING_NOTIFICATION_BOOL, true);
1169 final boolean notifyLimit = getBooleanDefeatingNullable(config,
1170 KEY_DATA_LIMIT_NOTIFICATION_BOOL, true);
1171 final boolean notifyRapid = getBooleanDefeatingNullable(config,
1172 KEY_DATA_RAPID_NOTIFICATION_BOOL, true);
1173
1174 // Notify when data usage is over warning
1175 if (notifyWarning) {
1176 if (policy.isOverWarning(totalBytes) && !policy.isOverLimit(totalBytes)) {
1177 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
1178 if (!snoozedThisCycle) {
1179 enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
1180 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001181 }
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001182 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001183
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001184 // Notify when data usage is over limit
1185 if (notifyLimit) {
1186 if (policy.isOverLimit(totalBytes)) {
1187 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
1188 if (snoozedThisCycle) {
1189 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
1190 } else {
1191 enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
1192 notifyOverLimitNL(policy.template);
1193 }
1194 } else {
1195 notifyUnderLimitNL(policy.template);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001196 }
1197 }
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001198
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001199 // Warn if average usage over last 4 days is on track to blow pretty
1200 // far past the plan limits.
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001201 if (notifyRapid && policy.limitBytes != LIMIT_DISABLED) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001202 final long recentDuration = TimeUnit.DAYS.toMillis(4);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001203 final long recentStart = now - recentDuration;
1204 final long recentEnd = now;
1205 final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001206
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001207 final long cycleDuration = cycleEnd - cycleStart;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001208 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001209 final long alertBytes = (policy.limitBytes * 3) / 2;
1210
1211 if (LOGD) {
1212 Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected "
1213 + projectedBytes + " alert " + alertBytes);
1214 }
1215
1216 final boolean snoozedRecently = policy.lastRapidSnooze >= now
1217 - DateUtils.DAY_IN_MILLIS;
1218 if (projectedBytes > alertBytes && !snoozedRecently) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001219 enqueueNotification(policy, TYPE_RAPID, 0,
1220 findRapidBlame(policy.template, recentStart, recentEnd));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001221 }
1222 }
1223 }
1224
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001225 // cancel stale notifications that we didn't renew above
Dianne Hackborn497175b2014-07-01 12:56:08 -07001226 for (int i = beforeNotifs.size()-1; i >= 0; i--) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001227 final NotificationId notificationId = beforeNotifs.valueAt(i);
1228 if (!mActiveNotifs.contains(notificationId)) {
1229 cancelNotification(notificationId);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001230 }
1231 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001232
1233 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001234 }
1235
1236 /**
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001237 * Attempt to find a specific app to blame for rapid data usage during the
1238 * given time period.
1239 */
1240 private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
1241 long start, long end) {
1242 long totalBytes = 0;
1243 long maxBytes = 0;
1244 int maxUid = 0;
1245
1246 final NetworkStats stats = getNetworkUidBytes(template, start, end);
1247 NetworkStats.Entry entry = null;
1248 for (int i = 0; i < stats.size(); i++) {
1249 entry = stats.getValues(i, entry);
1250 final long bytes = entry.rxBytes + entry.txBytes;
1251 totalBytes += bytes;
1252 if (bytes > maxBytes) {
1253 maxBytes = bytes;
1254 maxUid = entry.uid;
1255 }
1256 }
1257
1258 // Only point blame if the majority of usage was done by a single app.
1259 // TODO: support shared UIDs
1260 if (maxBytes > 0 && maxBytes > totalBytes / 2) {
1261 final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
Jeff Sharkeyd37154e2018-03-26 16:50:59 -06001262 if (packageNames != null && packageNames.length == 1) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001263 try {
1264 return mContext.getPackageManager().getApplicationInfo(packageNames[0],
1265 MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
1266 | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
1267 } catch (NameNotFoundException ignored) {
1268 }
1269 }
1270 }
1271
1272 return null;
1273 }
1274
1275 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001276 * Test if given {@link NetworkTemplate} is relevant to user based on
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001277 * current device state, such as when
1278 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
1279 * data connection status.
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001280 *
1281 * @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no
1282 * matching subId found.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001283 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001284 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey146bb332018-04-18 15:42:57 -06001285 private int findRelevantSubIdNL(NetworkTemplate template) {
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001286 // Mobile template is relevant when any active subscriber matches
Jeff Sharkey146bb332018-04-18 15:42:57 -06001287 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1288 final int subId = mSubIdToSubscriberId.keyAt(i);
1289 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001290 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1291 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1292 true);
1293 if (template.matches(probeIdent)) {
1294 return subId;
Jeff Sharkey32566012014-12-02 18:30:14 -08001295 }
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001296 }
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001297 return INVALID_SUBSCRIPTION_ID;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001298 }
1299
1300 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001301 * Notify that given {@link NetworkTemplate} is over
1302 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1303 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001304 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001305 private void notifyOverLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001306 if (!mOverLimitNotified.contains(template)) {
Wei Liu546cb772016-07-21 16:19:01 -07001307 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001308 mOverLimitNotified.add(template);
1309 }
1310 }
1311
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001312 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001313 private void notifyUnderLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001314 mOverLimitNotified.remove(template);
1315 }
1316
1317 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001318 * Show notification for combined {@link NetworkPolicy} and specific type,
1319 * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1320 */
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001321 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
1322 ApplicationInfo rapidBlame) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001323 final NotificationId notificationId = new NotificationId(policy, type);
Geoffrey Pitschaf759c52017-02-15 09:35:38 -05001324 final Notification.Builder builder =
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001325 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001326 builder.setOnlyAlertOnce(true);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001327 builder.setWhen(0L);
Alan Viverette4a357cd2015-03-18 18:37:18 -07001328 builder.setColor(mContext.getColor(
Selim Cinek255dd042014-08-19 22:29:02 +02001329 com.android.internal.R.color.system_notification_accent_color));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001330
1331 final Resources res = mContext.getResources();
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001332 final CharSequence title;
1333 final CharSequence body;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001334 switch (type) {
1335 case TYPE_WARNING: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001336 title = res.getText(R.string.data_usage_warning_title);
1337 body = res.getString(R.string.data_usage_warning_body,
Anton Hanssona6101e82019-03-29 15:50:09 +00001338 Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001339
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001340 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001341
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001342 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1343 builder.setDeleteIntent(PendingIntent.getBroadcast(
1344 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1345
Wei Liu546cb772016-07-21 16:19:01 -07001346 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001347 builder.setContentIntent(PendingIntent.getActivity(
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001348 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1349
Jeff Sharkey497e4432011-06-14 17:27:29 -07001350 break;
1351 }
1352 case TYPE_LIMIT: {
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001353 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001354 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001355 title = res.getText(R.string.data_usage_mobile_limit_title);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001356 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001357 case MATCH_WIFI:
1358 title = res.getText(R.string.data_usage_wifi_limit_title);
1359 break;
1360 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001361 return;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001362 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001363 body = res.getText(R.string.data_usage_limit_body);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001364
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001365 builder.setOngoing(true);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001366 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001367
Wei Liu546cb772016-07-21 16:19:01 -07001368 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001369 builder.setContentIntent(PendingIntent.getActivity(
1370 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1371 break;
1372 }
1373 case TYPE_LIMIT_SNOOZED: {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001374 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001375 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001376 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1377 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001378 case MATCH_WIFI:
1379 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1380 break;
1381 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001382 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001383 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001384 final long overBytes = totalBytes - policy.limitBytes;
1385 body = res.getString(R.string.data_usage_limit_snoozed_body,
Anton Hanssona6101e82019-03-29 15:50:09 +00001386 Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001387
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001388 builder.setOngoing(true);
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001389 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001390 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001391
Wei Liu546cb772016-07-21 16:19:01 -07001392 final Intent intent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001393 builder.setContentIntent(PendingIntent.getActivity(
1394 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001395 break;
1396 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001397 case TYPE_RAPID: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001398 title = res.getText(R.string.data_usage_rapid_title);
1399 if (rapidBlame != null) {
1400 body = res.getString(R.string.data_usage_rapid_app_body,
1401 rapidBlame.loadLabel(mContext.getPackageManager()));
1402 } else {
1403 body = res.getString(R.string.data_usage_rapid_body);
1404 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001405
Jeff Sharkey2e471452018-01-19 18:02:47 +09001406 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001407
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001408 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
1409 builder.setDeleteIntent(PendingIntent.getBroadcast(
1410 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1411
1412 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001413 builder.setContentIntent(PendingIntent.getActivity(
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001414 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001415 break;
1416 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001417 default: {
1418 return;
1419 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001420 }
1421
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001422 builder.setTicker(title);
1423 builder.setContentTitle(title);
1424 builder.setContentText(body);
1425 builder.setStyle(new Notification.BigTextStyle().bigText(body));
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001426
1427 mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
1428 notificationId.getId(), builder.build(), UserHandle.ALL);
1429 mActiveNotifs.add(notificationId);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001430 }
1431
Chris Wren193ae6b2017-03-31 15:17:11 -04001432 private void cancelNotification(NotificationId notificationId) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001433 mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(),
1434 notificationId.getId());
Jeff Sharkey497e4432011-06-14 17:27:29 -07001435 }
1436
1437 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001438 * Receiver that watches for {@link IConnectivityManager} to claim network
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001439 * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001440 */
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001441 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001442 @Override
1443 public void onReceive(Context context, Intent intent) {
1444 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1445 // permission above.
Jeff Sharkey146bb332018-04-18 15:42:57 -06001446 updateNetworksInternal();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001447 }
1448 };
1449
Jeff Sharkey146bb332018-04-18 15:42:57 -06001450 private void updateNetworksInternal() {
1451 // Get all of our cross-process communication with telephony out of
1452 // the way before we acquire internal locks.
1453 updateSubscriptions();
1454
1455 synchronized (mUidRulesFirstLock) {
1456 synchronized (mNetworkPoliciesSecondLock) {
1457 ensureActiveMobilePolicyAL();
1458 normalizePoliciesNL();
1459 updateNetworkEnabledNL();
1460 updateNetworkRulesNL();
1461 updateNotificationsNL();
1462 }
1463 }
1464 }
1465
Jeff Sharkey2e471452018-01-19 18:02:47 +09001466 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001467 void updateNetworks() throws InterruptedException {
Jeff Sharkey146bb332018-04-18 15:42:57 -06001468 updateNetworksInternal();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001469 final CountDownLatch latch = new CountDownLatch(1);
1470 mHandler.post(() -> {
1471 latch.countDown();
1472 });
1473 latch.await(5, TimeUnit.SECONDS);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001474 }
1475
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001476 /**
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001477 * Update mobile policies with data cycle information from {@link CarrierConfigManager}
1478 * if necessary.
1479 *
1480 * @param subId that has its associated NetworkPolicy updated if necessary
1481 * @return if any policies were updated
1482 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001483 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey146bb332018-04-18 15:42:57 -06001484 private boolean maybeUpdateMobilePolicyCycleAL(int subId, String subscriberId) {
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001485 if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001486
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001487 // find and update the mobile NetworkPolicy for this subscriber id
Jeff Sharkey146bb332018-04-18 15:42:57 -06001488 boolean policyUpdated = false;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001489 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001490 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001491 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1492 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1493 if (template.matches(probeIdent)) {
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001494 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1495 policyUpdated |= updateDefaultMobilePolicyAL(subId, policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001496 }
1497 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001498 return policyUpdated;
1499 }
1500
1501 /**
1502 * Returns the cycle day that should be used for a mobile NetworkPolicy.
1503 *
1504 * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
1505 * to do so, it returns the fallback value.
1506 *
1507 * @param config The CarrierConfig to read the value from.
1508 * @param fallbackCycleDay to return if the CarrierConfig can't be read.
1509 * @return cycleDay to use in the mobile NetworkPolicy.
1510 */
1511 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001512 int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001513 int fallbackCycleDay) {
1514 if (config == null) {
1515 return fallbackCycleDay;
1516 }
1517 int cycleDay =
1518 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1519 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1520 return fallbackCycleDay;
1521 }
1522 // validate cycleDay value
1523 final Calendar cal = Calendar.getInstance();
1524 if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
1525 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
1526 Slog.e(TAG, "Invalid date in "
1527 + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
1528 return fallbackCycleDay;
1529 }
1530 return cycleDay;
1531 }
1532
1533 /**
1534 * Returns the warning bytes that should be used for a mobile NetworkPolicy.
1535 *
1536 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1537 * to do so, it returns the fallback value.
1538 *
1539 * @param config The CarrierConfig to read the value from.
1540 * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
1541 * @return warningBytes to use in the mobile NetworkPolicy.
1542 */
1543 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001544 long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001545 long fallbackWarningBytes) {
1546 if (config == null) {
1547 return fallbackWarningBytes;
1548 }
1549 long warningBytes =
1550 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
1551
1552 if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1553 return WARNING_DISABLED;
1554 } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1555 return getPlatformDefaultWarningBytes();
1556 } else if (warningBytes < 0) {
1557 Slog.e(TAG, "Invalid value in "
1558 + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
1559 + "non-negative value but got: " + warningBytes);
1560 return fallbackWarningBytes;
1561 }
1562
1563 return warningBytes;
1564 }
1565
1566 /**
1567 * Returns the limit bytes that should be used for a mobile NetworkPolicy.
1568 *
1569 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1570 * to do so, it returns the fallback value.
1571 *
1572 * @param config The CarrierConfig to read the value from.
1573 * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
1574 * @return limitBytes to use in the mobile NetworkPolicy.
1575 */
1576 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08001577 long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001578 long fallbackLimitBytes) {
1579 if (config == null) {
1580 return fallbackLimitBytes;
1581 }
1582 long limitBytes =
1583 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
1584
1585 if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1586 return LIMIT_DISABLED;
1587 } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1588 return getPlatformDefaultLimitBytes();
1589 } else if (limitBytes < 0) {
1590 Slog.e(TAG, "Invalid value in "
1591 + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
1592 + "non-negative value but got: " + limitBytes);
1593 return fallbackLimitBytes;
1594 }
1595 return limitBytes;
1596 }
1597
1598 /**
1599 * Receiver that watches for {@link CarrierConfigManager} to be changed.
1600 */
1601 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
1602 @Override
1603 public void onReceive(Context context, Intent intent) {
1604 // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
1605 // broadcast is protected and can't be spoofed. Runs on a background handler thread.
1606
1607 if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
1608 return;
1609 }
1610 final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
Jeff Sharkey146bb332018-04-18 15:42:57 -06001611
1612 // Get all of our cross-process communication with telephony out of
1613 // the way before we acquire internal locks.
1614 updateSubscriptions();
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001615
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001616 synchronized (mUidRulesFirstLock) {
1617 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey146bb332018-04-18 15:42:57 -06001618 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
1619 if (subscriberId != null) {
1620 ensureActiveMobilePolicyAL(subId, subscriberId);
1621 maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
1622 } else {
1623 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
1624 }
1625
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001626 // update network and notification rules, as the data cycle changed and it's
1627 // possible that we should be triggering warnings/limits now
1628 handleNetworkPoliciesUpdateAL(true);
1629 }
1630 }
1631 }
1632 };
1633
1634 /**
1635 * Handles all tasks that need to be run after a new network policy has been set, or an existing
1636 * one has been updated.
1637 *
1638 * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1639 * update.
1640 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001641 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001642 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1643 if (shouldNormalizePolicies) {
1644 normalizePoliciesNL();
1645 }
1646 updateNetworkEnabledNL();
1647 updateNetworkRulesNL();
1648 updateNotificationsNL();
1649 writePolicyAL();
1650 }
1651
1652 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001653 * Proactively control network data connections when they exceed
1654 * {@link NetworkPolicy#limitBytes}.
1655 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001656 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001657 void updateNetworkEnabledNL() {
1658 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001659 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkEnabledNL");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001660
1661 // TODO: reset any policy-disabled networks when any policy is removed
1662 // completely, which is currently rare case.
1663
Makoto Onuki49392d32018-04-11 13:51:02 -07001664 final long startTime = mStatLogger.getTime();
1665
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001666 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1667 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001668 // shortcut when policy has no limit
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001669 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001670 setNetworkTemplateEnabled(policy.template, true);
1671 continue;
1672 }
1673
Jeff Sharkey53313d72017-07-13 16:47:32 -06001674 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1675 .cycleIterator(policy).next();
1676 final long start = cycle.first.toInstant().toEpochMilli();
1677 final long end = cycle.second.toInstant().toEpochMilli();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001678 final long totalBytes = getTotalBytes(policy.template, start, end);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001679
1680 // disable data connection when over limit and not snoozed
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001681 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
1682 && policy.lastLimitSnooze < start;
1683 final boolean networkEnabled = !overLimitWithoutSnooze;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001684
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001685 setNetworkTemplateEnabled(policy.template, networkEnabled);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001686 }
Makoto Onuki49392d32018-04-11 13:51:02 -07001687
1688 mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001689 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001690 }
1691
1692 /**
Jeff Sharkey32566012014-12-02 18:30:14 -08001693 * Proactively disable networks that match the given
1694 * {@link NetworkTemplate}.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001695 */
1696 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07001697 // Don't call setNetworkTemplateEnabledInner() directly because we may have a lock
1698 // held. Call it via the handler.
1699 mHandler.obtainMessage(MSG_SET_NETWORK_TEMPLATE_ENABLED, enabled ? 1 : 0, 0, template)
1700 .sendToTarget();
1701 }
1702
1703 private void setNetworkTemplateEnabledInner(NetworkTemplate template, boolean enabled) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001704 // TODO: reach into ConnectivityManager to proactively disable bringing
1705 // up this network, since we know that traffic will be blocked.
Jack Yu8781b682016-07-08 14:28:51 -07001706
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001707 if (template.getMatchRule() == MATCH_MOBILE) {
Jack Yu8781b682016-07-08 14:28:51 -07001708 // If mobile data usage hits the limit or if the user resumes the data, we need to
1709 // notify telephony.
Jack Yu8781b682016-07-08 14:28:51 -07001710
Jeff Sharkey146bb332018-04-18 15:42:57 -06001711 final IntArray matchingSubIds = new IntArray();
1712 synchronized (mNetworkPoliciesSecondLock) {
1713 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1714 final int subId = mSubIdToSubscriberId.keyAt(i);
1715 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
1716
1717 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1718 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1719 true);
1720 // Template is matched when subscriber id matches.
1721 if (template.matches(probeIdent)) {
1722 matchingSubIds.add(subId);
1723 }
Jack Yu8781b682016-07-08 14:28:51 -07001724 }
1725 }
Jeff Sharkey146bb332018-04-18 15:42:57 -06001726
1727 // Only talk with telephony outside of locks
1728 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1729 for (int i = 0; i < matchingSubIds.size(); i++) {
1730 final int subId = matchingSubIds.get(i);
1731 tm.setPolicyDataEnabled(enabled, subId);
1732 }
Jack Yu8781b682016-07-08 14:28:51 -07001733 }
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001734 }
1735
1736 /**
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001737 * Collect all ifaces from a {@link NetworkState} into the given set.
1738 */
1739 private static void collectIfaces(ArraySet<String> ifaces, NetworkState state) {
1740 final String baseIface = state.linkProperties.getInterfaceName();
1741 if (baseIface != null) {
1742 ifaces.add(baseIface);
1743 }
1744 for (LinkProperties stackedLink : state.linkProperties.getStackedLinks()) {
1745 final String stackedIface = stackedLink.getInterfaceName();
1746 if (stackedIface != null) {
1747 ifaces.add(stackedIface);
1748 }
1749 }
1750 }
1751
1752 /**
Jeff Sharkey146bb332018-04-18 15:42:57 -06001753 * Examine all currently active subscriptions from
1754 * {@link SubscriptionManager#getActiveSubscriptionIdList()} and update
1755 * internal data structures.
1756 * <p>
1757 * Callers <em>must not</em> hold any locks when this method called.
1758 */
1759 void updateSubscriptions() {
1760 if (LOGV) Slog.v(TAG, "updateSubscriptions()");
1761 Trace.traceBegin(TRACE_TAG_NETWORK, "updateSubscriptions");
1762
1763 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1764 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
1765
1766 final int[] subIds = ArrayUtils.defeatNullable(sm.getActiveSubscriptionIdList());
1767 final String[] mergedSubscriberIds = ArrayUtils.defeatNullable(tm.getMergedSubscriberIds());
1768
1769 final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subIds.length);
1770 for (int subId : subIds) {
1771 final String subscriberId = tm.getSubscriberId(subId);
1772 if (!TextUtils.isEmpty(subscriberId)) {
1773 subIdToSubscriberId.put(subId, subscriberId);
1774 } else {
1775 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
1776 }
1777 }
1778
1779 synchronized (mNetworkPoliciesSecondLock) {
1780 mSubIdToSubscriberId.clear();
1781 for (int i = 0; i < subIdToSubscriberId.size(); i++) {
1782 mSubIdToSubscriberId.put(subIdToSubscriberId.keyAt(i),
1783 subIdToSubscriberId.valueAt(i));
1784 }
1785
1786 mMergedSubscriberIds = mergedSubscriberIds;
1787 }
1788
1789 Trace.traceEnd(TRACE_TAG_NETWORK);
1790 }
1791
1792 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001793 * Examine all connected {@link NetworkState}, looking for
1794 * {@link NetworkPolicy} that need to be enforced. When matches found, set
1795 * remaining quota based on usage cycle and historical stats.
1796 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001797 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07001798 void updateNetworkRulesNL() {
1799 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
Jeff Sharkey00072392018-04-12 14:26:32 -06001800 Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001801
1802 final NetworkState[] states;
1803 try {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001804 states = defeatNullable(mConnManager.getAllNetworkState());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001805 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001806 // ignored; service lives in system_server
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001807 return;
1808 }
1809
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001810 // First, generate identities of all connected networks so we can
1811 // quickly compare them against all defined policies below.
Jeff Sharkey9252b342018-01-19 07:58:35 +09001812 mNetIdToSubId.clear();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001813 final ArrayMap<NetworkState, NetworkIdentity> identified = new ArrayMap<>();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001814 for (NetworkState state : states) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001815 if (state.network != null) {
1816 mNetIdToSubId.put(state.network.netId, parseSubId(state));
1817 }
Wei Liub8eaf452016-01-25 10:32:27 -08001818 if (state.networkInfo != null && state.networkInfo.isConnected()) {
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001819 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1820 true);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001821 identified.put(state, ident);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001822 }
1823 }
1824
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001825 final ArraySet<String> newMeteredIfaces = new ArraySet<>();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001826 long lowestRule = Long.MAX_VALUE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001827
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001828 // For every well-defined policy, compute remaining data based on
1829 // current cycle and historical stats, and push to kernel.
1830 final ArraySet<String> matchingIfaces = new ArraySet<>();
1831 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1832 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1833
1834 // Collect all ifaces that match this policy
1835 matchingIfaces.clear();
1836 for (int j = identified.size() - 1; j >= 0; j--) {
1837 if (policy.template.matches(identified.valueAt(j))) {
1838 collectIfaces(matchingIfaces, identified.keyAt(j));
1839 }
1840 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001841
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001842 if (LOGD) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001843 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001844 }
1845
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001846 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001847 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001848 if (hasLimit || policy.metered) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001849 final long quotaBytes;
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001850 if (hasLimit && policy.hasCycle()) {
1851 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1852 .cycleIterator(policy).next();
1853 final long start = cycle.first.toInstant().toEpochMilli();
1854 final long end = cycle.second.toInstant().toEpochMilli();
1855 final long totalBytes = getTotalBytes(policy.template, start, end);
1856
1857 if (policy.lastLimitSnooze >= start) {
1858 // snoozing past quota, but we still need to restrict apps,
1859 // so push really high quota.
1860 quotaBytes = Long.MAX_VALUE;
1861 } else {
1862 // remaining "quota" bytes are based on total usage in
1863 // current cycle. kernel doesn't like 0-byte rules, so we
1864 // set 1-byte quota and disable the radio later.
1865 quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
1866 }
1867 } else {
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001868 // metered network, but no policy limit; we still need to
1869 // restrict apps, so push really high quota.
1870 quotaBytes = Long.MAX_VALUE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001871 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001872
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001873 if (matchingIfaces.size() > 1) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001874 // TODO: switch to shared quota once NMS supports
1875 Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001876 }
1877
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001878 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1879 final String iface = matchingIfaces.valueAt(j);
1880 setInterfaceQuotaAsync(iface, quotaBytes);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001881 newMeteredIfaces.add(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001882 }
1883 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001884
1885 // keep track of lowest warning or limit of active policies
1886 if (hasWarning && policy.warningBytes < lowestRule) {
1887 lowestRule = policy.warningBytes;
1888 }
1889 if (hasLimit && policy.limitBytes < lowestRule) {
1890 lowestRule = policy.limitBytes;
1891 }
1892 }
1893
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001894 // One final pass to catch any metered ifaces that don't have explicitly
1895 // defined policies; typically Wi-Fi networks.
1896 for (NetworkState state : states) {
1897 if (state.networkInfo != null && state.networkInfo.isConnected()
1898 && !state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
1899 matchingIfaces.clear();
1900 collectIfaces(matchingIfaces, state);
1901 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1902 final String iface = matchingIfaces.valueAt(j);
1903 if (!newMeteredIfaces.contains(iface)) {
1904 setInterfaceQuotaAsync(iface, Long.MAX_VALUE);
1905 newMeteredIfaces.add(iface);
1906 }
1907 }
1908 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001909 }
1910
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001911 // Remove quota from any interfaces that are no longer metered.
Dianne Hackborn497175b2014-07-01 12:56:08 -07001912 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
1913 final String iface = mMeteredIfaces.valueAt(i);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001914 if (!newMeteredIfaces.contains(iface)) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001915 removeInterfaceQuotaAsync(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001916 }
1917 }
1918 mMeteredIfaces = newMeteredIfaces;
1919
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001920 final ContentResolver cr = mContext.getContentResolver();
1921 final boolean quotaEnabled = Settings.Global.getInt(cr,
1922 NETPOLICY_QUOTA_ENABLED, 1) != 0;
1923 final long quotaUnlimited = Settings.Global.getLong(cr,
1924 NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
1925 final float quotaLimited = Settings.Global.getFloat(cr,
1926 NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
1927
Jeff Sharkey9252b342018-01-19 07:58:35 +09001928 // Finally, calculate our opportunistic quotas
Jeff Sharkey9252b342018-01-19 07:58:35 +09001929 mSubscriptionOpportunisticQuota.clear();
1930 for (NetworkState state : states) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001931 if (!quotaEnabled) continue;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001932 if (state.network == null) continue;
Jeff Sharkey9252b342018-01-19 07:58:35 +09001933 final int subId = getSubIdLocked(state.network);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001934 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09001935 if (plan == null) continue;
1936
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001937 final long quotaBytes;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001938 final long limitBytes = plan.getDataLimitBytes();
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001939 if (!state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
1940 // Clamp to 0 when roaming
1941 quotaBytes = 0;
1942 } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001943 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001944 } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09001945 // Unlimited data; let's use 20MiB/day (600MiB/month)
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001946 quotaBytes = quotaUnlimited;
Jeff Sharkey9252b342018-01-19 07:58:35 +09001947 } else {
1948 // Limited data; let's only use 10% of remaining budget
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06001949 final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
1950 final long start = cycle.getLower().toInstant().toEpochMilli();
1951 final long end = cycle.getUpper().toInstant().toEpochMilli();
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001952 final Instant now = mClock.instant();
Jeff Sharkey0fc6d032018-03-30 16:25:11 -06001953 final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001954 .truncatedTo(ChronoUnit.DAYS)
1955 .toInstant().toEpochMilli();
Jeff Sharkey9252b342018-01-19 07:58:35 +09001956 final long totalBytes = getTotalBytes(
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001957 NetworkTemplate.buildTemplateMobileAll(state.subscriberId),
1958 start, startOfDay);
Jeff Sharkey9252b342018-01-19 07:58:35 +09001959 final long remainingBytes = limitBytes - totalBytes;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001960 // Number of remaining days including current day
1961 final long remainingDays =
1962 1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001963
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001964 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
Jeff Sharkey9252b342018-01-19 07:58:35 +09001965 }
1966
1967 mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
1968 }
1969
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001970 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07001971 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001972
1973 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
Jeff Sharkey00072392018-04-12 14:26:32 -06001974
1975 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001976 }
1977
1978 /**
1979 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1980 * have at least a default mobile policy defined.
1981 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07001982 @GuardedBy("mNetworkPoliciesSecondLock")
Hugo Benichi446c9c92017-04-10 09:41:10 +09001983 private void ensureActiveMobilePolicyAL() {
1984 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001985 if (mSuppressDefaultPolicy) return;
1986
Jeff Sharkey146bb332018-04-18 15:42:57 -06001987 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
1988 final int subId = mSubIdToSubscriberId.keyAt(i);
1989 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001990
Hugo Benichi446c9c92017-04-10 09:41:10 +09001991 ensureActiveMobilePolicyAL(subId, subscriberId);
Jeff Sharkey32566012014-12-02 18:30:14 -08001992 }
1993 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001994
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001995 /**
1996 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1997 * have at least a default mobile policy defined.
1998 *
1999 * @param subId to build a default policy for
2000 * @param subscriberId that we check for an existing policy
2001 * @return true if a mobile network policy was added, or false one already existed.
2002 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002003 @GuardedBy("mNetworkPoliciesSecondLock")
Hugo Benichi446c9c92017-04-10 09:41:10 +09002004 private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002005 // Poke around to see if we already have a policy
2006 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09002007 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Jeff Sharkey32566012014-12-02 18:30:14 -08002008 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
2009 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
2010 if (template.matches(probeIdent)) {
2011 if (LOGD) {
2012 Slog.d(TAG, "Found template " + template + " which matches subscriber "
2013 + NetworkIdentity.scrubSubscriberId(subscriberId));
2014 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002015 return false;
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002016 }
2017 }
2018
Jeff Sharkey32566012014-12-02 18:30:14 -08002019 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
2020 + "; generating default policy");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002021 final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
Hugo Benichi446c9c92017-04-10 09:41:10 +09002022 addNetworkPolicyAL(policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002023 return true;
2024 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002025
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002026 private long getPlatformDefaultWarningBytes() {
Fan Zhangda71ca02016-09-12 17:36:22 -07002027 final int dataWarningConfig = mContext.getResources().getInteger(
2028 com.android.internal.R.integer.config_networkPolicyDefaultWarning);
Fan Zhangda71ca02016-09-12 17:36:22 -07002029 if (dataWarningConfig == WARNING_DISABLED) {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002030 return WARNING_DISABLED;
Fan Zhangda71ca02016-09-12 17:36:22 -07002031 } else {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002032 return dataWarningConfig * MB_IN_BYTES;
Fan Zhangda71ca02016-09-12 17:36:22 -07002033 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002034 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002035
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002036 private long getPlatformDefaultLimitBytes() {
2037 return LIMIT_DISABLED;
2038 }
2039
2040 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08002041 NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002042 final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002043 final RecurrenceRule cycleRule = NetworkPolicy
2044 .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002045 final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002046 getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(),
2047 SNOOZE_NEVER, SNOOZE_NEVER, true, true);
2048 synchronized (mUidRulesFirstLock) {
2049 synchronized (mNetworkPoliciesSecondLock) {
2050 updateDefaultMobilePolicyAL(subId, policy);
2051 }
2052 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002053 return policy;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002054 }
2055
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002056 /**
2057 * Update the given {@link NetworkPolicy} based on any carrier-provided
2058 * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}.
2059 * Leaves policy untouched if the user has modified it.
2060 *
2061 * @return if the policy was modified
2062 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002063 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06002064 private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
2065 if (!policy.inferred) {
2066 if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
2067 return false;
2068 }
2069
2070 final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
2071 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
2072 policy.lastLimitSnooze, policy.metered, policy.inferred);
2073
2074 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
2075 if (!ArrayUtils.isEmpty(plans)) {
2076 final SubscriptionPlan plan = plans[0];
2077 policy.cycleRule = plan.getCycleRule();
2078 final long planLimitBytes = plan.getDataLimitBytes();
2079 if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
2080 policy.warningBytes = getPlatformDefaultWarningBytes();
2081 policy.limitBytes = getPlatformDefaultLimitBytes();
2082 } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
2083 policy.warningBytes = NetworkPolicy.WARNING_DISABLED;
2084 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2085 } else {
2086 policy.warningBytes = (planLimitBytes * 9) / 10;
2087 switch (plan.getDataLimitBehavior()) {
2088 case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED:
2089 case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED:
2090 policy.limitBytes = planLimitBytes;
2091 break;
2092 default:
2093 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
2094 break;
2095 }
2096 }
2097 } else {
2098 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
2099 final int currentCycleDay;
2100 if (policy.cycleRule.isMonthly()) {
2101 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
2102 } else {
2103 currentCycleDay = NetworkPolicy.CYCLE_NONE;
2104 }
2105 final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
2106 policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
2107 policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes);
2108 policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes);
2109 }
2110
2111 if (policy.equals(original)) {
2112 return false;
2113 } else {
2114 Slog.d(TAG, "Updated " + original + " to " + policy);
2115 return true;
2116 }
2117 }
2118
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002119 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07002120 private void readPolicyAL() {
2121 if (LOGV) Slog.v(TAG, "readPolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002122
2123 // clear any existing policy and read from disk
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002124 mNetworkPolicy.clear();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002125 mSubscriptionPlans.clear();
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002126 mSubscriptionPlansOwner.clear();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002127 mUidPolicy.clear();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002128
2129 FileInputStream fis = null;
2130 try {
2131 fis = mPolicyFile.openRead();
2132 final XmlPullParser in = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002133 in.setInput(fis, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002134
Felipe Leme46b451f2016-08-19 08:46:17 -07002135 // Must save the <restrict-background> tags and convert them to <uid-policy> later,
2136 // to skip UIDs that were explicitly blacklisted.
2137 final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray();
2138
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002139 int type;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002140 int version = VERSION_INIT;
Felipe Lemeb85a6372016-01-14 16:16:16 -08002141 boolean insideWhitelist = false;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002142 while ((type = in.next()) != END_DOCUMENT) {
2143 final String tag = in.getName();
2144 if (type == START_TAG) {
2145 if (TAG_POLICY_LIST.equals(tag)) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06002146 final boolean oldValue = mRestrictBackground;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002147 version = readIntAttribute(in, ATTR_VERSION);
Sudheer Shanka543339f2017-07-28 15:18:07 -07002148 mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
2149 && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002150 } else if (TAG_NETWORK_POLICY.equals(tag)) {
2151 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
2152 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002153 final String networkId;
2154 if (version >= VERSION_ADDED_NETWORK_ID) {
2155 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
2156 } else {
2157 networkId = null;
2158 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002159 final RecurrenceRule cycleRule;
2160 if (version >= VERSION_ADDED_CYCLE) {
2161 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2162 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2163 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2164 cycleRule = new RecurrenceRule(
2165 RecurrenceRule.convertZonedDateTime(start),
2166 RecurrenceRule.convertZonedDateTime(end),
2167 RecurrenceRule.convertPeriod(period));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002168 } else {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002169 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
2170 final String cycleTimezone;
2171 if (version >= VERSION_ADDED_TIMEZONE) {
2172 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
2173 } else {
2174 cycleTimezone = "UTC";
2175 }
2176 cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002177 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002178 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
2179 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002180 final long lastLimitSnooze;
2181 if (version >= VERSION_SPLIT_SNOOZE) {
2182 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
2183 } else if (version >= VERSION_ADDED_SNOOZE) {
2184 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002185 } else {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002186 lastLimitSnooze = SNOOZE_NEVER;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002187 }
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002188 final boolean metered;
2189 if (version >= VERSION_ADDED_METERED) {
2190 metered = readBooleanAttribute(in, ATTR_METERED);
2191 } else {
2192 switch (networkTemplate) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07002193 case MATCH_MOBILE:
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002194 metered = true;
2195 break;
2196 default:
2197 metered = false;
2198 }
2199 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002200 final long lastWarningSnooze;
2201 if (version >= VERSION_SPLIT_SNOOZE) {
2202 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
2203 } else {
2204 lastWarningSnooze = SNOOZE_NEVER;
2205 }
Jeff Sharkey837f9242012-03-20 16:52:20 -07002206 final boolean inferred;
2207 if (version >= VERSION_ADDED_INFERRED) {
2208 inferred = readBooleanAttribute(in, ATTR_INFERRED);
2209 } else {
2210 inferred = false;
2211 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002212
Jeff Sharkey32566012014-12-02 18:30:14 -08002213 final NetworkTemplate template = new NetworkTemplate(networkTemplate,
2214 subscriberId, networkId);
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002215 if (template.isPersistable()) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002216 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
2217 warningBytes, limitBytes, lastWarningSnooze,
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002218 lastLimitSnooze, metered, inferred));
2219 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002220
2221 } else if (TAG_SUBSCRIPTION_PLAN.equals(tag)) {
2222 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2223 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2224 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2225 final SubscriptionPlan.Builder builder = new SubscriptionPlan.Builder(
2226 RecurrenceRule.convertZonedDateTime(start),
2227 RecurrenceRule.convertZonedDateTime(end),
2228 RecurrenceRule.convertPeriod(period));
2229 builder.setTitle(readStringAttribute(in, ATTR_TITLE));
2230 builder.setSummary(readStringAttribute(in, ATTR_SUMMARY));
2231
2232 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES,
2233 SubscriptionPlan.BYTES_UNKNOWN);
2234 final int limitBehavior = readIntAttribute(in, ATTR_LIMIT_BEHAVIOR,
2235 SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN);
2236 if (limitBytes != SubscriptionPlan.BYTES_UNKNOWN
2237 && limitBehavior != SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
2238 builder.setDataLimit(limitBytes, limitBehavior);
2239 }
2240
2241 final long usageBytes = readLongAttribute(in, ATTR_USAGE_BYTES,
2242 SubscriptionPlan.BYTES_UNKNOWN);
2243 final long usageTime = readLongAttribute(in, ATTR_USAGE_TIME,
2244 SubscriptionPlan.TIME_UNKNOWN);
2245 if (usageBytes != SubscriptionPlan.BYTES_UNKNOWN
2246 && usageTime != SubscriptionPlan.TIME_UNKNOWN) {
2247 builder.setDataUsage(usageBytes, usageTime);
2248 }
2249
2250 final int subId = readIntAttribute(in, ATTR_SUB_ID);
2251 final SubscriptionPlan plan = builder.build();
2252 mSubscriptionPlans.put(subId, ArrayUtils.appendElement(
2253 SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
2254
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002255 final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
2256 mSubscriptionPlansOwner.put(subId, ownerPackage);
2257
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002258 } else if (TAG_UID_POLICY.equals(tag)) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002259 final int uid = readIntAttribute(in, ATTR_UID);
2260 final int policy = readIntAttribute(in, ATTR_POLICY);
2261
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002262 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002263 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002264 } else {
2265 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
2266 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002267 } else if (TAG_APP_POLICY.equals(tag)) {
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002268 final int appId = readIntAttribute(in, ATTR_APP_ID);
2269 final int policy = readIntAttribute(in, ATTR_POLICY);
2270
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002271 // TODO: set for other users during upgrade
Xiaohui Chenbe3b0672015-09-02 13:29:22 -07002272 // app policy is deprecated so this is only used in pre system user split.
2273 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002274 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002275 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002276 } else {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002277 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002278 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002279 } else if (TAG_WHITELIST.equals(tag)) {
2280 insideWhitelist = true;
2281 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2282 final int uid = readIntAttribute(in, ATTR_UID);
Felipe Leme46b451f2016-08-19 08:46:17 -07002283 whitelistedRestrictBackground.append(uid, true);
Felipe Lemea9505cc2016-02-26 10:28:41 -08002284 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2285 final int uid = readIntAttribute(in, ATTR_UID);
2286 mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002287 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002288 } else if (type == END_TAG) {
2289 if (TAG_WHITELIST.equals(tag)) {
2290 insideWhitelist = false;
2291 }
2292
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002293 }
2294 }
2295
Felipe Leme46b451f2016-08-19 08:46:17 -07002296 final int size = whitelistedRestrictBackground.size();
2297 for (int i = 0; i < size; i++) {
2298 final int uid = whitelistedRestrictBackground.keyAt(i);
2299 final int policy = mUidPolicy.get(uid, POLICY_NONE);
2300 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
2301 Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid
2302 + " because its policy is " + uidPoliciesToString(policy));
2303 continue;
2304 }
2305 if (UserHandle.isApp(uid)) {
2306 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
2307 if (LOGV)
2308 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
2309 setUidPolicyUncheckedUL(uid, newPolicy, false);
2310 } else {
2311 Slog.w(TAG, "unable to update policy on UID " + uid);
2312 }
2313 }
2314
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002315 } catch (FileNotFoundException e) {
2316 // missing policy is okay, probably first boot
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002317 upgradeDefaultBackgroundDataUL();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002318 } catch (Exception e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07002319 Log.wtf(TAG, "problem reading network policy", e);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002320 } finally {
2321 IoUtils.closeQuietly(fis);
2322 }
2323 }
2324
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002325 /**
2326 * Upgrade legacy background data flags, notifying listeners of one last
2327 * change to always-true.
2328 */
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002329 private void upgradeDefaultBackgroundDataUL() {
2330 // This method is only called when we're unable to find the network policy flag, which
2331 // usually happens on first boot of a new device and not one that has received an OTA.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002332
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002333 // Seed from the default value configured for this device.
Sudheer Shanka543339f2017-07-28 15:18:07 -07002334 mLoadedRestrictBackground = Settings.Global.getInt(
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002335 mContext.getContentResolver(), Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 0) == 1;
2336
2337 // NOTE: We used to read the legacy setting here :
2338 //
2339 // final int legacyFlagValue = Settings.Secure.getInt(
2340 // mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..);
2341 //
2342 // This is no longer necessary because we will never upgrade directly from Gingerbread
2343 // to O+. Devices upgrading from ICS onwards to O will have a netpolicy.xml file that
2344 // contains the correct value that we will continue to use.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002345 }
2346
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002347 /**
2348 * Perform upgrade step of moving any user-defined meterness overrides over
2349 * into {@link WifiConfiguration}.
2350 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002351 @GuardedBy({"mNetworkPoliciesSecondLock", "mUidRulesFirstLock"})
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002352 private void upgradeWifiMeteredOverrideAL() {
2353 boolean modified = false;
2354 final WifiManager wm = mContext.getSystemService(WifiManager.class);
2355 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2356 for (int i = 0; i < mNetworkPolicy.size(); ) {
2357 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2358 if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
2359 && !policy.inferred) {
2360 mNetworkPolicy.removeAt(i);
2361 modified = true;
2362
2363 final String networkId = resolveNetworkId(policy.template.getNetworkId());
2364 for (WifiConfiguration config : configs) {
2365 if (Objects.equals(resolveNetworkId(config), networkId)) {
2366 Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint");
2367 config.meteredOverride = policy.metered
2368 ? WifiConfiguration.METERED_OVERRIDE_METERED
2369 : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
2370 wm.updateNetwork(config);
2371 }
2372 }
2373 } else {
2374 i++;
2375 }
2376 }
2377 if (modified) {
2378 writePolicyAL();
2379 }
2380 }
2381
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002382 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07002383 void writePolicyAL() {
2384 if (LOGV) Slog.v(TAG, "writePolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002385
2386 FileOutputStream fos = null;
2387 try {
2388 fos = mPolicyFile.startWrite();
2389
2390 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002391 out.setOutput(fos, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002392 out.startDocument(null, true);
2393
2394 out.startTag(null, TAG_POLICY_LIST);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002395 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
Jeff Sharkey46645002011-07-27 21:11:21 -07002396 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002397
2398 // write all known network policies
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002399 for (int i = 0; i < mNetworkPolicy.size(); i++) {
2400 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002401 final NetworkTemplate template = policy.template;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002402 if (!template.isPersistable()) continue;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002403
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002404 out.startTag(null, TAG_NETWORK_POLICY);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002405 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
2406 final String subscriberId = template.getSubscriberId();
2407 if (subscriberId != null) {
2408 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002409 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002410 final String networkId = template.getNetworkId();
2411 if (networkId != null) {
2412 out.attribute(null, ATTR_NETWORK_ID, networkId);
2413 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002414 writeStringAttribute(out, ATTR_CYCLE_START,
2415 RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
2416 writeStringAttribute(out, ATTR_CYCLE_END,
2417 RecurrenceRule.convertZonedDateTime(policy.cycleRule.end));
2418 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2419 RecurrenceRule.convertPeriod(policy.cycleRule.period));
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002420 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
2421 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002422 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
2423 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002424 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
Jeff Sharkey837f9242012-03-20 16:52:20 -07002425 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002426 out.endTag(null, TAG_NETWORK_POLICY);
2427 }
2428
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002429 // write all known subscription plans
2430 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
2431 final int subId = mSubscriptionPlans.keyAt(i);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002432 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002433 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
2434 if (ArrayUtils.isEmpty(plans)) continue;
2435
2436 for (SubscriptionPlan plan : plans) {
2437 out.startTag(null, TAG_SUBSCRIPTION_PLAN);
2438 writeIntAttribute(out, ATTR_SUB_ID, subId);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002439 writeStringAttribute(out, ATTR_OWNER_PACKAGE, ownerPackage);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002440 final RecurrenceRule cycleRule = plan.getCycleRule();
2441 writeStringAttribute(out, ATTR_CYCLE_START,
2442 RecurrenceRule.convertZonedDateTime(cycleRule.start));
2443 writeStringAttribute(out, ATTR_CYCLE_END,
2444 RecurrenceRule.convertZonedDateTime(cycleRule.end));
2445 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2446 RecurrenceRule.convertPeriod(cycleRule.period));
2447 writeStringAttribute(out, ATTR_TITLE, plan.getTitle());
2448 writeStringAttribute(out, ATTR_SUMMARY, plan.getSummary());
2449 writeLongAttribute(out, ATTR_LIMIT_BYTES, plan.getDataLimitBytes());
2450 writeIntAttribute(out, ATTR_LIMIT_BEHAVIOR, plan.getDataLimitBehavior());
2451 writeLongAttribute(out, ATTR_USAGE_BYTES, plan.getDataUsageBytes());
2452 writeLongAttribute(out, ATTR_USAGE_TIME, plan.getDataUsageTime());
2453 out.endTag(null, TAG_SUBSCRIPTION_PLAN);
2454 }
2455 }
2456
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002457 // write all known uid policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002458 for (int i = 0; i < mUidPolicy.size(); i++) {
2459 final int uid = mUidPolicy.keyAt(i);
2460 final int policy = mUidPolicy.valueAt(i);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002461
Jeff Sharkey497e4432011-06-14 17:27:29 -07002462 // skip writing empty policies
2463 if (policy == POLICY_NONE) continue;
2464
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002465 out.startTag(null, TAG_UID_POLICY);
2466 writeIntAttribute(out, ATTR_UID, uid);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002467 writeIntAttribute(out, ATTR_POLICY, policy);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002468 out.endTag(null, TAG_UID_POLICY);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002469 }
2470
2471 out.endTag(null, TAG_POLICY_LIST);
Felipe Lemeb85a6372016-01-14 16:16:16 -08002472
2473 // write all whitelists
2474 out.startTag(null, TAG_WHITELIST);
2475
Felipe Lemea9505cc2016-02-26 10:28:41 -08002476 // revoked restrict background whitelist
Felipe Leme46b451f2016-08-19 08:46:17 -07002477 int size = mRestrictBackgroundWhitelistRevokedUids.size();
Felipe Lemea9505cc2016-02-26 10:28:41 -08002478 for (int i = 0; i < size; i++) {
2479 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2480 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2481 writeIntAttribute(out, ATTR_UID, uid);
2482 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2483 }
2484
Felipe Lemeb85a6372016-01-14 16:16:16 -08002485 out.endTag(null, TAG_WHITELIST);
2486
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002487 out.endDocument();
2488
2489 mPolicyFile.finishWrite(fos);
2490 } catch (IOException e) {
2491 if (fos != null) {
2492 mPolicyFile.failWrite(fos);
2493 }
2494 }
2495 }
2496
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002497 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002498 public void setUidPolicy(int uid, int policy) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002499 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002500
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002501 if (!UserHandle.isApp(uid)) {
2502 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002503 }
Felipe Lemef0823852016-06-08 13:43:08 -07002504 synchronized (mUidRulesFirstLock) {
Julia Reynolds72f83d62015-07-27 15:10:42 -04002505 final long token = Binder.clearCallingIdentity();
2506 try {
2507 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2508 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002509 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002510 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Julia Reynolds72f83d62015-07-27 15:10:42 -04002511 }
2512 } finally {
2513 Binder.restoreCallingIdentity(token);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002514 }
2515 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07002516 }
2517
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002518 @Override
2519 public void addUidPolicy(int uid, int policy) {
2520 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002521
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002522 if (!UserHandle.isApp(uid)) {
2523 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2524 }
2525
Felipe Lemef0823852016-06-08 13:43:08 -07002526 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002527 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2528 policy |= oldPolicy;
2529 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002530 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002531 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002532 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002533 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002534 }
2535
2536 @Override
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002537 public void removeUidPolicy(int uid, int policy) {
2538 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2539
2540 if (!UserHandle.isApp(uid)) {
2541 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2542 }
2543
Felipe Lemef0823852016-06-08 13:43:08 -07002544 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002545 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2546 policy = oldPolicy & ~policy;
2547 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002548 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002549 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002550 }
2551 }
2552 }
2553
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002554 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002555 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002556 setUidPolicyUncheckedUL(uid, policy, false);
Felipe Leme923845f2016-03-02 13:42:48 -08002557
Felipe Leme57e3d312016-08-23 14:42:52 -07002558 final boolean notifyApp;
2559 if (!isUidValidForWhitelistRules(uid)) {
2560 notifyApp = false;
2561 } else {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002562 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
2563 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
2564 final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
2565 final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND;
Felipe Leme57e3d312016-08-23 14:42:52 -07002566 final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted);
2567 final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted);
Felipe Leme03f90292016-09-08 18:10:32 -07002568 if ((wasWhitelisted && (!isWhitelisted || isBlacklisted))
2569 && mDefaultRestrictBackgroundWhitelistUids.get(uid)
2570 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2571 if (LOGD)
2572 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist");
2573 mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2574 }
Felipe Leme57e3d312016-08-23 14:42:52 -07002575 notifyApp = wasBlocked != isBlocked;
2576 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002577 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2578 .sendToTarget();
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002579 if (persist) {
2580 synchronized (mNetworkPoliciesSecondLock) {
2581 writePolicyAL();
2582 }
2583 }
Felipe Leme923845f2016-03-02 13:42:48 -08002584 }
2585
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002586 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002587 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
Felipe Leme03f90292016-09-08 18:10:32 -07002588 if (policy == POLICY_NONE) {
2589 mUidPolicy.delete(uid);
2590 } else {
2591 mUidPolicy.put(uid, policy);
2592 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002593
2594 // uid policy changed, recompute rules and persist policy.
Sudheer Shankac9d94072017-02-22 22:13:55 +00002595 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002596 if (persist) {
Felipe Lemef0823852016-06-08 13:43:08 -07002597 synchronized (mNetworkPoliciesSecondLock) {
2598 writePolicyAL();
2599 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002600 }
2601 }
2602
2603 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002604 public int getUidPolicy(int uid) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002605 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2606
Felipe Lemef0823852016-06-08 13:43:08 -07002607 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002608 return mUidPolicy.get(uid, POLICY_NONE);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002609 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002610 }
2611
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002612 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002613 public int[] getUidsWithPolicy(int policy) {
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002614 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2615
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002616 int[] uids = new int[0];
Felipe Lemef0823852016-06-08 13:43:08 -07002617 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002618 for (int i = 0; i < mUidPolicy.size(); i++) {
2619 final int uid = mUidPolicy.keyAt(i);
2620 final int uidPolicy = mUidPolicy.valueAt(i);
Felipe Leme6f51a0a2016-08-24 15:11:51 -07002621 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
2622 (uidPolicy & policy) != 0) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002623 uids = appendInt(uids, uid);
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002624 }
2625 }
2626 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002627 return uids;
2628 }
2629
2630 /**
Felipe Lemed17fda42016-04-29 11:12:45 -07002631 * Removes any persistable state associated with given {@link UserHandle}, persisting
2632 * if any changes that are made.
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002633 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002634 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002635 boolean removeUserStateUL(int userId, boolean writePolicy) {
Felipe Lemed17fda42016-04-29 11:12:45 -07002636
Sudheer Shanka352dc572017-09-22 17:09:38 -07002637 mLogger.removingUserState(userId);
Felipe Lemed17fda42016-04-29 11:12:45 -07002638 boolean changed = false;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002639
Felipe Lemea110eec2016-04-29 09:58:06 -07002640 // Remove entries from revoked default restricted background UID whitelist
2641 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
2642 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2643 if (UserHandle.getUserId(uid) == userId) {
2644 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
Felipe Lemed17fda42016-04-29 11:12:45 -07002645 changed = true;
Felipe Lemea110eec2016-04-29 09:58:06 -07002646 }
2647 }
2648
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002649 // Remove associated UID policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002650 int[] uids = new int[0];
2651 for (int i = 0; i < mUidPolicy.size(); i++) {
2652 final int uid = mUidPolicy.keyAt(i);
2653 if (UserHandle.getUserId(uid) == userId) {
2654 uids = appendInt(uids, uid);
2655 }
2656 }
2657
2658 if (uids.length > 0) {
2659 for (int uid : uids) {
2660 mUidPolicy.delete(uid);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002661 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002662 changed = true;
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002663 }
Felipe Lemef0823852016-06-08 13:43:08 -07002664 synchronized (mNetworkPoliciesSecondLock) {
2665 updateRulesForGlobalChangeAL(true);
2666 if (writePolicy && changed) {
2667 writePolicyAL();
2668 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002669 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002670 return changed;
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002671 }
2672
2673 @Override
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002674 public void registerListener(INetworkPolicyListener listener) {
Jeff Sharkey1a303952011-06-16 13:04:20 -07002675 // TODO: create permission for observing network policy
2676 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002677 mListeners.register(listener);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002678 }
2679
2680 @Override
2681 public void unregisterListener(INetworkPolicyListener listener) {
Jeff Sharkey1a303952011-06-16 13:04:20 -07002682 // TODO: create permission for observing network policy
2683 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002684 mListeners.unregister(listener);
2685 }
2686
Jeff Sharkey1b861272011-05-22 00:34:52 -07002687 @Override
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002688 public void setNetworkPolicies(NetworkPolicy[] policies) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002689 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2690
Felipe Leme6a05eee2016-02-19 14:43:51 -08002691 final long token = Binder.clearCallingIdentity();
2692 try {
Felipe Lemef0823852016-06-08 13:43:08 -07002693 synchronized (mUidRulesFirstLock) {
2694 synchronized (mNetworkPoliciesSecondLock) {
2695 normalizePoliciesNL(policies);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002696 handleNetworkPoliciesUpdateAL(false);
Felipe Lemef0823852016-06-08 13:43:08 -07002697 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002698 }
2699 } finally {
2700 Binder.restoreCallingIdentity(token);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002701 }
2702 }
2703
Hugo Benichi446c9c92017-04-10 09:41:10 +09002704 void addNetworkPolicyAL(NetworkPolicy policy) {
Svet Ganov16a16892015-04-16 10:32:04 -07002705 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Jeff Sharkey32566012014-12-02 18:30:14 -08002706 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
2707 setNetworkPolicies(policies);
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07002708 }
2709
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002710 @Override
Svet Ganov16a16892015-04-16 10:32:04 -07002711 public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002712 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002713 try {
Amit Mahajana9e72a72015-07-30 16:04:13 -07002714 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
2715 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
2716 // permission
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002717 } catch (SecurityException e) {
2718 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002719
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002720 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
2721 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2722 return new NetworkPolicy[0];
2723 }
Svet Ganov16a16892015-04-16 10:32:04 -07002724 }
2725
Felipe Lemef0823852016-06-08 13:43:08 -07002726 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002727 final int size = mNetworkPolicy.size();
2728 final NetworkPolicy[] policies = new NetworkPolicy[size];
2729 for (int i = 0; i < size; i++) {
2730 policies[i] = mNetworkPolicy.valueAt(i);
2731 }
2732 return policies;
2733 }
2734 }
2735
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002736 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002737 private void normalizePoliciesNL() {
2738 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
Jeff Sharkey32566012014-12-02 18:30:14 -08002739 }
2740
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002741 @GuardedBy("mNetworkPoliciesSecondLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002742 private void normalizePoliciesNL(NetworkPolicy[] policies) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002743 mNetworkPolicy.clear();
2744 for (NetworkPolicy policy : policies) {
Annie Meng20b4d842018-05-18 15:00:49 +01002745 if (policy == null) {
2746 continue;
2747 }
Jeff Sharkey32566012014-12-02 18:30:14 -08002748 // When two normalized templates conflict, prefer the most
2749 // restrictive policy
Jeff Sharkey146bb332018-04-18 15:42:57 -06002750 policy.template = NetworkTemplate.normalize(policy.template, mMergedSubscriberIds);
Jeff Sharkey32566012014-12-02 18:30:14 -08002751 final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
2752 if (existing == null || existing.compareTo(policy) > 0) {
2753 if (existing != null) {
2754 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
2755 }
2756 mNetworkPolicy.put(policy.template, policy);
2757 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002758 }
2759 }
2760
2761 @Override
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002762 public void snoozeLimit(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002763 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkey6c0b4f32012-06-12 21:06:30 -07002764
2765 final long token = Binder.clearCallingIdentity();
2766 try {
2767 performSnooze(template, TYPE_LIMIT);
2768 } finally {
2769 Binder.restoreCallingIdentity(token);
2770 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002771 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002772
Dianne Hackborn497175b2014-07-01 12:56:08 -07002773 void performSnooze(NetworkTemplate template, int type) {
Jeff Sharkey9911a282018-02-14 22:29:11 -07002774 final long currentTime = mClock.millis();
Felipe Lemef0823852016-06-08 13:43:08 -07002775 synchronized (mUidRulesFirstLock) {
2776 synchronized (mNetworkPoliciesSecondLock) {
2777 // find and snooze local policy that matches
2778 final NetworkPolicy policy = mNetworkPolicy.get(template);
2779 if (policy == null) {
2780 throw new IllegalArgumentException("unable to find policy for " + template);
2781 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002782
Felipe Lemef0823852016-06-08 13:43:08 -07002783 switch (type) {
2784 case TYPE_WARNING:
2785 policy.lastWarningSnooze = currentTime;
2786 break;
2787 case TYPE_LIMIT:
2788 policy.lastLimitSnooze = currentTime;
2789 break;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07002790 case TYPE_RAPID:
2791 policy.lastRapidSnooze = currentTime;
2792 break;
Felipe Lemef0823852016-06-08 13:43:08 -07002793 default:
2794 throw new IllegalArgumentException("unexpected type");
2795 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002796
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002797 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07002798 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002799 }
2800 }
2801
2802 @Override
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002803 public void onTetheringChanged(String iface, boolean tethering) {
2804 // No need to enforce permission because setRestrictBackground() will do it.
Felipe Lemef0823852016-06-08 13:43:08 -07002805 synchronized (mUidRulesFirstLock) {
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002806 if (mRestrictBackground && tethering) {
2807 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
2808 setRestrictBackground(false);
2809 }
2810 }
2811 }
2812
2813 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002814 public void setRestrictBackground(boolean restrictBackground) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002815 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
Felipe Leme6a05eee2016-02-19 14:43:51 -08002816 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002817 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2818 final long token = Binder.clearCallingIdentity();
2819 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002820 synchronized (mUidRulesFirstLock) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002821 setRestrictBackgroundUL(restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002822 }
Felipe Leme29e72ea2016-09-08 13:26:55 -07002823 } finally {
2824 Binder.restoreCallingIdentity(token);
Felipe Leme6a05eee2016-02-19 14:43:51 -08002825 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002826 } finally {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002827 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey46645002011-07-27 21:11:21 -07002828 }
2829 }
2830
Andreas Gampeaae5aa32018-07-20 12:55:38 -07002831 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07002832 private void setRestrictBackgroundUL(boolean restrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002833 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL");
Felipe Leme70c57c22016-03-29 10:45:13 -07002834 try {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002835 if (restrictBackground == mRestrictBackground) {
2836 // Ideally, UI should never allow this scenario...
2837 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002838 return;
2839 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002840 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
2841 final boolean oldRestrictBackground = mRestrictBackground;
2842 mRestrictBackground = restrictBackground;
2843 // Must whitelist foreground apps before turning data saver mode on.
2844 // TODO: there is no need to iterate through all apps here, just those in the foreground,
2845 // so it could call AM to get the UIDs of such apps, and iterate through them instead.
2846 updateRulesForRestrictBackgroundUL();
2847 try {
2848 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
2849 Slog.e(TAG,
2850 "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
2851 mRestrictBackground = oldRestrictBackground;
2852 // TODO: if it knew the foreground apps (see TODO above), it could call
2853 // updateRulesForRestrictBackgroundUL() again to restore state.
2854 return;
2855 }
2856 } catch (RemoteException e) {
2857 // ignored; service lives in system_server
2858 }
jackqdyulei29c82ab2017-03-10 14:09:16 -08002859
Sudheer Shanka543339f2017-07-28 15:18:07 -07002860 sendRestrictBackgroundChangedMsg();
Sudheer Shanka352dc572017-09-22 17:09:38 -07002861 mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
Sudheer Shanka543339f2017-07-28 15:18:07 -07002862
2863 if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
2864 mRestrictBackgroundChangedInBsm = true;
2865 }
2866 synchronized (mNetworkPoliciesSecondLock) {
2867 updateNotificationsNL();
2868 writePolicyAL();
2869 }
2870 } finally {
2871 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
jackqdyulei29c82ab2017-03-10 14:09:16 -08002872 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002873 }
2874
2875 private void sendRestrictBackgroundChangedMsg() {
2876 mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED);
2877 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0)
2878 .sendToTarget();
Felipe Leme70c57c22016-03-29 10:45:13 -07002879 }
2880
Felipe Lemeb85a6372016-01-14 16:16:16 -08002881 @Override
Felipe Leme1b103232016-01-22 09:44:57 -08002882 public int getRestrictBackgroundByCaller() {
2883 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2884 final int uid = Binder.getCallingUid();
Felipe Leme923845f2016-03-02 13:42:48 -08002885
Felipe Lemef0823852016-06-08 13:43:08 -07002886 synchronized (mUidRulesFirstLock) {
Felipe Leme923845f2016-03-02 13:42:48 -08002887 // Must clear identity because getUidPolicy() is restricted to system.
2888 final long token = Binder.clearCallingIdentity();
2889 final int policy;
2890 try {
2891 policy = getUidPolicy(uid);
2892 } finally {
2893 Binder.restoreCallingIdentity(token);
2894 }
2895 if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2896 // App is blacklisted.
2897 return RESTRICT_BACKGROUND_STATUS_ENABLED;
2898 }
Felipe Leme1b103232016-01-22 09:44:57 -08002899 if (!mRestrictBackground) {
2900 return RESTRICT_BACKGROUND_STATUS_DISABLED;
2901 }
Felipe Leme46b451f2016-08-19 08:46:17 -07002902 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
Felipe Leme1b103232016-01-22 09:44:57 -08002903 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2904 : RESTRICT_BACKGROUND_STATUS_ENABLED;
2905 }
2906 }
2907
2908 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002909 public boolean getRestrictBackground() {
2910 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2911
Felipe Lemef0823852016-06-08 13:43:08 -07002912 synchronized (mUidRulesFirstLock) {
Jeff Sharkey46645002011-07-27 21:11:21 -07002913 return mRestrictBackground;
2914 }
2915 }
2916
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002917 @Override
2918 public void setDeviceIdleMode(boolean enabled) {
2919 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Felipe Leme873a83a2016-09-07 11:34:10 -07002920 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2921 try {
2922 synchronized (mUidRulesFirstLock) {
Felipe Lemeea014392016-09-06 13:59:54 -07002923 if (mDeviceIdleMode == enabled) {
2924 return;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002925 }
Felipe Lemeea014392016-09-06 13:59:54 -07002926 mDeviceIdleMode = enabled;
Sudheer Shanka352dc572017-09-22 17:09:38 -07002927 mLogger.deviceIdleModeEnabled(enabled);
Felipe Lemeea014392016-09-06 13:59:54 -07002928 if (mSystemReady) {
2929 // Device idle change means we need to rebuild rules for all
2930 // known apps, so do a global refresh.
2931 updateRulesForRestrictPowerUL();
2932 }
2933 }
2934 if (enabled) {
2935 EventLogTags.writeDeviceIdleOnPhase("net");
2936 } else {
2937 EventLogTags.writeDeviceIdleOffPhase("net");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002938 }
Felipe Leme873a83a2016-09-07 11:34:10 -07002939 } finally {
2940 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002941 }
2942 }
2943
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002944 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002945 public void setWifiMeteredOverride(String networkId, int meteredOverride) {
2946 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002947 final long token = Binder.clearCallingIdentity();
2948 try {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002949 final WifiManager wm = mContext.getSystemService(WifiManager.class);
2950 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2951 for (WifiConfiguration config : configs) {
2952 if (Objects.equals(resolveNetworkId(config), networkId)) {
2953 config.meteredOverride = meteredOverride;
2954 wm.updateNetwork(config);
2955 }
2956 }
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002957 } finally {
2958 Binder.restoreCallingIdentity(token);
2959 }
2960 }
2961
Jeff Sharkey46645002011-07-27 21:11:21 -07002962 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002963 @Deprecated
2964 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
2965 Log.w(TAG, "Shame on UID " + Binder.getCallingUid()
2966 + " for calling the hidden API getNetworkQuotaInfo(). Shame!");
2967 return new NetworkQuotaInfo();
Jeff Sharkey9f7cbf02012-04-12 18:34:54 -07002968 }
2969
Jeff Sharkey53313d72017-07-13 16:47:32 -06002970 private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) {
2971 // Verify they're not lying about package name
2972 mAppOps.checkPackage(callingUid, callingPackage);
2973
Jeff Sharkey53313d72017-07-13 16:47:32 -06002974 final SubscriptionInfo si;
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002975 final PersistableBundle config;
Jeff Sharkey53313d72017-07-13 16:47:32 -06002976 final long token = Binder.clearCallingIdentity();
2977 try {
2978 si = mContext.getSystemService(SubscriptionManager.class)
2979 .getActiveSubscriptionInfo(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002980 config = mCarrierConfigManager.getConfigForSubId(subId);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002981 } finally {
2982 Binder.restoreCallingIdentity(token);
2983 }
2984
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002985 // First check: is caller the CarrierService?
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002986 if (si != null) {
2987 if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
2988 return;
2989 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002990 }
2991
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002992 // Second check: has the CarrierService delegated access?
2993 if (config != null) {
2994 final String overridePackage = config
2995 .getString(CarrierConfigManager.KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING, null);
2996 if (!TextUtils.isEmpty(overridePackage)
2997 && Objects.equals(overridePackage, callingPackage)) {
2998 return;
2999 }
3000 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003001
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003002 // Third check: is caller the fallback/default CarrierService?
3003 final String defaultPackage = mCarrierConfigManager.getDefaultCarrierServicePackageName();
3004 if (!TextUtils.isEmpty(defaultPackage)
3005 && Objects.equals(defaultPackage, callingPackage)) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06003006 return;
3007 }
3008
Jeff Sharkey003d3e62018-03-30 14:35:04 -06003009 // Fourth check: is caller a testing app?
3010 final String testPackage = SystemProperties.get(PROP_SUB_PLAN_OWNER + "." + subId, null);
3011 if (!TextUtils.isEmpty(testPackage)
3012 && Objects.equals(testPackage, callingPackage)) {
3013 return;
3014 }
3015
3016 // Fifth check: is caller a legacy testing app?
3017 final String legacyTestPackage = SystemProperties.get("fw.sub_plan_owner." + subId, null);
3018 if (!TextUtils.isEmpty(legacyTestPackage)
3019 && Objects.equals(legacyTestPackage, callingPackage)) {
Jeff Sharkeya7f50462018-02-14 14:26:10 -07003020 return;
3021 }
3022
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003023 // Final check: does the caller hold a permission?
3024 mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003025 }
3026
3027 @Override
3028 public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
3029 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3030
Jeff Sharkey53313d72017-07-13 16:47:32 -06003031 final String fake = SystemProperties.get("fw.fake_plan");
3032 if (!TextUtils.isEmpty(fake)) {
3033 final List<SubscriptionPlan> plans = new ArrayList<>();
3034 if ("month_hard".equals(fake)) {
3035 plans.add(SubscriptionPlan.Builder
3036 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3037 .setTitle("G-Mobile")
Jeff Sharkey53313d72017-07-13 16:47:32 -06003038 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3039 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3040 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
3041 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3042 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003043 plans.add(SubscriptionPlan.Builder
3044 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3045 .setTitle("G-Mobile Happy")
3046 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3047 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3048 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3049 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3050 .build());
3051 plans.add(SubscriptionPlan.Builder
3052 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3053 .setTitle("G-Mobile, Charged after limit")
3054 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3055 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
3056 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3057 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
3058 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003059 } else if ("month_soft".equals(fake)) {
3060 plans.add(SubscriptionPlan.Builder
3061 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3062 .setTitle("G-Mobile is the carriers name who this plan belongs to")
3063 .setSummary("Crazy unlimited bandwidth plan with incredibly long title "
3064 + "that should be cut off to prevent UI from looking terrible")
Jeff Sharkey53313d72017-07-13 16:47:32 -06003065 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3066 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3067 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
3068 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3069 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003070 plans.add(SubscriptionPlan.Builder
3071 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3072 .setTitle("G-Mobile, Throttled after limit")
3073 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3074 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3075 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3076 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3077 .build());
3078 plans.add(SubscriptionPlan.Builder
3079 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3080 .setTitle("G-Mobile, No data connection after limit")
3081 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3082 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3083 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3084 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3085 .build());
3086
Sundeep Ghuman09e0f572018-03-14 23:20:23 -07003087 } else if ("month_over".equals(fake)) {
3088 plans.add(SubscriptionPlan.Builder
3089 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3090 .setTitle("G-Mobile is the carriers name who this plan belongs to")
3091 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3092 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3093 .setDataUsage(6 * TrafficStats.GB_IN_BYTES,
3094 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3095 .build());
3096 plans.add(SubscriptionPlan.Builder
3097 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3098 .setTitle("G-Mobile, Throttled after limit")
3099 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3100 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3101 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3102 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3103 .build());
3104 plans.add(SubscriptionPlan.Builder
3105 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
3106 .setTitle("G-Mobile, No data connection after limit")
3107 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3108 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3109 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
3110 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3111 .build());
3112
Jeff Sharkey53313d72017-07-13 16:47:32 -06003113 } else if ("month_none".equals(fake)) {
3114 plans.add(SubscriptionPlan.Builder
3115 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
3116 .setTitle("G-Mobile")
3117 .build());
3118 } else if ("prepaid".equals(fake)) {
3119 plans.add(SubscriptionPlan.Builder
3120 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3121 ZonedDateTime.now().plusDays(10))
3122 .setTitle("G-Mobile")
3123 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
3124 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3125 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
3126 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3127 .build());
3128 } else if ("prepaid_crazy".equals(fake)) {
3129 plans.add(SubscriptionPlan.Builder
3130 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3131 ZonedDateTime.now().plusDays(10))
3132 .setTitle("G-Mobile Anytime")
3133 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
3134 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
3135 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
3136 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3137 .build());
3138 plans.add(SubscriptionPlan.Builder
3139 .createNonrecurring(ZonedDateTime.now().minusDays(10),
3140 ZonedDateTime.now().plusDays(20))
3141 .setTitle("G-Mobile Nickel Nights")
3142 .setSummary("5¢/GB between 1-5AM")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003143 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
3144 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
Jeff Sharkey53313d72017-07-13 16:47:32 -06003145 .setDataUsage(15 * TrafficStats.MB_IN_BYTES,
3146 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
3147 .build());
3148 plans.add(SubscriptionPlan.Builder
3149 .createNonrecurring(ZonedDateTime.now().minusDays(10),
3150 ZonedDateTime.now().plusDays(20))
3151 .setTitle("G-Mobile Bonus 3G")
3152 .setSummary("Unlimited 3G data")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003153 .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
Jeff Sharkey53313d72017-07-13 16:47:32 -06003154 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3155 .setDataUsage(300 * TrafficStats.MB_IN_BYTES,
3156 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
3157 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07003158 } else if ("unlimited".equals(fake)) {
3159 plans.add(SubscriptionPlan.Builder
3160 .createNonrecurring(ZonedDateTime.now().minusDays(20),
3161 ZonedDateTime.now().plusDays(10))
3162 .setTitle("G-Mobile Awesome")
3163 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3164 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3165 .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
3166 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3167 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003168 }
3169 return plans.toArray(new SubscriptionPlan[plans.size()]);
3170 }
3171
Jeff Sharkey4635f102017-09-01 11:27:13 -06003172 synchronized (mNetworkPoliciesSecondLock) {
3173 // Only give out plan details to the package that defined them,
3174 // so that we don't risk leaking plans between apps. We always
3175 // let in core system components (like the Settings app).
3176 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
3177 if (Objects.equals(ownerPackage, callingPackage)
3178 || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)) {
3179 return mSubscriptionPlans.get(subId);
3180 } else {
3181 Log.w(TAG, "Not returning plans because caller " + callingPackage
3182 + " doesn't match owner " + ownerPackage);
3183 return null;
Jeff Sharkey53313d72017-07-13 16:47:32 -06003184 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003185 }
3186 }
3187
3188 @Override
3189 public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) {
3190 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3191
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003192 for (SubscriptionPlan plan : plans) {
3193 Preconditions.checkNotNull(plan);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003194 }
3195
3196 final long token = Binder.clearCallingIdentity();
3197 try {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003198 synchronized (mUidRulesFirstLock) {
3199 synchronized (mNetworkPoliciesSecondLock) {
3200 mSubscriptionPlans.put(subId, plans);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003201 mSubscriptionPlansOwner.put(subId, callingPackage);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003202
Jeff Sharkey146bb332018-04-18 15:42:57 -06003203 final String subscriberId = mSubIdToSubscriberId.get(subId, null);
3204 if (subscriberId != null) {
3205 ensureActiveMobilePolicyAL(subId, subscriberId);
3206 maybeUpdateMobilePolicyCycleAL(subId, subscriberId);
3207 } else {
3208 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
3209 }
3210
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003211 handleNetworkPoliciesUpdateAL(true);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003212 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003213 }
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07003214
3215 final Intent intent = new Intent(SubscriptionManager.ACTION_SUBSCRIPTION_PLANS_CHANGED);
3216 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3217 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3218 mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003219 } finally {
3220 Binder.restoreCallingIdentity(token);
3221 }
3222 }
3223
Jeff Sharkey003d3e62018-03-30 14:35:04 -06003224 /**
3225 * Only visible for testing purposes. This doesn't give any access to
3226 * existing plans; it simply lets the debug package define new plans.
3227 */
3228 void setSubscriptionPlansOwner(int subId, String packageName) {
3229 SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName);
3230 }
3231
Jeff Sharkey53313d72017-07-13 16:47:32 -06003232 @Override
Jeff Sharkey717f52f2018-01-04 16:04:11 -07003233 public String getSubscriptionPlansOwner(int subId) {
3234 if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) {
3235 throw new SecurityException();
3236 }
3237
3238 synchronized (mNetworkPoliciesSecondLock) {
3239 return mSubscriptionPlansOwner.get(subId);
3240 }
3241 }
3242
3243 @Override
Jeff Sharkey9252b342018-01-19 07:58:35 +09003244 public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
3245 long timeoutMillis, String callingPackage) {
3246 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3247
3248 // We can only override when carrier told us about plans
3249 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06003250 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
3251 if (plan == null
3252 || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09003253 throw new IllegalStateException(
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06003254 "Must provide valid SubscriptionPlan to enable overriding");
Jeff Sharkey9252b342018-01-19 07:58:35 +09003255 }
3256 }
3257
Jeff Sharkey36b414b2018-03-30 11:00:03 -06003258 // Only allow overrides when feature is enabled. However, we always
3259 // allow disabling of overrides for safety reasons.
3260 final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
3261 NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
3262 if (overrideEnabled || overrideValue == 0) {
3263 mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3264 overrideMask, overrideValue, subId));
3265 if (timeoutMillis > 0) {
3266 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3267 overrideMask, 0, subId), timeoutMillis);
3268 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09003269 }
3270 }
3271
3272 @Override
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003273 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06003274 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Jeff Sharkey1b861272011-05-22 00:34:52 -07003275
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003276 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
3277
Dianne Hackborn497175b2014-07-01 12:56:08 -07003278 final ArraySet<String> argSet = new ArraySet<String>(args.length);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003279 for (String arg : args) {
3280 argSet.add(arg);
3281 }
3282
Felipe Lemef0823852016-06-08 13:43:08 -07003283 synchronized (mUidRulesFirstLock) {
3284 synchronized (mNetworkPoliciesSecondLock) {
3285 if (argSet.contains("--unsnooze")) {
3286 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
3287 mNetworkPolicy.valueAt(i).clearSnooze();
3288 }
3289
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07003290 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07003291
3292 fout.println("Cleared snooze timestamps");
3293 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003294 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08003295
Felipe Lemef0823852016-06-08 13:43:08 -07003296 fout.print("System ready: "); fout.println(mSystemReady);
3297 fout.print("Restrict background: "); fout.println(mRestrictBackground);
3298 fout.print("Restrict power: "); fout.println(mRestrictPower);
3299 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003300 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
3301
3302 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003303 fout.println("Network policies:");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003304 fout.increaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003305 for (int i = 0; i < mNetworkPolicy.size(); i++) {
3306 fout.println(mNetworkPolicy.valueAt(i).toString());
3307 }
3308 fout.decreaseIndent();
3309
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003310 fout.println();
3311 fout.println("Subscription plans:");
3312 fout.increaseIndent();
3313 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
3314 final int subId = mSubscriptionPlans.keyAt(i);
3315 fout.println("Subscriber ID " + subId + ":");
3316 fout.increaseIndent();
3317 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
3318 if (!ArrayUtils.isEmpty(plans)) {
3319 for (SubscriptionPlan plan : plans) {
3320 fout.println(plan);
3321 }
3322 }
3323 fout.decreaseIndent();
3324 }
3325 fout.decreaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003326
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003327 fout.println();
Jeff Sharkey146bb332018-04-18 15:42:57 -06003328 fout.println("Active subscriptions:");
3329 fout.increaseIndent();
3330 for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
3331 final int subId = mSubIdToSubscriberId.keyAt(i);
3332 final String subscriberId = mSubIdToSubscriberId.valueAt(i);
3333
3334 fout.println(subId + "=" + NetworkIdentity.scrubSubscriberId(subscriberId));
3335 }
3336 fout.decreaseIndent();
3337
3338 fout.println();
3339 fout.println("Merged subscriptions: "
3340 + Arrays.toString(NetworkIdentity.scrubSubscriberId(mMergedSubscriberIds)));
3341
3342 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003343 fout.println("Policy for UIDs:");
3344 fout.increaseIndent();
3345 int size = mUidPolicy.size();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003346 for (int i = 0; i < size; i++) {
Felipe Lemef0823852016-06-08 13:43:08 -07003347 final int uid = mUidPolicy.keyAt(i);
3348 final int policy = mUidPolicy.valueAt(i);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003349 fout.print("UID=");
Felipe Lemef0823852016-06-08 13:43:08 -07003350 fout.print(uid);
3351 fout.print(" policy=");
Felipe Lemeb146f762016-08-19 09:52:16 -07003352 fout.print(uidPoliciesToString(policy));
Felipe Lemef0823852016-06-08 13:43:08 -07003353 fout.println();
3354 }
3355 fout.decreaseIndent();
3356
3357 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3358 if (size > 0) {
3359 fout.println("Power save whitelist (except idle) app ids:");
3360 fout.increaseIndent();
3361 for (int i = 0; i < size; i++) {
3362 fout.print("UID=");
3363 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3364 fout.print(": ");
3365 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
3366 fout.println();
3367 }
3368 fout.decreaseIndent();
3369 }
3370
3371 size = mPowerSaveWhitelistAppIds.size();
3372 if (size > 0) {
3373 fout.println("Power save whitelist app ids:");
3374 fout.increaseIndent();
3375 for (int i = 0; i < size; i++) {
3376 fout.print("UID=");
3377 fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
3378 fout.print(": ");
3379 fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
3380 fout.println();
3381 }
3382 fout.decreaseIndent();
3383 }
3384
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003385 size = mAppIdleTempWhitelistAppIds.size();
3386 if (size > 0) {
3387 fout.println("App idle whitelist app ids:");
3388 fout.increaseIndent();
3389 for (int i = 0; i < size; i++) {
3390 fout.print("UID=");
3391 fout.print(mAppIdleTempWhitelistAppIds.keyAt(i));
3392 fout.print(": ");
3393 fout.print(mAppIdleTempWhitelistAppIds.valueAt(i));
3394 fout.println();
3395 }
3396 fout.decreaseIndent();
3397 }
3398
Felipe Lemef0823852016-06-08 13:43:08 -07003399 size = mDefaultRestrictBackgroundWhitelistUids.size();
3400 if (size > 0) {
3401 fout.println("Default restrict background whitelist uids:");
3402 fout.increaseIndent();
3403 for (int i = 0; i < size; i++) {
3404 fout.print("UID=");
3405 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
3406 fout.println();
3407 }
3408 fout.decreaseIndent();
3409 }
3410
3411 size = mRestrictBackgroundWhitelistRevokedUids.size();
3412 if (size > 0) {
3413 fout.println("Default restrict background whitelist uids revoked by users:");
3414 fout.increaseIndent();
3415 for (int i = 0; i < size; i++) {
3416 fout.print("UID=");
3417 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
3418 fout.println();
3419 }
3420 fout.decreaseIndent();
3421 }
3422
3423 final SparseBooleanArray knownUids = new SparseBooleanArray();
3424 collectKeys(mUidState, knownUids);
3425 collectKeys(mUidRules, knownUids);
3426
3427 fout.println("Status for all known UIDs:");
3428 fout.increaseIndent();
3429 size = knownUids.size();
3430 for (int i = 0; i < size; i++) {
3431 final int uid = knownUids.keyAt(i);
3432 fout.print("UID=");
3433 fout.print(uid);
3434
3435 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3436 fout.print(" state=");
3437 fout.print(state);
3438 if (state <= ActivityManager.PROCESS_STATE_TOP) {
3439 fout.print(" (fg)");
3440 } else {
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -08003441 fout.print(state <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Felipe Lemef0823852016-06-08 13:43:08 -07003442 ? " (fg svc)" : " (bg)");
3443 }
3444
3445 final int uidRules = mUidRules.get(uid, RULE_NONE);
3446 fout.print(" rules=");
3447 fout.print(uidRulesToString(uidRules));
3448 fout.println();
3449 }
3450 fout.decreaseIndent();
3451
3452 fout.println("Status for just UIDs with rules:");
3453 fout.increaseIndent();
3454 size = mUidRules.size();
3455 for (int i = 0; i < size; i++) {
3456 final int uid = mUidRules.keyAt(i);
3457 fout.print("UID=");
3458 fout.print(uid);
3459 final int uidRules = mUidRules.get(uid, RULE_NONE);
3460 fout.print(" rules=");
3461 fout.print(uidRulesToString(uidRules));
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003462 fout.println();
3463 }
3464 fout.decreaseIndent();
Sudheer Shankae7361852017-03-07 11:51:46 -08003465
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003466 fout.println("Admin restricted uids for metered data:");
3467 fout.increaseIndent();
3468 size = mMeteredRestrictedUids.size();
3469 for (int i = 0; i < size; ++i) {
3470 fout.print("u" + mMeteredRestrictedUids.keyAt(i) + ": ");
3471 fout.println(mMeteredRestrictedUids.valueAt(i));
3472 }
3473 fout.decreaseIndent();
3474
Makoto Onuki49392d32018-04-11 13:51:02 -07003475 fout.println();
3476 mStatLogger.dump(fout);
3477
Sudheer Shanka352dc572017-09-22 17:09:38 -07003478 mLogger.dumpLogs(fout);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003479 }
Jeff Sharkey1b861272011-05-22 00:34:52 -07003480 }
3481 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003482
3483 @Override
Felipe Leme50a235e2016-01-15 18:37:06 -08003484 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
Dianne Hackborn354736e2016-08-22 17:00:05 -07003485 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
Felipe Lemeb1a65ee2016-02-08 10:12:01 -08003486 (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
Dianne Hackborn354736e2016-08-22 17:00:05 -07003487 this, in, out, err, args, callback, resultReceiver);
Felipe Leme50a235e2016-01-15 18:37:06 -08003488 }
3489
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003490 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08003491 boolean isUidForeground(int uid) {
Felipe Lemef0823852016-06-08 13:43:08 -07003492 synchronized (mUidRulesFirstLock) {
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003493 return isUidStateForeground(
3494 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003495 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07003496 }
3497
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003498 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003499 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003500 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003501 return isProcStateAllowedWhileOnRestrictBackground(procState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003502 }
3503
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003504 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003505 private boolean isUidForegroundOnRestrictPowerUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07003506 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3507 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
3508 }
3509
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003510 private boolean isUidStateForeground(int state) {
Dianne Hackborn497175b2014-07-01 12:56:08 -07003511 // only really in foreground when screen is also on
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003512 return state <= NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
Dianne Hackborn497175b2014-07-01 12:56:08 -07003513 }
3514
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003515 /**
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003516 * Process state of UID changed; if needed, will trigger
Felipe Lemef0823852016-06-08 13:43:08 -07003517 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
3518 * {@link #updateRulesForPowerRestrictionsUL(int)}
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003519 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003520 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankac9d94072017-02-22 22:13:55 +00003521 private void updateUidStateUL(int uid, int uidState) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003522 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
3523 try {
3524 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3525 if (oldUidState != uidState) {
3526 // state changed, push updated rules
3527 mUidState.put(uid, uidState);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003528 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
3529 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
3530 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
Sudheer Shanka9e77d232017-08-14 14:43:11 -07003531 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003532 if (mDeviceIdleMode) {
3533 updateRuleForDeviceIdleUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003534 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003535 if (mRestrictPower) {
3536 updateRuleForRestrictPowerUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003537 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003538 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003539 }
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003540 updateNetworkStats(uid, isUidStateForeground(uidState));
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003541 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003542 } finally {
3543 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003544 }
3545 }
3546
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003547 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003548 private void removeUidStateUL(int uid) {
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003549 final int index = mUidState.indexOfKey(uid);
3550 if (index >= 0) {
3551 final int oldUidState = mUidState.valueAt(index);
3552 mUidState.removeAt(index);
3553 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
Felipe Lemef0823852016-06-08 13:43:08 -07003554 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
Sudheer Shankac9d94072017-02-22 22:13:55 +00003555 ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003556 if (mDeviceIdleMode) {
Felipe Lemef0823852016-06-08 13:43:08 -07003557 updateRuleForDeviceIdleUL(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003558 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003559 if (mRestrictPower) {
Felipe Lemef0823852016-06-08 13:43:08 -07003560 updateRuleForRestrictPowerUL(uid);
Felipe Leme011b98f2016-02-10 17:28:31 -08003561 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003562 updateRulesForPowerRestrictionsUL(uid);
Felipe Lemef28983d2016-03-25 12:18:23 -07003563 updateNetworkStats(uid, false);
Dianne Hackborn497175b2014-07-01 12:56:08 -07003564 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003565 }
3566 }
3567
Felipe Lemef28983d2016-03-25 12:18:23 -07003568 // adjust stats accounting based on foreground status
3569 private void updateNetworkStats(int uid, boolean uidForeground) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003570 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3571 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3572 "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B"));
3573 }
Felipe Lemef28983d2016-03-25 12:18:23 -07003574 try {
3575 mNetworkStats.setUidForeground(uid, uidForeground);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003576 } finally {
3577 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Lemef28983d2016-03-25 12:18:23 -07003578 }
3579 }
3580
Sudheer Shankac9d94072017-02-22 22:13:55 +00003581 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
3582 int newUidState) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003583 final boolean oldForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003584 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003585 final boolean newForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003586 isProcStateAllowedWhileOnRestrictBackground(newUidState);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003587 if (oldForeground != newForeground) {
Sudheer Shankac9d94072017-02-22 22:13:55 +00003588 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003589 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003590 }
3591
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003592 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003593 void updateRulesForPowerSaveUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003594 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
3595 try {
3596 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
3597 mUidFirewallPowerSaveRules);
3598 } finally {
3599 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3600 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003601 }
3602
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003603 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003604 void updateRuleForRestrictPowerUL(int uid) {
3605 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003606 }
3607
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003608 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003609 void updateRulesForDeviceIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003610 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
3611 try {
3612 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
3613 mUidFirewallDozableRules);
3614 } finally {
3615 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3616 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003617 }
3618
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003619 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003620 void updateRuleForDeviceIdleUL(int uid) {
3621 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003622 }
3623
Felipe Lemef28983d2016-03-25 12:18:23 -07003624 // NOTE: since both fw_dozable and fw_powersave uses the same map
3625 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003626 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003627 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
Felipe Leme011b98f2016-02-10 17:28:31 -08003628 SparseIntArray rules) {
3629 if (enabled) {
3630 // Sync the whitelists before enabling the chain. We don't care about the rules if
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003631 // we are disabling the chain.
Felipe Leme011b98f2016-02-10 17:28:31 -08003632 final SparseIntArray uidRules = rules;
Jeff Sharkeydc988062015-09-14 10:09:47 -07003633 uidRules.clear();
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003634 final List<UserInfo> users = mUserManager.getUsers();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003635 for (int ui = users.size() - 1; ui >= 0; ui--) {
3636 UserInfo user = users.get(ui);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003637 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
3638 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
3639 if (chain == FIREWALL_CHAIN_POWERSAVE) {
3640 updateRulesForWhitelistedAppIds(uidRules,
3641 mPowerSaveWhitelistExceptIdleAppIds, user.id);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003642 }
3643 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003644 for (int i = mUidState.size() - 1; i >= 0; i--) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003645 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003646 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
3647 }
3648 }
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003649 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);
Felipe Lemebc853dd2016-09-08 13:26:55 -07003650 } else {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003651 setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003652 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07003653 }
3654
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003655 private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
3656 final SparseBooleanArray whitelistedAppIds, int userId) {
3657 for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
3658 if (whitelistedAppIds.valueAt(i)) {
3659 final int appId = whitelistedAppIds.keyAt(i);
3660 final int uid = UserHandle.getUid(userId, appId);
3661 uidRules.put(uid, FIREWALL_RULE_ALLOW);
3662 }
3663 }
3664 }
3665
3666 /**
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003667 * Returns whether a uid is whitelisted from power saving restrictions (eg: Battery Saver, Doze
3668 * mode, and app idle).
3669 *
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003670 * @param deviceIdleMode if true then we don't consider
3671 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
3672 * whitelisted.
3673 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003674 @GuardedBy("mUidRulesFirstLock")
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003675 private boolean isWhitelistedFromPowerSaveUL(int uid, boolean deviceIdleMode) {
Felipe Leme46c4fc32016-05-04 09:21:43 -07003676 final int appId = UserHandle.getAppId(uid);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003677 boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
3678 || mPowerSaveWhitelistAppIds.get(appId);
3679 if (!deviceIdleMode) {
3680 isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
3681 }
3682 return isWhitelisted;
Felipe Leme46c4fc32016-05-04 09:21:43 -07003683 }
3684
Felipe Lemef28983d2016-03-25 12:18:23 -07003685 // NOTE: since both fw_dozable and fw_powersave uses the same map
3686 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003687 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003688 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003689 if (enabled) {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003690 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid,
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003691 chain == FIREWALL_CHAIN_DOZABLE);
3692 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003693 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003694 } else {
Felipe Leme011b98f2016-02-10 17:28:31 -08003695 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003696 }
3697 }
3698 }
3699
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003700 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003701 void updateRulesForAppIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003702 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
3703 try {
3704 final SparseIntArray uidRules = mUidFirewallStandbyRules;
3705 uidRules.clear();
Jeff Sharkeydc988062015-09-14 10:09:47 -07003706
Felipe Leme873a83a2016-09-07 11:34:10 -07003707 // Fully update the app idle firewall chain.
3708 final List<UserInfo> users = mUserManager.getUsers();
3709 for (int ui = users.size() - 1; ui >= 0; ui--) {
3710 UserInfo user = users.get(ui);
3711 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
3712 for (int uid : idleUids) {
3713 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
3714 // quick check: if this uid doesn't have INTERNET permission, it
3715 // doesn't have network access anyway, so it is a waste to mess
3716 // with it here.
3717 if (hasInternetPermissions(uid)) {
3718 uidRules.put(uid, FIREWALL_RULE_DENY);
3719 }
Soi, Yoshinaria065da12015-12-22 12:02:18 +09003720 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003721 }
3722 }
Jeff Sharkeydc988062015-09-14 10:09:47 -07003723
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003724 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
Felipe Leme873a83a2016-09-07 11:34:10 -07003725 } finally {
3726 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3727 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003728 }
3729
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003730 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003731 void updateRuleForAppIdleUL(int uid) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003732 if (!isUidValidForBlacklistRules(uid)) return;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003733
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003734 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3735 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
3736 }
3737 try {
3738 int appId = UserHandle.getAppId(uid);
3739 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
3740 && !isUidForegroundOnRestrictPowerUL(uid)) {
3741 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003742 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL DENY " + uid);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003743 } else {
3744 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003745 if (LOGD) Log.d(TAG, "updateRuleForAppIdleUL " + uid + " to DEFAULT");
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003746 }
3747 } finally {
3748 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003749 }
3750 }
3751
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003752 /**
3753 * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
3754 * changed.
3755 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003756 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003757 void updateRulesForAppIdleParoleUL() {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003758 boolean paroled = mUsageStats.isAppIdleParoleOn();
3759 boolean enableChain = !paroled;
Felipe Lemef0823852016-06-08 13:43:08 -07003760 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003761
3762 int ruleCount = mUidFirewallStandbyRules.size();
3763 for (int i = 0; i < ruleCount; i++) {
3764 int uid = mUidFirewallStandbyRules.keyAt(i);
3765 int oldRules = mUidRules.get(uid);
3766 if (enableChain) {
3767 // Chain wasn't enabled before and the other power-related
3768 // chains are whitelists, so we can clear the
3769 // MASK_ALL_NETWORKS part of the rules and re-inform listeners if
3770 // the effective rules result in blocking network access.
3771 oldRules &= MASK_METERED_NETWORKS;
3772 } else {
3773 // Skip if it had no restrictions to begin with
3774 if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
3775 }
Sudheer Shanka3af02942017-04-12 14:29:14 -07003776 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
3777 if (newUidRules == RULE_NONE) {
3778 mUidRules.delete(uid);
3779 } else {
3780 mUidRules.put(uid, newUidRules);
3781 }
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003782 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003783 }
3784
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003785 /**
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003786 * Update rules that might be changed by {@link #mRestrictBackground},
3787 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003788 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003789 @GuardedBy({"mUidRulesFirstLock", "mNetworkPoliciesSecondLock"})
Felipe Lemef0823852016-06-08 13:43:08 -07003790 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003791 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3792 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3793 "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
3794 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003795 try {
Felipe Leme09700462016-09-08 09:33:48 -07003796 updateRulesForAppIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003797 updateRulesForRestrictPowerUL();
3798 updateRulesForRestrictBackgroundUL();
Felipe Leme03e689d2016-03-02 16:17:38 -08003799
Felipe Leme873a83a2016-09-07 11:34:10 -07003800 // If the set of restricted networks may have changed, re-evaluate those.
3801 if (restrictedNetworksChanged) {
3802 normalizePoliciesNL();
3803 updateNetworkRulesNL();
3804 }
3805 } finally {
3806 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Leme76010a32016-03-17 13:03:11 -07003807 }
3808 }
3809
Felipe Leme09700462016-09-08 09:33:48 -07003810 // TODO: rename / document to make it clear these are global (not app-specific) rules
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003811 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003812 private void updateRulesForRestrictPowerUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003813 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
3814 try {
3815 updateRulesForDeviceIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003816 updateRulesForPowerSaveUL();
3817 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
3818 } finally {
3819 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3820 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003821 }
3822
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003823 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003824 private void updateRulesForRestrictBackgroundUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003825 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
3826 try {
3827 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
3828 } finally {
3829 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3830 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003831 }
3832
3833 private static final int TYPE_RESTRICT_BACKGROUND = 1;
3834 private static final int TYPE_RESTRICT_POWER = 2;
3835 @Retention(RetentionPolicy.SOURCE)
3836 @IntDef(flag = false, value = {
3837 TYPE_RESTRICT_BACKGROUND,
3838 TYPE_RESTRICT_POWER,
3839 })
3840 public @interface RestrictType {
3841 }
3842
3843 // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003844 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07003845 private void updateRulesForAllAppsUL(@RestrictType int type) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003846 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3847 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
3848 }
3849 try {
Felipe Leme873a83a2016-09-07 11:34:10 -07003850 // update rules for all installed applications
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003851
3852 final PackageManager pm = mContext.getPackageManager();
3853 final List<UserInfo> users;
3854 final List<ApplicationInfo> apps;
3855
3856 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
3857 try {
3858 users = mUserManager.getUsers();
3859 } finally {
3860 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3861 }
3862 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids");
3863 try {
3864 apps = pm.getInstalledApplications(
3865 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS
3866 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3867 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
3868 } finally {
3869 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3870 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003871
Felipe Leme873a83a2016-09-07 11:34:10 -07003872 final int usersSize = users.size();
3873 final int appsSize = apps.size();
3874 for (int i = 0; i < usersSize; i++) {
3875 final UserInfo user = users.get(i);
3876 for (int j = 0; j < appsSize; j++) {
3877 final ApplicationInfo app = apps.get(j);
3878 final int uid = UserHandle.getUid(user.id, app.uid);
3879 switch (type) {
3880 case TYPE_RESTRICT_BACKGROUND:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003881 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003882 break;
3883 case TYPE_RESTRICT_POWER:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003884 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003885 break;
3886 default:
3887 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
3888 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003889 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003890 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003891 } finally {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003892 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003893 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003894 }
3895
Andreas Gampeaae5aa32018-07-20 12:55:38 -07003896 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003897 private void updateRulesForTempWhitelistChangeUL(int appId) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003898 final List<UserInfo> users = mUserManager.getUsers();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003899 final int numUsers = users.size();
3900 for (int i = 0; i < numUsers; i++) {
Felipe Leme03e689d2016-03-02 16:17:38 -08003901 final UserInfo user = users.get(i);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003902 int uid = UserHandle.getUid(user.id, appId);
3903 // Update external firewall rules.
3904 updateRuleForAppIdleUL(uid);
3905 updateRuleForDeviceIdleUL(uid);
3906 updateRuleForRestrictPowerUL(uid);
3907 // Update internal rules.
3908 updateRulesForPowerRestrictionsUL(uid);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003909 }
3910 }
3911
Felipe Leme70c57c22016-03-29 10:45:13 -07003912 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
3913 // methods below could be merged into a isUidValidForRules() method.
3914 private boolean isUidValidForBlacklistRules(int uid) {
3915 // allow rules on specific system services, and any apps
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003916 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
Felipe Leme70c57c22016-03-29 10:45:13 -07003917 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003918 return true;
3919 }
3920
3921 return false;
3922 }
3923
Felipe Leme70c57c22016-03-29 10:45:13 -07003924 private boolean isUidValidForWhitelistRules(int uid) {
3925 return UserHandle.isApp(uid) && hasInternetPermissions(uid);
3926 }
3927
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003928 /**
3929 * Set whether or not an app should be whitelisted for network access while in app idle. Other
3930 * power saving restrictions may still apply.
3931 */
3932 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08003933 void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
Sudheer Shankadb02ccd2018-11-29 11:27:21 -08003934 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3935
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003936 synchronized (mUidRulesFirstLock) {
3937 if (mAppIdleTempWhitelistAppIds.get(uid) == shouldWhitelist) {
3938 // No change.
3939 return;
3940 }
3941
3942 final long token = Binder.clearCallingIdentity();
3943 try {
3944 mLogger.appIdleWlChanged(uid, shouldWhitelist);
3945 if (shouldWhitelist) {
3946 mAppIdleTempWhitelistAppIds.put(uid, true);
3947 } else {
3948 mAppIdleTempWhitelistAppIds.delete(uid);
3949 }
3950 updateRuleForAppIdleUL(uid);
3951 updateRulesForPowerRestrictionsUL(uid);
3952 } finally {
3953 Binder.restoreCallingIdentity(token);
3954 }
3955 }
3956 }
3957
3958 /** Return the list of UIDs currently in the app idle whitelist. */
3959 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08003960 int[] getAppIdleWhitelist() {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003961 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
3962
3963 synchronized (mUidRulesFirstLock) {
3964 final int len = mAppIdleTempWhitelistAppIds.size();
3965 int[] uids = new int[len];
3966 for (int i = 0; i < len; ++i) {
3967 uids[i] = mAppIdleTempWhitelistAppIds.keyAt(i);
3968 }
3969 return uids;
3970 }
3971 }
3972
3973 /** Returns if the UID is currently considered idle. */
3974 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08003975 boolean isUidIdle(int uid) {
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08003976 synchronized (mUidRulesFirstLock) {
3977 if (mAppIdleTempWhitelistAppIds.get(uid)) {
3978 // UID is temporarily whitelisted.
3979 return false;
3980 }
3981 }
3982
Amith Yamasani15e472352015-04-24 19:06:07 -07003983 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
3984 final int userId = UserHandle.getUserId(uid);
3985
songjinshi0655edd2016-05-18 19:55:32 +08003986 if (packages != null) {
Jeff Sharkey377ded0f2016-01-10 13:15:41 -07003987 for (String packageName : packages) {
3988 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
3989 return false;
3990 }
Amith Yamasani15e472352015-04-24 19:06:07 -07003991 }
3992 }
3993 return true;
3994 }
3995
3996 /**
Felipe Leme47585ba2016-02-09 16:56:32 -08003997 * Checks if an uid has INTERNET permissions.
3998 * <p>
3999 * Useful for the cases where the lack of network access can simplify the rules.
Amith Yamasani15e472352015-04-24 19:06:07 -07004000 */
Felipe Leme47585ba2016-02-09 16:56:32 -08004001 private boolean hasInternetPermissions(int uid) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004002 try {
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -08004003 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004004 != PackageManager.PERMISSION_GRANTED) {
Felipe Leme47585ba2016-02-09 16:56:32 -08004005 return false;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004006 }
4007 } catch (RemoteException e) {
4008 }
Felipe Leme47585ba2016-02-09 16:56:32 -08004009 return true;
4010 }
4011
4012 /**
Felipe Leme03e95e22016-09-09 09:25:31 -07004013 * Clears all state - internal and external - associated with an UID.
4014 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004015 @GuardedBy("mUidRulesFirstLock")
Felipe Leme03e95e22016-09-09 09:25:31 -07004016 private void onUidDeletedUL(int uid) {
4017 // First cleanup in-memory state synchronously...
4018 mUidRules.delete(uid);
4019 mUidPolicy.delete(uid);
4020 mUidFirewallStandbyRules.delete(uid);
4021 mUidFirewallDozableRules.delete(uid);
4022 mUidFirewallPowerSaveRules.delete(uid);
4023 mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
4024 mPowerSaveWhitelistAppIds.delete(uid);
4025 mPowerSaveTempWhitelistAppIds.delete(uid);
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004026 mAppIdleTempWhitelistAppIds.delete(uid);
Felipe Leme03e95e22016-09-09 09:25:31 -07004027
4028 // ...then update iptables asynchronously.
4029 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
4030 }
4031
4032 /**
Felipe Lemef28983d2016-03-25 12:18:23 -07004033 * Applies network rules to bandwidth and firewall controllers based on uid policy.
Felipe Leme76010a32016-03-17 13:03:11 -07004034 *
Felipe Leme781ba142016-05-09 16:24:48 -07004035 * <p>There are currently 4 types of restriction rules:
Felipe Lemef28983d2016-03-25 12:18:23 -07004036 * <ul>
Felipe Leme781ba142016-05-09 16:24:48 -07004037 * <li>Doze mode
4038 * <li>App idle mode
Felipe Lemef28983d2016-03-25 12:18:23 -07004039 * <li>Battery Saver Mode (also referred as power save).
Felipe Leme46c4fc32016-05-04 09:21:43 -07004040 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
Felipe Lemef28983d2016-03-25 12:18:23 -07004041 * </ul>
Felipe Leme781ba142016-05-09 16:24:48 -07004042 *
4043 * <p>This method changes both the external firewall rules and the internal state.
Felipe Leme47585ba2016-02-09 16:56:32 -08004044 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004045 @GuardedBy("mUidRulesFirstLock")
Felipe Leme03e95e22016-09-09 09:25:31 -07004046 private void updateRestrictionRulesForUidUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07004047 // Methods below only changes the firewall rules for the power-related modes.
Felipe Lemef0823852016-06-08 13:43:08 -07004048 updateRuleForDeviceIdleUL(uid);
4049 updateRuleForAppIdleUL(uid);
4050 updateRuleForRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004051
4052 // Update internal state for power-related modes.
Sudheer Shankac9d94072017-02-22 22:13:55 +00004053 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004054
4055 // Update firewall and internal rules for Data Saver Mode.
Sudheer Shankac9d94072017-02-22 22:13:55 +00004056 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Lemef28983d2016-03-25 12:18:23 -07004057 }
4058
Felipe Leme70c57c22016-03-29 10:45:13 -07004059 /**
4060 * Applies network rules to bandwidth controllers based on process state and user-defined
4061 * restrictions (blacklist / whitelist).
4062 *
4063 * <p>
4064 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
4065 * networks:
4066 * <ul>
4067 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
4068 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
4069 * also blacklisted.
4070 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004071 * no UIDs other than those whitelisted will have access.
Felipe Leme70c57c22016-03-29 10:45:13 -07004072 * <ul>
4073 *
4074 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
4075 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
4076 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
4077 * respectively): these methods set the proper internal state (blacklist / whitelist), then call
Felipe Lemef0823852016-06-08 13:43:08 -07004078 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
Felipe Leme70c57c22016-03-29 10:45:13 -07004079 * {@link INetworkManagementService}, but this method should also be called in events (like
4080 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
4081 * following rules should also be applied:
4082 *
4083 * <ul>
4084 * <li>When Data Saver mode is on, the foreground app should be temporarily added to
4085 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
4086 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
4087 * {@code bw_penalty_box}.
4088 * <li>When the app leaves foreground state, the temporary changes above should be reverted.
4089 * </ul>
4090 *
4091 * <p>For optimization, the rules are only applied on user apps that have internet access
4092 * permission, since there is no need to change the {@code iptables} rule if the app does not
4093 * have permission to use the internet.
4094 *
4095 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
Felipe Lemed31a97f2016-05-06 14:53:50 -07004096 *
Felipe Leme70c57c22016-03-29 10:45:13 -07004097 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00004098 private void updateRulesForDataUsageRestrictionsUL(int uid) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004099 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4100 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4101 "updateRulesForDataUsageRestrictionsUL: " + uid);
4102 }
4103 try {
4104 updateRulesForDataUsageRestrictionsULInner(uid);
4105 } finally {
4106 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4107 }
4108 }
4109
4110 private void updateRulesForDataUsageRestrictionsULInner(int uid) {
Felipe Leme03e95e22016-09-09 09:25:31 -07004111 if (!isUidValidForWhitelistRules(uid)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004112 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004113 return;
Felipe Leme70c57c22016-03-29 10:45:13 -07004114 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004115
Dianne Hackborn497175b2014-07-01 12:56:08 -07004116 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
Felipe Leme46c4fc32016-05-04 09:21:43 -07004117 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
Felipe Lemef0823852016-06-08 13:43:08 -07004118 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004119 final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004120
Felipe Leme781ba142016-05-09 16:24:48 -07004121 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
Felipe Leme46b451f2016-08-19 08:46:17 -07004122 final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
Felipe Leme781ba142016-05-09 16:24:48 -07004123 final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
4124 int newRule = RULE_NONE;
Felipe Leme76010a32016-03-17 13:03:11 -07004125
Felipe Leme70c57c22016-03-29 10:45:13 -07004126 // First step: define the new rule based on user restrictions and foreground state.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004127 if (isRestrictedByAdmin) {
4128 newRule = RULE_REJECT_METERED;
4129 } else if (isForeground) {
Felipe Leme781ba142016-05-09 16:24:48 -07004130 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
4131 newRule = RULE_TEMPORARY_ALLOW_METERED;
4132 } else if (isWhitelisted) {
4133 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004134 }
4135 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07004136 if (isBlacklisted) {
4137 newRule = RULE_REJECT_METERED;
4138 } else if (mRestrictBackground && isWhitelisted) {
4139 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004140 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004141 }
Felipe Leme781ba142016-05-09 16:24:48 -07004142 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
Felipe Leme46c4fc32016-05-04 09:21:43 -07004143
Felipe Lemef28983d2016-03-25 12:18:23 -07004144 if (LOGV) {
Felipe Lemef0823852016-06-08 13:43:08 -07004145 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07004146 + ": isForeground=" +isForeground
4147 + ", isBlacklisted=" + isBlacklisted
4148 + ", isWhitelisted=" + isWhitelisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004149 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Leme781ba142016-05-09 16:24:48 -07004150 + ", oldRule=" + uidRulesToString(oldRule)
4151 + ", newRule=" + uidRulesToString(newRule)
4152 + ", newUidRules=" + uidRulesToString(newUidRules)
4153 + ", oldUidRules=" + uidRulesToString(oldUidRules));
Felipe Lemef28983d2016-03-25 12:18:23 -07004154 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07004155
Felipe Leme46c4fc32016-05-04 09:21:43 -07004156 if (newUidRules == RULE_NONE) {
Jeff Sharkey350083e2011-06-29 10:45:16 -07004157 mUidRules.delete(uid);
4158 } else {
Felipe Leme46c4fc32016-05-04 09:21:43 -07004159 mUidRules.put(uid, newUidRules);
Jeff Sharkey350083e2011-06-29 10:45:16 -07004160 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07004161
Felipe Leme70c57c22016-03-29 10:45:13 -07004162 // Second step: apply bw changes based on change of state.
Felipe Leme781ba142016-05-09 16:24:48 -07004163 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09004164 if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004165 // Temporarily whitelist foreground app, removing from blacklist if necessary
4166 // (since bw_penalty_box prevails over bw_happy_box).
4167
4168 setMeteredNetworkWhitelist(uid, true);
4169 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
4170 // but ideally it should be just:
4171 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07004172 if (isBlacklisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004173 setMeteredNetworkBlacklist(uid, false);
4174 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004175 } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004176 // Remove temporary whitelist from app that is not on foreground anymore.
4177
4178 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
4179 // but ideally they should be just:
4180 // setMeteredNetworkWhitelist(uid, isWhitelisted);
4181 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07004182 if (!isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004183 setMeteredNetworkWhitelist(uid, false);
4184 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004185 if (isBlacklisted || isRestrictedByAdmin) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004186 setMeteredNetworkBlacklist(uid, true);
4187 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004188 } else if (hasRule(newRule, RULE_REJECT_METERED)
4189 || hasRule(oldRule, RULE_REJECT_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004190 // Flip state because app was explicitly added or removed to blacklist.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004191 setMeteredNetworkBlacklist(uid, (isBlacklisted || isRestrictedByAdmin));
Hugo Benichi2966c182017-03-28 17:17:13 +09004192 if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004193 // Since blacklist prevails over whitelist, we need to handle the special case
4194 // where app is whitelisted and blacklisted at the same time (although such
4195 // scenario should be blocked by the UI), then blacklist is removed.
Felipe Leme781ba142016-05-09 16:24:48 -07004196 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07004197 }
Hugo Benichi2966c182017-03-28 17:17:13 +09004198 } else if (hasRule(newRule, RULE_ALLOW_METERED)
4199 || hasRule(oldRule, RULE_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004200 // Flip state because app was explicitly added or removed to whitelist.
Felipe Leme781ba142016-05-09 16:24:48 -07004201 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07004202 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07004203 // All scenarios should have been covered above.
Felipe Leme46c4fc32016-05-04 09:21:43 -07004204 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
4205 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07004206 + ", whitelisted=" + isWhitelisted
4207 + ", blacklisted=" + isBlacklisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004208 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Lemed31a97f2016-05-06 14:53:50 -07004209 + ", newRule=" + uidRulesToString(newUidRules)
4210 + ", oldRule=" + uidRulesToString(oldUidRules));
Felipe Leme70c57c22016-03-29 10:45:13 -07004211 }
Felipe Leme781ba142016-05-09 16:24:48 -07004212
Sudheer Shankac9d94072017-02-22 22:13:55 +00004213 // Dispatch changed rule to existing listeners.
4214 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Felipe Leme781ba142016-05-09 16:24:48 -07004215 }
4216 }
4217
4218 /**
4219 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
4220 * listeners in case of change.
4221 * <p>
4222 * There are 3 power-related rules that affects whether an app has background access on
4223 * non-metered networks, and when the condition applies and the UID is not whitelisted for power
4224 * restriction, it's added to the equivalent firewall chain:
4225 * <ul>
4226 * <li>App is idle: {@code fw_standby} firewall chain.
4227 * <li>Device is idle: {@code fw_dozable} firewall chain.
4228 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
4229 * </ul>
4230 * <p>
4231 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
4232 * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
4233 * <p>
4234 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
4235 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004236 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankac9d94072017-02-22 22:13:55 +00004237 private void updateRulesForPowerRestrictionsUL(int uid) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004238 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
4239
Sudheer Shankac9d94072017-02-22 22:13:55 +00004240 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004241
Sudheer Shankac9d94072017-02-22 22:13:55 +00004242 if (newUidRules == RULE_NONE) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004243 mUidRules.delete(uid);
4244 } else {
Sudheer Shankac9d94072017-02-22 22:13:55 +00004245 mUidRules.put(uid, newUidRules);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004246 }
4247 }
4248
4249 /**
4250 * Similar to above but ignores idle state if app standby is currently disabled by parole.
4251 *
4252 * @param uid the uid of the app to update rules for
4253 * @param oldUidRules the current rules for the uid, in order to determine if there's a change
4254 * @param paroled whether to ignore idle state of apps and only look at other restrictions.
4255 *
Sudheer Shankac9d94072017-02-22 22:13:55 +00004256 * @return the new computed rules for the uid
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004257 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00004258 private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004259 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4260 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4261 "updateRulesForPowerRestrictionsUL: " + uid + "/" + oldUidRules + "/"
4262 + (paroled ? "P" : "-"));
4263 }
4264 try {
4265 return updateRulesForPowerRestrictionsULInner(uid, oldUidRules, paroled);
4266 } finally {
4267 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4268 }
4269 }
4270
4271 private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled) {
Felipe Leme781ba142016-05-09 16:24:48 -07004272 if (!isUidValidForBlacklistRules(uid)) {
4273 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004274 return RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -07004275 }
Felipe Lemef28983d2016-03-25 12:18:23 -07004276
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004277 final boolean isIdle = !paroled && isUidIdle(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004278 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
Felipe Lemef0823852016-06-08 13:43:08 -07004279 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004280
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08004281 final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode);
Felipe Leme781ba142016-05-09 16:24:48 -07004282 final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
4283 int newRule = RULE_NONE;
4284
4285 // First step: define the new rule based on user restrictions and foreground state.
4286
4287 // NOTE: if statements below could be inlined, but it's easier to understand the logic
4288 // by considering the foreground and non-foreground states.
4289 if (isForeground) {
4290 if (restrictMode) {
4291 newRule = RULE_ALLOW_ALL;
4292 }
4293 } else if (restrictMode) {
4294 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
4295 }
4296
4297 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
4298
4299 if (LOGV) {
Felipe Leme88f40ad2016-08-10 13:00:32 -07004300 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07004301 + ", isIdle: " + isIdle
4302 + ", mRestrictPower: " + mRestrictPower
4303 + ", mDeviceIdleMode: " + mDeviceIdleMode
4304 + ", isForeground=" + isForeground
4305 + ", isWhitelisted=" + isWhitelisted
4306 + ", oldRule=" + uidRulesToString(oldRule)
4307 + ", newRule=" + uidRulesToString(newRule)
4308 + ", newUidRules=" + uidRulesToString(newUidRules)
4309 + ", oldUidRules=" + uidRulesToString(oldUidRules));
4310 }
4311
Felipe Leme781ba142016-05-09 16:24:48 -07004312 // Second step: notify listeners if state changed.
4313 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09004314 if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004315 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
Hugo Benichi2966c182017-03-28 17:17:13 +09004316 } else if (hasRule(newRule, RULE_REJECT_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004317 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
4318 } else {
4319 // All scenarios should have been covered above
4320 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
4321 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07004322 + ", whitelisted=" + isWhitelisted
Felipe Lemed31a97f2016-05-06 14:53:50 -07004323 + ", newRule=" + uidRulesToString(newUidRules)
4324 + ", oldRule=" + uidRulesToString(oldUidRules));
4325 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004326 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Amith Yamasani15e472352015-04-24 19:06:07 -07004327 }
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004328
Sudheer Shankac9d94072017-02-22 22:13:55 +00004329 return newUidRules;
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004330 }
4331
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004332 private class AppIdleStateChangeListener
4333 extends UsageStatsManagerInternal.AppIdleStateChangeListener {
4334
4335 @Override
Amith Yamasani119be9a2018-02-18 22:23:00 -08004336 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
4337 int reason) {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004338 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07004339 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
4340 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
Felipe Lemef0823852016-06-08 13:43:08 -07004341 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004342 mLogger.appIdleStateChanged(uid, idle);
Felipe Lemef0823852016-06-08 13:43:08 -07004343 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004344 updateRulesForPowerRestrictionsUL(uid);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004345 }
4346 } catch (NameNotFoundException nnfe) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004347 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004348 }
4349
4350 @Override
4351 public void onParoleStateChanged(boolean isParoleOn) {
Felipe Lemef0823852016-06-08 13:43:08 -07004352 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004353 mLogger.paroleStateChanged(isParoleOn);
Felipe Lemef0823852016-06-08 13:43:08 -07004354 updateRulesForAppIdleParoleUL();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004355 }
Amith Yamasani15e472352015-04-24 19:06:07 -07004356 }
4357 }
4358
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004359 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
4360 if (listener != null) {
4361 try {
4362 listener.onUidRulesChanged(uid, uidRules);
4363 } catch (RemoteException ignored) {
4364 }
4365 }
4366 }
4367
4368 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
4369 String[] meteredIfaces) {
4370 if (listener != null) {
4371 try {
4372 listener.onMeteredIfacesChanged(meteredIfaces);
4373 } catch (RemoteException ignored) {
4374 }
4375 }
4376 }
4377
4378 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
4379 boolean restrictBackground) {
4380 if (listener != null) {
4381 try {
4382 listener.onRestrictBackgroundChanged(restrictBackground);
4383 } catch (RemoteException ignored) {
4384 }
4385 }
4386 }
4387
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004388 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
4389 int uidPolicies) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004390 if (listener != null) {
4391 try {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004392 listener.onUidPoliciesChanged(uid, uidPolicies);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004393 } catch (RemoteException ignored) {
4394 }
4395 }
4396 }
4397
Jeff Sharkey9252b342018-01-19 07:58:35 +09004398 private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
4399 int overrideMask, int overrideValue) {
4400 if (listener != null) {
4401 try {
4402 listener.onSubscriptionOverride(subId, overrideMask, overrideValue);
4403 } catch (RemoteException ignored) {
4404 }
4405 }
4406 }
4407
Makoto Onuki8e777332017-03-28 11:25:47 -07004408 private final Handler.Callback mHandlerCallback = new Handler.Callback() {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07004409 @Override
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004410 public boolean handleMessage(Message msg) {
4411 switch (msg.what) {
4412 case MSG_RULES_CHANGED: {
4413 final int uid = msg.arg1;
4414 final int uidRules = msg.arg2;
Sudheer Shankac9d94072017-02-22 22:13:55 +00004415 final int length = mListeners.beginBroadcast();
4416 for (int i = 0; i < length; i++) {
4417 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4418 dispatchUidRulesChanged(listener, uid, uidRules);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004419 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004420 mListeners.finishBroadcast();
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004421 return true;
4422 }
4423 case MSG_METERED_IFACES_CHANGED: {
4424 final String[] meteredIfaces = (String[]) msg.obj;
4425 final int length = mListeners.beginBroadcast();
4426 for (int i = 0; i < length; i++) {
4427 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004428 dispatchMeteredIfacesChanged(listener, meteredIfaces);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004429 }
4430 mListeners.finishBroadcast();
4431 return true;
4432 }
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004433 case MSG_LIMIT_REACHED: {
4434 final String iface = (String) msg.obj;
4435
Felipe Lemef0823852016-06-08 13:43:08 -07004436 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004437 if (mMeteredIfaces.contains(iface)) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004438 // force stats update to make sure we have
4439 // numbers that caused alert to trigger.
4440 mNetworkStats.forceUpdate();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004441
Felipe Lemef0823852016-06-08 13:43:08 -07004442 updateNetworkEnabledNL();
4443 updateNotificationsNL();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004444 }
4445 }
4446 return true;
4447 }
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004448 case MSG_RESTRICT_BACKGROUND_CHANGED: {
4449 final boolean restrictBackground = msg.arg1 != 0;
4450 final int length = mListeners.beginBroadcast();
4451 for (int i = 0; i < length; i++) {
4452 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004453 dispatchRestrictBackgroundChanged(listener, restrictBackground);
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004454 }
4455 mListeners.finishBroadcast();
Felipe Leme9778f762016-01-27 14:46:39 -08004456 final Intent intent =
4457 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4458 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4459 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4460 return true;
4461 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004462 case MSG_POLICIES_CHANGED: {
Felipe Leme9778f762016-01-27 14:46:39 -08004463 final int uid = msg.arg1;
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004464 final int policy = msg.arg2;
Felipe Leme57e3d312016-08-23 14:42:52 -07004465 final Boolean notifyApp = (Boolean) msg.obj;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004466 // First notify internal listeners...
Felipe Leme57e3d312016-08-23 14:42:52 -07004467 final int length = mListeners.beginBroadcast();
4468 for (int i = 0; i < length; i++) {
4469 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004470 dispatchUidPoliciesChanged(listener, uid, policy);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004471 }
4472 mListeners.finishBroadcast();
Felipe Leme57e3d312016-08-23 14:42:52 -07004473 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
4474 if (notifyApp.booleanValue()) {
4475 broadcastRestrictBackgroundChanged(uid, notifyApp);
4476 }
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004477 return true;
4478 }
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004479 case MSG_ADVISE_PERSIST_THRESHOLD: {
4480 final long lowestRule = (Long) msg.obj;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004481 // make sure stats are recorded frequently enough; we aim
4482 // for 2MB threshold for 2GB/month rules.
4483 final long persistThreshold = lowestRule / 1000;
4484 mNetworkStats.advisePersistThreshold(persistThreshold);
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004485 return true;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004486 }
Amith Yamasani3646cbd2016-04-13 14:04:53 -07004487 case MSG_UPDATE_INTERFACE_QUOTA: {
4488 removeInterfaceQuota((String) msg.obj);
4489 // int params need to be stitched back into a long
4490 setInterfaceQuota((String) msg.obj,
4491 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
4492 return true;
4493 }
4494 case MSG_REMOVE_INTERFACE_QUOTA: {
4495 removeInterfaceQuota((String) msg.obj);
4496 return true;
4497 }
Felipe Leme03e95e22016-09-09 09:25:31 -07004498 case MSG_RESET_FIREWALL_RULES_BY_UID: {
4499 resetUidFirewallRules(msg.arg1);
4500 return true;
4501 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004502 case MSG_SUBSCRIPTION_OVERRIDE: {
4503 final int overrideMask = msg.arg1;
4504 final int overrideValue = msg.arg2;
4505 final int subId = (int) msg.obj;
4506 final int length = mListeners.beginBroadcast();
4507 for (int i = 0; i < length; i++) {
4508 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4509 dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue);
4510 }
4511 mListeners.finishBroadcast();
4512 return true;
4513 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004514 case MSG_METERED_RESTRICTED_PACKAGES_CHANGED: {
4515 final int userId = msg.arg1;
4516 final Set<String> packageNames = (Set<String>) msg.obj;
4517 setMeteredRestrictedPackagesInternal(packageNames, userId);
4518 return true;
4519 }
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07004520 case MSG_SET_NETWORK_TEMPLATE_ENABLED: {
4521 final NetworkTemplate template = (NetworkTemplate) msg.obj;
4522 final boolean enabled = msg.arg1 != 0;
4523 setNetworkTemplateEnabledInner(template, enabled);
4524 return true;
4525 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004526 default: {
4527 return false;
Jeff Sharkeyaf11d482011-06-13 00:14:31 -07004528 }
4529 }
4530 }
Makoto Onuki8e777332017-03-28 11:25:47 -07004531 };
4532
4533 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
4534 @Override
4535 public boolean handleMessage(Message msg) {
4536 switch (msg.what) {
4537 case UID_MSG_STATE_CHANGED: {
4538 final int uid = msg.arg1;
4539 final int procState = msg.arg2;
4540 final long procStateSeq = (Long) msg.obj;
4541
4542 handleUidChanged(uid, procState, procStateSeq);
4543 return true;
4544 }
4545 case UID_MSG_GONE: {
4546 final int uid = msg.arg1;
4547 handleUidGone(uid);
4548 return true;
4549 }
4550 default: {
4551 return false;
4552 }
4553 }
4554 }
Felipe Leme57e3d312016-08-23 14:42:52 -07004555
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004556 };
Jeff Sharkey22c055e2011-06-12 21:13:51 -07004557
Makoto Onuki8e777332017-03-28 11:25:47 -07004558 void handleUidChanged(int uid, int procState, long procStateSeq) {
4559 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
4560 try {
4561 synchronized (mUidRulesFirstLock) {
4562 // We received a uid state change callback, add it to the history so that it
4563 // will be useful for debugging.
Sudheer Shanka352dc572017-09-22 17:09:38 -07004564 mLogger.uidStateChanged(uid, procState, procStateSeq);
Makoto Onuki8e777332017-03-28 11:25:47 -07004565 // Now update the network policy rules as per the updated uid state.
4566 updateUidStateUL(uid, procState);
4567 // Updating the network rules is done, so notify AMS about this.
4568 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
4569 }
4570 } finally {
4571 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4572 }
4573 }
4574
4575 void handleUidGone(int uid) {
4576 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
4577 try {
4578 synchronized (mUidRulesFirstLock) {
4579 removeUidStateUL(uid);
4580 }
4581 } finally {
4582 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4583 }
4584 }
4585
Felipe Leme57e3d312016-08-23 14:42:52 -07004586 private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
4587 final PackageManager pm = mContext.getPackageManager();
4588 final String[] packages = pm.getPackagesForUid(uid);
4589 if (packages != null) {
4590 final int userId = UserHandle.getUserId(uid);
4591 for (String packageName : packages) {
4592 final Intent intent =
4593 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4594 intent.setPackage(packageName);
4595 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4596 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
4597 }
4598 }
4599 }
4600
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004601 private void setInterfaceQuotaAsync(String iface, long quotaBytes) {
4602 // long quotaBytes split up into two ints to fit in message
4603 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, (int) (quotaBytes >> 32),
4604 (int) (quotaBytes & 0xFFFFFFFF), iface).sendToTarget();
4605 }
4606
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004607 private void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004608 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004609 mNetworkManager.setInterfaceQuota(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004610 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004611 Log.wtf(TAG, "problem setting interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004612 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004613 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004614 }
4615 }
4616
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004617 private void removeInterfaceQuotaAsync(String iface) {
4618 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface).sendToTarget();
4619 }
4620
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004621 private void removeInterfaceQuota(String iface) {
4622 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004623 mNetworkManager.removeInterfaceQuota(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004624 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004625 Log.wtf(TAG, "problem removing interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004626 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004627 // ignored; service lives in system_server
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004628 }
4629 }
4630
Felipe Leme70c57c22016-03-29 10:45:13 -07004631 private void setMeteredNetworkBlacklist(int uid, boolean enable) {
4632 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004633 try {
Felipe Leme70c57c22016-03-29 10:45:13 -07004634 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004635 } catch (IllegalStateException e) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004636 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
4637 } catch (RemoteException e) {
4638 // ignored; service lives in system_server
4639 }
4640 }
4641
4642 private void setMeteredNetworkWhitelist(int uid, boolean enable) {
4643 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
4644 try {
4645 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
4646 } catch (IllegalStateException e) {
4647 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004648 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004649 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004650 }
4651 }
4652
Felipe Lemebc853dd2016-09-08 13:26:55 -07004653 private static final int CHAIN_TOGGLE_NONE = 0;
4654 private static final int CHAIN_TOGGLE_ENABLE = 1;
4655 private static final int CHAIN_TOGGLE_DISABLE = 2;
4656 @Retention(RetentionPolicy.SOURCE)
4657 @IntDef(flag = false, value = {
4658 CHAIN_TOGGLE_NONE,
4659 CHAIN_TOGGLE_ENABLE,
4660 CHAIN_TOGGLE_DISABLE
4661 })
4662 public @interface ChainToggleType {
4663 }
4664
4665 /**
4666 * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004667 * {@link #enableFirewallChainUL(int, boolean)} synchronously.
Felipe Lemebc853dd2016-09-08 13:26:55 -07004668 *
4669 * @param chain firewall chain.
4670 * @param uidRules new UID rules; if {@code null}, only toggles chain state.
4671 * @param toggle whether the chain should be enabled, disabled, or not changed.
4672 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004673 @GuardedBy("mUidRulesFirstLock")
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004674 private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,
Felipe Lemebc853dd2016-09-08 13:26:55 -07004675 @ChainToggleType int toggle) {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004676 if (uidRules != null) {
4677 setUidFirewallRulesUL(chain, uidRules);
4678 }
4679 if (toggle != CHAIN_TOGGLE_NONE) {
4680 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
4681 }
Felipe Lemebc853dd2016-09-08 13:26:55 -07004682 }
4683
Amith Yamasani15e472352015-04-24 19:06:07 -07004684 /**
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004685 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
4686 * here to netd. It will clean up dead rules and make sure the target chain only contains rules
4687 * specified here.
Amith Yamasani15e472352015-04-24 19:06:07 -07004688 */
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004689 private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004690 try {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004691 int size = uidRules.size();
4692 int[] uids = new int[size];
4693 int[] rules = new int[size];
4694 for(int index = size - 1; index >= 0; --index) {
4695 uids[index] = uidRules.keyAt(index);
4696 rules[index] = uidRules.valueAt(index);
4697 }
4698 mNetworkManager.setFirewallUidRules(chain, uids, rules);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004699 mLogger.firewallRulesChanged(chain, uids, rules);
Amith Yamasani15e472352015-04-24 19:06:07 -07004700 } catch (IllegalStateException e) {
4701 Log.wtf(TAG, "problem setting firewall uid rules", e);
4702 } catch (RemoteException e) {
4703 // ignored; service lives in system_server
4704 }
4705 }
4706
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004707 /**
4708 * Add or remove a uid to the firewall blacklist for all network ifaces.
4709 */
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004710 private void setUidFirewallRule(int chain, int uid, int rule) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004711 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4712 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4713 "setUidFirewallRule: " + chain + "/" + uid + "/" + rule);
Jeff Sharkeydc988062015-09-14 10:09:47 -07004714 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004715 try {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004716 if (chain == FIREWALL_CHAIN_DOZABLE) {
4717 mUidFirewallDozableRules.put(uid, rule);
4718 } else if (chain == FIREWALL_CHAIN_STANDBY) {
4719 mUidFirewallStandbyRules.put(uid, rule);
4720 } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
4721 mUidFirewallPowerSaveRules.put(uid, rule);
4722 }
4723
4724 try {
4725 mNetworkManager.setFirewallUidRule(chain, uid, rule);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004726 mLogger.uidFirewallRuleChanged(chain, uid, rule);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004727 } catch (IllegalStateException e) {
4728 Log.wtf(TAG, "problem setting firewall uid rules", e);
4729 } catch (RemoteException e) {
4730 // ignored; service lives in system_server
4731 }
4732 } finally {
4733 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004734 }
4735 }
4736
4737 /**
4738 * Add or remove a uid to the firewall blacklist for all network ifaces.
4739 */
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004740 @GuardedBy("mUidRulesFirstLock")
Felipe Lemef0823852016-06-08 13:43:08 -07004741 private void enableFirewallChainUL(int chain, boolean enable) {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004742 if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
4743 mFirewallChainStates.get(chain) == enable) {
4744 // All is the same, nothing to do.
4745 return;
4746 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004747 mFirewallChainStates.put(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004748 try {
4749 mNetworkManager.setFirewallChainEnabled(chain, enable);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004750 mLogger.firewallChainEnabled(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004751 } catch (IllegalStateException e) {
4752 Log.wtf(TAG, "problem enable firewall chain", e);
4753 } catch (RemoteException e) {
4754 // ignored; service lives in system_server
4755 }
4756 }
4757
Felipe Leme03e95e22016-09-09 09:25:31 -07004758 /**
4759 * Resets all firewall rules associated with an UID.
4760 */
4761 private void resetUidFirewallRules(int uid) {
4762 try {
4763 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
4764 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
4765 mNetworkManager
4766 .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
4767 mNetworkManager.setUidMeteredNetworkWhitelist(uid, false);
4768 mNetworkManager.setUidMeteredNetworkBlacklist(uid, false);
4769 } catch (IllegalStateException e) {
4770 Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
4771 } catch (RemoteException e) {
4772 // ignored; service lives in system_server
4773 }
4774 }
4775
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004776 @Deprecated
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004777 private long getTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004778 return getNetworkTotalBytes(template, start, end);
4779 }
4780
4781 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004782 try {
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -07004783 return mNetworkStats.getNetworkTotalBytes(template, start, end);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004784 } catch (RuntimeException e) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004785 Slog.w(TAG, "Failed to read network stats: " + e);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004786 return 0;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004787 }
4788 }
4789
4790 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
4791 try {
4792 return mNetworkStats.getNetworkUidBytes(template, start, end);
4793 } catch (RuntimeException e) {
4794 Slog.w(TAG, "Failed to read network stats: " + e);
4795 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004796 }
4797 }
4798
Jeff Sharkey8c1dc722012-05-04 14:49:37 -07004799 private boolean isBandwidthControlEnabled() {
4800 final long token = Binder.clearCallingIdentity();
4801 try {
4802 return mNetworkManager.isBandwidthControlEnabled();
4803 } catch (RemoteException e) {
4804 // ignored; service lives in system_server
4805 return false;
4806 } finally {
4807 Binder.restoreCallingIdentity(token);
4808 }
4809 }
4810
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07004811 private static Intent buildAllowBackgroundDataIntent() {
4812 return new Intent(ACTION_ALLOW_BACKGROUND);
4813 }
4814
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004815 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
4816 final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07004817 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4818 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4819 return intent;
4820 }
4821
4822 private static Intent buildSnoozeRapidIntent(NetworkTemplate template) {
4823 final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
4824 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004825 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4826 return intent;
4827 }
4828
Wei Liu546cb772016-07-21 16:19:01 -07004829 private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004830 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004831 intent.setComponent(ComponentName.unflattenFromString(
4832 res.getString(R.string.config_networkOverLimitComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004833 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4834 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4835 return intent;
4836 }
4837
Wei Liu546cb772016-07-21 16:19:01 -07004838 private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004839 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004840 intent.setComponent(ComponentName.unflattenFromString(
4841 res.getString(R.string.config_dataUsageSummaryComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004842 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4843 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4844 return intent;
4845 }
4846
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -08004847 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004848 void addIdleHandler(IdleHandler handler) {
Jeff Sharkey163e6442011-10-31 16:37:52 -07004849 mHandler.getLooper().getQueue().addIdleHandler(handler);
4850 }
4851
Andreas Gampeaae5aa32018-07-20 12:55:38 -07004852 @GuardedBy("mUidRulesFirstLock")
jackqdyulei29c82ab2017-03-10 14:09:16 -08004853 @VisibleForTesting
Sudheer Shanka8ab22992018-11-29 00:08:58 -08004854 void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
jackqdyulei29c82ab2017-03-10 14:09:16 -08004855 mRestrictBackgroundPowerState = result;
4856
4857 boolean restrictBackground = result.batterySaverEnabled;
4858 boolean shouldInvokeRestrictBackground;
4859 // store the temporary mRestrictBackgroundChangedInBsm and update it at last
4860 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
4861
4862 if (result.globalBatterySaverEnabled) {
4863 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
4864 // turn it on.
4865 shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
4866 mRestrictBackgroundBeforeBsm = mRestrictBackground;
4867 localRestrictBgChangedInBsm = false;
4868 } else {
4869 // Try to restore the restrictBackground if it doesn't change in bsm
4870 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
4871 restrictBackground = mRestrictBackgroundBeforeBsm;
4872 }
4873
4874 if (shouldInvokeRestrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07004875 setRestrictBackgroundUL(restrictBackground);
jackqdyulei29c82ab2017-03-10 14:09:16 -08004876 }
4877
4878 // Change it at last so setRestrictBackground() won't affect this variable
4879 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
4880 }
4881
Jeff Sharkey1b861272011-05-22 00:34:52 -07004882 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
4883 final int size = source.size();
4884 for (int i = 0; i < size; i++) {
4885 target.put(source.keyAt(i), true);
4886 }
4887 }
4888
Stuart Scottf1fb3972015-04-02 18:00:02 -07004889 @Override
4890 public void factoryReset(String subscriber) {
4891 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
4892
Stuart Scotte3e314d2015-04-20 14:07:45 -07004893 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4894 return;
4895 }
4896
Stuart Scottf1fb3972015-04-02 18:00:02 -07004897 // Turn mobile data limit off
Stuart Scott9a9a1d92015-04-20 11:33:06 -07004898 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Stuart Scottf1fb3972015-04-02 18:00:02 -07004899 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
4900 for (NetworkPolicy policy : policies) {
4901 if (policy.template.equals(template)) {
4902 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
4903 policy.inferred = false;
4904 policy.clearSnooze();
4905 }
4906 }
4907 setNetworkPolicies(policies);
4908
4909 // Turn restrict background data off
4910 setRestrictBackground(false);
4911
Stuart Scotte3e314d2015-04-20 14:07:45 -07004912 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
4913 // Remove app's "restrict background data" flag
4914 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
4915 setUidPolicy(uid, POLICY_NONE);
4916 }
Stuart Scottf1fb3972015-04-02 18:00:02 -07004917 }
4918 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08004919
Sudheer Shankab8f23162017-08-04 13:30:10 -07004920 @Override
4921 public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
Makoto Onuki49392d32018-04-11 13:51:02 -07004922 final long startTime = mStatLogger.getTime();
4923
Sudheer Shankab8f23162017-08-04 13:30:10 -07004924 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004925 final int uidRules;
4926 final boolean isBackgroundRestricted;
4927 synchronized (mUidRulesFirstLock) {
4928 uidRules = mUidRules.get(uid, RULE_NONE);
4929 isBackgroundRestricted = mRestrictBackground;
4930 }
junyulai05986c62018-08-07 19:50:45 +08004931 final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
4932 isBackgroundRestricted, mLogger);
4933
4934 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
4935
4936 return ret;
4937 }
4938
4939 private static boolean isSystem(int uid) {
4940 return uid < Process.FIRST_APPLICATION_UID;
4941 }
4942
4943 static boolean isUidNetworkingBlockedInternal(int uid, int uidRules, boolean isNetworkMetered,
4944 boolean isBackgroundRestricted, @Nullable NetworkPolicyLogger logger) {
4945 final int reason;
4946 // Networks are never blocked for system components
4947 if (isSystem(uid)) {
4948 reason = NTWK_ALLOWED_SYSTEM;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004949 }
junyulai05986c62018-08-07 19:50:45 +08004950 else if (hasRule(uidRules, RULE_REJECT_ALL)) {
4951 reason = NTWK_BLOCKED_POWER;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004952 }
junyulai05986c62018-08-07 19:50:45 +08004953 else if (!isNetworkMetered) {
4954 reason = NTWK_ALLOWED_NON_METERED;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004955 }
junyulai05986c62018-08-07 19:50:45 +08004956 else if (hasRule(uidRules, RULE_REJECT_METERED)) {
4957 reason = NTWK_BLOCKED_BLACKLIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004958 }
junyulai05986c62018-08-07 19:50:45 +08004959 else if (hasRule(uidRules, RULE_ALLOW_METERED)) {
4960 reason = NTWK_ALLOWED_WHITELIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004961 }
junyulai05986c62018-08-07 19:50:45 +08004962 else if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
4963 reason = NTWK_ALLOWED_TMP_WHITELIST;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004964 }
junyulai05986c62018-08-07 19:50:45 +08004965 else if (isBackgroundRestricted) {
4966 reason = NTWK_BLOCKED_BG_RESTRICT;
4967 }
4968 else {
4969 reason = NTWK_ALLOWED_DEFAULT;
4970 }
4971
4972 final boolean blocked;
4973 switch(reason) {
4974 case NTWK_ALLOWED_DEFAULT:
4975 case NTWK_ALLOWED_NON_METERED:
4976 case NTWK_ALLOWED_TMP_WHITELIST:
4977 case NTWK_ALLOWED_WHITELIST:
4978 case NTWK_ALLOWED_SYSTEM:
4979 blocked = false;
4980 break;
4981 case NTWK_BLOCKED_POWER:
4982 case NTWK_BLOCKED_BLACKLIST:
4983 case NTWK_BLOCKED_BG_RESTRICT:
4984 blocked = true;
4985 break;
4986 default:
4987 throw new IllegalArgumentException();
4988 }
4989 if (logger != null) {
4990 logger.networkBlocked(uid, reason);
4991 }
4992
4993 return blocked;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004994 }
4995
Felipe Lemed17fda42016-04-29 11:12:45 -07004996 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
4997
4998 @Override
4999 public void resetUserState(int userId) {
Felipe Lemef0823852016-06-08 13:43:08 -07005000 synchronized (mUidRulesFirstLock) {
5001 boolean changed = removeUserStateUL(userId, false);
5002 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
Felipe Lemed17fda42016-04-29 11:12:45 -07005003 if (changed) {
Felipe Lemef0823852016-06-08 13:43:08 -07005004 synchronized (mNetworkPoliciesSecondLock) {
5005 writePolicyAL();
5006 }
Felipe Lemed17fda42016-04-29 11:12:45 -07005007 }
5008 }
5009 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005010
5011 /**
5012 * @return true if the given uid is restricted from doing networking on metered networks.
5013 */
5014 @Override
5015 public boolean isUidRestrictedOnMeteredNetworks(int uid) {
5016 final int uidRules;
5017 final boolean isBackgroundRestricted;
5018 synchronized (mUidRulesFirstLock) {
5019 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
5020 isBackgroundRestricted = mRestrictBackground;
5021 }
5022 return isBackgroundRestricted
5023 && !hasRule(uidRules, RULE_ALLOW_METERED)
5024 && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
5025 }
5026
5027 /**
5028 * @return true if networking is blocked on the given interface for the given uid according
5029 * to current networking policies.
5030 */
5031 @Override
5032 public boolean isUidNetworkingBlocked(int uid, String ifname) {
Makoto Onuki49392d32018-04-11 13:51:02 -07005033 final long startTime = mStatLogger.getTime();
5034
junyulai05986c62018-08-07 19:50:45 +08005035 final int uidRules;
5036 final boolean isBackgroundRestricted;
5037 synchronized (mUidRulesFirstLock) {
5038 uidRules = mUidRules.get(uid, RULE_NONE);
5039 isBackgroundRestricted = mRestrictBackground;
5040 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005041 final boolean isNetworkMetered;
Sudheer Shankab8f23162017-08-04 13:30:10 -07005042 synchronized (mNetworkPoliciesSecondLock) {
5043 isNetworkMetered = mMeteredIfaces.contains(ifname);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005044 }
junyulai05986c62018-08-07 19:50:45 +08005045 final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
5046 isBackgroundRestricted, mLogger);
Makoto Onuki49392d32018-04-11 13:51:02 -07005047
5048 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
5049
5050 return ret;
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005051 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07005052
5053 @Override
5054 public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
5055 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07005056 mLogger.tempPowerSaveWlChanged(appId, added);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07005057 if (added) {
5058 mPowerSaveTempWhitelistAppIds.put(appId, true);
5059 } else {
5060 mPowerSaveTempWhitelistAppIds.delete(appId);
5061 }
5062 updateRulesForTempWhitelistChangeUL(appId);
5063 }
5064 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005065
5066 @Override
5067 public SubscriptionPlan getSubscriptionPlan(Network network) {
5068 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09005069 final int subId = getSubIdLocked(network);
5070 return getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09005071 }
5072 }
5073
5074 @Override
Jeff Sharkey146bb332018-04-18 15:42:57 -06005075 public SubscriptionPlan getSubscriptionPlan(NetworkTemplate template) {
5076 synchronized (mNetworkPoliciesSecondLock) {
5077 final int subId = findRelevantSubIdNL(template);
5078 return getPrimarySubscriptionPlanLocked(subId);
5079 }
5080 }
5081
5082 @Override
Jeff Sharkey9252b342018-01-19 07:58:35 +09005083 public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005084 final long quotaBytes;
Jeff Sharkey9252b342018-01-19 07:58:35 +09005085 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005086 quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09005087 OPPORTUNISTIC_QUOTA_UNKNOWN);
Jeff Sharkey9252b342018-01-19 07:58:35 +09005088 }
Jeff Sharkey36b414b2018-03-30 11:00:03 -06005089 if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
5090 return OPPORTUNISTIC_QUOTA_UNKNOWN;
5091 }
5092
5093 if (quotaType == QUOTA_TYPE_JOBS) {
5094 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
5095 NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
5096 } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
5097 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
5098 NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
5099 } else {
5100 return OPPORTUNISTIC_QUOTA_UNKNOWN;
5101 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005102 }
Sudheer Shankac53c47f2018-01-16 12:01:00 -08005103
5104 @Override
5105 public void onAdminDataAvailable() {
5106 mAdminDataAvailableLatch.countDown();
5107 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005108
5109 @Override
Kweku Adamsa9e55bc2018-11-19 14:59:15 -08005110 public void setAppIdleWhitelist(int uid, boolean shouldWhitelist) {
5111 NetworkPolicyManagerService.this.setAppIdleWhitelist(uid, shouldWhitelist);
5112 }
5113
5114 @Override
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005115 public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) {
5116 setMeteredRestrictedPackagesInternal(packageNames, userId);
5117 }
5118
5119 @Override
5120 public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) {
5121 mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
5122 userId, 0, packageNames).sendToTarget();
5123 }
5124 }
5125
5126 private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
5127 synchronized (mUidRulesFirstLock) {
5128 final Set<Integer> newRestrictedUids = new ArraySet<>();
5129 for (String packageName : packageNames) {
5130 final int uid = getUidForPackage(packageName, userId);
5131 if (uid >= 0) {
5132 newRestrictedUids.add(uid);
5133 }
5134 }
5135 final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId);
5136 mMeteredRestrictedUids.put(userId, newRestrictedUids);
5137 handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids);
5138 mLogger.meteredRestrictedPkgsChanged(newRestrictedUids);
5139 }
5140 }
5141
5142 private int getUidForPackage(String packageName, int userId) {
5143 try {
5144 return mContext.getPackageManager().getPackageUidAsUser(packageName,
5145 PackageManager.MATCH_KNOWN_PACKAGES, userId);
5146 } catch (NameNotFoundException e) {
5147 return -1;
5148 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09005149 }
5150
5151 private int parseSubId(NetworkState state) {
5152 // TODO: moved to using a legitimate NetworkSpecifier instead of string parsing
5153 int subId = INVALID_SUBSCRIPTION_ID;
5154 if (state != null && state.networkCapabilities != null
5155 && state.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
5156 NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier();
5157 if (spec instanceof StringNetworkSpecifier) {
5158 try {
5159 subId = Integer.parseInt(((StringNetworkSpecifier) spec).specifier);
5160 } catch (NumberFormatException e) {
5161 }
5162 }
5163 }
5164 return subId;
5165 }
5166
Andreas Gampea36dc622018-02-05 17:19:22 -08005167 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey9252b342018-01-19 07:58:35 +09005168 private int getSubIdLocked(Network network) {
5169 return mNetIdToSubId.get(network.netId, INVALID_SUBSCRIPTION_ID);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005170 }
5171
Andreas Gampea36dc622018-02-05 17:19:22 -08005172 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey2e471452018-01-19 18:02:47 +09005173 private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) {
5174 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06005175 if (!ArrayUtils.isEmpty(plans)) {
5176 for (SubscriptionPlan plan : plans) {
5177 if (plan.getCycleRule().isRecurring()) {
5178 // Recurring plans will always have an active cycle
5179 return plan;
5180 } else {
5181 // Non-recurring plans need manual test for active cycle
5182 final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
5183 if (cycle.contains(ZonedDateTime.now(mClock))) {
5184 return plan;
5185 }
5186 }
5187 }
5188 }
5189 return null;
Jeff Sharkey2e471452018-01-19 18:02:47 +09005190 }
5191
Sudheer Shankac53c47f2018-01-16 12:01:00 -08005192 /**
5193 * This will only ever be called once - during device boot.
5194 */
5195 private void waitForAdminData() {
5196 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
5197 ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch,
5198 WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data");
5199 }
5200 }
5201
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005202 private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids,
5203 Set<Integer> newRestrictedUids) {
Sudheer Shanka1536fb62018-07-05 11:52:36 -07005204 if (!mNetworkManagerReady) {
5205 return;
5206 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005207 if (oldRestrictedUids == null) {
5208 for (int uid : newRestrictedUids) {
5209 updateRulesForDataUsageRestrictionsUL(uid);
5210 }
5211 return;
5212 }
5213 for (int uid : oldRestrictedUids) {
5214 if (!newRestrictedUids.contains(uid)) {
5215 updateRulesForDataUsageRestrictionsUL(uid);
5216 }
5217 }
5218 for (int uid : newRestrictedUids) {
5219 if (!oldRestrictedUids.contains(uid)) {
5220 updateRulesForDataUsageRestrictionsUL(uid);
5221 }
5222 }
5223 }
5224
Andreas Gampeaae5aa32018-07-20 12:55:38 -07005225 @GuardedBy("mUidRulesFirstLock")
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08005226 private boolean isRestrictedByAdminUL(int uid) {
5227 final Set<Integer> restrictedUids = mMeteredRestrictedUids.get(
5228 UserHandle.getUserId(uid));
5229 return restrictedUids != null && restrictedUids.contains(uid);
5230 }
5231
Hugo Benichi938ab4f2017-02-11 17:04:43 +09005232 private static boolean hasRule(int uidRules, int rule) {
5233 return (uidRules & rule) != 0;
5234 }
5235
Jeff Sharkey2e471452018-01-19 18:02:47 +09005236 private static @NonNull NetworkState[] defeatNullable(@Nullable NetworkState[] val) {
5237 return (val != null) ? val : new NetworkState[0];
5238 }
5239
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06005240 private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle,
5241 String key, boolean defaultValue) {
5242 return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
5243 }
5244
Chris Wren193ae6b2017-03-31 15:17:11 -04005245 private class NotificationId {
5246 private final String mTag;
5247 private final int mId;
5248
5249 NotificationId(NetworkPolicy policy, int type) {
5250 mTag = buildNotificationTag(policy, type);
5251 mId = type;
5252 }
5253
5254 @Override
5255 public boolean equals(Object o) {
5256 if (this == o) return true;
5257 if (!(o instanceof NotificationId)) return false;
5258 NotificationId that = (NotificationId) o;
5259 return Objects.equals(mTag, that.mTag);
5260 }
5261
5262 @Override
5263 public int hashCode() {
5264 return Objects.hash(mTag);
5265 }
5266
5267 /**
5268 * Build unique tag that identifies an active {@link NetworkPolicy}
5269 * notification of a specific type, like {@link #TYPE_LIMIT}.
5270 */
5271 private String buildNotificationTag(NetworkPolicy policy, int type) {
5272 return TAG + ":" + policy.template.hashCode() + ":" + type;
5273 }
5274
5275 public String getTag() {
5276 return mTag;
5277 }
5278
5279 public int getId() {
5280 return mId;
5281 }
5282 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07005283}